aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2400pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 25e9dcf65c4e..116244b72371 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -879,7 +879,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
879static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 879static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
880 enum dev_state state) 880 enum dev_state state)
881{ 881{
882 int mask = (state == STATE_RADIO_IRQ_OFF); 882 int mask = (state == STATE_RADIO_IRQ_OFF) ||
883 (state == STATE_RADIO_IRQ_OFF_ISR);
883 u32 reg; 884 u32 reg;
884 885
885 /* 886 /*
@@ -980,7 +981,9 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
980 rt2400pci_toggle_rx(rt2x00dev, state); 981 rt2400pci_toggle_rx(rt2x00dev, state);
981 break; 982 break;
982 case STATE_RADIO_IRQ_ON: 983 case STATE_RADIO_IRQ_ON:
984 case STATE_RADIO_IRQ_ON_ISR:
983 case STATE_RADIO_IRQ_OFF: 985 case STATE_RADIO_IRQ_OFF:
986 case STATE_RADIO_IRQ_OFF_ISR:
984 rt2400pci_toggle_irq(rt2x00dev, state); 987 rt2400pci_toggle_irq(rt2x00dev, state);
985 break; 988 break;
986 case STATE_DEEP_SLEEP: 989 case STATE_DEEP_SLEEP:
@@ -1235,23 +1238,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
1235 } 1238 }
1236} 1239}
1237 1240
1238static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) 1241static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
1239{ 1242{
1240 struct rt2x00_dev *rt2x00dev = dev_instance; 1243 struct rt2x00_dev *rt2x00dev = dev_instance;
1241 u32 reg; 1244 u32 reg = rt2x00dev->irqvalue[0];
1242
1243 /*
1244 * Get the interrupt sources & saved to local variable.
1245 * Write register value back to clear pending interrupts.
1246 */
1247 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1248 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1249
1250 if (!reg)
1251 return IRQ_NONE;
1252
1253 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1254 return IRQ_HANDLED;
1255 1245
1256 /* 1246 /*
1257 * Handle interrupts, walk through all bits 1247 * Handle interrupts, walk through all bits
@@ -1289,9 +1279,40 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
1289 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) 1279 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
1290 rt2400pci_txdone(rt2x00dev, QID_AC_BK); 1280 rt2400pci_txdone(rt2x00dev, QID_AC_BK);
1291 1281
1282 /* Enable interrupts again. */
1283 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
1284 STATE_RADIO_IRQ_ON_ISR);
1292 return IRQ_HANDLED; 1285 return IRQ_HANDLED;
1293} 1286}
1294 1287
1288static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
1289{
1290 struct rt2x00_dev *rt2x00dev = dev_instance;
1291 u32 reg;
1292
1293 /*
1294 * Get the interrupt sources & saved to local variable.
1295 * Write register value back to clear pending interrupts.
1296 */
1297 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1298 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1299
1300 if (!reg)
1301 return IRQ_NONE;
1302
1303 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1304 return IRQ_HANDLED;
1305
1306 /* Store irqvalues for use in the interrupt thread. */
1307 rt2x00dev->irqvalue[0] = reg;
1308
1309 /* Disable interrupts, will be enabled again in the interrupt thread. */
1310 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
1311 STATE_RADIO_IRQ_OFF_ISR);
1312
1313 return IRQ_WAKE_THREAD;
1314}
1315
1295/* 1316/*
1296 * Device probe functions. 1317 * Device probe functions.
1297 */ 1318 */
@@ -1581,6 +1602,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1581 1602
1582static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { 1603static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1583 .irq_handler = rt2400pci_interrupt, 1604 .irq_handler = rt2400pci_interrupt,
1605 .irq_handler_thread = rt2400pci_interrupt_thread,
1584 .probe_hw = rt2400pci_probe_hw, 1606 .probe_hw = rt2400pci_probe_hw,
1585 .initialize = rt2x00pci_initialize, 1607 .initialize = rt2x00pci_initialize,
1586 .uninitialize = rt2x00pci_uninitialize, 1608 .uninitialize = rt2x00pci_uninitialize,