From 25f526507b8ccc6ac3a43bc094d09b1f9b0b90ae Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Mon, 25 Aug 2025 10:34:35 +0100 Subject: [PATCH 1/5] bus: fsl-mc: Check return value of platform_get_resource() platform_get_resource() returns NULL in case of failure, so check its return value and propagate the error in order to prevent NULL pointer dereference. Fixes: 6305166c8771 ("bus: fsl-mc: Add ACPI support for fsl-mc") Cc: stable@vger.kernel.org Signed-off-by: Salah Triki Acked-by: Ioana Ciornei Link: https://lore.kernel.org/r/aKwuK6TRr5XNYQ8u@pc Signed-off-by: Christophe Leroy --- drivers/bus/fsl-mc/fsl-mc-bus.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index c1c0a4759c7e..5027da143728 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -1104,6 +1104,9 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) * Get physical address of MC portal for the root DPRC: */ plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!plat_res) + return -EINVAL; + mc_portal_phys_addr = plat_res->start; mc_portal_size = resource_size(plat_res); mc_portal_base_phys_addr = mc_portal_phys_addr & ~0x3ffffff; From a50522c805a6c575c80f41b04706e084d814e116 Mon Sep 17 00:00:00 2001 From: Chelsy Ratnawat Date: Fri, 22 Aug 2025 05:43:39 -0700 Subject: [PATCH 2/5] bus: fsl-mc: Replace snprintf and sprintf with sysfs_emit in sysfs show functions Use sysfs_emit() instead of snprintf()/sprintf() when writing to sysfs buffers, as recommended by the kernel documentation. Signed-off-by: Chelsy Ratnawat Acked-by: Ioana Ciornei Link: https://lore.kernel.org/r/20250822124339.1739290-1-chelsyratnawat2001@gmail.com Signed-off-by: Christophe Leroy --- drivers/bus/fsl-mc/fsl-mc-bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5027da143728..25845c04e562 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -176,8 +176,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, { struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor, - mc_dev->obj_desc.type); + return sysfs_emit(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor, + mc_dev->obj_desc.type); } static DEVICE_ATTR_RO(modalias); @@ -203,7 +203,7 @@ static ssize_t driver_override_show(struct device *dev, { struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override); + return sysfs_emit(buf, "%s\n", mc_dev->driver_override); } static DEVICE_ATTR_RW(driver_override); From 156460811def1ae699eebe40d9678e4ce3d1d9bc Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 18 Sep 2025 18:23:22 +0200 Subject: [PATCH 3/5] soc: fsl: qe: Change GPIO driver to a proper platform driver 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. Remove linux/of.h and linux/property.h which are unused. And to improve readability and reduce risk of errors, add a macro to transform a pin number into the mask that matches the associated bit in registers. Reviewed-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/b0b4480255569c7f0dfe58854a444f9a40da6681.1758212309.git.christophe.leroy@csgroup.eu Signed-off-by: Christophe Leroy --- drivers/soc/fsl/qe/gpio.c | 90 +++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 8df1e8fa86a5..04b44fc2bb58 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -12,16 +12,17 @@ #include #include #include -#include #include #include #include #include #include -#include +#include #include +#define PIN_MASK(gpio) (1UL << (QE_PIO_PINS - 1 - (gpio))) + struct qe_gpio_chip { struct of_mm_gpio_chip mm_gc; spinlock_t lock; @@ -52,7 +53,7 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct qe_pio_regs __iomem *regs = mm_gc->regs; - u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); + u32 pin_mask = PIN_MASK(gpio); return !!(ioread32be(®s->cpdata) & pin_mask); } @@ -63,7 +64,7 @@ static int qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc); struct qe_pio_regs __iomem *regs = mm_gc->regs; unsigned long flags; - u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); + u32 pin_mask = PIN_MASK(gpio); spin_lock_irqsave(&qe_gc->lock, flags); @@ -95,9 +96,9 @@ static int qe_gpio_set_multiple(struct gpio_chip *gc, break; if (__test_and_clear_bit(i, mask)) { if (test_bit(i, bits)) - qe_gc->cpdata |= (1U << (QE_PIO_PINS - 1 - i)); + qe_gc->cpdata |= PIN_MASK(i); else - qe_gc->cpdata &= ~(1U << (QE_PIO_PINS - 1 - i)); + qe_gc->cpdata &= ~PIN_MASK(i); } } @@ -295,45 +296,52 @@ 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; + struct device *dev = &ofdev->dev; + struct device_node *np = dev->of_node; + struct qe_gpio_chip *qe_gc; + struct of_mm_gpio_chip *mm_gc; + struct gpio_chip *gc; - 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 = devm_kzalloc(dev, sizeof(*qe_gc), GFP_KERNEL); + if (!qe_gc) + return -ENOMEM; - 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; -err: - pr_err("%pOF: registration failed with status %d\n", - np, ret); - kfree(qe_gc); - /* try others anyway */ - } - return 0; + return of_mm_gpiochip_add_data(np, mm_gc, qe_gc); } -arch_initcall(qe_add_gpiochips); + +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_gpio_init); From e9713655b29a47d23cbf07aacf50b0ce8ee0a850 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 18 Sep 2025 18:23:23 +0200 Subject: [PATCH 4/5] soc: fsl: qe: Drop legacy-of-mm-gpiochip.h header from GPIO driver Remove legacy-of-mm-gpiochip.h header file. The above mentioned file provides an OF API that's deprecated. There is no agnostic alternatives to it and we have to open code the logic which was hidden behind of_mm_gpiochip_add_data(). Note, most of the GPIO drivers are using their own labeling schemas and resource retrieval that only a few may gain of the code deduplication, so whenever alternative is appear we can move drivers again to use that one. As a side effect this change fixes a potential memory leak on an error path, if of_mm_gpiochip_add_data() fails. [Text copied from commit 34064c8267a6 ("powerpc/8xx: Drop legacy-of-mm-gpiochip.h header")] Suggested-by: Bartosz Golaszewski Reviewed-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/e8a5d2c5b72233bd36da7fecc0a551ca54d39478.1758212309.git.christophe.leroy@csgroup.eu Signed-off-by: Christophe Leroy --- arch/powerpc/platforms/Kconfig | 1 - drivers/soc/fsl/qe/gpio.c | 51 ++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index fea3766eac0f..5b689bd3ddf4 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -232,7 +232,6 @@ config QE_GPIO bool "QE GPIO support" depends on QUICC_ENGINE select GPIOLIB - select OF_GPIO_MM_GPIOCHIP help Say Y here if you're going to use hardware that connects to the QE GPIOs. diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 04b44fc2bb58..c54154b404df 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -24,7 +23,8 @@ #define PIN_MASK(gpio) (1UL << (QE_PIO_PINS - 1 - (gpio))) struct qe_gpio_chip { - struct of_mm_gpio_chip mm_gc; + struct gpio_chip gc; + void __iomem *regs; spinlock_t lock; /* shadowed data register to clear/set bits safely */ @@ -34,11 +34,9 @@ struct qe_gpio_chip { struct qe_pio_regs saved_regs; }; -static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) +static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc) { - struct qe_gpio_chip *qe_gc = - container_of(mm_gc, struct qe_gpio_chip, mm_gc); - struct qe_pio_regs __iomem *regs = mm_gc->regs; + struct qe_pio_regs __iomem *regs = qe_gc->regs; qe_gc->cpdata = ioread32be(®s->cpdata); qe_gc->saved_regs.cpdata = qe_gc->cpdata; @@ -51,8 +49,8 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) { - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct qe_pio_regs __iomem *regs = mm_gc->regs; + struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc); + struct qe_pio_regs __iomem *regs = qe_gc->regs; u32 pin_mask = PIN_MASK(gpio); return !!(ioread32be(®s->cpdata) & pin_mask); @@ -60,9 +58,8 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) static int qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) { - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc); - struct qe_pio_regs __iomem *regs = mm_gc->regs; + struct qe_pio_regs __iomem *regs = qe_gc->regs; unsigned long flags; u32 pin_mask = PIN_MASK(gpio); @@ -83,9 +80,8 @@ static int qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) static int qe_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc); - struct qe_pio_regs __iomem *regs = mm_gc->regs; + struct qe_pio_regs __iomem *regs = qe_gc->regs; unsigned long flags; int i; @@ -111,13 +107,12 @@ static int qe_gpio_set_multiple(struct gpio_chip *gc, static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) { - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc); unsigned long flags; spin_lock_irqsave(&qe_gc->lock, flags); - __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0); + __par_io_config_pin(qe_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0); spin_unlock_irqrestore(&qe_gc->lock, flags); @@ -126,7 +121,6 @@ static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc); unsigned long flags; @@ -134,7 +128,7 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) spin_lock_irqsave(&qe_gc->lock, flags); - __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0); + __par_io_config_pin(qe_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0); spin_unlock_irqrestore(&qe_gc->lock, flags); @@ -240,7 +234,7 @@ EXPORT_SYMBOL(qe_pin_free); void qe_pin_set_dedicated(struct qe_pin *qe_pin) { struct qe_gpio_chip *qe_gc = qe_pin->controller; - struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; + struct qe_pio_regs __iomem *regs = qe_gc->regs; struct qe_pio_regs *sregs = &qe_gc->saved_regs; int pin = qe_pin->num; u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1)); @@ -269,7 +263,6 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin) iowrite32be(qe_gc->cpdata, ®s->cpdata); qe_clrsetbits_be32(®s->cpodr, mask1, sregs->cpodr & mask1); - spin_unlock_irqrestore(&qe_gc->lock, flags); } EXPORT_SYMBOL(qe_pin_set_dedicated); @@ -284,7 +277,7 @@ EXPORT_SYMBOL(qe_pin_set_dedicated); void qe_pin_set_gpio(struct qe_pin *qe_pin) { struct qe_gpio_chip *qe_gc = qe_pin->controller; - struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; + struct qe_pio_regs __iomem *regs = qe_gc->regs; unsigned long flags; spin_lock_irqsave(&qe_gc->lock, flags); @@ -301,7 +294,6 @@ static int qe_gpio_probe(struct platform_device *ofdev) struct device *dev = &ofdev->dev; struct device_node *np = dev->of_node; struct qe_gpio_chip *qe_gc; - struct of_mm_gpio_chip *mm_gc; struct gpio_chip *gc; qe_gc = devm_kzalloc(dev, sizeof(*qe_gc), GFP_KERNEL); @@ -310,18 +302,29 @@ static int qe_gpio_probe(struct platform_device *ofdev) spin_lock_init(&qe_gc->lock); - mm_gc = &qe_gc->mm_gc; - gc = &mm_gc->gc; + gc = &qe_gc->gc; - mm_gc->save_regs = qe_gpio_save_regs; + gc->base = -1; 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; + gc->parent = dev; + gc->owner = THIS_MODULE; - return of_mm_gpiochip_add_data(np, mm_gc, qe_gc); + gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np); + if (!gc->label) + return -ENOMEM; + + qe_gc->regs = devm_of_iomap(dev, np, 0, NULL); + if (IS_ERR(qe_gc->regs)) + return PTR_ERR(qe_gc->regs); + + qe_gpio_save_regs(qe_gc); + + return devm_gpiochip_add_data(dev, gc, qe_gc); } static const struct of_device_id qe_gpio_match[] = { From 5498f07842cbddd86c725b960acb8e478684ca45 Mon Sep 17 00:00:00 2001 From: Fushuai Wang Date: Mon, 11 Aug 2025 14:52:16 +0800 Subject: [PATCH 5/5] soc/fsl/qbman: Use for_each_online_cpu() instead of for_each_cpu() Replace the opencoded for_each_cpu(cpu, cpu_online_mask) loop with the more readable and equivalent for_each_online_cpu(cpu) macro. Signed-off-by: Fushuai Wang Link: https://lore.kernel.org/r/20250811065216.3320-1-wangfushuai@baidu.com Signed-off-by: Christophe Leroy --- drivers/soc/fsl/qbman/qman_test_stash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/fsl/qbman/qman_test_stash.c b/drivers/soc/fsl/qbman/qman_test_stash.c index f4d3c2146f4f..6f7597950aa3 100644 --- a/drivers/soc/fsl/qbman/qman_test_stash.c +++ b/drivers/soc/fsl/qbman/qman_test_stash.c @@ -103,7 +103,7 @@ static int on_all_cpus(int (*fn)(void)) { int cpu; - for_each_cpu(cpu, cpu_online_mask) { + for_each_online_cpu(cpu) { struct bstrap bstrap = { .fn = fn, .started = ATOMIC_INIT(0)