diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-19 20:54:08 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-19 20:54:08 -0700 |
| commit | 70b19ef9d8fddf33471b81ec98b1fe60af5d535a (patch) | |
| tree | b0d24db1f3011454b8afd2a8c1f0724244dc028e /usb | |
| parent | 78f45e0b908f2f3c79c6445b936105e9423942fd (diff) | |
| download | patches-70b19ef9d8fddf33471b81ec98b1fe60af5d535a.tar.gz | |
more patches
Diffstat (limited to 'usb')
| -rw-r--r-- | usb/usb-gadget-composite-device-level-suspend-resume-hooks.patch | 85 | ||||
| -rw-r--r-- | usb/usb-r8a66597-hcd-suspend-resume-support.patch | 184 |
2 files changed, 269 insertions, 0 deletions
diff --git a/usb/usb-gadget-composite-device-level-suspend-resume-hooks.patch b/usb/usb-gadget-composite-device-level-suspend-resume-hooks.patch new file mode 100644 index 00000000000000..02fbbdee2a55db --- /dev/null +++ b/usb/usb-gadget-composite-device-level-suspend-resume-hooks.patch @@ -0,0 +1,85 @@ +From david-b@pacbell.net Thu Mar 19 20:32:29 2009 +From: David Brownell <david-b@pacbell.net> +Date: Thu, 19 Mar 2009 14:14:17 -0700 +Subject: USB: gadget: composite device-level suspend/resume hooks +To: Greg KH <greg@kroah.com> +Cc: Felipe Balbi <felipe.balbi@nokia.com> +Message-ID: <200903191414.17132.david-b@pacbell.net> +Content-Disposition: inline + + +From: David Brownell <dbrownell@users.sourceforge.net> + +Address one open question in the composite gadget framework: +Yes, we should have device-level suspend/resume callbacks +in addition to the function-level ones. We have at least one +scenario (with gadget zero in OTG test mode) that's awkward +to handle without it. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Cc: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/composite.c | 8 ++++++-- + include/linux/usb/composite.h | 8 ++++++++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1014,7 +1014,7 @@ composite_suspend(struct usb_gadget *gad + struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_function *f; + +- /* REVISIT: should we have config and device level ++ /* REVISIT: should we have config level + * suspend/resume callbacks? + */ + DBG(cdev, "suspend\n"); +@@ -1024,6 +1024,8 @@ composite_suspend(struct usb_gadget *gad + f->suspend(f); + } + } ++ if (composite->suspend) ++ composite->suspend(cdev); + } + + static void +@@ -1032,10 +1034,12 @@ composite_resume(struct usb_gadget *gadg + struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_function *f; + +- /* REVISIT: should we have config and device level ++ /* REVISIT: should we have config level + * suspend/resume callbacks? + */ + DBG(cdev, "resume\n"); ++ if (composite->resume) ++ composite->resume(cdev); + if (cdev->config) { + list_for_each_entry(f, &cdev->config->functions, list) { + if (f->resume) +--- a/include/linux/usb/composite.h ++++ b/include/linux/usb/composite.h +@@ -244,6 +244,10 @@ int usb_add_config(struct usb_composite_ + * value; it should return zero on successful initialization. + * @unbind: Reverses @bind(); called as a side effect of unregistering + * this driver. ++ * @suspend: Notifies when the host stops sending USB traffic, ++ * after function notifications ++ * @resume: Notifies configuration when the host restarts USB traffic, ++ * before function notifications + * + * Devices default to reporting self powered operation. Devices which rely + * on bus powered operation should report this in their @bind() method. +@@ -268,6 +272,10 @@ struct usb_composite_driver { + + int (*bind)(struct usb_composite_dev *); + int (*unbind)(struct usb_composite_dev *); ++ ++ /* global suspend hooks */ ++ void (*suspend)(struct usb_composite_dev *); ++ void (*resume)(struct usb_composite_dev *); + }; + + extern int usb_composite_register(struct usb_composite_driver *); diff --git a/usb/usb-r8a66597-hcd-suspend-resume-support.patch b/usb/usb-r8a66597-hcd-suspend-resume-support.patch new file mode 100644 index 00000000000000..5252fd83819196 --- /dev/null +++ b/usb/usb-r8a66597-hcd-suspend-resume-support.patch @@ -0,0 +1,184 @@ +From shimoda.yoshihiro@renesas.com Thu Mar 19 20:31:31 2009 +From: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> +Date: Thu, 19 Mar 2009 14:18:15 +0900 +Subject: USB: r8a66597-hcd: suspend/resume support +To: greg@kroah.com +Message-ID: <49C1D597.6010206@renesas.com> + + +Fix the problem that system cannot suspend. + +Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/r8a66597-hcd.c | 101 +++++++++++++++++++++++++++++++++++++++- + drivers/usb/host/r8a66597.h | 2 + 2 files changed, 102 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/r8a66597.h ++++ b/drivers/usb/host/r8a66597.h +@@ -504,6 +504,8 @@ struct r8a66597 { + + struct list_head child_device; + unsigned long child_connect_map[4]; ++ ++ unsigned bus_suspended:1; + }; + + static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd) +--- a/drivers/usb/host/r8a66597-hcd.c ++++ b/drivers/usb/host/r8a66597-hcd.c +@@ -1013,6 +1013,9 @@ static void r8a66597_check_syssts(struct + + r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); + r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); ++ ++ if (r8a66597->bus_suspended) ++ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); + } + + /* this function must be called with interrupt disabled */ +@@ -1614,6 +1617,11 @@ static irqreturn_t r8a66597_irq(struct u + r8a66597_bclr(r8a66597, DTCHE, INTENB2); + r8a66597_usb_disconnect(r8a66597, 1); + } ++ if (mask2 & BCHG) { ++ r8a66597_write(r8a66597, ~BCHG, INTSTS2); ++ r8a66597_bclr(r8a66597, BCHGE, INTENB2); ++ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); ++ } + } + + if (mask1) { +@@ -1629,6 +1637,12 @@ static irqreturn_t r8a66597_irq(struct u + r8a66597_bclr(r8a66597, DTCHE, INTENB1); + r8a66597_usb_disconnect(r8a66597, 0); + } ++ if (mask1 & BCHG) { ++ r8a66597_write(r8a66597, ~BCHG, INTSTS1); ++ r8a66597_bclr(r8a66597, BCHGE, INTENB1); ++ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); ++ } ++ + if (mask1 & SIGN) { + r8a66597_write(r8a66597, ~SIGN, INTSTS1); + status = get_urb_error(r8a66597, 0); +@@ -2140,7 +2154,7 @@ static int r8a66597_hub_control(struct u + + switch (wValue) { + case USB_PORT_FEAT_ENABLE: +- rh->port &= (1 << USB_PORT_FEAT_POWER); ++ rh->port &= ~(1 << USB_PORT_FEAT_POWER); + break; + case USB_PORT_FEAT_SUSPEND: + break; +@@ -2212,6 +2226,68 @@ error: + return ret; + } + ++#if defined(CONFIG_PM) ++static int r8a66597_bus_suspend(struct usb_hcd *hcd) ++{ ++ struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); ++ int port; ++ ++ dbg("%s", __func__); ++ ++ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { ++ struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; ++ unsigned long dvstctr_reg = get_dvstctr_reg(port); ++ ++ if (!(rh->port & (1 << USB_PORT_FEAT_ENABLE))) ++ continue; ++ ++ dbg("suspend port = %d", port); ++ r8a66597_bclr(r8a66597, UACT, dvstctr_reg); /* suspend */ ++ rh->port |= 1 << USB_PORT_FEAT_SUSPEND; ++ ++ if (rh->dev->udev->do_remote_wakeup) { ++ msleep(3); /* waiting last SOF */ ++ r8a66597_bset(r8a66597, RWUPE, dvstctr_reg); ++ r8a66597_write(r8a66597, ~BCHG, get_intsts_reg(port)); ++ r8a66597_bset(r8a66597, BCHGE, get_intenb_reg(port)); ++ } ++ } ++ ++ r8a66597->bus_suspended = 1; ++ ++ return 0; ++} ++ ++static int r8a66597_bus_resume(struct usb_hcd *hcd) ++{ ++ struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); ++ int port; ++ ++ dbg("%s", __func__); ++ ++ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { ++ struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; ++ unsigned long dvstctr_reg = get_dvstctr_reg(port); ++ ++ if (!(rh->port & (1 << USB_PORT_FEAT_SUSPEND))) ++ continue; ++ ++ dbg("resume port = %d", port); ++ rh->port &= ~(1 << USB_PORT_FEAT_SUSPEND); ++ rh->port |= 1 << USB_PORT_FEAT_C_SUSPEND; ++ r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg); ++ msleep(50); ++ r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg); ++ } ++ ++ return 0; ++ ++} ++#else ++#define r8a66597_bus_suspend NULL ++#define r8a66597_bus_resume NULL ++#endif ++ + static struct hc_driver r8a66597_hc_driver = { + .description = hcd_name, + .hcd_priv_size = sizeof(struct r8a66597), +@@ -2242,16 +2318,39 @@ static struct hc_driver r8a66597_hc_driv + */ + .hub_status_data = r8a66597_hub_status_data, + .hub_control = r8a66597_hub_control, ++ .bus_suspend = r8a66597_bus_suspend, ++ .bus_resume = r8a66597_bus_resume, + }; + + #if defined(CONFIG_PM) + static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) + { ++ struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); ++ int port; ++ ++ dbg("%s", __func__); ++ ++ disable_controller(r8a66597); ++ ++ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { ++ struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; ++ ++ rh->port = 0x00000000; ++ } ++ + return 0; + } + + static int r8a66597_resume(struct platform_device *pdev) + { ++ struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); ++ struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); ++ ++ dbg("%s", __func__); ++ ++ enable_controller(r8a66597); ++ usb_root_hub_lost_power(hcd->self.root_hub); ++ + return 0; + } + #else /* if defined(CONFIG_PM) */ |
