diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 021009e9085b..5db794d65eb5 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -11,8 +11,10 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include +#include #include #include #include @@ -360,6 +362,61 @@ static const struct software_node *cherryview_gpiochip_node_group[] = { NULL }; +static void gpio_secondary_unset(void *data) +{ + struct device *dev = data; + + set_secondary_fwnode(dev, NULL); +} + +static void gpio_secondary_unregister_node_group(void *data) +{ + const struct software_node **nodes = data; + + software_node_unregister_node_group(nodes); +} + +static int gpio_secondary_fwnode_init(struct device *parent) +{ + const struct software_node *const *swnode; + struct fwnode_handle *fwnode; + int ret; + + if (!gpiochip_node_group) + return 0; + + ret = software_node_register_node_group(gpiochip_node_group); + if (ret) + return ret; + + ret = devm_add_action_or_reset(parent, + gpio_secondary_unregister_node_group, + gpiochip_node_group); + if (ret) + return ret; + + for (swnode = gpiochip_node_group; *swnode; swnode++) { + struct device *dev __free(put_device) = + acpi_bus_find_device_by_name((*swnode)->name); + if (!dev) + return dev_err_probe(parent, + -ENODEV, "Failed to find the required GPIO controller: %s\n", + (*swnode)->name); + + fwnode = software_node_fwnode(*swnode); + if (WARN_ON(!fwnode)) + return -ENOENT; + + set_secondary_fwnode(dev, fwnode); + + ret = devm_add_action_or_reset(parent, gpio_secondary_unset, dev); + if (ret) + return ret; + } + + return 0; +} + static void x86_android_tablet_remove(struct platform_device *pdev) { int i; @@ -391,7 +448,6 @@ static void x86_android_tablet_remove(struct platform_device *pdev) software_node_unregister_node_group(gpio_button_swnodes); software_node_unregister_node_group(swnode_group); - software_node_unregister_node_group(gpiochip_node_group); } static __init int x86_android_tablet_probe(struct platform_device *pdev) @@ -427,9 +483,11 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) break; } - ret = software_node_register_node_group(gpiochip_node_group); - if (ret) + ret = gpio_secondary_fwnode_init(&pdev->dev); + if (ret) { + x86_android_tablet_remove(pdev); return ret; + } ret = software_node_register_node_group(dev_info->swnode_group); if (ret) {