@@ -285,6 +285,8 @@ struct wl1251_if_operations {
void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
void (*reset)(struct wl1251 *wl);
+ void (*enable_irq)(struct wl1251 *wl);
+ void (*disable_irq)(struct wl1251 *wl);
};
struct wl1251 {
@@ -404,10 +406,11 @@ struct wl1251 {
int wl1251_plt_start(struct wl1251 *wl);
int wl1251_plt_stop(struct wl1251 *wl);
-irqreturn_t wl1251_irq(int irq, void *cookie);
struct ieee80211_hw *wl1251_alloc_hw(void);
int wl1251_free_hw(struct wl1251 *wl);
int wl1251_init_ieee80211(struct wl1251 *wl);
+void wl1251_enable_interrupts(struct wl1251 *wl);
+void wl1251_disable_interrupts(struct wl1251 *wl);
#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */
#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS
@@ -29,11 +29,6 @@
#include "wl1251_spi.h"
#include "wl1251_event.h"
-static void wl1251_boot_enable_interrupts(struct wl1251 *wl)
-{
- enable_irq(wl->irq);
-}
-
void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
{
wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
@@ -278,7 +273,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
*/
/* enable gpio interrupts */
- wl1251_boot_enable_interrupts(wl);
+ wl1251_enable_interrupts(wl);
wl->chip.op_target_enable_interrupts(wl);
@@ -42,9 +42,14 @@
#include "wl1251_init.h"
#include "wl1251_debugfs.h"
-static void wl1251_disable_interrupts(struct wl1251 *wl)
+void wl1251_enable_interrupts(struct wl1251 *wl)
{
- disable_irq(wl->irq);
+ wl->if_ops->enable_irq(wl);
+}
+
+void wl1251_disable_interrupts(struct wl1251 *wl)
+{
+ wl->if_ops->disable_irq(wl);
}
static void wl1251_power_off(struct wl1251 *wl)
@@ -57,20 +62,6 @@ static void wl1251_power_on(struct wl1251 *wl)
wl->set_power(true);
}
-irqreturn_t wl1251_irq(int irq, void *cookie)
-{
- struct wl1251 *wl;
-
- wl1251_debug(DEBUG_IRQ, "IRQ");
-
- wl = cookie;
-
- schedule_work(&wl->irq_work);
-
- return IRQ_HANDLED;
-}
-EXPORT_SYMBOL_GPL(wl1251_irq);
-
static int wl1251_fetch_firmware(struct wl1251 *wl)
{
const struct firmware *fw;
@@ -1280,7 +1271,6 @@ int wl1251_free_hw(struct wl1251 *wl)
wl1251_debugfs_exit(wl);
- free_irq(wl->irq, wl);
kfree(wl->target_mem_map);
kfree(wl->data_path);
kfree(wl->fw);
@@ -50,7 +50,12 @@ static struct sdio_func *wl_to_func(struct wl1251 *wl)
static void wl1251_sdio_interrupt(struct sdio_func *func)
{
- wl1251_irq(0, sdio_get_drvdata(func));
+ struct wl1251 *wl = sdio_get_drvdata(func);
+
+ wl1251_debug(DEBUG_IRQ, "IRQ");
+
+ /* FIXME should be synchronous for sdio */
+ schedule_work(&wl->irq_work);
}
static const struct sdio_device_id wl1251_devices[] = {
@@ -88,6 +93,24 @@ void wl1251_sdio_reset(struct wl1251 *wl)
{
}
+static void wl1251_sdio_enable_irq(struct wl1251 *wl)
+{
+ struct sdio_func *func = wl_to_func(wl);
+
+ sdio_claim_host(func);
+ sdio_claim_irq(func, wl1251_sdio_interrupt);
+ sdio_release_host(func);
+}
+
+static void wl1251_sdio_disable_irq(struct wl1251 *wl)
+{
+ struct sdio_func *func = wl_to_func(wl);
+
+ sdio_claim_host(func);
+ sdio_release_irq(func);
+ sdio_release_host(func);
+}
+
void wl1251_sdio_set_power(bool enable)
{
}
@@ -96,6 +119,8 @@ struct wl1251_if_operations wl1251_sdio_ops = {
.read = wl1251_sdio_read,
.write = wl1251_sdio_write,
.reset = wl1251_sdio_reset,
+ .enable_irq = wl1251_sdio_enable_irq,
+ .disable_irq = wl1251_sdio_disable_irq,
};
int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
@@ -124,21 +149,14 @@ int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
sdio_release_host(func);
ret = wl1251_init_ieee80211(wl);
- sdio_claim_host(func);
if (ret)
goto disable;
- ret = sdio_claim_irq(func, wl1251_sdio_interrupt);
- if (ret)
- goto no_irq;
-
- sdio_release_host(func);
sdio_set_drvdata(func, wl);
return ret;
-no_irq:
- wl1251_free_hw(wl);
disable:
+ sdio_claim_host(func);
sdio_disable_func(func);
release:
sdio_release_host(func);
@@ -31,6 +31,19 @@
#include "reg.h"
#include "wl1251_spi.h"
+static irqreturn_t wl1251_irq(int irq, void *cookie)
+{
+ struct wl1251 *wl;
+
+ wl1251_debug(DEBUG_IRQ, "IRQ");
+
+ wl = cookie;
+
+ schedule_work(&wl->irq_work);
+
+ return IRQ_HANDLED;
+}
+
static struct spi_device *wl_to_spi(struct wl1251 *wl)
{
return wl->if_priv;
@@ -193,10 +206,22 @@ static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
}
+static void wl1251_spi_enable_irq(struct wl1251 *wl)
+{
+ return enable_irq(wl->irq);
+}
+
+static void wl1251_spi_disable_irq(struct wl1251 *wl)
+{
+ return disable_irq(wl->irq);
+}
+
static const struct wl1251_if_operations wl1251_spi_ops = {
.read = wl1251_spi_read,
.write = wl1251_spi_write,
.reset = wl1251_spi_reset_wake,
+ .enable_irq = wl1251_spi_enable_irq,
+ .disable_irq = wl1251_spi_disable_irq,
};
static int __devinit wl1251_spi_probe(struct spi_device *spi)
@@ -274,6 +299,7 @@ static int __devexit wl1251_spi_remove(struct spi_device *spi)
{
struct wl1251 *wl = dev_get_drvdata(&spi->dev);
+ free_irq(wl->irq, wl);
wl1251_free_hw(wl);
return 0;