Message ID | 20250227-04-gpio-irq-threecell-v1-2-4ae4d91baadc@gentoo.org (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | gpio: irq: support describing three-cell interrupts | expand |
Context | Check | Description |
---|---|---|
bjorn/pre-ci_am | success | Success |
bjorn/build-rv32-defconfig | fail | build-rv32-defconfig |
bjorn/build-rv64-clang-allmodconfig | fail | build-rv64-clang-allmodconfig |
bjorn/build-rv64-gcc-allmodconfig | fail | build-rv64-gcc-allmodconfig |
bjorn/build-rv64-nommu-k210-defconfig | fail | build-rv64-nommu-k210-defconfig |
bjorn/build-rv64-nommu-k210-virt | success | build-rv64-nommu-k210-virt |
bjorn/checkpatch | warning | checkpatch |
bjorn/dtb-warn-rv64 | success | dtb-warn-rv64 |
bjorn/header-inline | success | header-inline |
bjorn/kdoc | success | kdoc |
bjorn/module-param | success | module-param |
bjorn/verify-fixes | success | verify-fixes |
bjorn/verify-signedoff | success | verify-signedoff |
Hi Yixun, thanks for working so hard on this! I'm really happy to see the threecell support integrated into gpiolib. On Thu, Feb 27, 2025 at 12:25 PM Yixun Lan <dlan@gentoo.org> wrote: > gpio irq which using three-cell scheme should always call > instance_match() function to find the correct irqdomain. > > Signed-off-by: Yixun Lan <dlan@gentoo.org> > --- > The select() function will be called with !DOMAIN_BUS_ANY, > kernel/irq/irqdomain.c:556: if (h->ops->select && bus_token != DOMAIN_BUS_ANY) > > so vendor gpio driver need to explicitly set bus_token, something like: > > drivers/gpio/gpio-spacemit-k1.c > irq_domain_update_bus_token(girq->domain, DOMAIN_BUS_WIRED); > > I hope this is a feasible way.. Yes this looks fair, I think you can put the description into the commit message. > /* We support standard DT translation */ > - if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { > + if (is_of_node(fwspec->fwnode) && fwspec->param_count <= 3) > return irq_domain_translate_twocell(d, fwspec, hwirq, type); > - } This looks good. > +static int gpiochip_irq_select(struct irq_domain *d, struct irq_fwspec *fwspec, > + enum irq_domain_bus_token bus_token) > +{ > + struct fwnode_handle *fwnode = fwspec->fwnode; > + struct gpio_chip *gc = d->host_data; > + unsigned int index = fwspec->param[0]; > + > + if ((gc->of_gpio_n_cells == 3) && gc->of_node_instance_match) > + return gc->of_node_instance_match(gc, index); We need to hide the OF-specific things into gpiolib-of.c|h so systems not using OF does not need to see it. Something like: if (fwspec->param_count == 3) { if (is_of_node(fwnode)) return of_gpiochip_instance_match(gc, index); /* Add other threeparam handlers here */ } Then add of_gpiochip_instance_match() into gpiolib-of.h as a static inline (no need to an entire extern function...) static inline bool of_gpiochip_instance_match(struct gpio_chip *gc, int index) { if ((gc->of_gpio_n_cells == 3) && gc->of_node_instance_match) return gc->of_node_instance_match(gc, index); } And also an empty stub for !CONFIG_OF_GPIO so we get this compiled out if OF is not configured in. Yours, Linus Walleij
Hi Linus Walleij: On 10:11 Fri 28 Feb , Linus Walleij wrote: > Hi Yixun, > > thanks for working so hard on this! > > I'm really happy to see the threecell support integrated into gpiolib. > > On Thu, Feb 27, 2025 at 12:25 PM Yixun Lan <dlan@gentoo.org> wrote: > > > gpio irq which using three-cell scheme should always call > > instance_match() function to find the correct irqdomain. > > > > Signed-off-by: Yixun Lan <dlan@gentoo.org> > > --- > > The select() function will be called with !DOMAIN_BUS_ANY, > > kernel/irq/irqdomain.c:556: if (h->ops->select && bus_token != DOMAIN_BUS_ANY) > > > > so vendor gpio driver need to explicitly set bus_token, something like: > > > > drivers/gpio/gpio-spacemit-k1.c > > irq_domain_update_bus_token(girq->domain, DOMAIN_BUS_WIRED); > > > > I hope this is a feasible way.. > > Yes this looks fair, I think you can put the description into the > commit message. > ok, will do > > /* We support standard DT translation */ > > - if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { > > + if (is_of_node(fwspec->fwnode) && fwspec->param_count <= 3) > > return irq_domain_translate_twocell(d, fwspec, hwirq, type); > > - } > > This looks good. > > > +static int gpiochip_irq_select(struct irq_domain *d, struct irq_fwspec *fwspec, > > + enum irq_domain_bus_token bus_token) > > +{ > > + struct fwnode_handle *fwnode = fwspec->fwnode; > > + struct gpio_chip *gc = d->host_data; > > + unsigned int index = fwspec->param[0]; > > + > > + if ((gc->of_gpio_n_cells == 3) && gc->of_node_instance_match) > > + return gc->of_node_instance_match(gc, index); > > We need to hide the OF-specific things into gpiolib-of.c|h so systems > not using OF does not need to see it. > > Something like: > > if (fwspec->param_count == 3) { > if (is_of_node(fwnode)) > return of_gpiochip_instance_match(gc, index); > /* Add other threeparam handlers here */ not sure if non OF-specific driver will also support threecells mode? we probably can adjust when it really does, so now I would simply make it if (fwspec->param_count == 3 && is_of_node(fwnode)) return of_gpiochip_instance_match(gc, index); > } > > Then add of_gpiochip_instance_match() into gpiolib-of.h as a > static inline (no need to an entire extern function...) > > static inline bool of_gpiochip_instance_match(struct gpio_chip *gc, int index) > { > if ((gc->of_gpio_n_cells == 3) && gc->of_node_instance_match) > return gc->of_node_instance_match(gc, index); > } > > And also an empty stub for !CONFIG_OF_GPIO so we get this compiled > out if OF is not configured in. > ok, I got your idea, thanks
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 679ed764cb143c4b3357106de1570e8d38441372..7912ae1d049d7c2574400c6ff53405d130521773 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1450,9 +1450,8 @@ static int gpiochip_hierarchy_irq_domain_translate(struct irq_domain *d, unsigned int *type) { /* We support standard DT translation */ - if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { + if (is_of_node(fwspec->fwnode) && fwspec->param_count <= 3) return irq_domain_translate_twocell(d, fwspec, hwirq, type); - } /* This is for board files and others not using DT */ if (is_fwnode_irqchip(fwspec->fwnode)) { @@ -1754,9 +1753,25 @@ static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) irq_set_chip_data(irq, NULL); } +static int gpiochip_irq_select(struct irq_domain *d, struct irq_fwspec *fwspec, + enum irq_domain_bus_token bus_token) +{ + struct fwnode_handle *fwnode = fwspec->fwnode; + struct gpio_chip *gc = d->host_data; + unsigned int index = fwspec->param[0]; + + if ((gc->of_gpio_n_cells == 3) && gc->of_node_instance_match) + return gc->of_node_instance_match(gc, index); + + /* Fallback for twocells */ + return ((fwnode != NULL) && (d->fwnode == fwnode) && + (d->bus_token == bus_token)); +} + static const struct irq_domain_ops gpiochip_domain_ops = { .map = gpiochip_irq_map, .unmap = gpiochip_irq_unmap, + .select = gpiochip_irq_select, /* Virtually all GPIO irqchips are twocell:ed */ .xlate = irq_domain_xlate_twocell, };
gpio irq which using three-cell scheme should always call instance_match() function to find the correct irqdomain. Signed-off-by: Yixun Lan <dlan@gentoo.org> --- The select() function will be called with !DOMAIN_BUS_ANY, kernel/irq/irqdomain.c:556: if (h->ops->select && bus_token != DOMAIN_BUS_ANY) so vendor gpio driver need to explicitly set bus_token, something like: drivers/gpio/gpio-spacemit-k1.c irq_domain_update_bus_token(girq->domain, DOMAIN_BUS_WIRED); I hope this is a feasible way.. --- drivers/gpio/gpiolib.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)