wl12xx: move common init code from bus modules to main
authorFelipe Balbi <balbi@ti.com>
Thu, 6 Oct 2011 07:07:44 +0000 (10:07 +0300)
committerLuciano Coelho <coelho@ti.com>
Tue, 11 Oct 2011 13:01:09 +0000 (16:01 +0300)
Move all common parts from sdio.c and spi.c to main.c, since they now
can be handled as part of the platform driver.

Signed-off-by: Felipe Balbi <balbi@ti.com>
[forward-ported, cleaned-up and rephrased commit message]
[added a bunch of fixes and a new pdata element]
[moved some new code into main.c as well]
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/io.c
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx_platform_data.c
include/linux/wl12xx.h

index c2da66f45046774e183160bb45f6ef6bc773a5d3..1a7df8a7ed2d9745eef4b9ef61f4fcb26513c2bc 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/interrupt.h>
 
 #include "wl12xx.h"
 #include "wl12xx_80211.h"
@@ -46,7 +47,7 @@
 bool wl1271_set_block_size(struct wl1271 *wl)
 {
        if (wl->if_ops->set_block_size) {
-               wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE);
+               wl->if_ops->set_block_size(wl->dev, WL12XX_BUS_BLOCK_SIZE);
                return true;
        }
 
@@ -55,12 +56,12 @@ bool wl1271_set_block_size(struct wl1271 *wl)
 
 void wl1271_disable_interrupts(struct wl1271 *wl)
 {
-       wl->if_ops->disable_irq(wl);
+       disable_irq(wl->irq);
 }
 
 void wl1271_enable_interrupts(struct wl1271 *wl)
 {
-       wl->if_ops->enable_irq(wl);
+       enable_irq(wl->irq);
 }
 
 /* Set the SPI partitions to access the chip addresses
@@ -128,13 +129,13 @@ EXPORT_SYMBOL_GPL(wl1271_set_partition);
 void wl1271_io_reset(struct wl1271 *wl)
 {
        if (wl->if_ops->reset)
-               wl->if_ops->reset(wl);
+               wl->if_ops->reset(wl->dev);
 }
 
 void wl1271_io_init(struct wl1271 *wl)
 {
        if (wl->if_ops->init)
-               wl->if_ops->init(wl);
+               wl->if_ops->init(wl->dev);
 }
 
 void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
index e839341dfafeac3faa0b0c0d7daf22171a149fd9..e82dad19aa30afbc9adec0aaa33351ffb740cfb6 100644 (file)
@@ -51,23 +51,17 @@ void wl1271_enable_interrupts(struct wl1271 *wl);
 void wl1271_io_reset(struct wl1271 *wl);
 void wl1271_io_init(struct wl1271 *wl);
 
-static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl)
-{
-       return wl->if_ops->dev(wl);
-}
-
-
 /* Raw target IO, address is not translated */
 static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
                                    size_t len, bool fixed)
 {
-       wl->if_ops->write(wl, addr, buf, len, fixed);
+       wl->if_ops->write(wl->dev, addr, buf, len, fixed);
 }
 
 static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
                                   size_t len, bool fixed)
 {
-       wl->if_ops->read(wl, addr, buf, len, fixed);
+       wl->if_ops->read(wl->dev, addr, buf, len, fixed);
 }
 
 static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
@@ -155,13 +149,13 @@ static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
 
 static inline void wl1271_power_off(struct wl1271 *wl)
 {
-       wl->if_ops->power(wl, false);
+       wl->if_ops->power(wl->dev, false);
        clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 }
 
 static inline int wl1271_power_on(struct wl1271 *wl)
 {
-       int ret = wl->if_ops->power(wl, true);
+       int ret = wl->if_ops->power(wl->dev, true);
        if (ret == 0)
                set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 
index 3262e8a6c4750f6ee86c17a7bc65411566ebdc7f..1cf987785053d518863ce4984f6ddf5f1cb14735 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/wl12xx.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 
 #include "wl12xx.h"
 #include "wl12xx_80211.h"
@@ -1067,7 +1068,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
 
        wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);
 
