diff options
| -rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/wl12xx/sdio.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/wl12xx/spi.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 3 | ||||
| -rw-r--r-- | include/linux/wl12xx.h | 4 | 
5 files changed, 32 insertions, 2 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 1feb9551ef8..7126506611c 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -30,6 +30,7 @@  #include <linux/vmalloc.h>  #include <linux/platform_device.h>  #include <linux/slab.h> +#include <linux/wl12xx.h>  #include "wl12xx.h"  #include "wl12xx_80211.h" @@ -719,6 +720,13 @@ irqreturn_t wl1271_irq(int irq, void *cookie)  	set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);  	cancel_work_sync(&wl->tx_work); +	/* +	 * In case edge triggered interrupt must be used, we cannot iterate +	 * more than once without introducing race conditions with the hardirq. +	 */ +	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) +		loopcount = 1; +  	mutex_lock(&wl->mutex);  	wl1271_debug(DEBUG_IRQ, "IRQ work"); @@ -3648,6 +3656,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)  	wl->ap_ps_map = 0;  	wl->ap_fw_ps_map = 0;  	wl->quirks = 0; +	wl->platform_quirks = 0;  	memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));  	for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 8246e9de430..bcd4ad7ba90 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -220,6 +220,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,  	struct ieee80211_hw *hw;  	const struct wl12xx_platform_data *wlan_data;  	struct wl1271 *wl; +	unsigned long irqflags;  	int ret;  	/* We are only able to handle the wlan function */ @@ -251,9 +252,15 @@ static int __devinit wl1271_probe(struct sdio_func *func,  	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, -				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT, +				   irqflags,  				   DRIVER_NAME, wl);  	if (ret < 0) {  		wl1271_error("request_irq() failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 7b82b5f0e49..51662bb6801 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -364,6 +364,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)  	struct wl12xx_platform_data *pdata;  	struct ieee80211_hw *hw;  	struct wl1271 *wl; +	unsigned long irqflags;  	int ret;  	pdata = spi->dev.platform_data; @@ -402,6 +403,12 @@ static int __devinit wl1271_probe(struct spi_device *spi)  	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) { @@ -411,7 +418,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)  	}  	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, -				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT, +				   irqflags,  				   DRIVER_NAME, wl);  	if (ret < 0) {  		wl1271_error("request_irq() failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 9ccbcfdd080..fb2b79fa42b 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -579,6 +579,9 @@ struct wl1271 {  	/* Quirks of specific hardware revisions */  	unsigned int quirks; + +	/* Platform limitations */ +	unsigned int platform_quirks;  };  struct wl1271_station { diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index c1a743ea747..4b697395326 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -53,8 +53,12 @@ struct wl12xx_platform_data {  	bool use_eeprom;  	int board_ref_clock;  	int board_tcxo_clock; +	unsigned long platform_quirks;  }; +/* Platform does not support level trigger interrupts */ +#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ	BIT(0) +  #ifdef CONFIG_WL12XX_PLATFORM_DATA  int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);  |