From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/4] MIPS: alchemy: mtx1: attach software nodes to GPIO chips
Date: Mon, 09 Mar 2026 23:11:58 -0700 [thread overview]
Message-ID: <20260309-alchemy-v1-1-f55e9dc60ba1@gmail.com> (raw)
In-Reply-To: <20260309-alchemy-v1-0-f55e9dc60ba1@gmail.com>
GPIO subsystem is switching the way it locates GPIO chip instances for
GPIO references in software nodes from matching on node names to
identity matching, which necessitates assigning firmware nodes
(software nodes) to GPIO chips.
Move the node definitions for alchemy-gpio1 and alchemy-gpio2 to
arch/misp/alchemy/common/gpiolib.c, register them there, and attach
them to gpio_chip instances. Adjust MTX1 board file to use these nodes.
Note that because nodes need to be registered before they can be used in
PROPERTY_ENTRY_GPIO() we have to do the registration at
postcore_initcall level, otherwise (due to the link order) MTX1 board
initialization code will run first.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
arch/mips/alchemy/board-mtx1.c | 79 +++++++++++--------------
arch/mips/alchemy/common/gpiolib.c | 39 +++++++++++-
arch/mips/include/asm/mach-au1x00/gpio-au1000.h | 4 ++
3 files changed, 75 insertions(+), 47 deletions(-)
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c
index cb6be58808a0..740b38c0b81e 100644
--- a/arch/mips/alchemy/board-mtx1.c
+++ b/arch/mips/alchemy/board-mtx1.c
@@ -9,6 +9,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
#include <linux/input.h>
@@ -78,27 +79,22 @@ void __init board_setup(void)
/******************************************************************************/
-static const struct software_node mtx1_gpiochip_node = {
- .name = "alchemy-gpio2",
-};
-
static const struct software_node mtx1_gpio_keys_node = {
.name = "mtx1-gpio-keys",
};
-static const struct property_entry mtx1_button_props[] = {
- PROPERTY_ENTRY_U32("linux,code", BTN_0),
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 7, GPIO_ACTIVE_HIGH),
- PROPERTY_ENTRY_STRING("label", "System button"),
- { }
-};
-
static const struct software_node mtx1_button_node = {
.parent = &mtx1_gpio_keys_node,
- .properties = mtx1_button_props,
+ .properties = (const struct property_entry[]){
+ PROPERTY_ENTRY_U32("linux,code", BTN_0),
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 7,
+ GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_STRING("label", "System button"),
+ { }
+ },
};
-static const struct software_node *mtx1_gpio_keys_swnodes[] __initconst = {
+static const struct software_node * const mtx1_gpio_keys_swnodes[] __initconst = {
&mtx1_gpio_keys_node,
&mtx1_button_node,
NULL
@@ -127,16 +123,15 @@ static void __init mtx1_keys_init(void)
pr_err("failed to create gpio-keys device: %d\n", err);
}
-/* Global number 215 is offset 15 on Alchemy GPIO 2 */
-static const struct property_entry mtx1_wdt_props[] = {
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 15, GPIO_ACTIVE_HIGH),
- { }
-};
-
-static struct platform_device_info mtx1_wdt_info __initconst = {
+static const struct platform_device_info mtx1_wdt_info __initconst = {
.name = "mtx1-wdt",
.id = 0,
- .properties = mtx1_wdt_props,
+ .properties = (const struct property_entry[]){
+ /* Global number 215 is offset 15 on Alchemy GPIO 2 */
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 15,
+ GPIO_ACTIVE_HIGH),
+ { }
+ },
};
static void __init mtx1_wdt_init(void)
@@ -147,36 +142,34 @@ static void __init mtx1_wdt_init(void)
pd = platform_device_register_full(&mtx1_wdt_info);
err = PTR_ERR_OR_ZERO(pd);
if (err)
- pr_err("failed to create gpio-keys device: %d\n", err);
+ pr_err("failed to create watchdog device: %d\n", err);
}
static const struct software_node mtx1_gpio_leds_node = {
.name = "mtx1-leds",
};
-static const struct property_entry mtx1_green_led_props[] = {
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 11, GPIO_ACTIVE_HIGH),
- { }
-};
-
static const struct software_node mtx1_green_led_node = {
.name = "mtx1:green",
.parent = &mtx1_gpio_leds_node,
- .properties = mtx1_green_led_props,
-};
-
-static const struct property_entry mtx1_red_led_props[] = {
- PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 12, GPIO_ACTIVE_HIGH),
- { }
+ .properties = (const struct property_entry[]){
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 11,
+ GPIO_ACTIVE_HIGH),
+ { }
+ },
};
static const struct software_node mtx1_red_led_node = {
.name = "mtx1:red",
.parent = &mtx1_gpio_leds_node,
- .properties = mtx1_red_led_props,
+ .properties = (const struct property_entry[]){
+ PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 12,
+ GPIO_ACTIVE_HIGH),
+ { }
+ },
};
-static const struct software_node *mtx1_gpio_leds_swnodes[] = {
+static const struct software_node * const mtx1_gpio_leds_swnodes[] __initconst = {
&mtx1_gpio_leds_node,
&mtx1_green_led_node,
&mtx1_red_led_node,
@@ -185,10 +178,6 @@ static const struct software_node *mtx1_gpio_leds_swnodes[] = {
static void __init mtx1_leds_init(void)
{
- struct platform_device_info led_info = {
- .name = "leds-gpio",
- .id = PLATFORM_DEVID_NONE,
- };
struct platform_device *led_dev;
int err;
@@ -198,9 +187,11 @@ static void __init mtx1_leds_init(void)
return;
}
- led_info.fwnode = software_node_fwnode(&mtx1_gpio_leds_node);
-
- led_dev = platform_device_register_full(&led_info);
+ led_dev = platform_device_register_full(&(struct platform_device_info){
+ .name = "leds-gpio",
+ .id = PLATFORM_DEVID_NONE,
+ .fwnode = software_node_fwnode(&mtx1_gpio_leds_node),
+ });
err = PTR_ERR_OR_ZERO(led_dev);
if (err)
pr_err("failed to create LED device: %d\n", err);
@@ -335,10 +326,6 @@ static int __init mtx1_register_devices(void)
au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
- rc = software_node_register(&mtx1_gpiochip_node);
- if (rc)
- return rc;
-
rc = platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
if (rc)
return rc;
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c
index e79e26ffac99..2141eae5ce45 100644
--- a/arch/mips/alchemy/common/gpiolib.c
+++ b/arch/mips/alchemy/common/gpiolib.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/property.h>
#include <linux/types.h>
#include <linux/gpio/driver.h>
#include <asm/mach-au1x00/gpio-au1000.h>
@@ -95,7 +96,21 @@ static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset)
return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
}
-struct gpio_chip alchemy_gpio_chip[] = {
+const struct software_node alchemy_gpio1_node = {
+ .name = "alchemy-gpio1",
+};
+
+const struct software_node alchemy_gpio2_node = {
+ .name = "alchemy-gpio2",
+};
+
+static const struct software_node *alchemy_gpio_node_group[] = {
+ &alchemy_gpio1_node,
+ &alchemy_gpio2_node,
+ NULL
+};
+
+static struct gpio_chip alchemy_gpio_chip[] = {
[0] = {
.label = "alchemy-gpio1",
.direction_input = gpio1_direction_input,
@@ -157,6 +172,28 @@ static struct gpio_chip au1300_gpiochip = {
.ngpio = AU1300_GPIO_NUM,
};
+/*
+ * Software nodes must be registered before board-specific code (that runs
+ * at arch_initcall level) attempts to use them as GPIO targets or as fwnodes
+ * for registered devices. We can not do registration in alchemy_gpiochip_init
+ * because it also runs as arch_initcall and runs after board-specific code
+ * because of the link order, and so we do it at postcore_initcall level.
+ */
+static int __init alchemy_gpio_nodes_init(void)
+{
+ int ret;
+
+ ret = software_node_register_node_group(alchemy_gpio_node_group);
+ if (ret)
+ return ret;
+
+ alchemy_gpio_chip[0].fwnode = software_node_fwnode(&alchemy_gpio1_node);
+ alchemy_gpio_chip[1].fwnode = software_node_fwnode(&alchemy_gpio2_node);
+
+ return 0;
+}
+postcore_initcall(alchemy_gpio_nodes_init);
+
static int __init alchemy_gpiochip_init(void)
{
int ret = 0;
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
index d820b481ac56..a0eebc24c4a8 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
@@ -41,6 +41,10 @@
#define AU1000_GPIO2_ENABLE 0x14
struct gpio;
+struct software_node;
+
+extern const struct software_node alchemy_gpio1_node;
+extern const struct software_node alchemy_gpio2_node;
static inline int au1000_gpio1_to_irq(int gpio)
{
--
2.53.0.473.g4a7958ca14-goog
next prev parent reply other threads:[~2026-03-10 6:12 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-10 6:11 [PATCH 0/4] MIPS: alchemy: attach software nodes to GPIO controllers and use properties Dmitry Torokhov
2026-03-10 6:11 ` Dmitry Torokhov [this message]
2026-03-10 6:11 ` [PATCH 2/4] MIPS: alchemy: db1000: use nodes attached to GPIO chips in properties Dmitry Torokhov
2026-03-10 6:12 ` [PATCH 3/4] MIPS: alchemy: gpr: switch to static device properties Dmitry Torokhov
2026-03-10 6:12 ` [PATCH 4/4] MIPS: alchemy: db1300: " Dmitry Torokhov
2026-04-30 9:30 ` [PATCH 0/4] MIPS: alchemy: attach software nodes to GPIO controllers and use properties Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260309-alchemy-v1-1-f55e9dc60ba1@gmail.com \
--to=dmitry.torokhov@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=tsbogend@alpha.franken.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).