aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
authorStephan Gatzka <stephan@gatzka.org>2011-07-25 16:16:24 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2011-09-16 16:30:28 -0400
commit2d7a36e23300d268599f6eae4093643d22fbb356 (patch)
tree8ab2e18f979af804a4f069ac77cbbd34801c5e88 /drivers/firewire/ohci.c
parent32ce38f40337cf4a805552e494354d961587c838 (diff)
firewire: ohci: Move code from the bus reset tasklet into a workqueue
Code inside bus_reset_work may now sleep. This is a prerequisite to support a phy from Texas Instruments cleanly. The patch to support this phy will be submitted later. Signed-off-by: Stephan Gatzka <stephan@gatzka.org> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index fd7170a9ad2c..c026f46fc157 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -42,6 +42,7 @@
42#include <linux/string.h> 42#include <linux/string.h>
43#include <linux/time.h> 43#include <linux/time.h>
44#include <linux/vmalloc.h> 44#include <linux/vmalloc.h>
45#include <linux/workqueue.h>
45 46
46#include <asm/byteorder.h> 47#include <asm/byteorder.h>
47#include <asm/page.h> 48#include <asm/page.h>
@@ -226,7 +227,7 @@ struct fw_ohci {
226 227
227 __le32 *self_id_cpu; 228 __le32 *self_id_cpu;
228 dma_addr_t self_id_bus; 229 dma_addr_t self_id_bus;
229 struct tasklet_struct bus_reset_tasklet; 230 struct work_struct bus_reset_work;
230 231
231 u32 self_id_buffer[512]; 232 u32 self_id_buffer[512];
232}; 233};
@@ -859,7 +860,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
859 * 860 *
860 * Alas some chips sometimes emit bus reset packets with a 861 * Alas some chips sometimes emit bus reset packets with a
861 * wrong generation. We set the correct generation for these 862 * wrong generation. We set the correct generation for these
862 * at a slightly incorrect time (in bus_reset_tasklet). 863 * at a slightly incorrect time (in bus_reset_work).
863 */ 864 */
864 if (evt == OHCI1394_evt_bus_reset) { 865 if (evt == OHCI1394_evt_bus_reset) {
865 if (!(ohci->quirks & QUIRK_RESET_PACKET)) 866 if (!(ohci->quirks & QUIRK_RESET_PACKET))
@@ -1713,9 +1714,10 @@ static u32 update_bus_time(struct fw_ohci *ohci)
1713 return ohci->bus_time | cycle_time_seconds; 1714 return ohci->bus_time | cycle_time_seconds;
1714} 1715}
1715 1716
1716static void bus_reset_tasklet(unsigned long data) 1717static void bus_reset_work(struct work_struct *work)
1717{ 1718{
1718 struct fw_ohci *ohci = (struct fw_ohci *)data; 1719 struct fw_ohci *ohci =
1720 container_of(work, struct fw_ohci, bus_reset_work);
1719 int self_id_count, i, j, reg; 1721 int self_id_count, i, j, reg;
1720 int generation, new_generation; 1722 int generation, new_generation;
1721 unsigned long flags; 1723 unsigned long flags;
@@ -1887,7 +1889,7 @@ static irqreturn_t irq_handler(int irq, void *data)
1887 log_irqs(event); 1889 log_irqs(event);
1888 1890
1889 if (event & OHCI1394_selfIDComplete) 1891 if (event & OHCI1394_selfIDComplete)
1890 tasklet_schedule(&ohci->bus_reset_tasklet); 1892 queue_work(fw_workqueue, &ohci->bus_reset_work);
1891 1893
1892 if (event & OHCI1394_RQPkt) 1894 if (event & OHCI1394_RQPkt)
1893 tasklet_schedule(&ohci->ar_request_ctx.tasklet); 1895 tasklet_schedule(&ohci->ar_request_ctx.tasklet);
@@ -2260,7 +2262,7 @@ static int ohci_set_config_rom(struct fw_card *card,
2260 * then set up the real values for the two registers. 2262 * then set up the real values for the two registers.
2261 * 2263 *
2262 * We use ohci->lock to avoid racing with the code that sets 2264 * We use ohci->lock to avoid racing with the code that sets
2263 * ohci->next_config_rom to NULL (see bus_reset_tasklet). 2265 * ohci->next_config_rom to NULL (see bus_reset_work).
2264 */ 2266 */
2265 2267
2266 next_config_rom = 2268 next_config_rom =
@@ -3239,8 +3241,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
3239 spin_lock_init(&ohci->lock); 3241 spin_lock_init(&ohci->lock);
3240 mutex_init(&ohci->phy_reg_mutex); 3242 mutex_init(&ohci->phy_reg_mutex);
3241 3243
3242 tasklet_init(&ohci->bus_reset_tasklet, 3244 INIT_WORK(&ohci->bus_reset_work, bus_reset_work);
3243 bus_reset_tasklet, (unsigned long)ohci);
3244 3245
3245 err = pci_request_region(dev, 0, ohci_driver_name); 3246 err = pci_request_region(dev, 0, ohci_driver_name);
3246 if (err) { 3247 if (err) {
@@ -3382,6 +3383,7 @@ static void pci_remove(struct pci_dev *dev)
3382 ohci = pci_get_drvdata(dev); 3383 ohci = pci_get_drvdata(dev);
3383 reg_write(ohci, OHCI1394_IntMaskClear, ~0); 3384 reg_write(ohci, OHCI1394_IntMaskClear, ~0);
3384 flush_writes(ohci); 3385 flush_writes(ohci);
3386 cancel_work_sync(&ohci->bus_reset_work);
3385 fw_core_remove_card(&ohci->card); 3387 fw_core_remove_card(&ohci->card);
3386 3388
3387 /* 3389 /*