From 355486a914f043e09568e03d987bccc5402a0695 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 8 Sep 2006 10:54:03 +0300 Subject: [PATCH] MUSB: Add back irq_work for cable events This is needed to avoid sleeping function called from invalid context. Signed-off-by: Tony Lindgren Signed-off-by: David Brownell --- drivers/usb/musb/musb_gadget.c | 4 ++-- drivers/usb/musb/musbdefs.h | 1 + drivers/usb/musb/plat_uds.c | 14 ++++++++++++-- drivers/usb/musb/tusb6010.c | 4 ++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c1652124ebb..df9d2245f1f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -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); diff --git a/drivers/usb/musb/musbdefs.h b/drivers/usb/musb/musbdefs.h index a4512a62c06..6ec73166fad 100644 --- a/drivers/usb/musb/musbdefs.h +++ b/drivers/usb/musb/musbdefs.h @@ -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 diff --git a/drivers/usb/musb/plat_uds.c b/drivers/usb/musb/plat_uds.c index 4f859246f9c..2d684c0870c 100644 --- a/drivers/usb/musb/plat_uds.c +++ b/drivers/usb/musb/plat_uds.c @@ -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); diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 9f145e5c165..182711e09f5 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -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); -- 2.41.1