Alan,

> 
> > This regulator is only available after scu is initialized.
> > So we need to declare it in the scu initialized callback.
> 
> Why not just delay the wl12xx creation the same way as I²C and SPI
> devices can already be delayed ? No need for hacks nailed onto the end
> of the creation code that will end up with hack after hack for devices
> otherwise.
Because the wl12xx is not i2c nor spi driver, and has a number of specific init 
that must be done after scu is up.

Would you be happier if we propose another solution based on the following 
refactorisation of delayed devices mechanism:

From 2811c70dae93ad1907277bbb8b0ee352980e3b48 Mon Sep 17 00:00:00 2001
From: Pierre Tardy <[email protected]>
Date: Thu, 18 Nov 2010 20:11:37 +0100
Subject: [PATCH] mrst.c: make the delayed device mechanism more generic

This allows platform drivers with uncommon requirements
to fit the design pattern more cleanly.
This patch is a proof of concept and is untested.

Signed-off-by: Pierre Tardy <[email protected]>
---
 arch/x86/kernel/mrst.c |  106 ++++++++++++++++++++++++-----------------------
 1 files changed, 54 insertions(+), 52 deletions(-)

diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c
index 0ad674e..5697173 100644
--- a/arch/x86/kernel/mrst.c
+++ b/arch/x86/kernel/mrst.c
@@ -1078,59 +1078,79 @@ static const struct devs_id device_ids[] = {
        {},
 };
 
-#define MAX_IPCDEVS    20
-static struct platform_device *ipc_devs[MAX_IPCDEVS];
-static int ipc_next_dev;
-
-#define MAX_DELAYED_SPI        20
-static struct spi_board_info *spi_devs[MAX_DELAYED_SPI];
-static int spi_next_dev;
-
-#define MAX_DELAYED_I2C        20
-static struct i2c_board_info *i2c_devs[MAX_DELAYED_SPI];
-static int i2c_bus[MAX_DELAYED_I2C];
-static int i2c_next_dev;
+#define MAX_DELAYEDDEVS        60
+static void *delayed_devs[MAX_DELAYEDDEVS];
+typedef void (*delayed_callback_t)(void*dev_desc);
+static delayed_callback_t delayed_callbacks[MAX_DELAYEDDEVS];
+static int delayed_next_dev;
 
+static void intel_delayed_device_register(void*dev,  void 
(*delayed_callback)(void*dev_desc))
+{
+       delayed_devs[delayed_next_dev] = dev;
+       delayed_callbacks[delayed_next_dev++] = delayed_callback;
+       BUG_ON(delayed_next_dev == MAX_DELAYEDDEVS);
+}
+static void intel_scu_device_register_cb(void *pdev)
+{
+       platform_device_register((struct platform_device*)pdev);
+}
 static void intel_scu_device_register(struct platform_device *pdev)
 {
-       BUG_ON(ipc_next_dev == MAX_IPCDEVS);
-       ipc_devs[ipc_next_dev++] = pdev;
+       intel_delayed_device_register(pdev, intel_scu_device_register_cb);
+}
+static void intel_delayed_spi_device_register_cb(void *dev)
+{
+       spi_register_board_info(dev, 1);
+       kfree(dev);
 }
 
 static void intel_delayed_spi_device_register(struct spi_board_info *sdev)
 {
        struct spi_board_info *new_dev;
 
-       BUG_ON(spi_next_dev == MAX_DELAYED_SPI);
-
-       new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+       new_dev = kmemdup(sdev, sizeof(*sdev), GFP_KERNEL);
        if (!new_dev) {
                pr_err("MRST: fail to alloc mem for delayed spi dev %s\n",
                        sdev->modalias);
                return;
        }
-       memcpy(new_dev, sdev, sizeof(*sdev));
-
-       spi_devs[spi_next_dev++] = new_dev;
+       intel_delayed_device_register(sdev, 
intel_delayed_spi_device_register_cb);
+}
+struct i2c_delayed_dev
+{
+       int bus;
+       struct i2c_board_info dev;
+};
+static void intel_delayed_i2c_device_register_cb(void *dev)
+{
+       struct i2c_delayed_dev *idev = (struct i2c_delayed_dev*)dev;
+       struct i2c_adapter *adapter;
+       struct i2c_client *client;
+
+       adapter = i2c_get_adapter(idev->bus);
+       if (adapter) {
+               client = i2c_new_device(adapter, &idev->dev);
+               if (!client)
+                       pr_err("mrst: can't create i2c device %s\n",
+                              idev->dev.type);
+       } else
+               i2c_register_board_info(idev->bus, &idev->dev, 1);
+       kfree(idev);
 }
-
 static void intel_delayed_i2c_device_register(int bus,
                                                struct i2c_board_info *idev)
 {
-       struct i2c_board_info *new_dev;
+       struct i2c_delayed_dev *new_dev;
 
-       BUG_ON(i2c_next_dev == MAX_DELAYED_I2C);
-
-       new_dev = kzalloc(sizeof(*idev), GFP_KERNEL);
+       new_dev = kzalloc(sizeof(struct i2c_delayed_dev), GFP_KERNEL);
        if (!new_dev) {
                pr_err("MRST: fail to alloc mem for delayed i2c dev %s\n",
                        idev->type);
                return;
        }
-       memcpy(new_dev, idev, sizeof(*idev));
-
-       i2c_bus[i2c_next_dev] = bus;
-       i2c_devs[i2c_next_dev++] = new_dev;
+       new_dev->bus = bus;
+       memcpy(&new_dev->dev, idev, sizeof(*idev));
+       intel_delayed_device_register(idev, 
intel_delayed_i2c_device_register_cb);
 }
 
 /* Called by IPC driver */
@@ -1138,28 +1158,9 @@ void intel_scu_devices_create(void)
 {
        int i;
 
-       for (i = 0; i < ipc_next_dev; i++)
-               platform_device_add(ipc_devs[i]);
+       for (i = 0; i < delayed_next_dev; i++)
+               delayed_callbacks[i](delayed_devs[i]);
 
-       for (i = 0; i < spi_next_dev; i++) {
-               spi_register_board_info(spi_devs[i], 1);
-               kfree(spi_devs[i]);
-       }
-
-       for (i = 0; i < i2c_next_dev; i++) {
-               struct i2c_adapter *adapter;
-               struct i2c_client *client;
-
-               adapter = i2c_get_adapter(i2c_bus[i]);
-               if (adapter) {
-                       client = i2c_new_device(adapter, i2c_devs[i]);
-                       if (!client)
-                               pr_err("mrst: can't create i2c device %s\n",
-                                       i2c_devs[i]->type);
-               } else
-                       i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
-               kfree(i2c_devs[i]);
-       }
 }
 EXPORT_SYMBOL_GPL(intel_scu_devices_create);
 
@@ -1168,8 +1169,9 @@ void intel_scu_devices_destroy(void)
 {
        int i;
 
-       for (i = 0; i < ipc_next_dev; i++)
-               platform_device_del(ipc_devs[i]);
+       for (i = 0; i < delayed_next_dev; i++)
+               if (delayed_callbacks[i] == intel_scu_device_register_cb)
+                       platform_device_del(delayed_devs[i]);
 }
 EXPORT_SYMBOL_GPL(intel_scu_devices_destroy);
 
-- 
1.7.0.4

---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris, 
92196 Meudon Cedex, France
Registration Number:  302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to