mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
usb: gadget: pch_udc: Revert d3cb25a121 completely
commit50a318cc9bupstream. 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 revertd3cb25a121completely. 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
6b922dc1d1
commit
0781a13c9c
|
|
@ -596,18 +596,22 @@ static void pch_udc_reconnect(struct pch_udc_dev *dev)
|
||||||
static inline void pch_udc_vbus_session(struct pch_udc_dev *dev,
|
static inline void pch_udc_vbus_session(struct pch_udc_dev *dev,
|
||||||
int is_active)
|
int is_active)
|
||||||
{
|
{
|
||||||
|
unsigned long iflags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->lock, iflags);
|
||||||
if (is_active) {
|
if (is_active) {
|
||||||
pch_udc_reconnect(dev);
|
pch_udc_reconnect(dev);
|
||||||
dev->vbus_session = 1;
|
dev->vbus_session = 1;
|
||||||
} else {
|
} else {
|
||||||
if (dev->driver && dev->driver->disconnect) {
|
if (dev->driver && dev->driver->disconnect) {
|
||||||
spin_lock(&dev->lock);
|
spin_unlock_irqrestore(&dev->lock, iflags);
|
||||||
dev->driver->disconnect(&dev->gadget);
|
dev->driver->disconnect(&dev->gadget);
|
||||||
spin_unlock(&dev->lock);
|
spin_lock_irqsave(&dev->lock, iflags);
|
||||||
}
|
}
|
||||||
pch_udc_set_disconnect(dev);
|
pch_udc_set_disconnect(dev);
|
||||||
dev->vbus_session = 0;
|
dev->vbus_session = 0;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&dev->lock, iflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1166,20 +1170,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)
|
static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on)
|
||||||
{
|
{
|
||||||
struct pch_udc_dev *dev;
|
struct pch_udc_dev *dev;
|
||||||
|
unsigned long iflags;
|
||||||
|
|
||||||
if (!gadget)
|
if (!gadget)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dev = container_of(gadget, struct pch_udc_dev, gadget);
|
dev = container_of(gadget, struct pch_udc_dev, gadget);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->lock, iflags);
|
||||||
if (is_on) {
|
if (is_on) {
|
||||||
pch_udc_reconnect(dev);
|
pch_udc_reconnect(dev);
|
||||||
} else {
|
} else {
|
||||||
if (dev->driver && dev->driver->disconnect) {
|
if (dev->driver && dev->driver->disconnect) {
|
||||||
spin_lock(&dev->lock);
|
spin_unlock_irqrestore(&dev->lock, iflags);
|
||||||
dev->driver->disconnect(&dev->gadget);
|
dev->driver->disconnect(&dev->gadget);
|
||||||
spin_unlock(&dev->lock);
|
spin_lock_irqsave(&dev->lock, iflags);
|
||||||
}
|
}
|
||||||
pch_udc_set_disconnect(dev);
|
pch_udc_set_disconnect(dev);
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&dev->lock, iflags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user