[PATCH v3 03/10] ARM: s3c: register and attach software nodes for Samsung gpio_chips
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2026-07-12 02:13:24
Also in:
linux-arm-kernel, linux-devicetree, linux-samsung-soc, lkml
Subsystem:
arm port, arm/samsung s3c, s5p and exynos arm architectures, the rest · Maintainers:
Russell King, Krzysztof Kozlowski, Peter Griffin, Linus Torvalds
Define and register software nodes for the Samsung GPIO chips on legacy (non-DT) platforms. Attach the matching software node to each gpio_chip's fwnode during registration, using the bank label to calculate the index. This provides the infrastructure for converting board files and drivers to use software nodes/properties instead of legacy platform data or GPIO lookup tables. Assisted-by: Antigravity:gemini-3.5-flash Acked-by: Bartosz Golaszewski <redacted> Reviewed-by: Linus Walleij <linusw@kernel.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- arch/arm/mach-s3c/gpio-core.h | 3 ++ arch/arm/mach-s3c/gpio-samsung-s3c64xx.h | 5 +++ arch/arm/mach-s3c/gpio-samsung.c | 72 ++++++++++++++++++++++++-------- 3 files changed, 63 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-s3c/gpio-core.h b/arch/arm/mach-s3c/gpio-core.h
index 6801c85fb9da..464b0d02f102 100644
--- a/arch/arm/mach-s3c/gpio-core.h
+++ b/arch/arm/mach-s3c/gpio-core.h@@ -14,6 +14,8 @@ #include "gpio-samsung.h" #include <linux/gpio/driver.h> +struct software_node; + #define GPIOCON_OFF (0x00) #define GPIODAT_OFF (0x04)
@@ -66,6 +68,7 @@ struct samsung_gpio_cfg; */ struct samsung_gpio_chip { struct gpio_chip chip; + const struct software_node *swnode; struct samsung_gpio_cfg *config; struct samsung_gpio_pm *pm; void __iomem *base;
diff --git a/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h b/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h
index 8ed144a0d474..fc21d3f50ce9 100644
--- a/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h
+++ b/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h@@ -13,6 +13,8 @@ #ifdef CONFIG_GPIO_SAMSUNG +#include <linux/property.h> + /* GPIO bank sizes */ #define S3C64XX_GPIO_A_NR (8) #define S3C64XX_GPIO_B_NR (7)
@@ -89,6 +91,9 @@ enum s3c_gpio_number { /* define the number of gpios we need to the one after the GPQ() range */ #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) +extern const struct software_node samsung_gpiochip_nodes[]; +#define SAMSUNG_GPIO_NODE(node) (&samsung_gpiochip_nodes[(node) - 'A']) + #endif /* GPIO_SAMSUNG */ #endif /* GPIO_SAMSUNG_S3C64XX_H */
diff --git a/arch/arm/mach-s3c/gpio-samsung.c b/arch/arm/mach-s3c/gpio-samsung.c
index 81e198e5a6d3..b35cf62a9157 100644
--- a/arch/arm/mach-s3c/gpio-samsung.c
+++ b/arch/arm/mach-s3c/gpio-samsung.c@@ -37,6 +37,28 @@ #include "gpio-cfg-helpers.h" #include "pm.h" +const struct software_node samsung_gpiochip_nodes[] = { + SOFTWARE_NODE("GPA", NULL, NULL), + SOFTWARE_NODE("GPB", NULL, NULL), + SOFTWARE_NODE("GPC", NULL, NULL), + SOFTWARE_NODE("GPD", NULL, NULL), + SOFTWARE_NODE("GPE", NULL, NULL), + SOFTWARE_NODE("GPF", NULL, NULL), + SOFTWARE_NODE("GPG", NULL, NULL), + SOFTWARE_NODE("GPH", NULL, NULL), + SOFTWARE_NODE("GPI", NULL, NULL), + SOFTWARE_NODE("GPJ", NULL, NULL), + SOFTWARE_NODE("GPK", NULL, NULL), + SOFTWARE_NODE("GPL", NULL, NULL), + SOFTWARE_NODE("GPM", NULL, NULL), + SOFTWARE_NODE("GPN", NULL, NULL), + SOFTWARE_NODE("GPO", NULL, NULL), + SOFTWARE_NODE("GPP", NULL, NULL), + SOFTWARE_NODE("GPQ", NULL, NULL), +}; + +#define NUM_SAMSUNG_GPIOCHIPS ARRAY_SIZE(samsung_gpiochip_nodes) + static int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, unsigned int off, samsung_gpio_pull_t pull) {
@@ -491,6 +513,16 @@ static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip) } #endif /* CONFIG_S3C_GPIO_TRACK */ +static void __init samsung_setup_gpiochip_nodes(void) +{ + const struct software_node *group[NUM_SAMSUNG_GPIOCHIPS + 1] = { 0 }; + + for (unsigned int i = 0; i < NUM_SAMSUNG_GPIOCHIPS; i++) + group[i] = &samsung_gpiochip_nodes[i]; + + software_node_register_node_group(group); +} + /* * samsung_gpiolib_add() - add the Samsung gpio_chip. * @chip: The chip to register
@@ -506,12 +538,16 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) struct gpio_chip *gc = &chip->chip; int ret; + gc->label = chip->swnode->name; + BUG_ON(!chip->base); BUG_ON(!gc->label); BUG_ON(!gc->ngpio); spin_lock_init(&chip->lock); + gc->fwnode = software_node_fwnode(chip->swnode); + if (!gc->direction_input) gc->direction_input = samsung_gpiolib_2bit_input; if (!gc->direction_output)
@@ -659,49 +695,49 @@ static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = { .chip = { .base = S3C64XX_GPA(0), .ngpio = S3C64XX_GPIO_A_NR, - .label = "GPA", }, + .swnode = SAMSUNG_GPIO_NODE('A'), }, { .chip = { .base = S3C64XX_GPB(0), .ngpio = S3C64XX_GPIO_B_NR, - .label = "GPB", }, + .swnode = SAMSUNG_GPIO_NODE('B'), }, { .chip = { .base = S3C64XX_GPC(0), .ngpio = S3C64XX_GPIO_C_NR, - .label = "GPC", }, + .swnode = SAMSUNG_GPIO_NODE('C'), }, { .chip = { .base = S3C64XX_GPD(0), .ngpio = S3C64XX_GPIO_D_NR, - .label = "GPD", }, + .swnode = SAMSUNG_GPIO_NODE('D'), }, { .config = &samsung_gpio_cfgs[0], .chip = { .base = S3C64XX_GPE(0), .ngpio = S3C64XX_GPIO_E_NR, - .label = "GPE", }, + .swnode = SAMSUNG_GPIO_NODE('E'), }, { .base = S3C64XX_GPG_BASE, .chip = { .base = S3C64XX_GPG(0), .ngpio = S3C64XX_GPIO_G_NR, - .label = "GPG", }, + .swnode = SAMSUNG_GPIO_NODE('G'), }, { .base = S3C64XX_GPM_BASE, .config = &samsung_gpio_cfgs[1], .chip = { .base = S3C64XX_GPM(0), .ngpio = S3C64XX_GPIO_M_NR, - .label = "GPM", .to_irq = s3c64xx_gpiolib_mbank_to_irq, }, + .swnode = SAMSUNG_GPIO_NODE('M'), }, };
@@ -711,25 +747,25 @@ static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = { .chip = { .base = S3C64XX_GPH(0), .ngpio = S3C64XX_GPIO_H_NR, - .label = "GPH", }, + .swnode = SAMSUNG_GPIO_NODE('H'), }, { .base = S3C64XX_GPK_BASE + 0x4, .config = &samsung_gpio_cfgs[0], .chip = { .base = S3C64XX_GPK(0), .ngpio = S3C64XX_GPIO_K_NR, - .label = "GPK", }, + .swnode = SAMSUNG_GPIO_NODE('K'), }, { .base = S3C64XX_GPL_BASE + 0x4, .config = &samsung_gpio_cfgs[1], .chip = { .base = S3C64XX_GPL(0), .ngpio = S3C64XX_GPIO_L_NR, - .label = "GPL", .to_irq = s3c64xx_gpiolib_lbank_to_irq, }, + .swnode = SAMSUNG_GPIO_NODE('L'), }, };
@@ -740,43 +776,43 @@ static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { .chip = { .base = S3C64XX_GPF(0), .ngpio = S3C64XX_GPIO_F_NR, - .label = "GPF", }, + .swnode = SAMSUNG_GPIO_NODE('F'), }, { .config = &samsung_gpio_cfgs[7], .chip = { .base = S3C64XX_GPI(0), .ngpio = S3C64XX_GPIO_I_NR, - .label = "GPI", }, + .swnode = SAMSUNG_GPIO_NODE('I'), }, { .config = &samsung_gpio_cfgs[7], .chip = { .base = S3C64XX_GPJ(0), .ngpio = S3C64XX_GPIO_J_NR, - .label = "GPJ", }, + .swnode = SAMSUNG_GPIO_NODE('J'), }, { .config = &samsung_gpio_cfgs[6], .chip = { .base = S3C64XX_GPO(0), .ngpio = S3C64XX_GPIO_O_NR, - .label = "GPO", }, + .swnode = SAMSUNG_GPIO_NODE('O'), }, { .config = &samsung_gpio_cfgs[6], .chip = { .base = S3C64XX_GPP(0), .ngpio = S3C64XX_GPIO_P_NR, - .label = "GPP", }, + .swnode = SAMSUNG_GPIO_NODE('P'), }, { .config = &samsung_gpio_cfgs[6], .chip = { .base = S3C64XX_GPQ(0), .ngpio = S3C64XX_GPIO_Q_NR, - .label = "GPQ", }, + .swnode = SAMSUNG_GPIO_NODE('Q'), }, { .base = S3C64XX_GPN_BASE, .irq_base = IRQ_EINT(0),
@@ -784,9 +820,9 @@ static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { .chip = { .base = S3C64XX_GPN(0), .ngpio = S3C64XX_GPIO_N_NR, - .label = "GPN", .to_irq = samsung_gpiolib_to_irq, }, + .swnode = SAMSUNG_GPIO_NODE('N'), }, };
@@ -803,6 +839,8 @@ static __init int samsung_gpiolib_init(void) return 0; if (soc_is_s3c64xx()) { + samsung_setup_gpiochip_nodes(); + samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
--
2.55.0.795.g602f6c329a-goog