#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/acpi.h>
+#include <linux/bug.h>
#include <linux/device.h>
#include <linux/dmi.h>
+#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/irq.h>
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;
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)
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) {