-       ret = request_firmware(&fw, fw_name, wl1271_wl_to_dev(wl));
+       ret = request_firmware(&fw, fw_name, wl->dev);
 
        if (ret < 0) {
                wl1271_error("could not get firmware: %d", ret);
@@ -1105,7 +1106,7 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
        const struct firmware *fw;
        int ret;
 
-       ret = request_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl));
+       ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev);
 
        if (ret < 0) {
                wl1271_error("could not get nvs file: %d", ret);
@@ -4979,7 +4980,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
 
        wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
 
-       SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
+       SET_IEEE80211_DEV(wl->hw, wl->dev);
 
        wl->hw->sta_data_size = sizeof(struct wl1271_station);
        wl->hw->vif_data_size = sizeof(struct wl12xx_vif);
@@ -5200,13 +5201,116 @@ int wl1271_free_hw(struct wl1271 *wl)
 }
 EXPORT_SYMBOL_GPL(wl1271_free_hw);
 
+static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
+{
+       struct wl1271 *wl = cookie;
+       unsigned long flags;
+
+       wl1271_debug(DEBUG_IRQ, "IRQ");
+
+       /* complete the ELP completion */
+       spin_lock_irqsave(&wl->wl_lock, flags);
+       set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
+       if (wl->elp_compl) {
+               complete(wl->elp_compl);
+               wl->elp_compl = NULL;
+       }
+
+       if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
+               /* don't enqueue a work right now. mark it as pending */
+               set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
+               wl1271_debug(DEBUG_IRQ, "should not enqueue work");
+               disable_irq_nosync(wl->irq);
+               pm_wakeup_event(wl->dev, 0);
+               spin_unlock_irqrestore(&wl->wl_lock, flags);
+               return IRQ_HANDLED;
+       }
+       spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+       return IRQ_WAKE_THREAD;
+}
+
 static int __devinit wl12xx_probe(struct platform_device *pdev)
 {
+       struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
+       struct ieee80211_hw *hw;
+       struct wl1271 *wl;
+       unsigned long irqflags;
+       int ret = -ENODEV;
+
+       hw = wl1271_alloc_hw();
+       if (IS_ERR(hw)) {
+               wl1271_error("can't allocate hw");
+               ret = PTR_ERR(hw);
+               goto out;
+       }
+
+       wl = hw->priv;
+       wl->irq = platform_get_irq(pdev, 0);
+       wl->ref_clock = pdata->board_ref_clock;
+       wl->tcxo_clock = pdata->board_tcxo_clock;
+       wl->platform_quirks = pdata->platform_quirks;
+       wl->set_power = pdata->set_power;
+       wl->dev = &pdev->dev;
+       wl->if_ops = pdata->ops;
+
+       platform_set_drvdata(pdev, wl);
+
+       if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+               irqflags = IRQF_TRIGGER_RISING;
+       else
+               irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+
+       ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wl1271_irq,
+                                  irqflags,
+                                  pdev->name, wl);
+       if (ret < 0) {
+               wl1271_error("request_irq() failed: %d", ret);
+               goto out_free_hw;
+       }
+
+       ret = enable_irq_wake(wl->irq);
+       if (!ret) {
+               wl->irq_wake_enabled = true;
+               device_init_wakeup(wl->dev, 1);
+               if (pdata->pwr_in_suspend)
+                       hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
+
+       }
+       disable_irq(wl->irq);
+
+       ret = wl1271_init_ieee80211(wl);
+       if (ret)
+               goto out_irq;
+
+       ret = wl1271_register_hw(wl);
+       if (ret)
+               goto out_irq;
+
        return 0;
+
+out_irq:
+       free_irq(wl->irq, wl);
+
+out_free_hw:
+       wl1271_free_hw(wl);
+
+out:
+       return ret;
 }
 
 static int __devexit wl12xx_remove(struct platform_device *pdev)
 {
+       struct wl1271 *wl = platform_get_drvdata(pdev);
+
+       if (wl->irq_wake_enabled) {
+               device_init_wakeup(wl->dev, 0);
+               disable_irq_wake(wl->irq);
+       }
+       wl1271_unregister_hw(wl);
+       free_irq(wl->irq, wl);
+       wl1271_free_hw(wl);
+
        return 0;
 }
 
