Commit 355486a9 authored by Tony Lindgren's avatar Tony Lindgren

MUSB: Add back irq_work for cable events

This is needed to avoid sleeping function called from invalid context.
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent f7efccb5
......@@ -973,7 +973,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
pEnd->dma ? "dma, " : "",
pEnd->wPacketSize);
sysfs_notify(&pThis->controller->kobj, NULL, "cable");
schedule_work(&pThis->irq_work);
fail:
spin_unlock_irqrestore(&pThis->Lock, flags);
......@@ -1016,7 +1016,7 @@ static int musb_gadget_disable(struct usb_ep *ep)
/* abort all pending DMA and requests */
nuke(pEnd, -ESHUTDOWN);
sysfs_notify(&pThis->controller->kobj, NULL, "cable");
schedule_work(&pThis->irq_work);
spin_unlock_irqrestore(&(pThis->Lock), flags);
......
......@@ -392,6 +392,7 @@ struct musb {
spinlock_t Lock;
struct clk *clock;
irqreturn_t (*isr)(int, void *, struct pt_regs *);
struct work_struct irq_work;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
......
......@@ -530,7 +530,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
(power & MGC_M_POWER_SUSPENDM)
? TRUE : FALSE);
sysfs_notify(&pThis->controller->kobj, NULL, "cable");
schedule_work(&pThis->irq_work);
}
handled = IRQ_HANDLED;
......@@ -615,7 +615,7 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
/* REVISIT all OTG state machine transitions */
otg_input_changed_X(pThis, FALSE, FALSE);
sysfs_notify(&pThis->controller->kobj, NULL, "cable");
schedule_work(&pThis->irq_work);
}
if (bIntrUSB & MGC_M_INTR_SUSPEND) {
......@@ -1461,6 +1461,14 @@ static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
#endif
/* Only used to provide cable state change events */
static void musb_irq_work(void *data)
{
struct musb *musb = (struct musb *)data;
sysfs_notify(&musb->controller->kobj, NULL, "cable");
}
/* --------------------------------------------------------------------------
* Init support
*/
......@@ -1736,6 +1744,8 @@ fail:
return status;
}
INIT_WORK(&pThis->irq_work, musb_irq_work, pThis);
#ifdef CONFIG_SYSFS
device_create_file(dev, &dev_attr_mode);
device_create_file(dev, &dev_attr_cable);
......
......@@ -344,7 +344,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *base)
DBG(1, "%s\n", musb->is_active
? "b_peripheral" : "b_idle");
sysfs_notify(&musb->controller->kobj, NULL, "cable");
schedule_work(&musb->irq_work);
}
}
......@@ -398,7 +398,7 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r)
musb_writel(base, TUSB_PRCM_WAKEUP_CLEAR, reg);
if (reg & ~TUSB_PRCM_WNORCS) {
musb->is_active = 1;
sysfs_notify(&musb->controller->kobj, NULL, "cable");
schedule_work(&musb->irq_work);
}
DBG(3, "wake %sactive %02x\n",
musb->is_active ? "" : "in", reg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment