From nobody Sun Oct 5 00:14:42 2025 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (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 A5F4019D065; Mon, 11 Aug 2025 22:47:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754952434; cv=none; b=p8mlMMPfVC1VCY2kOeMjkVVzwHaUKtbkgnHMJkXhDtqulKtfvrJu2mQY5gdHIejHkw0KKppgbrxH7+rQAQHMfOrlq5RHW8NXMwiSXT6vkUUYBc1Rox0u0ycsNwh0HccyR2AB9tCZdxjojhmoZmdRL4Vb74ID1paMVUlKncZwAPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754952434; c=relaxed/simple; bh=G1PXVZ0UA9QR41dSWs8gtM+5c+QX+/q3d7AQMM//YIc=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=TnKeZCiVeXNMhWGwZV3gTx1zJVcvvYurKkmrrCKqarHWZ0QWEOvPA7ZlGWf4sDBPeC1T1PSFQTTxWMDP2HH8LhggqbL6wxHej2Oo9KtbhPEUGXRf22oUay598ZyQleQQMGVhRv4fxrZwkBaBQqakc2vMyndhLMWbv28XtEAi8bs= 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=gnKL2Lgh; arc=none smtp.client-ip=209.85.210.171 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="gnKL2Lgh" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-76a3818eb9bso4464149b3a.3; Mon, 11 Aug 2025 15:47:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1754952432; x=1755557232; darn=vger.kernel.org; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=de0me9/YGHnRXlTnZjgcGffuWlmy2iUubpAeKN1WIyY=; b=gnKL2LghFDcUn+D6vgQkXlBUZ6ZbR9H8ZYwnd4i2WxDBJZcP1RKA1qyIKmix2DSPDa r4sHxHrwO0IH71WwYfys6GlWvQQcqN5AD9qhq1C/7AIZ7gUPhDYsWhqn1ug7cFDeZ7ia mG/24HQxG1FlHdk+A+FXrBnWbGXLclUFCm9iVhCUON985u+9g8djsv4Cn282UjhDXjRV IkAhDfhWwaVOIw+V8WJIG1zt+6L60PFg7RGB3M41jP2R75TLAbbkWV+GhOgUENjxU1RV ++wLDjWZZ3XPKd9sHJTkvOldXvFFhoKOLGX9b03ltI6iVBKc7EbpHVE4X/9RHJgh3nDZ zFOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754952432; x=1755557232; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=de0me9/YGHnRXlTnZjgcGffuWlmy2iUubpAeKN1WIyY=; b=qQqGXs9K6VEGgZyE9ucvTwzuiMSwt0lJG12NiiSe/xUYsddeUUI2Coi90a9OQjKNOt 1Xd8wZQ2LWczBbT3EATaMvS0XayY8cZg4HdEsAH7W+D8da6s0Zqq4GlLqHXxPX5aODLG WxucV4/BpXbHsTI1lRWrPe/hNR62WR8IEfrmDV5nleGMwTp5VbUHlQLqpUsvG9WmxTMn 6hzhsIEmdBf5BNc1QwoP3donKmnuK81yQ04gZzg8hQNVri6RRyd+FiJcCv5FcIs6BQEc +JLQzPKBIl8xjx4uEhgu69IUfHiKJ6FrtLZYwaeCZKoYGqoxY/3yprDz5duzQ63agfWe xPlA== X-Forwarded-Encrypted: i=1; AJvYcCWVcNNDNQnapblauREQCFF7s4ZaBvfNlJeFcxJ9Z2bx5ck+FqrgC1pvcNFSu2y4XRSFlr+vWdkt0D17nOLGbeydCg9teA==@vger.kernel.org, AJvYcCWy+5pi0d4kgQ6Zx6bx6Ldm0nU3wnQ5XW7EnN31s3onoeonutWcISCl0LousG2CxFSGiXK95eVjegr6p+c=@vger.kernel.org X-Gm-Message-State: AOJu0YxETtHkGhYTr9s8KAh9oev1rnwO2N5myDov/ddYXz7TGvn7ll9k 6ZFIZwGwu3ZrWtbYWdaHmUQQH+IK08HY8HCZDLpF85aqJ7PsI52HEf7q X-Gm-Gg: ASbGnct9XQXVC1qVA6LWncA0/XD5+mUIdqCfPCcsGJuSAgr9k6hLHU4WBNyGZtMeB0k zemqkjI459lY/E8na00gJAtgNhP3a550802EBUooHkfV7CSJuvMdKQbbjqatbivcwfCzXDmvvNF l88Pw2Oto2mD3cWEFbA5zINwxaodHxPefUUQcgH/8fxhkFMUn1Hglp7NknjmHa/6NfoCM3uT8uz fmMS60mI7eQXJVMd6DTt8RBwY1wUsZn0VAlnMBGL8mu0+ea7H8p6vole4Q5s8N7UUAeEyy2sY0q 49uNUQ7jvoQLK/FDNft31/5tDox4oKgQUYvflbTiktdeDUTzB0mRDCfpYBK8xWYozz+4lEV+N3G RRITmg+yPcxx6Zk7gc5meVqw= X-Google-Smtp-Source: AGHT+IEd0dxFQlD6GPQepFz/Y8Bd8LiRQimbwJf/I+mMRakh/i7T76SZamQZkrKQ//YkLZvuK3ZwTA== X-Received: by 2002:a05:6a00:14c2:b0:736:3979:369e with SMTP id d2e1a72fcca58-76c46070b0fmr20213971b3a.9.1754952431778; Mon, 11 Aug 2025 15:47:11 -0700 (PDT) Received: from google.com ([2620:15c:9d:2:7933:7499:67d8:279a]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-76bf1c6d5dcsm22360907b3a.74.2025.08.11.15.47.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Aug 2025 15:47:11 -0700 (PDT) Date: Mon, 11 Aug 2025 15:47:09 -0700 From: Dmitry Torokhov To: Hans de Goede , Ilpo =?utf-8?B?SsOkcnZpbmVu?= Cc: Arnd Bergmann , Bartosz Golaszewski , Linus Walleij , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] platform/x86: meraki-mx100: Use static device properties Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Convert the Meraki MX100 board driver to use software nodes and static device properties to describe the on-board LEDs and reset button. This moves away from the legacy gpiod_lookup_table and platform_data mechanisms, allowing consumer drivers like leds-gpio and gpio-keys to rely on the unified device properties interface instead of board-specific data. Signed-off-by: Dmitry Torokhov --- This compiles but I have not tried this on real hardware. drivers/platform/x86/meraki-mx100.c | 404 ++++++++++++++++++---------- 1 file changed, 262 insertions(+), 142 deletions(-) diff --git a/drivers/platform/x86/meraki-mx100.c b/drivers/platform/x86/mer= aki-mx100.c index 3751ed36a980..8c5276d98512 100644 --- a/drivers/platform/x86/meraki-mx100.c +++ b/drivers/platform/x86/meraki-mx100.c @@ -15,135 +15,256 @@ =20 #include #include -#include #include -#include +#include +#include #include #include -#include #include #include +#include =20 #define TINK_GPIO_DRIVER_NAME "gpio_ich" =20 +static const struct software_node gpio_ich_node =3D { + .name =3D TINK_GPIO_DRIVER_NAME, +}; + /* LEDs */ -static const struct gpio_led tink_leds[] =3D { - { - .name =3D "mx100:green:internet", - .default_trigger =3D "default-on", - }, - { - .name =3D "mx100:green:lan2", - }, - { - .name =3D "mx100:green:lan3", - }, - { - .name =3D "mx100:green:lan4", - }, - { - .name =3D "mx100:green:lan5", - }, - { - .name =3D "mx100:green:lan6", - }, - { - .name =3D "mx100:green:lan7", - }, - { - .name =3D "mx100:green:lan8", - }, - { - .name =3D "mx100:green:lan9", - }, - { - .name =3D "mx100:green:lan10", - }, - { - .name =3D "mx100:green:lan11", - }, - { - .name =3D "mx100:green:ha", - }, - { - .name =3D "mx100:orange:ha", - }, - { - .name =3D "mx100:green:usb", - }, - { - .name =3D "mx100:orange:usb", - }, +static const struct software_node tink_gpio_leds_node =3D { + .name =3D "meraki-mx100-leds", }; =20 -static const struct gpio_led_platform_data tink_leds_pdata =3D { - .num_leds =3D ARRAY_SIZE(tink_leds), - .leds =3D tink_leds, -}; - -static struct gpiod_lookup_table tink_leds_table =3D { - .dev_id =3D "leds-gpio", - .table =3D { - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 11, - NULL, 0, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 18, - NULL, 1, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 20, - NULL, 2, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 22, - NULL, 3, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 23, - NULL, 4, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 32, - NULL, 5, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 34, - NULL, 6, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 35, - NULL, 7, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 36, - NULL, 8, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 37, - NULL, 9, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 48, - NULL, 10, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 16, - NULL, 11, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 7, - NULL, 12, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 21, - NULL, 13, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 19, - NULL, 14, GPIO_ACTIVE_LOW), - {} /* Terminating entry */ - } +static const struct property_entry tink_internet_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:internet"), + PROPERTY_ENTRY_STRING("linux,default-trigger", "default-on"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 11, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node tink_internet_led_node =3D { + .name =3D "internet-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_internet_led_props, +}; + +static const struct property_entry tink_lan2_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan2"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 18, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan2_led_node =3D { + .name =3D "lan2-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan2_led_props, +}; + +static const struct property_entry tink_lan3_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan3"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 20, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan3_led_node =3D { + .name =3D "lan3-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan3_led_props, +}; + +static const struct property_entry tink_lan4_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan4"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 22, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan4_led_node =3D { + .name =3D "lan4-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan4_led_props, +}; + +static const struct property_entry tink_lan5_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan5"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 23, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan5_led_node =3D { + .name =3D "lan5-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan5_led_props, +}; + +static const struct property_entry tink_lan6_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan6"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 32, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan6_led_node =3D { + .name =3D "lan6-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan6_led_props, +}; + +static const struct property_entry tink_lan7_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan7"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 34, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan7_led_node =3D { + .name =3D "lan7-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan7_led_props, +}; + +static const struct property_entry tink_lan8_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan8"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 35, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan8_led_node =3D { + .name =3D "lan8-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan8_led_props, +}; + +static const struct property_entry tink_lan9_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan9"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 36, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan9_led_node =3D { + .name =3D "lan9-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan9_led_props, +}; + +static const struct property_entry tink_lan10_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan10"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 37, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan10_led_node =3D { + .name =3D "lan10-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan10_led_props, +}; + +static const struct property_entry tink_lan11_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:lan11"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 48, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node tink_lan11_led_node =3D { + .name =3D "lan11-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_lan11_led_props, +}; + +static const struct property_entry tink_ha_green_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:ha"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 16, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node tink_ha_green_led_node =3D { + .name =3D "ha-green-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_ha_green_led_props, +}; + +static const struct property_entry tink_ha_orange_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:orange:ha"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 7, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node tink_ha_orange_led_node =3D { + .name =3D "ha-orange-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_ha_orange_led_props, +}; + +static const struct property_entry tink_usb_green_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:green:usb"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 21, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node tink_usb_green_led_node =3D { + .name =3D "usb-green-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_usb_green_led_props, +}; + +static const struct property_entry tink_usb_orange_led_props[] =3D { + PROPERTY_ENTRY_STRING("label", "mx100:orange:usb"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 19, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node tink_usb_orange_led_node =3D { + .name =3D "usb-orange-led", + .parent =3D &tink_gpio_leds_node, + .properties =3D tink_usb_orange_led_props, }; =20 /* Reset Button */ -static struct gpio_keys_button tink_buttons[] =3D { - { - .desc =3D "Reset", - .type =3D EV_KEY, - .code =3D KEY_RESTART, - .active_low =3D 1, - .debounce_interval =3D 100, - }, +static const struct property_entry tink_gpio_keys_props[] =3D { + PROPERTY_ENTRY_U32("poll-interval", 20), + { } }; =20 -static const struct gpio_keys_platform_data tink_buttons_pdata =3D { - .buttons =3D tink_buttons, - .nbuttons =3D ARRAY_SIZE(tink_buttons), - .poll_interval =3D 20, - .rep =3D 0, - .name =3D "mx100-keys", +static const struct software_node tink_gpio_keys_node =3D { + .name =3D "mx100-keys", + .properties =3D tink_gpio_keys_props, }; =20 -static struct gpiod_lookup_table tink_keys_table =3D { - .dev_id =3D "gpio-keys-polled", - .table =3D { - GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 60, - NULL, 0, GPIO_ACTIVE_LOW), - {} /* Terminating entry */ - } +static const struct property_entry tink_reset_key_props[] =3D { + PROPERTY_ENTRY_U32("linux,code", KEY_RESTART), + PROPERTY_ENTRY_STRING("label", "Reset"), + PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 60, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("linux,input-type", EV_KEY), + PROPERTY_ENTRY_U32("debounce-interval", 100), + { } +}; + +static const struct software_node tink_reset_key_node =3D { + .name =3D "reset", + .parent =3D &tink_gpio_keys_node, + .properties =3D tink_reset_key_props, +}; + +static const struct software_node *tink_swnodes[] =3D { + &gpio_ich_node, + /* LEDs nodes */ + &tink_gpio_leds_node, + &tink_internet_led_node, + &tink_lan2_led_node, + &tink_lan3_led_node, + &tink_lan4_led_node, + &tink_lan5_led_node, + &tink_lan6_led_node, + &tink_lan7_led_node, + &tink_lan8_led_node, + &tink_lan9_led_node, + &tink_lan10_led_node, + &tink_lan11_led_node, + &tink_ha_green_led_node, + &tink_ha_orange_led_node, + &tink_usb_green_led_node, + &tink_usb_orange_led_node, + /* Keys nodes */ + &tink_gpio_keys_node, + &tink_reset_key_node, + NULL }; =20 /* Board setup */ @@ -161,22 +282,17 @@ MODULE_DEVICE_TABLE(dmi, tink_systems); static struct platform_device *tink_leds_pdev; static struct platform_device *tink_keys_pdev; =20 -static struct platform_device * __init tink_create_dev( - const char *name, const void *pdata, size_t sz) -{ - struct platform_device *pdev; - - pdev =3D platform_device_register_data(NULL, - name, PLATFORM_DEVID_NONE, pdata, sz); - if (IS_ERR(pdev)) - pr_err("failed registering %s: %ld\n", name, PTR_ERR(pdev)); - - return pdev; -} - static int __init tink_board_init(void) { - int ret; + struct platform_device_info keys_info =3D { + .name =3D "gpio-keys-polled", + .id =3D PLATFORM_DEVID_NONE, + }; + struct platform_device_info leds_info =3D { + .name =3D "leds-gpio", + .id =3D PLATFORM_DEVID_NONE, + }; + int err; =20 if (!dmi_first_match(tink_systems)) return -ENODEV; @@ -188,30 +304,35 @@ static int __init tink_board_init(void) */ outl(inl(0x530) | BIT(28), 0x530); =20 - gpiod_add_lookup_table(&tink_leds_table); - gpiod_add_lookup_table(&tink_keys_table); + err =3D software_node_register_node_group(tink_swnodes); + if (err) { + pr_err("failed to register software nodes: %d\n", err); + return err; + } =20 - tink_leds_pdev =3D tink_create_dev("leds-gpio", - &tink_leds_pdata, sizeof(tink_leds_pdata)); + leds_info.fwnode =3D software_node_fwnode(&tink_gpio_leds_node); + tink_leds_pdev =3D platform_device_register_full(&leds_info); if (IS_ERR(tink_leds_pdev)) { - ret =3D PTR_ERR(tink_leds_pdev); - goto err; + err =3D PTR_ERR(tink_leds_pdev); + pr_err("failed to create LED device: %d\n", err); + goto err_unregister_swnodes; } =20 - tink_keys_pdev =3D tink_create_dev("gpio-keys-polled", - &tink_buttons_pdata, sizeof(tink_buttons_pdata)); + keys_info.fwnode =3D software_node_fwnode(&tink_gpio_keys_node); + tink_keys_pdev =3D platform_device_register_full(&keys_info); if (IS_ERR(tink_keys_pdev)) { - ret =3D PTR_ERR(tink_keys_pdev); - platform_device_unregister(tink_leds_pdev); - goto err; + err =3D PTR_ERR(tink_keys_pdev); + pr_err("failed to create key device: %d\n", err); + goto err_unregister_leds; } =20 return 0; =20 -err: - gpiod_remove_lookup_table(&tink_keys_table); - gpiod_remove_lookup_table(&tink_leds_table); - return ret; +err_unregister_leds: + platform_device_unregister(tink_leds_pdev); +err_unregister_swnodes: + software_node_unregister_node_group(tink_swnodes); + return err; } module_init(tink_board_init); =20 @@ -219,8 +340,7 @@ static void __exit tink_board_exit(void) { platform_device_unregister(tink_keys_pdev); platform_device_unregister(tink_leds_pdev); - gpiod_remove_lookup_table(&tink_keys_table); - gpiod_remove_lookup_table(&tink_leds_table); + software_node_unregister_node_group(tink_swnodes); } module_exit(tink_board_exit); =20 --=20 2.51.0.rc0.155.g4a0f42376b-goog --=20 Dmitry