index e7ee5d155d347a1cf78c82e0389062fdd8ddb156..78e5352c40378c05afa4b1f834e0841706aa87b1 100644 (file)
@@ -47,7 +47,6 @@
 
 struct wl12xx_sdio_glue {
        struct device *dev;
-       struct wl1271 *wl;
        struct platform_device *core;
 };
 
@@ -57,67 +56,22 @@ static const struct sdio_device_id wl1271_devices[] __devinitconst = {
 };
 MODULE_DEVICE_TABLE(sdio, wl1271_devices);
 
-static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz)
+static void wl1271_sdio_set_block_size(struct device *child,
+                                      unsigned int blksz)
 {
-       sdio_claim_host(wl->if_priv);
-       sdio_set_block_size(wl->if_priv, blksz);
-       sdio_release_host(wl->if_priv);
-}
-
-static inline struct wl12xx_sdio_glue *wl_to_glue(struct wl1271 *wl)
-{
-       return wl->if_priv;
-}
-
-static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
-{
-       return wl_to_glue(wl)->dev;
-}
-
-static irqreturn_t wl1271_hardirq(int irq, void *cookie)
-{
-       struct wl1271 *wl = cookie;
-       unsigned long flags;
-
-       wl1271_debug(DEBUG_IRQ, "IRQ");
-
-       /* complete the ELP completion */
-       spin_lock_irqsave(&wl->wl_lock, flags);
-       set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
-       if (wl->elp_compl) {
-               complete(wl->elp_compl);
-               wl->elp_compl = NULL;
-       }
-
-       if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
-               /* don't enqueue a work right now. mark it as pending */
-               set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
-               wl1271_debug(DEBUG_IRQ, "should not enqueue work");
-               disable_irq_nosync(wl->irq);
-               pm_wakeup_event(wl1271_sdio_wl_to_dev(wl), 0);
-               spin_unlock_irqrestore(&wl->wl_lock, flags);
-               return IRQ_HANDLED;
-       }
-       spin_unlock_irqrestore(&wl->wl_lock, flags);
-
-       return IRQ_WAKE_THREAD;
-}
-
-static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
-{
-       disable_irq(wl->irq);
-}
+       struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+       struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
-static void wl1271_sdio_enable_interrupts(struct wl1271 *wl)
-{
-       enable_irq(wl->irq);
+       sdio_claim_host(func);
+       sdio_set_block_size(func, blksz);
+       sdio_release_host(func);
 }
 
-static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
+static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
                                 size_t len, bool fixed)
 {
        int ret;
-       struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
+       struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
        if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
@@ -139,11 +93,11 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
                wl1271_error("sdio read failed (%d)", ret);
 }
 
-static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
+static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
                                  size_t len, bool fixed)
 {
        int ret;
-       struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
+       struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
        if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
@@ -165,10 +119,9 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
                wl1271_error("sdio write failed (%d)", ret);
 }
 
-static int wl1271_sdio_power_on(struct wl1271 *wl)
+static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
 {
        int ret;
-       struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
        /* If enabled, tell runtime PM not to power off the card */
@@ -190,10 +143,9 @@ out:
        return ret;
 }
 
-static int wl1271_sdio_power_off(struct wl1271 *wl)
+static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
 {
        int ret;
-       struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
        sdio_disable_func(func);
@@ -211,33 +163,29 @@ static int wl1271_sdio_power_off(struct wl1271 *wl)
        return ret;
 }
 
-static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+static int wl12xx_sdio_set_power(struct device *child, bool enable)
 {
+       struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+
        if (enable)
-               return wl1271_sdio_power_on(wl);
+               return wl12xx_sdio_power_on(glue);
        else
-               return wl1271_sdio_power_off(wl);
+               return wl12xx_sdio_power_off(glue);
 }
 
 static struct wl1271_if_operations sdio_ops = {
-       .read           = wl1271_sdio_raw_read,
-       .write          = wl1271_sdio_raw_write,
-       .power          = wl1271_sdio_set_power,
-       .dev            = wl1271_sdio_wl_to_dev,
-       .enable_irq     = wl1271_sdio_enable_interrupts,
-       .disable_irq    = wl1271_sdio_disable_interrupts,
+       .read           = wl12xx_sdio_raw_read,
+       .write          = wl12xx_sdio_raw_write,
+       .power          = wl12xx_sdio_set_power,
        .set_block_size = wl1271_sdio_set_block_size,
 };
 
 static int __devinit wl1271_probe(struct sdio_func *func,
                                  const struct sdio_device_id *id)
 {
-       struct ieee80211_hw *hw;
-       const struct wl12xx_platform_data *wlan_data;
-       struct wl1271 *wl;
+       struct wl12xx_platform_data *wlan_data;
        struct wl12xx_sdio_glue *glue;
        struct resource res[1];
-       unsigned long irqflags;
        mmc_pm_flag_t mmcflags;
        int ret = -ENOMEM;
 
@@ -251,20 +199,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
                goto out;
        }
 
-       hw = wl1271_alloc_hw();
-       if (IS_ERR(hw)) {
-               wl1271_error("can't allocate hw");
-               ret = PTR_ERR(hw);
-               goto out_free_glue;
-       }
-
-       wl = hw->priv;
-
        glue->dev = &func->dev;
-       glue->wl = wl;
-
-       wl->if_priv = glue;
-       wl->if_ops = &sdio_ops;
 
        /* Grab access to FN0 for ELP reg. */
        func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
@@ -276,48 +211,17 @@ static int __devinit wl1271_probe(struct sdio_func *func,
        if (IS_ERR(wlan_data)) {
                ret = PTR_ERR(wlan_data);
                wl1271_error("missing wlan platform data: %d", ret);
-               goto out_free_hw;
-       }
-
-       wl->irq = wlan_data->irq;
-       wl->ref_clock = wlan_data->board_ref_clock;
-       wl->tcxo_clock = wlan_data->board_tcxo_clock;
-       wl->platform_quirks = wlan_data->platform_quirks;
-
-       if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
-               irqflags = IRQF_TRIGGER_RISING;
-       else
-               irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
-
-       ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
-                                  irqflags,
-                                  DRIVER_NAME, wl);
-       if (ret < 0) {
-               wl1271_error("request_irq() failed: %d", ret);
-               goto out_free_hw;
+               goto out_free_glue;
        }
 
-       ret = enable_irq_wake(wl->irq);
-       if (!ret) {
-               wl->irq_wake_enabled = true;
-               device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1);
+       /* if sdio can keep power while host is suspended, enable wow */
+       mmcflags = sdio_get_host_pm_caps(func);
+       wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags);
 
-               /* if sdio can keep power while host is suspended, enable wow */
-               mmcflags = sdio_get_host_pm_caps(func);
-               wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags);
+       if (mmcflags & MMC_PM_KEEP_POWER)
+               wlan_data->pwr_in_suspend = true;
 
-               if (mmcflags & MMC_PM_KEEP_POWER)
-                       hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
-       }
-       disable_irq(wl->irq);
-
-       ret = wl1271_init_ieee80211(wl);
-       if (ret)
-               goto out_irq;
-
-       ret = wl1271_register_hw(wl);
-       if (ret)
-               goto out_irq;
+       wlan_data->ops = &sdio_ops;
 
        sdio_set_drvdata(func, glue);
 
@@ -328,7 +232,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
        if (!glue->core) {
                wl1271_error("can't allocate platform_device");
                ret = -ENOMEM;
-               goto out_unreg_hw;
+               goto out_free_glue;
        }
 
        glue->core->dev.parent = &func->dev;
@@ -362,17 +266,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 out_dev_put:
        platform_device_put(glue->core);
 
