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>
This commit is contained in:
parent
32ce38f403
commit
2d7a36e233
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
@ -226,7 +227,7 @@ struct fw_ohci {
|
||||||
|
|
||||||
__le32 *self_id_cpu;
|
__le32 *self_id_cpu;
|
||||||
dma_addr_t self_id_bus;
|
dma_addr_t self_id_bus;
|
||||||
struct tasklet_struct bus_reset_tasklet;
|
struct work_struct bus_reset_work;
|
||||||
|
|
||||||
u32 self_id_buffer[512];
|
u32 self_id_buffer[512];
|
||||||
};
|
};
|
||||||
|
@ -859,7 +860,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
||||||
*
|
*
|
||||||
* Alas some chips sometimes emit bus reset packets with a
|
* Alas some chips sometimes emit bus reset packets with a
|
||||||
* wrong generation. We set the correct generation for these
|
* wrong generation. We set the correct generation for these
|
||||||
* at a slightly incorrect time (in bus_reset_tasklet).
|
* at a slightly incorrect time (in bus_reset_work).
|
||||||
*/
|
*/
|
||||||
if (evt == OHCI1394_evt_bus_reset) {
|
if (evt == OHCI1394_evt_bus_reset) {
|
||||||
if (!(ohci->quirks & QUIRK_RESET_PACKET))
|
if (!(ohci->quirks & QUIRK_RESET_PACKET))
|
||||||
|
@ -1713,9 +1714,10 @@ static u32 update_bus_time(struct fw_ohci *ohci)
|
||||||
return ohci->bus_time | cycle_time_seconds;
|
return ohci->bus_time | cycle_time_seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bus_reset_tasklet(unsigned long data)
|
static void bus_reset_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct fw_ohci *ohci = (struct fw_ohci *)data;
|
struct fw_ohci *ohci =
|
||||||
|
container_of(work, struct fw_ohci, bus_reset_work);
|
||||||
int self_id_count, i, j, reg;
|
int self_id_count, i, j, reg;
|
||||||
int generation, new_generation;
|
int generation, new_generation;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1887,7 +1889,7 @@ static irqreturn_t irq_handler(int irq, void *data)
|
||||||
log_irqs(event);
|
log_irqs(event);
|
||||||
|
|
||||||
if (event & OHCI1394_selfIDComplete)
|
if (event & OHCI1394_selfIDComplete)
|
||||||
tasklet_schedule(&ohci->bus_reset_tasklet);
|
queue_work(fw_workqueue, &ohci->bus_reset_work);
|
||||||
|
|
||||||
if (event & OHCI1394_RQPkt)
|
if (event & OHCI1394_RQPkt)
|
||||||
tasklet_schedule(&ohci->ar_request_ctx.tasklet);
|
tasklet_schedule(&ohci->ar_request_ctx.tasklet);
|
||||||
|
@ -2260,7 +2262,7 @@ static int ohci_set_config_rom(struct fw_card *card,
|
||||||
* then set up the real values for the two registers.
|
* then set up the real values for the two registers.
|
||||||
*
|
*
|
||||||
* We use ohci->lock to avoid racing with the code that sets
|
* We use ohci->lock to avoid racing with the code that sets
|
||||||
* ohci->next_config_rom to NULL (see bus_reset_tasklet).
|
* ohci->next_config_rom to NULL (see bus_reset_work).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
next_config_rom =
|
next_config_rom =
|
||||||
|
@ -3239,8 +3241,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
|
||||||
spin_lock_init(&ohci->lock);
|
spin_lock_init(&ohci->lock);
|
||||||
mutex_init(&ohci->phy_reg_mutex);
|
mutex_init(&ohci->phy_reg_mutex);
|
||||||
|
|
||||||
tasklet_init(&ohci->bus_reset_tasklet,
|
INIT_WORK(&ohci->bus_reset_work, bus_reset_work);
|
||||||
bus_reset_tasklet, (unsigned long)ohci);
|
|
||||||
|
|
||||||
err = pci_request_region(dev, 0, ohci_driver_name);
|
err = pci_request_region(dev, 0, ohci_driver_name);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -3382,6 +3383,7 @@ static void pci_remove(struct pci_dev *dev)
|
||||||
ohci = pci_get_drvdata(dev);
|
ohci = pci_get_drvdata(dev);
|
||||||
reg_write(ohci, OHCI1394_IntMaskClear, ~0);
|
reg_write(ohci, OHCI1394_IntMaskClear, ~0);
|
||||||
flush_writes(ohci);
|
flush_writes(ohci);
|
||||||
|
cancel_work_sync(&ohci->bus_reset_work);
|
||||||
fw_core_remove_card(&ohci->card);
|
fw_core_remove_card(&ohci->card);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue