Merge tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
[pandora-kernel.git] / drivers / mfd / twl-core.c
index 3d70012..4ae6423 100644 (file)
@@ -1104,12 +1104,7 @@ static void clocks_init(struct device *dev,
        u32 rate;
        u8 ctrl = HFCLK_FREQ_26_MHZ;
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       if (cpu_is_omap2430())
-               osc = clk_get(dev, "osc_ck");
-       else
-               osc = clk_get(dev, "osc_sys_ck");
-
+       osc = clk_get(dev, "fck");
        if (IS_ERR(osc)) {
                printk(KERN_WARNING "Skipping twl internal clock init and "
                                "using bootloader value (unknown osc rate)\n");
@@ -1119,18 +1114,6 @@ static void clocks_init(struct device *dev,
        rate = clk_get_rate(osc);
        clk_put(osc);
 
-#else
-       /* REVISIT for non-OMAP systems, pass the clock rate from
-        * board init code, using platform_data.
-        */
-       osc = ERR_PTR(-EIO);
-
-       printk(KERN_WARNING "Skipping twl internal clock init and "
-              "using bootloader value (unknown osc rate)\n");
-
-       return;
-#endif
-
        switch (rate) {
        case 19200000:
                ctrl = HFCLK_FREQ_19p2_MHZ;
@@ -1192,10 +1175,23 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
        struct twl4030_platform_data    *pdata = client->dev.platform_data;
        struct device_node              *node = client->dev.of_node;
+       struct platform_device          *pdev;
        int                             irq_base = 0;
        int                             status;
        unsigned                        i, num_slaves;
 
+       pdev = platform_device_alloc(DRIVER_NAME, -1);
+       if (!pdev) {
+               dev_err(&client->dev, "can't alloc pdev\n");
+               return -ENOMEM;
+       }
+
+       status = platform_device_add(pdev);
+       if (status) {
+               platform_device_put(pdev);
+               return status;
+       }
+
        if (node && !pdata) {
                /*
                 * XXX: Temporary pdata until the information is correctly
@@ -1204,23 +1200,30 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
                pdata = devm_kzalloc(&client->dev,
                                     sizeof(struct twl4030_platform_data),
                                     GFP_KERNEL);
-               if (!pdata)
-                       return -ENOMEM;
+               if (!pdata) {
+                       status = -ENOMEM;
+                       goto free;
+               }
        }
 
        if (!pdata) {
                dev_dbg(&client->dev, "no platform data?\n");
-               return -EINVAL;
+               status = -EINVAL;
+               goto free;
        }
 
+       platform_set_drvdata(pdev, pdata);
+
        if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
                dev_dbg(&client->dev, "can't talk I2C?\n");
-               return -EIO;
+               status = -EIO;
+               goto free;
        }
 
        if (inuse) {
                dev_dbg(&client->dev, "driver is already in use\n");
-               return -EBUSY;
+               status = -EBUSY;
+               goto free;
        }
 
        if ((id->driver_data) & TWL6030_CLASS) {
@@ -1255,7 +1258,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
        inuse = true;
 
        /* setup clock framework */
-       clocks_init(&client->dev, pdata->clock);
+       clocks_init(&pdev->dev, pdata->clock);
 
        /* read TWL IDCODE Register */
        if (twl_id == TWL4030_CLASS_ID) {
@@ -1305,6 +1308,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 fail:
        if (status < 0)
                twl_remove(client);
+free:
+       if (status < 0)
+               platform_device_unregister(pdev);
 
        return status;
 }