-out_unreg_hw:
-       wl1271_unregister_hw(wl);
-
-out_irq:
-       free_irq(wl->irq, wl);
-
-out_free_hw:
-       wl1271_free_hw(wl);
-
 out_free_glue:
        kfree(glue);
+
 out:
        return ret;
 }
@@ -380,18 +276,10 @@ out:
 static void __devexit wl1271_remove(struct sdio_func *func)
 {
        struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
-       struct wl1271 *wl = glue->wl;
 
        /* Undo decrement done above in wl1271_probe */
        pm_runtime_get_noresume(&func->dev);
 
-       wl1271_unregister_hw(wl);
-       if (wl->irq_wake_enabled) {
-               device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0);
-               disable_irq_wake(wl->irq);
-       }
-       free_irq(wl->irq, wl);
-       wl1271_free_hw(wl);
        platform_device_del(glue->core);
        platform_device_put(glue->core);
        kfree(glue);
index 2dd659886a04c27c7c2679faeabfed38c2c8a73e..22c1337ba883600ac65b94aaf36b42a09eaf8852 100644 (file)
 
 struct wl12xx_spi_glue {
        struct device *dev;
-       struct wl1271 *wl;
        struct platform_device *core;
 };
 
-static inline struct wl12xx_spi_glue *wl_to_glue(struct wl1271 *wl)
+static void wl12xx_spi_reset(struct device *child)
 {
-       return wl->if_priv;
-}
-
-static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl)
-{
-       return wl_to_glue(wl)->dev;
-}
-
-static void wl1271_spi_disable_interrupts(struct wl1271 *wl)
-{
-       disable_irq(wl->irq);
-}
-
-static void wl1271_spi_enable_interrupts(struct wl1271 *wl)
-{
-       enable_irq(wl->irq);
-}
-
-static void wl1271_spi_reset(struct wl1271 *wl)
-{
-       struct wl12xx_spi_glue *glue = wl_to_glue(wl);
+       struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
        u8 *cmd;
        struct spi_transfer t;
        struct spi_message m;
@@ -124,9 +103,9 @@ static void wl1271_spi_reset(struct wl1271 *wl)
        kfree(cmd);
 }
 
-static void wl1271_spi_init(struct wl1271 *wl)
+static void wl12xx_spi_init(struct device *child)
 {
-       struct wl12xx_spi_glue *glue = wl_to_glue(wl);
+       struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
        u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
        struct spi_transfer t;
        struct spi_message m;
@@ -181,9 +160,10 @@ static void wl1271_spi_init(struct wl1271 *wl)
 
 #define WL1271_BUSY_WORD_TIMEOUT 1000
 
-static int wl1271_spi_read_busy(struct wl1271 *wl)
+static int wl12xx_spi_read_busy(struct device *child)
 {
-       struct wl12xx_spi_glue *glue = wl_to_glue(wl);
+       struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+       struct wl1271 *wl = dev_get_drvdata(child);
        struct spi_transfer t[1];
        struct spi_message m;
        u32 *busy_buf;
@@ -215,10 +195,11 @@ static int wl1271_spi_read_busy(struct wl1271 *wl)
        return -ETIMEDOUT;
 }
 
-static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
+static void wl12xx_spi_raw_read(struct device *child, int addr, void *buf,
                                size_t len, bool fixed)
 {
-       struct wl12xx_spi_glue *glue = wl_to_glue(wl);
+       struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+       struct wl1271 *wl = dev_get_drvdata(child);
        struct spi_transfer t[2];
        struct spi_message m;
        u32 *busy_buf;
@@ -257,7 +238,7 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
                spi_sync(to_spi_device(glue->dev), &m);
 
                if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
-                   wl1271_spi_read_busy(wl)) {
+                   wl12xx_spi_read_busy(child)) {
                        memset(buf, 0, chunk_len);
                        return;
                }
@@ -282,10 +263,10 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
        }
 }
 
