usb: gadget: pch_udc: Revert d3cb25a121
completely
The commitd3cb25a121
("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 revertd3cb25a121
completely. While at it, narrow down the scope of unlocked section to prevent potential race when prot_stall is assigned. Fixes:d3cb25a121
("usb: gadget: udc: fix spin_lock in pch_udc") Fixes:9903b6bedd
("usb: gadget: pch-udc: fix lock") Fixes:1d23d16a88
("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>
This commit is contained in:
parent
5af196df27
commit
50a318cc9b
@ -597,18 +597,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1167,20 +1171,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user