In order to be able to add interrupts to the GPIOs, first change the
QE GPIO driver to the proper platform driver in order to allow
initialisation to be done in the right order, otherwise the GPIOs
get added before the interrupts are registered.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
drivers/soc/fsl/qe/gpio.c | 88 +++++++++++++++++++++++----------------
1 file changed, 53 insertions(+), 35 deletions(-)
diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c
index 8df1e8fa86a5f..b502377193192 100644
--- a/drivers/soc/fsl/qe/gpio.c
+++ b/drivers/soc/fsl/qe/gpio.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/property.h>
+#include <linux/platform_device.h>
#include <soc/fsl/qe/qe.h>
@@ -295,45 +296,62 @@ void qe_pin_set_gpio(struct qe_pin *qe_pin)
}
EXPORT_SYMBOL(qe_pin_set_gpio);
-static int __init qe_add_gpiochips(void)
+static int qe_gpio_probe(struct platform_device *ofdev)
{
- struct device_node *np;
-
- for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") {
- int ret;
- struct qe_gpio_chip *qe_gc;
- struct of_mm_gpio_chip *mm_gc;
- struct gpio_chip *gc;
-
- qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
- if (!qe_gc) {
- ret = -ENOMEM;
- goto err;
- }
+ struct device *dev = &ofdev->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+ struct qe_gpio_chip *qe_gc;
+ struct of_mm_gpio_chip *mm_gc;
+ struct gpio_chip *gc;
+
+ qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
+ if (!qe_gc) {
+ ret = -ENOMEM;
+ goto err;
+ }
- spin_lock_init(&qe_gc->lock);
+ spin_lock_init(&qe_gc->lock);
- mm_gc = &qe_gc->mm_gc;
- gc = &mm_gc->gc;
+ mm_gc = &qe_gc->mm_gc;
+ gc = &mm_gc->gc;
- mm_gc->save_regs = qe_gpio_save_regs;
- gc->ngpio = QE_PIO_PINS;
- gc->direction_input = qe_gpio_dir_in;
- gc->direction_output = qe_gpio_dir_out;
- gc->get = qe_gpio_get;
- gc->set = qe_gpio_set;
- gc->set_multiple = qe_gpio_set_multiple;
+ mm_gc->save_regs = qe_gpio_save_regs;
+ gc->ngpio = QE_PIO_PINS;
+ gc->direction_input = qe_gpio_dir_in;
+ gc->direction_output = qe_gpio_dir_out;
+ gc->get = qe_gpio_get;
+ gc->set = qe_gpio_set;
+ gc->set_multiple = qe_gpio_set_multiple;
- ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);
- if (ret)
- goto err;
- continue;
+ ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);
+ if (!ret)
+ return 0;
err:
- pr_err("%pOF: registration failed with status %d\n",
- np, ret);
- kfree(qe_gc);
- /* try others anyway */
- }
- return 0;
+ dev_err(dev, "registration failed with status %d\n", ret);
+ kfree(qe_gc);
+
+ return ret;
+}
+
+static const struct of_device_id qe_gpio_match[] = {
+ {
+ .compatible = "fsl,mpc8323-qe-pario-bank",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, qe_gpio_match);
+
+static struct platform_driver qe_gpio_driver = {
+ .probe = qe_gpio_probe,
+ .driver = {
+ .name = "qe-gpio",
+ .of_match_table = qe_gpio_match,
+ },
+};
+
+static int __init qe_gpio_init(void)
+{
+ return platform_driver_register(&qe_gpio_driver);
}
-arch_initcall(qe_add_gpiochips);
+arch_initcall(qe_gpio_init);
--
2.49.0
On Tue, 12 Aug 2025 13:02:52 +0200, Christophe Leroy <christophe.leroy@csgroup.eu> said: > In order to be able to add interrupts to the GPIOs, first change the > QE GPIO driver to the proper platform driver in order to allow > initialisation to be done in the right order, otherwise the GPIOs > get added before the interrupts are registered. > > Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> > --- > drivers/soc/fsl/qe/gpio.c | 88 +++++++++++++++++++++++---------------- > 1 file changed, 53 insertions(+), 35 deletions(-) > > diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c > index 8df1e8fa86a5f..b502377193192 100644 > --- a/drivers/soc/fsl/qe/gpio.c > +++ b/drivers/soc/fsl/qe/gpio.c > @@ -19,6 +19,7 @@ > #include <linux/slab.h> > #include <linux/export.h> > #include <linux/property.h> > +#include <linux/platform_device.h> > > #include <soc/fsl/qe/qe.h> > > @@ -295,45 +296,62 @@ void qe_pin_set_gpio(struct qe_pin *qe_pin) > } > EXPORT_SYMBOL(qe_pin_set_gpio); > > -static int __init qe_add_gpiochips(void) > +static int qe_gpio_probe(struct platform_device *ofdev) > { > - struct device_node *np; > - > - for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") { > - int ret; > - struct qe_gpio_chip *qe_gc; > - struct of_mm_gpio_chip *mm_gc; > - struct gpio_chip *gc; > - > - qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); > - if (!qe_gc) { > - ret = -ENOMEM; > - goto err; > - } > + struct device *dev = &ofdev->dev; > + struct device_node *np = dev->of_node; > + int ret; > + struct qe_gpio_chip *qe_gc; > + struct of_mm_gpio_chip *mm_gc; > + struct gpio_chip *gc; > + > + qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); > + if (!qe_gc) { > + ret = -ENOMEM; > + goto err; > + } > > - spin_lock_init(&qe_gc->lock); > + spin_lock_init(&qe_gc->lock); > > - mm_gc = &qe_gc->mm_gc; > - gc = &mm_gc->gc; > + mm_gc = &qe_gc->mm_gc; > + gc = &mm_gc->gc; > > - mm_gc->save_regs = qe_gpio_save_regs; > - gc->ngpio = QE_PIO_PINS; > - gc->direction_input = qe_gpio_dir_in; > - gc->direction_output = qe_gpio_dir_out; > - gc->get = qe_gpio_get; > - gc->set = qe_gpio_set; > - gc->set_multiple = qe_gpio_set_multiple; > + mm_gc->save_regs = qe_gpio_save_regs; > + gc->ngpio = QE_PIO_PINS; > + gc->direction_input = qe_gpio_dir_in; > + gc->direction_output = qe_gpio_dir_out; > + gc->get = qe_gpio_get; > + gc->set = qe_gpio_set; > + gc->set_multiple = qe_gpio_set_multiple; > > - ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc); > - if (ret) > - goto err; > - continue; > + ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc); Actually scratch my R-b, on second glance - this should now be replaced with devm_gpiochip_add_data(). I don't see anything that would be in the way now that it's an actuall platform device. Bartosz > + if (!ret) > + return 0; > err: > - pr_err("%pOF: registration failed with status %d\n", > - np, ret); > - kfree(qe_gc); > - /* try others anyway */ > - } > - return 0; > + dev_err(dev, "registration failed with status %d\n", ret); > + kfree(qe_gc); > + > + return ret; > +} > + > +static const struct of_device_id qe_gpio_match[] = { > + { > + .compatible = "fsl,mpc8323-qe-pario-bank", > + }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, qe_gpio_match); > + > +static struct platform_driver qe_gpio_driver = { > + .probe = qe_gpio_probe, > + .driver = { > + .name = "qe-gpio", > + .of_match_table = qe_gpio_match, > + }, > +}; > + > +static int __init qe_gpio_init(void) > +{ > + return platform_driver_register(&qe_gpio_driver); > } > -arch_initcall(qe_add_gpiochips); > +arch_initcall(qe_gpio_init); > -- > 2.49.0 > >
On Tue, 12 Aug 2025 13:02:52 +0200, Christophe Leroy <christophe.leroy@csgroup.eu> said: > In order to be able to add interrupts to the GPIOs, first change the > QE GPIO driver to the proper platform driver in order to allow > initialisation to be done in the right order, otherwise the GPIOs > get added before the interrupts are registered. > > Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> > --- Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
© 2016 - 2025 Red Hat, Inc.