-static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
-                         size_t len, bool fixed)
+static void wl12xx_spi_raw_write(struct device *child, int addr, void *buf,
+                                size_t len, bool fixed)
 {
-       struct wl12xx_spi_glue *glue = wl_to_glue(wl);
+       struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
        struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
        struct spi_message m;
        u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
@@ -333,42 +314,11 @@ static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
        spi_sync(to_spi_device(glue->dev), &m);
 }
 
-static irqreturn_t wl1271_hardirq(int irq, void *cookie)
-{
-       struct wl1271 *wl = cookie;
-       unsigned long flags;
-
-       wl1271_debug(DEBUG_IRQ, "IRQ");
-
-       /* complete the ELP completion */
-       spin_lock_irqsave(&wl->wl_lock, flags);
-       set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
-       if (wl->elp_compl) {
-               complete(wl->elp_compl);
-               wl->elp_compl = NULL;
-       }
-       spin_unlock_irqrestore(&wl->wl_lock, flags);
-
-       return IRQ_WAKE_THREAD;
-}
-
-static int wl1271_spi_set_power(struct wl1271 *wl, bool enable)
-{
-       if (wl->set_power)
-               wl->set_power(enable);
-
-       return 0;
-}
-
 static struct wl1271_if_operations spi_ops = {
-       .read           = wl1271_spi_raw_read,
-       .write          = wl1271_spi_raw_write,
-       .reset          = wl1271_spi_reset,
-       .init           = wl1271_spi_init,
-       .power          = wl1271_spi_set_power,
-       .dev            = wl1271_spi_wl_to_dev,
-       .enable_irq     = wl1271_spi_enable_interrupts,
-       .disable_irq    = wl1271_spi_disable_interrupts,
+       .read           = wl12xx_spi_raw_read,
+       .write          = wl12xx_spi_raw_write,
+       .reset          = wl12xx_spi_reset,
+       .init           = wl12xx_spi_init,
        .set_block_size = NULL,
 };
 
@@ -376,10 +326,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
 {
        struct wl12xx_spi_glue *glue;
        struct wl12xx_platform_data *pdata;
-       struct ieee80211_hw *hw;
-       struct wl1271 *wl;
        struct resource res[1];
-       unsigned long irqflags;
        int ret = -ENOMEM;
 
        pdata = spi->dev.platform_data;
@@ -388,27 +335,17 @@ static int __devinit wl1271_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
+       pdata->ops = &spi_ops;
+
        glue = kzalloc(sizeof(*glue), GFP_KERNEL);
        if (!glue) {
                wl1271_error("can't allocate glue");
                goto out;
        }
 
-       hw = wl1271_alloc_hw();
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto out_free_glue;
-       }
-
-       wl = hw->priv;
-
        glue->dev = &spi->dev;
-       glue->wl = wl;
 
        spi_set_drvdata(spi, glue);
-       wl->if_priv = glue;
-
-       wl->if_ops = &spi_ops;
 
        /* This is the only SPI value that we need to set here, the rest
         * comes from the board-peripherals file */
@@ -417,55 +354,14 @@ static int __devinit wl1271_probe(struct spi_device *spi)
        ret = spi_setup(spi);
        if (ret < 0) {
                wl1271_error("spi_setup failed");
-               goto out_free_hw;
-       }
-
-       wl->set_power = pdata->set_power;
-       if (!wl->set_power) {
-               wl1271_error("set power function missing in platform data");
-               ret = -ENODEV;
-               goto out_free_hw;
-       }
-
-       wl->ref_clock = pdata->board_ref_clock;
-       wl->tcxo_clock = pdata->board_tcxo_clock;
-       wl->platform_quirks = pdata->platform_quirks;
-
-       if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
-               irqflags = IRQF_TRIGGER_RISING;
-       else
-               irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
-
-       wl->irq = spi->irq;
-       if (wl->irq < 0) {
-               wl1271_error("irq missing in platform data");
-               ret = -ENODEV;
-               goto out_free_hw;
-       }
-
-       ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
-                                  irqflags,
-                                  DRIVER_NAME, wl);
-       if (ret < 0) {
-               wl1271_error("request_irq() failed: %d", ret);
-               goto out_free_hw;
+               goto out_free_glue;
        }
 
