mirror of
https://github.com/torvalds/linux.git
synced 2026-06-10 07:32:29 +02:00
Merge branch android-tegra-2.6.36 into android-tegra-moto-2.6.36
Change-Id: Id806720fee83d7515a38dc601a7570a3da55fec3
This commit is contained in:
commit
0fe8d7bf98
|
|
@ -110,10 +110,7 @@ void usb_composite_force_reset(struct usb_composite_dev *cdev)
|
|||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
/* force reenumeration */
|
||||
if (cdev && cdev->gadget &&
|
||||
cdev->gadget->speed != USB_SPEED_UNKNOWN) {
|
||||
/* avoid sending a disconnect switch event until after we disconnect */
|
||||
cdev->mute_switch = 1;
|
||||
if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) {
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
|
||||
usb_gadget_disconnect(cdev->gadget);
|
||||
|
|
@ -885,6 +882,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
|||
u16 w_length = le16_to_cpu(ctrl->wLength);
|
||||
struct usb_function *f = NULL;
|
||||
u8 endp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
if (!cdev->connected) {
|
||||
cdev->connected = 1;
|
||||
schedule_work(&cdev->switch_work);
|
||||
}
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
|
||||
/* partial re-init of the response message; the function or the
|
||||
* gadget might need to intercept e.g. a control-OUT completion
|
||||
|
|
@ -1103,10 +1108,8 @@ static void composite_disconnect(struct usb_gadget *gadget)
|
|||
if (composite->disconnect)
|
||||
composite->disconnect(cdev);
|
||||
|
||||
if (cdev->mute_switch)
|
||||
cdev->mute_switch = 0;
|
||||
else
|
||||
schedule_work(&cdev->switch_work);
|
||||
cdev->connected = 0;
|
||||
schedule_work(&cdev->switch_work);
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -1169,7 +1172,8 @@ composite_unbind(struct usb_gadget *gadget)
|
|||
usb_ep_free_request(gadget->ep0, cdev->req);
|
||||
}
|
||||
|
||||
switch_dev_unregister(&cdev->sdev);
|
||||
switch_dev_unregister(&cdev->sw_connected);
|
||||
switch_dev_unregister(&cdev->sw_config);
|
||||
kfree(cdev);
|
||||
set_gadget_data(gadget, NULL);
|
||||
device_remove_file(&gadget->dev, &dev_attr_suspended);
|
||||
|
|
@ -1204,11 +1208,22 @@ composite_switch_work(struct work_struct *data)
|
|||
struct usb_composite_dev *cdev =
|
||||
container_of(data, struct usb_composite_dev, switch_work);
|
||||
struct usb_configuration *config = cdev->config;
|
||||
int connected;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
if (cdev->connected != cdev->sw_connected.state) {
|
||||
connected = cdev->connected;
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
switch_set_state(&cdev->sw_connected, connected);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
}
|
||||
|
||||
if (config)
|
||||
switch_set_state(&cdev->sdev, config->bConfigurationValue);
|
||||
switch_set_state(&cdev->sw_config, config->bConfigurationValue);
|
||||
else
|
||||
switch_set_state(&cdev->sdev, 0);
|
||||
switch_set_state(&cdev->sw_config, 0);
|
||||
}
|
||||
|
||||
static int composite_bind(struct usb_gadget *gadget)
|
||||
|
|
@ -1262,8 +1277,12 @@ static int composite_bind(struct usb_gadget *gadget)
|
|||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
cdev->sdev.name = "usb_configuration";
|
||||
status = switch_dev_register(&cdev->sdev);
|
||||
cdev->sw_connected.name = "usb_connected";
|
||||
status = switch_dev_register(&cdev->sw_connected);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
cdev->sw_config.name = "usb_configuration";
|
||||
status = switch_dev_register(&cdev->sw_config);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
INIT_WORK(&cdev->switch_work, composite_switch_work);
|
||||
|
|
|
|||
|
|
@ -357,9 +357,13 @@ struct usb_composite_dev {
|
|||
/* protects at least deactivation count */
|
||||
spinlock_t lock;
|
||||
|
||||
struct switch_dev sdev;
|
||||
/* used by usb_composite_force_reset to avoid signalling switch changes */
|
||||
bool mute_switch;
|
||||
/* switch indicating connected/disconnected state */
|
||||
struct switch_dev sw_connected;
|
||||
/* switch indicating current configuration */
|
||||
struct switch_dev sw_config;
|
||||
/* current connected state for sw_connected */
|
||||
bool connected;
|
||||
|
||||
struct work_struct switch_work;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user