Skip to content

Commit

Permalink
wl12xx: move common init code from bus modules to main
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Felipe Balbi authored and Luciano Coelho committed Oct 11, 2011
1 parent ce2a217 commit a390e85
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 312 deletions.
11 changes: 6 additions & 5 deletions drivers/net/wireless/wl12xx/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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;
}

Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
14 changes: 4 additions & 10 deletions drivers/net/wireless/wl12xx/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down
110 changes: 107 additions & 3 deletions drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
Loading

0 comments on commit a390e85

Please sign in to comment.