Skip to content

Commit

Permalink
usb: gadget: pch_udc: Revert d3cb25a completely
Browse files Browse the repository at this point in the history
commit 50a318c upstream.

The commit d3cb25a ("usb: gadget: udc: fix spin_lock in pch_udc")
obviously was not thought through and had made the situation even worse
than it was before. Two changes after almost reverted it. but a few
leftovers have been left as it. With this revert d3cb25a completely.

While at it, narrow down the scope of unlocked section to prevent
potential race when prot_stall is assigned.

Fixes: d3cb25a ("usb: gadget: udc: fix spin_lock in pch_udc")
Fixes: 9903b6b ("usb: gadget: pch-udc: fix lock")
Fixes: 1d23d16 ("usb: gadget: pch_udc: reorder spin_[un]lock to avoid deadlock")
Cc: Iago Abal <mail@iagoabal.eu>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20210323153626.54908-5-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
andy-shev authored and gregkh committed May 22, 2021
1 parent 3db4eb9 commit 22d7a55
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions drivers/usb/gadget/udc/pch_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,18 +604,22 @@ static void pch_udc_reconnect(struct pch_udc_dev *dev)
static inline void pch_udc_vbus_session(struct pch_udc_dev *dev,
int is_active)
{
unsigned long iflags;

spin_lock_irqsave(&dev->lock, iflags);
if (is_active) {
pch_udc_reconnect(dev);
dev->vbus_session = 1;
} else {
if (dev->driver && dev->driver->disconnect) {
spin_lock(&dev->lock);
spin_unlock_irqrestore(&dev->lock, iflags);
dev->driver->disconnect(&dev->gadget);
spin_unlock(&dev->lock);
spin_lock_irqsave(&dev->lock, iflags);
}
pch_udc_set_disconnect(dev);
dev->vbus_session = 0;
}
spin_unlock_irqrestore(&dev->lock, iflags);
}

/**
Expand Down Expand Up @@ -1172,20 +1176,25 @@ static int pch_udc_pcd_selfpowered(struct usb_gadget *gadget, int value)
static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on)
{
struct pch_udc_dev *dev;
unsigned long iflags;

if (!gadget)
return -EINVAL;

dev = container_of(gadget, struct pch_udc_dev, gadget);

spin_lock_irqsave(&dev->lock, iflags);
if (is_on) {
pch_udc_reconnect(dev);
} else {
if (dev->driver && dev->driver->disconnect) {
spin_lock(&dev->lock);
spin_unlock_irqrestore(&dev->lock, iflags);
dev->driver->disconnect(&dev->gadget);
spin_unlock(&dev->lock);
spin_lock_irqsave(&dev->lock, iflags);
}
pch_udc_set_disconnect(dev);
}
spin_unlock_irqrestore(&dev->lock, iflags);

return 0;
}
Expand Down

0 comments on commit 22d7a55

Please sign in to comment.