@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <linux/irq_sim.h>
#include <linux/irqdomain.h>
+#include <linux/list.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
@@ -24,12 +25,11 @@
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define GPIO_MOCKUP_MAX_GC 10
/*
* We're storing two values per chip: the GPIO base and the number
* of GPIO lines.
*/
-#define GPIO_MOCKUP_MAX_RANGES (GPIO_MOCKUP_MAX_GC * 2)
+#define GPIO_MOCKUP_MAX_RANGES (10 * 2)
/* Maximum of three properties + the sentinel. */
#define GPIO_MOCKUP_MAX_PROP 4
@@ -505,27 +505,37 @@ static struct platform_driver gpio_mockup_driver = {
.probe = gpio_mockup_probe,
};
-static struct platform_device *gpio_mockup_pdevs[GPIO_MOCKUP_MAX_GC];
+struct gpio_mockup_device {
+ struct list_head list;
+ struct platform_device *pdev;
+};
-static void gpio_mockup_unregister_pdevs(void)
+static LIST_HEAD(gpio_mockup_devices);
+
+static void gpio_mockup_unregister_one_device(struct gpio_mockup_device *dev)
{
- struct platform_device *pdev;
- int i;
+ list_del(&dev->list);
+ platform_device_unregister(dev->pdev);
+ kfree(dev);
+}
- for (i = 0; i < GPIO_MOCKUP_MAX_GC; i++) {
- pdev = gpio_mockup_pdevs[i];
+static void gpio_mockup_unregister_devices(void)
+{
+ struct gpio_mockup_device *mockup_dev;
+ struct list_head *curr, *next;
- if (pdev)
- platform_device_unregister(pdev);
+ list_for_each_safe(curr, next, &gpio_mockup_devices) {
+ mockup_dev = list_entry(curr, struct gpio_mockup_device, list);
+ gpio_mockup_unregister_one_device(mockup_dev);
}
}
static int __init gpio_mockup_init(void)
{
struct property_entry properties[GPIO_MOCKUP_MAX_PROP];
+ struct gpio_mockup_device *mockup_dev;
int i, prop, num_chips, err = 0, base;
struct platform_device_info pdevinfo;
- struct platform_device *pdev;
u16 ngpio;
if ((gpio_mockup_num_ranges < 2) ||
@@ -576,26 +586,37 @@ static int __init gpio_mockup_init(void)
pdevinfo.id = i;
pdevinfo.properties = properties;
- pdev = platform_device_register_full(&pdevinfo);
- if (IS_ERR(pdev)) {
+ mockup_dev = kzalloc(sizeof(*mockup_dev), GFP_KERNEL);
+ if (!mockup_dev) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ mockup_dev->pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(mockup_dev->pdev)) {
pr_err("error registering device");
- platform_driver_unregister(&gpio_mockup_driver);
- gpio_mockup_unregister_pdevs();
- debugfs_remove_recursive(gpio_mockup_dbg_dir);
- return PTR_ERR(pdev);
+ kfree(mockup_dev);
+ err = PTR_ERR(mockup_dev->pdev);
+ goto err_out;
}
- gpio_mockup_pdevs[i] = pdev;
+ list_add(&mockup_dev->list, &gpio_mockup_devices);
}
return 0;
+
+err_out:
+ platform_driver_unregister(&gpio_mockup_driver);
+ gpio_mockup_unregister_devices();
+ debugfs_remove_recursive(gpio_mockup_dbg_dir);
+ return err;
}
static void __exit gpio_mockup_exit(void)
{
debugfs_remove_recursive(gpio_mockup_dbg_dir);
platform_driver_unregister(&gpio_mockup_driver);
- gpio_mockup_unregister_pdevs();
+ gpio_mockup_unregister_devices();
}
module_init(gpio_mockup_init);