[PATCH v3 03/10] ARM: s3c: register and attach software nodes for Samsung gpio_chips
From: Dmitry Torokhov
Date: Sat Jul 11 2026 - 22:14:36 EST
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 <bartosz.golaszewski@xxxxxxxxxxxxxxxx>
Reviewed-by: Linus Walleij <linusw@xxxxxxxxxx>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
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