-       disable_irq(wl->irq);
-
-       ret = wl1271_init_ieee80211(wl);
-       if (ret)
-               goto out_irq;
-
-       ret = wl1271_register_hw(wl);
-       if (ret)
-               goto out_irq;
-
        glue->core = platform_device_alloc("wl12xx-spi", -1);
        if (!glue->core) {
                wl1271_error("can't allocate platform_device");
                ret = -ENOMEM;
-               goto out_unreg_hw;
+               goto out_free_glue;
        }
 
        glue->core->dev.parent = &spi->dev;
@@ -499,15 +395,6 @@ static int __devinit wl1271_probe(struct spi_device *spi)
 out_dev_put:
        platform_device_put(glue->core);
 
-out_unreg_hw:
-       wl1271_unregister_hw(wl);
-
-out_irq:
-       free_irq(wl->irq, wl);
-
-out_free_hw:
-       wl1271_free_hw(wl);
-
 out_free_glue:
        kfree(glue);
 out:
@@ -517,11 +404,7 @@ out:
 static int __devexit wl1271_remove(struct spi_device *spi)
 {
        struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
-       struct wl1271 *wl = glue->wl;
 
-       wl1271_unregister_hw(wl);
-       free_irq(wl->irq, wl);
-       wl1271_free_hw(wl);
        platform_device_del(glue->core);
        platform_device_put(glue->core);
        kfree(glue);
index 8815fd9a0f47cfcc5dbafb3af3275cdd0e08dfe0..d2028939eee5bf07379d4639eb84060a13a94fd3 100644 (file)
@@ -288,17 +288,14 @@ struct wl1271_scan {
 };
 
 struct wl1271_if_operations {
-       void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len,
+       void (*read)(struct device *child, int addr, void *buf, size_t len,
                     bool fixed);
-       void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len,
+       void (*write)(struct device *child, int addr, void *buf, size_t len,
                     bool fixed);
-       void (*reset)(struct wl1271 *wl);
-       void (*init)(struct wl1271 *wl);
-       int (*power)(struct wl1271 *wl, bool enable);
-       struct device* (*dev)(struct wl1271 *wl);
-       void (*enable_irq)(struct wl1271 *wl);
-       void (*disable_irq)(struct wl1271 *wl);
-       void (*set_block_size) (struct wl1271 *wl, unsigned int blksz);
+       void (*reset)(struct device *child);
+       void (*init)(struct device *child);
+       int (*power)(struct device *child, bool enable);
+       void (*set_block_size) (struct device *child, unsigned int blksz);
 };
 
 #define MAX_NUM_KEYS 14
@@ -362,6 +359,8 @@ struct wl1271 {
        struct ieee80211_hw *hw;
        bool mac80211_registered;
 
+       struct device *dev;
+
        void *if_priv;
 
        struct wl1271_if_operations *if_ops;
index 973b11060a8f2674d2ff75b72209c51d4ec95ace..3c96b332184ee059c91ef3452e498a9e7ad7223d 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/err.h>
 #include <linux/wl12xx.h>
 
-static const struct wl12xx_platform_data *platform_data;
+static struct wl12xx_platform_data *platform_data;
 
 int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 {
@@ -18,7 +18,7 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
        return 0;
 }
 
-const struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 {
        if (!platform_data)
                return ERR_PTR(-ENODEV);
index 4b697395326eb4e660a099faf352a91c0c8df915..0d6373195d32c115a1d0f86b2a8ebe43e9ba7f46 100644 (file)
@@ -54,6 +54,9 @@ struct wl12xx_platform_data {
        int board_ref_clock;
        int board_tcxo_clock;
        unsigned long platform_quirks;
+       bool pwr_in_suspend;
+
+       struct wl1271_if_operations *ops;
 };
 
 /* Platform does not support level trigger interrupts */
@@ -73,6 +76,6 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 
 #endif
 
-const struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+struct wl12xx_platform_data *wl12xx_get_platform_data(void);
 
 #endif