diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 54 |
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, | |||
879 | static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | 879 | static 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 | ||
1238 | static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | 1241 | static 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, ®); | ||
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 | ||
1288 | static 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, ®); | ||
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 | ||
1582 | static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | 1603 | static 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, |