Add support for instantiating platform-devs, note this also makes some small changes to the i2c_client instantiating code to make the 2 flows identical. Specifically for the pdevs flow pdev_count must only be set after allocating the pdevs array, to avoid a NULL ptr deref in x86_android_tablet_cleanup() and the i2c_clients flow is updated to work the same way. Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- drivers/platform/x86/x86-android-tablets.c | 36 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c index 44138882bc9f..4bcad05d4039 100644 --- a/drivers/platform/x86/x86-android-tablets.c +++ b/drivers/platform/x86/x86-android-tablets.c @@ -20,6 +20,7 @@ #include <linux/irqdomain.h> #include <linux/module.h> #include <linux/mod_devicetable.h> +#include <linux/platform_device.h> #include <linux/string.h> /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */ #include "../../gpio/gpiolib.h" @@ -128,7 +129,9 @@ struct x86_i2c_client_info { struct x86_dev_info { const struct x86_i2c_client_info *i2c_client_info; + const struct platform_device_info *pdev_info; int i2c_client_count; + int pdev_count; }; /* @@ -269,7 +272,9 @@ static const struct dmi_system_id x86_android_tablet_ids[] __initconst = { MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids); static int i2c_client_count; +static int pdev_count; static struct i2c_client **i2c_clients; +static struct platform_device **pdevs; static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info, int idx) @@ -309,6 +314,11 @@ static void x86_android_tablet_cleanup(void) { int i; + for (i = 0; i < pdev_count; i++) + platform_device_unregister(pdevs[i]); + + kfree(pdevs); + for (i = 0; i < i2c_client_count; i++) i2c_unregister_device(i2c_clients[i]); @@ -327,21 +337,35 @@ static __init int x86_android_tablet_init(void) dev_info = id->driver_data; - i2c_client_count = dev_info->i2c_client_count; - - i2c_clients = kcalloc(i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); + i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); if (!i2c_clients) return -ENOMEM; - for (i = 0; i < dev_info->i2c_client_count; i++) { + i2c_client_count = dev_info->i2c_client_count; + for (i = 0; i < i2c_client_count; i++) { ret = x86_instantiate_i2c_client(dev_info, i); if (ret < 0) { x86_android_tablet_cleanup(); - break; + return ret; + } + } + + pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL); + if (!pdevs) { + x86_android_tablet_cleanup(); + return -ENOMEM; + } + + pdev_count = dev_info->pdev_count; + for (i = 0; i < pdev_count; i++) { + pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); + if (IS_ERR(pdevs[i])) { + x86_android_tablet_cleanup(); + return PTR_ERR(pdevs[i]); } } - return ret; + return 0; } module_init(x86_android_tablet_init); -- 2.33.1