From nobody Sun Apr 5 15:48:13 2026 Received: from mail-dy1-f172.google.com (mail-dy1-f172.google.com [74.125.82.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01CD22BE621 for ; Tue, 10 Mar 2026 06:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773123142; cv=none; b=bEK5ngUf03N1Ecb73IbeLmohF3EWyBxf2HM39wLNqxluXZ3QRrVjxz1OdBZbD5kEBzJc8bpOk7mYGS5bG8mQ+2MOrLwSdle9jgtyxGqfOrpSb7UoJEjvkWeWGSKxVXnRamBajVr/QXb/Zo4waaJe2Lwa2x0yMyBmSJQWK5XTAII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773123142; c=relaxed/simple; bh=XRio9G3PpzIKf5fTbcsvkoxkVC0WokjbqLbKOkmTnjc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=t8t0hyrPuKWAkt52oZHrk0iWbnFpmFFMIh/ygsj8J1h544fqsPrUJil0pfssxUzZamdw+xkTkDMVOcfzqVtcw+AlMLW8gsAyY2JcORLuiXj2/KV2oYkRNFSkEt0/COgQjqBKoTE5exC/IQwNG82Pr+OLymtrGVXcyPcBcHnIfpQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=f95H87We; arc=none smtp.client-ip=74.125.82.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="f95H87We" Received: by mail-dy1-f172.google.com with SMTP id 5a478bee46e88-2be3bdfda8eso5852640eec.1 for ; Mon, 09 Mar 2026 23:12:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773123140; x=1773727940; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=T3lT/PTNwNOc4iufAidrAcgLB/0uuZoI/g6mDpTtk9I=; b=f95H87We702gnCPFjBpwZwpQiNh3nQEHi3ebfJyw/vkGPpWrOIV+oTePVIWGbcqLkA 6c/gJhtln3TTdZWjcqXRvSaSW5hWfHkcBi8jomkNzWK7/8ieV4iF6XW2aY1avZ7d/fgF sD32uQxod32f/ddWYvkm97X7uUdv7rJruuGIHKfx2sMTkaBAYmuhKu40593ocKg2vOcc /rPx2Kmh3gY23QP06xM/Qc16bu8Xzp9YXUUWUZp7BGIHB7WKHnNMO+VNxkDxbTZ+zU/W QOzbgfmUzRVUMJaYzKrGCXIYn2xH5T1G6irsWCla3oddAC8rgdeYw82s67ixbm68CbJL m8+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773123140; x=1773727940; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=T3lT/PTNwNOc4iufAidrAcgLB/0uuZoI/g6mDpTtk9I=; b=YLlLtba40E1h/ntD/XdeXeYXovl2XN1VflWdgZBUA0YFe9asm05Kutuq8xCkew4JDW 23kvp4Ehizo+77AiC6QUAEE3rN6w5suwrBPvzixV5Oegqh5yT95/ShZNcZOflP15tVPX fmIzgOcTZ12P+i3du4ZPceLugjK0AK1plwqgvWi99Q7NpDq7kaW461P9NowBK1jXf7z+ WEN90tmkHqiiKzqARhjxxttVKpEQeJrMi2q3o6RWTtJs+Wfi7cAtZjPrSGQTPp8BOKU3 p1NTOGu+zH4KUbRs57h7OteaW8g4y+NWvQSGq2tao1LnQHwDsNROBHEbeokMI2dn7XCW 5y7w== X-Forwarded-Encrypted: i=1; AJvYcCURznCgH5JxOD42gnBWDbW1xXh8kPJ1jOHpHNKmQYFLQa9+mAPHlxQob5Zu0/JvMN/DvyEbwRyU90ERWhM=@vger.kernel.org X-Gm-Message-State: AOJu0YxYbt6s+0dk1U19F9kXAivRukd5PEvRfSxVN03S5OQ1dhMak7u0 tzerM0Us5RKG/3fEonwqZzsR0mvTjeSm89jahFQmF+vFEasjg/qdkAYh X-Gm-Gg: ATEYQzwzWJ8r9sQQjUGbozDZ2tBjCyCwjOJTxvj8Ag5Na0ATFQKEEGUno2OQNTiGfRV iuNGRGQnZGRGkY/C5UJ1201oXitMG2NiZV7OWUK7efep0wdl07n5M2LF6aJX7m9ShMADU+n4x/B eZvAev65YO1I5khRqGn3RfOCyn8TtSv455TPr4bcLJDEsR7Ohp5kqheNVxw6ksEBe6Ws2G8x1M2 5AW+27l6yB8oA0uKKLARH6yOA3Zsed+edEFf3bZi0PI4vdcAMxby9HLnKbu4PKJvQRHqbM9i4+3 aUYn3REZFgZCKB/LlGTyOGQtMlp/GxjWPap+73O+ZNipS3SaX9y3yWp/tsOrSACcuvnAk9JXRUt gJAEiYqjiXbqrWyR+HormQ2TeCo+zzH3EB5veTT8cbKqToGwDg5OqSQvsAOR1HkBJfXfRBBMj+/ RMwsSdEDusijErOQGxP7ua2gqGXXxnOn9g+qrRyVCSdjFqoOoL+BP4X5L7BmEM8RD3+/nUd5TYa V4W2hb99geLgxM= X-Received: by 2002:a05:7300:f194:b0:2be:2bc5:ba05 with SMTP id 5a478bee46e88-2be4de63f5emr4444129eec.7.1773123139778; Mon, 09 Mar 2026 23:12:19 -0700 (PDT) Received: from dtor-ws.sjc.corp.google.com ([2a00:79e0:2ebe:8:2a0a:17c2:21e7:dcfb]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2be4f96aa32sm11787106eec.26.2026.03.09.23.12.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 23:12:18 -0700 (PDT) From: Dmitry Torokhov Date: Mon, 09 Mar 2026 23:11:58 -0700 Subject: [PATCH 1/4] MIPS: alchemy: mtx1: attach software nodes to GPIO chips Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260309-alchemy-v1-1-f55e9dc60ba1@gmail.com> References: <20260309-alchemy-v1-0-f55e9dc60ba1@gmail.com> In-Reply-To: <20260309-alchemy-v1-0-f55e9dc60ba1@gmail.com> To: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.15-dev-a6826 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 --- 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 #include #include +#include #include #include #include @@ -78,27 +79,22 @@ void __init board_setup(void) =20 /*************************************************************************= *****/ =20 -static const struct software_node mtx1_gpiochip_node =3D { - .name =3D "alchemy-gpio2", -}; - static const struct software_node mtx1_gpio_keys_node =3D { .name =3D "mtx1-gpio-keys", }; =20 -static const struct property_entry mtx1_button_props[] =3D { - 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 =3D { .parent =3D &mtx1_gpio_keys_node, - .properties =3D mtx1_button_props, + .properties =3D (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"), + { } + }, }; =20 -static const struct software_node *mtx1_gpio_keys_swnodes[] __initconst = =3D { +static const struct software_node * const mtx1_gpio_keys_swnodes[] __initc= onst =3D { &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); } =20 -/* Global number 215 is offset 15 on Alchemy GPIO 2 */ -static const struct property_entry mtx1_wdt_props[] =3D { - PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 15, GPIO_ACTIVE_HIGH), - { } -}; - -static struct platform_device_info mtx1_wdt_info __initconst =3D { +static const struct platform_device_info mtx1_wdt_info __initconst =3D { .name =3D "mtx1-wdt", .id =3D 0, - .properties =3D mtx1_wdt_props, + .properties =3D (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), + { } + }, }; =20 static void __init mtx1_wdt_init(void) @@ -147,36 +142,34 @@ static void __init mtx1_wdt_init(void) pd =3D platform_device_register_full(&mtx1_wdt_info); err =3D 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); } =20 static const struct software_node mtx1_gpio_leds_node =3D { .name =3D "mtx1-leds", }; =20 -static const struct property_entry mtx1_green_led_props[] =3D { - PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 11, GPIO_ACTIVE_HIGH), - { } -}; - static const struct software_node mtx1_green_led_node =3D { .name =3D "mtx1:green", .parent =3D &mtx1_gpio_leds_node, - .properties =3D mtx1_green_led_props, -}; - -static const struct property_entry mtx1_red_led_props[] =3D { - PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 12, GPIO_ACTIVE_HIGH), - { } + .properties =3D (const struct property_entry[]){ + PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 11, + GPIO_ACTIVE_HIGH), + { } + }, }; =20 static const struct software_node mtx1_red_led_node =3D { .name =3D "mtx1:red", .parent =3D &mtx1_gpio_leds_node, - .properties =3D mtx1_red_led_props, + .properties =3D (const struct property_entry[]){ + PROPERTY_ENTRY_GPIO("gpios", &alchemy_gpio2_node, 12, + GPIO_ACTIVE_HIGH), + { } + }, }; =20 -static const struct software_node *mtx1_gpio_leds_swnodes[] =3D { +static const struct software_node * const mtx1_gpio_leds_swnodes[] __initc= onst =3D { &mtx1_gpio_leds_node, &mtx1_green_led_node, &mtx1_red_led_node, @@ -185,10 +178,6 @@ static const struct software_node *mtx1_gpio_leds_swno= des[] =3D { =20 static void __init mtx1_leds_init(void) { - struct platform_device_info led_info =3D { - .name =3D "leds-gpio", - .id =3D PLATFORM_DEVID_NONE, - }; struct platform_device *led_dev; int err; =20 @@ -198,9 +187,11 @@ static void __init mtx1_leds_init(void) return; } =20 - led_info.fwnode =3D software_node_fwnode(&mtx1_gpio_leds_node); - - led_dev =3D platform_device_register_full(&led_info); + led_dev =3D platform_device_register_full(&(struct platform_device_info){ + .name =3D "leds-gpio", + .id =3D PLATFORM_DEVID_NONE, + .fwnode =3D software_node_fwnode(&mtx1_gpio_leds_node), + }); err =3D 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) =20 au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata); =20 - rc =3D software_node_register(&mtx1_gpiochip_node); - if (rc) - return rc; - rc =3D 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 @@ =20 #include #include +#include #include #include #include @@ -95,7 +96,21 @@ static int gpio1_to_irq(struct gpio_chip *chip, unsigned= offset) return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE); } =20 -struct gpio_chip alchemy_gpio_chip[] =3D { +const struct software_node alchemy_gpio1_node =3D { + .name =3D "alchemy-gpio1", +}; + +const struct software_node alchemy_gpio2_node =3D { + .name =3D "alchemy-gpio2", +}; + +static const struct software_node *alchemy_gpio_node_group[] =3D { + &alchemy_gpio1_node, + &alchemy_gpio2_node, + NULL +}; + +static struct gpio_chip alchemy_gpio_chip[] =3D { [0] =3D { .label =3D "alchemy-gpio1", .direction_input =3D gpio1_direction_input, @@ -157,6 +172,28 @@ static struct gpio_chip au1300_gpiochip =3D { .ngpio =3D AU1300_GPIO_NUM, }; =20 +/* + * Software nodes must be registered before board-specific code (that runs + * at arch_initcall level) attempts to use them as GPIO targets or as fwno= des + * 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 =3D software_node_register_node_group(alchemy_gpio_node_group); + if (ret) + return ret; + + alchemy_gpio_chip[0].fwnode =3D software_node_fwnode(&alchemy_gpio1_node); + alchemy_gpio_chip[1].fwnode =3D software_node_fwnode(&alchemy_gpio2_node); + + return 0; +} +postcore_initcall(alchemy_gpio_nodes_init); + static int __init alchemy_gpiochip_init(void) { int ret =3D 0; diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/in= clude/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 =20 struct gpio; +struct software_node; + +extern const struct software_node alchemy_gpio1_node; +extern const struct software_node alchemy_gpio2_node; =20 static inline int au1000_gpio1_to_irq(int gpio) { --=20 2.53.0.473.g4a7958ca14-goog