diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-11 14:23:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-11 14:23:10 -0400 |
commit | 246baac2fd2917259ba5dd34f3be7d6d195cbeb8 (patch) | |
tree | 3672942e06445c6ab006d4620aa57767dfd206af | |
parent | ef918d3c80f5e2c42076f2b23c7ec4767b5ec925 (diff) | |
parent | 29532e7b67f0ce0576e56f8ab0eeda311cde3b4b (diff) |
Merge tag 'usb-4.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH:
"Here are some small USB fixes for 4.12-rc5
They are for some reported issues in the chipidea and gadget drivers.
Nothing major. All have been in linux-next for a while with no
reported issues"
* tag 'usb-4.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
usb: gadget: udc: renesas_usb3: Fix PN_INT_ENA disabling timing
usb: gadget: udc: renesas_usb3: lock for PN_ registers access
usb: gadget: udc: renesas_usb3: fix deadlock by spinlock
usb: gadget: udc: renesas_usb3: fix pm_runtime functions calling
usb: gadget: f_mass_storage: Serialize wake and sleep execution
usb: dwc2: add support for the DWC2 controller on Meson8 SoCs
phy: qualcomm: phy-qcom-qmp: fix application of sizeof to pointer
usb: musb: dsps: keep VBUS on for host-only mode
usb: chipidea: core: check before accessing ci_role in ci_role_show
usb: chipidea: debug: check before accessing ci_role
phy: qcom-qmp: fix return value check in qcom_qmp_phy_create()
usb: chipidea: udc: fix NULL pointer dereference if udc_start failed
usb: chipidea: imx: Do not access CLKONOFF on i.MX51
-rw-r--r-- | Documentation/devicetree/bindings/usb/dwc2.txt | 1 | ||||
-rw-r--r-- | drivers/phy/phy-qcom-qmp.c | 14 | ||||
-rw-r--r-- | drivers/usb/chipidea/core.c | 5 | ||||
-rw-r--r-- | drivers/usb/chipidea/debug.c | 3 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.c | 8 | ||||
-rw-r--r-- | drivers/usb/chipidea/usbmisc_imx.c | 41 | ||||
-rw-r--r-- | drivers/usb/dwc2/params.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_mass_storage.c | 13 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/renesas_usb3.c | 45 | ||||
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 5 |
10 files changed, 102 insertions, 35 deletions
diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 00bea038639e..fcf199b64d3d 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt | |||
@@ -10,6 +10,7 @@ Required properties: | |||
10 | - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; | 10 | - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; |
11 | - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; | 11 | - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; |
12 | - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs; | 12 | - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs; |
13 | - "amlogic,meson8-usb": The DWC2 USB controller instance in Amlogic Meson8 SoCs; | ||
13 | - "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs; | 14 | - "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs; |
14 | - "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs; | 15 | - "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs; |
15 | - "amcc,dwc-otg": The DWC2 USB controller instance in AMCC Canyonlands 460EX SoCs; | 16 | - "amcc,dwc-otg": The DWC2 USB controller instance in AMCC Canyonlands 460EX SoCs; |
diff --git a/drivers/phy/phy-qcom-qmp.c b/drivers/phy/phy-qcom-qmp.c index 727e23be7cac..78ca62897784 100644 --- a/drivers/phy/phy-qcom-qmp.c +++ b/drivers/phy/phy-qcom-qmp.c | |||
@@ -844,7 +844,7 @@ static int qcom_qmp_phy_vreg_init(struct device *dev) | |||
844 | int num = qmp->cfg->num_vregs; | 844 | int num = qmp->cfg->num_vregs; |
845 | int i; | 845 | int i; |
846 | 846 | ||
847 | qmp->vregs = devm_kcalloc(dev, num, sizeof(qmp->vregs), GFP_KERNEL); | 847 | qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); |
848 | if (!qmp->vregs) | 848 | if (!qmp->vregs) |
849 | return -ENOMEM; | 849 | return -ENOMEM; |
850 | 850 | ||
@@ -983,16 +983,16 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id) | |||
983 | * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. | 983 | * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. |
984 | */ | 984 | */ |
985 | qphy->tx = of_iomap(np, 0); | 985 | qphy->tx = of_iomap(np, 0); |
986 | if (IS_ERR(qphy->tx)) | 986 | if (!qphy->tx) |
987 | return PTR_ERR(qphy->tx); | 987 | return -ENOMEM; |
988 | 988 | ||
989 | qphy->rx = of_iomap(np, 1); | 989 | qphy->rx = of_iomap(np, 1); |
990 | if (IS_ERR(qphy->rx)) | 990 | if (!qphy->rx) |
991 | return PTR_ERR(qphy->rx); | 991 | return -ENOMEM; |
992 | 992 | ||
993 | qphy->pcs = of_iomap(np, 2); | 993 | qphy->pcs = of_iomap(np, 2); |
994 | if (IS_ERR(qphy->pcs)) | 994 | if (!qphy->pcs) |
995 | return PTR_ERR(qphy->pcs); | 995 | return -ENOMEM; |
996 | 996 | ||
997 | /* | 997 | /* |
998 | * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3 | 998 | * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3 |
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9e217b1361ea..fe4fe2440729 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -843,7 +843,10 @@ static ssize_t ci_role_show(struct device *dev, struct device_attribute *attr, | |||
843 | { | 843 | { |
844 | struct ci_hdrc *ci = dev_get_drvdata(dev); | 844 | struct ci_hdrc *ci = dev_get_drvdata(dev); |
845 | 845 | ||
846 | return sprintf(buf, "%s\n", ci_role(ci)->name); | 846 | if (ci->role != CI_ROLE_END) |
847 | return sprintf(buf, "%s\n", ci_role(ci)->name); | ||
848 | |||
849 | return 0; | ||
847 | } | 850 | } |
848 | 851 | ||
849 | static ssize_t ci_role_store(struct device *dev, | 852 | static ssize_t ci_role_store(struct device *dev, |
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 6d23eede4d8c..1c31e8a08810 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c | |||
@@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data) | |||
294 | { | 294 | { |
295 | struct ci_hdrc *ci = s->private; | 295 | struct ci_hdrc *ci = s->private; |
296 | 296 | ||
297 | seq_printf(s, "%s\n", ci_role(ci)->name); | 297 | if (ci->role != CI_ROLE_END) |
298 | seq_printf(s, "%s\n", ci_role(ci)->name); | ||
298 | 299 | ||
299 | return 0; | 300 | return 0; |
300 | } | 301 | } |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 56d2d3213076..d68b125796f9 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -1993,6 +1993,7 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci) | |||
1993 | int ci_hdrc_gadget_init(struct ci_hdrc *ci) | 1993 | int ci_hdrc_gadget_init(struct ci_hdrc *ci) |
1994 | { | 1994 | { |
1995 | struct ci_role_driver *rdrv; | 1995 | struct ci_role_driver *rdrv; |
1996 | int ret; | ||
1996 | 1997 | ||
1997 | if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) | 1998 | if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) |
1998 | return -ENXIO; | 1999 | return -ENXIO; |
@@ -2005,7 +2006,10 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci) | |||
2005 | rdrv->stop = udc_id_switch_for_host; | 2006 | rdrv->stop = udc_id_switch_for_host; |
2006 | rdrv->irq = udc_irq; | 2007 | rdrv->irq = udc_irq; |
2007 | rdrv->name = "gadget"; | 2008 | rdrv->name = "gadget"; |
2008 | ci->roles[CI_ROLE_GADGET] = rdrv; | ||
2009 | 2009 | ||
2010 | return udc_start(ci); | 2010 | ret = udc_start(ci); |
2011 | if (!ret) | ||
2012 | ci->roles[CI_ROLE_GADGET] = rdrv; | ||
2013 | |||
2014 | return ret; | ||
2011 | } | 2015 | } |
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index e77a4ed4f021..9f4a0185dd60 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c | |||
@@ -108,6 +108,8 @@ struct imx_usbmisc { | |||
108 | const struct usbmisc_ops *ops; | 108 | const struct usbmisc_ops *ops; |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); | ||
112 | |||
111 | static int usbmisc_imx25_init(struct imx_usbmisc_data *data) | 113 | static int usbmisc_imx25_init(struct imx_usbmisc_data *data) |
112 | { | 114 | { |
113 | struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); | 115 | struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); |
@@ -242,10 +244,15 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) | |||
242 | val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN | 244 | val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN |
243 | | MX53_USB_UHx_CTRL_ULPI_INT_EN; | 245 | | MX53_USB_UHx_CTRL_ULPI_INT_EN; |
244 | writel(val, reg); | 246 | writel(val, reg); |
245 | /* Disable internal 60Mhz clock */ | 247 | if (is_imx53_usbmisc(data)) { |
246 | reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET; | 248 | /* Disable internal 60Mhz clock */ |
247 | val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; | 249 | reg = usbmisc->base + |
248 | writel(val, reg); | 250 | MX53_USB_CLKONOFF_CTRL_OFFSET; |
251 | val = readl(reg) | | ||
252 | MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; | ||
253 | writel(val, reg); | ||
254 | } | ||
255 | |||
249 | } | 256 | } |
250 | if (data->disable_oc) { | 257 | if (data->disable_oc) { |
251 | reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; | 258 | reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; |
@@ -267,10 +274,15 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) | |||
267 | val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN | 274 | val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN |
268 | | MX53_USB_UHx_CTRL_ULPI_INT_EN; | 275 | | MX53_USB_UHx_CTRL_ULPI_INT_EN; |
269 | writel(val, reg); | 276 | writel(val, reg); |
270 | /* Disable internal 60Mhz clock */ | 277 | |
271 | reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET; | 278 | if (is_imx53_usbmisc(data)) { |
272 | val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; | 279 | /* Disable internal 60Mhz clock */ |
273 | writel(val, reg); | 280 | reg = usbmisc->base + |
281 | MX53_USB_CLKONOFF_CTRL_OFFSET; | ||
282 | val = readl(reg) | | ||
283 | MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; | ||
284 | writel(val, reg); | ||
285 | } | ||
274 | } | 286 | } |
275 | if (data->disable_oc) { | 287 | if (data->disable_oc) { |
276 | reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; | 288 | reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; |
@@ -456,6 +468,10 @@ static const struct usbmisc_ops imx27_usbmisc_ops = { | |||
456 | .init = usbmisc_imx27_init, | 468 | .init = usbmisc_imx27_init, |
457 | }; | 469 | }; |
458 | 470 | ||
471 | static const struct usbmisc_ops imx51_usbmisc_ops = { | ||
472 | .init = usbmisc_imx53_init, | ||
473 | }; | ||
474 | |||
459 | static const struct usbmisc_ops imx53_usbmisc_ops = { | 475 | static const struct usbmisc_ops imx53_usbmisc_ops = { |
460 | .init = usbmisc_imx53_init, | 476 | .init = usbmisc_imx53_init, |
461 | }; | 477 | }; |
@@ -479,6 +495,13 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = { | |||
479 | .set_wakeup = usbmisc_imx7d_set_wakeup, | 495 | .set_wakeup = usbmisc_imx7d_set_wakeup, |
480 | }; | 496 | }; |
481 | 497 | ||
498 | static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) | ||
499 | { | ||
500 | struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); | ||
501 | |||
502 | return usbmisc->ops == &imx53_usbmisc_ops; | ||
503 | } | ||
504 | |||
482 | int imx_usbmisc_init(struct imx_usbmisc_data *data) | 505 | int imx_usbmisc_init(struct imx_usbmisc_data *data) |
483 | { | 506 | { |
484 | struct imx_usbmisc *usbmisc; | 507 | struct imx_usbmisc *usbmisc; |
@@ -536,7 +559,7 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { | |||
536 | }, | 559 | }, |
537 | { | 560 | { |
538 | .compatible = "fsl,imx51-usbmisc", | 561 | .compatible = "fsl,imx51-usbmisc", |
539 | .data = &imx53_usbmisc_ops, | 562 | .data = &imx51_usbmisc_ops, |
540 | }, | 563 | }, |
541 | { | 564 | { |
542 | .compatible = "fsl,imx53-usbmisc", | 565 | .compatible = "fsl,imx53-usbmisc", |
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 9cd8722f24f6..a3ffe97170ff 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c | |||
@@ -144,6 +144,8 @@ const struct of_device_id dwc2_of_match_table[] = { | |||
144 | { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params }, | 144 | { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params }, |
145 | { .compatible = "snps,dwc2" }, | 145 | { .compatible = "snps,dwc2" }, |
146 | { .compatible = "samsung,s3c6400-hsotg" }, | 146 | { .compatible = "samsung,s3c6400-hsotg" }, |
147 | { .compatible = "amlogic,meson8-usb", | ||
148 | .data = dwc2_set_amlogic_params }, | ||
147 | { .compatible = "amlogic,meson8b-usb", | 149 | { .compatible = "amlogic,meson8b-usb", |
148 | .data = dwc2_set_amlogic_params }, | 150 | .data = dwc2_set_amlogic_params }, |
149 | { .compatible = "amlogic,meson-gxbb-usb", | 151 | { .compatible = "amlogic,meson-gxbb-usb", |
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 4c8aacc232c0..74d57d6994da 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c | |||
@@ -396,7 +396,11 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | |||
396 | /* Caller must hold fsg->lock */ | 396 | /* Caller must hold fsg->lock */ |
397 | static void wakeup_thread(struct fsg_common *common) | 397 | static void wakeup_thread(struct fsg_common *common) |
398 | { | 398 | { |
399 | smp_wmb(); /* ensure the write of bh->state is complete */ | 399 | /* |
400 | * Ensure the reading of thread_wakeup_needed | ||
401 | * and the writing of bh->state are completed | ||
402 | */ | ||
403 | smp_mb(); | ||
400 | /* Tell the main thread that something has happened */ | 404 | /* Tell the main thread that something has happened */ |
401 | common->thread_wakeup_needed = 1; | 405 | common->thread_wakeup_needed = 1; |
402 | if (common->thread_task) | 406 | if (common->thread_task) |
@@ -627,7 +631,12 @@ static int sleep_thread(struct fsg_common *common, bool can_freeze) | |||
627 | } | 631 | } |
628 | __set_current_state(TASK_RUNNING); | 632 | __set_current_state(TASK_RUNNING); |
629 | common->thread_wakeup_needed = 0; | 633 | common->thread_wakeup_needed = 0; |
630 | smp_rmb(); /* ensure the latest bh->state is visible */ | 634 | |
635 | /* | ||
636 | * Ensure the writing of thread_wakeup_needed | ||
637 | * and the reading of bh->state are completed | ||
638 | */ | ||
639 | smp_mb(); | ||
631 | return rc; | 640 | return rc; |
632 | } | 641 | } |
633 | 642 | ||
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 5a2d845fb1a6..cd4c88529721 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c | |||
@@ -623,7 +623,6 @@ static void renesas_usb3_stop_controller(struct renesas_usb3 *usb3) | |||
623 | { | 623 | { |
624 | usb3_disconnect(usb3); | 624 | usb3_disconnect(usb3); |
625 | usb3_write(usb3, 0, USB3_P0_INT_ENA); | 625 | usb3_write(usb3, 0, USB3_P0_INT_ENA); |
626 | usb3_write(usb3, 0, USB3_PN_INT_ENA); | ||
627 | usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA); | 626 | usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA); |
628 | usb3_write(usb3, 0, USB3_USB_INT_ENA_1); | 627 | usb3_write(usb3, 0, USB3_USB_INT_ENA_1); |
629 | usb3_write(usb3, 0, USB3_USB_INT_ENA_2); | 628 | usb3_write(usb3, 0, USB3_USB_INT_ENA_2); |
@@ -1475,7 +1474,13 @@ static void usb3_request_done_pipen(struct renesas_usb3 *usb3, | |||
1475 | struct renesas_usb3_request *usb3_req, | 1474 | struct renesas_usb3_request *usb3_req, |
1476 | int status) | 1475 | int status) |
1477 | { | 1476 | { |
1478 | usb3_pn_stop(usb3); | 1477 | unsigned long flags; |
1478 | |||
1479 | spin_lock_irqsave(&usb3->lock, flags); | ||
1480 | if (usb3_pn_change(usb3, usb3_ep->num)) | ||
1481 | usb3_pn_stop(usb3); | ||
1482 | spin_unlock_irqrestore(&usb3->lock, flags); | ||
1483 | |||
1479 | usb3_disable_pipe_irq(usb3, usb3_ep->num); | 1484 | usb3_disable_pipe_irq(usb3, usb3_ep->num); |
1480 | usb3_request_done(usb3_ep, usb3_req, status); | 1485 | usb3_request_done(usb3_ep, usb3_req, status); |
1481 | 1486 | ||
@@ -1504,30 +1509,46 @@ static void usb3_irq_epc_pipen_bfrdy(struct renesas_usb3 *usb3, int num) | |||
1504 | { | 1509 | { |
1505 | struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num); | 1510 | struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num); |
1506 | struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); | 1511 | struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); |
1512 | bool done = false; | ||
1507 | 1513 | ||
1508 | if (!usb3_req) | 1514 | if (!usb3_req) |
1509 | return; | 1515 | return; |
1510 | 1516 | ||
1517 | spin_lock(&usb3->lock); | ||
1518 | if (usb3_pn_change(usb3, num)) | ||
1519 | goto out; | ||
1520 | |||
1511 | if (usb3_ep->dir_in) { | 1521 | if (usb3_ep->dir_in) { |
1512 | /* Do not stop the IN pipe here to detect LSTTR interrupt */ | 1522 | /* Do not stop the IN pipe here to detect LSTTR interrupt */ |
1513 | if (!usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE)) | 1523 | if (!usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE)) |
1514 | usb3_clear_bit(usb3, PN_INT_BFRDY, USB3_PN_INT_ENA); | 1524 | usb3_clear_bit(usb3, PN_INT_BFRDY, USB3_PN_INT_ENA); |
1515 | } else { | 1525 | } else { |
1516 | if (!usb3_read_pipe(usb3_ep, usb3_req, USB3_PN_READ)) | 1526 | if (!usb3_read_pipe(usb3_ep, usb3_req, USB3_PN_READ)) |
1517 | usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); | 1527 | done = true; |
1518 | } | 1528 | } |
1529 | |||
1530 | out: | ||
1531 | /* need to unlock because usb3_request_done_pipen() locks it */ | ||
1532 | spin_unlock(&usb3->lock); | ||
1533 | |||
1534 | if (done) | ||
1535 | usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); | ||
1519 | } | 1536 | } |
1520 | 1537 | ||
1521 | static void usb3_irq_epc_pipen(struct renesas_usb3 *usb3, int num) | 1538 | static void usb3_irq_epc_pipen(struct renesas_usb3 *usb3, int num) |
1522 | { | 1539 | { |
1523 | u32 pn_int_sta; | 1540 | u32 pn_int_sta; |
1524 | 1541 | ||
1525 | if (usb3_pn_change(usb3, num) < 0) | 1542 | spin_lock(&usb3->lock); |
1543 | if (usb3_pn_change(usb3, num) < 0) { | ||
1544 | spin_unlock(&usb3->lock); | ||
1526 | return; | 1545 | return; |
1546 | } | ||
1527 | 1547 | ||
1528 | pn_int_sta = usb3_read(usb3, USB3_PN_INT_STA); | 1548 | pn_int_sta = usb3_read(usb3, USB3_PN_INT_STA); |
1529 | pn_int_sta &= usb3_read(usb3, USB3_PN_INT_ENA); | 1549 | pn_int_sta &= usb3_read(usb3, USB3_PN_INT_ENA); |
1530 | usb3_write(usb3, pn_int_sta, USB3_PN_INT_STA); | 1550 | usb3_write(usb3, pn_int_sta, USB3_PN_INT_STA); |
1551 | spin_unlock(&usb3->lock); | ||
1531 | if (pn_int_sta & PN_INT_LSTTR) | 1552 | if (pn_int_sta & PN_INT_LSTTR) |
1532 | usb3_irq_epc_pipen_lsttr(usb3, num); | 1553 | usb3_irq_epc_pipen_lsttr(usb3, num); |
1533 | if (pn_int_sta & PN_INT_BFRDY) | 1554 | if (pn_int_sta & PN_INT_BFRDY) |
@@ -1660,6 +1681,7 @@ static int usb3_disable_pipe_n(struct renesas_usb3_ep *usb3_ep) | |||
1660 | 1681 | ||
1661 | spin_lock_irqsave(&usb3->lock, flags); | 1682 | spin_lock_irqsave(&usb3->lock, flags); |
1662 | if (!usb3_pn_change(usb3, usb3_ep->num)) { | 1683 | if (!usb3_pn_change(usb3, usb3_ep->num)) { |
1684 | usb3_write(usb3, 0, USB3_PN_INT_ENA); | ||
1663 | usb3_write(usb3, 0, USB3_PN_RAMMAP); | 1685 | usb3_write(usb3, 0, USB3_PN_RAMMAP); |
1664 | usb3_clear_bit(usb3, PN_CON_EN, USB3_PN_CON); | 1686 | usb3_clear_bit(usb3, PN_CON_EN, USB3_PN_CON); |
1665 | } | 1687 | } |
@@ -1799,6 +1821,9 @@ static int renesas_usb3_start(struct usb_gadget *gadget, | |||
1799 | /* hook up the driver */ | 1821 | /* hook up the driver */ |
1800 | usb3->driver = driver; | 1822 | usb3->driver = driver; |
1801 | 1823 | ||
1824 | pm_runtime_enable(usb3_to_dev(usb3)); | ||
1825 | pm_runtime_get_sync(usb3_to_dev(usb3)); | ||
1826 | |||
1802 | renesas_usb3_init_controller(usb3); | 1827 | renesas_usb3_init_controller(usb3); |
1803 | 1828 | ||
1804 | return 0; | 1829 | return 0; |
@@ -1807,14 +1832,14 @@ static int renesas_usb3_start(struct usb_gadget *gadget, | |||
1807 | static int renesas_usb3_stop(struct usb_gadget *gadget) | 1832 | static int renesas_usb3_stop(struct usb_gadget *gadget) |
1808 | { | 1833 | { |
1809 | struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); | 1834 | struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); |
1810 | unsigned long flags; | ||
1811 | 1835 | ||
1812 | spin_lock_irqsave(&usb3->lock, flags); | ||
1813 | usb3->softconnect = false; | 1836 | usb3->softconnect = false; |
1814 | usb3->gadget.speed = USB_SPEED_UNKNOWN; | 1837 | usb3->gadget.speed = USB_SPEED_UNKNOWN; |
1815 | usb3->driver = NULL; | 1838 | usb3->driver = NULL; |
1816 | renesas_usb3_stop_controller(usb3); | 1839 | renesas_usb3_stop_controller(usb3); |
1817 | spin_unlock_irqrestore(&usb3->lock, flags); | 1840 | |
1841 | pm_runtime_put(usb3_to_dev(usb3)); | ||
1842 | pm_runtime_disable(usb3_to_dev(usb3)); | ||
1818 | 1843 | ||
1819 | return 0; | 1844 | return 0; |
1820 | } | 1845 | } |
@@ -1891,9 +1916,6 @@ static int renesas_usb3_remove(struct platform_device *pdev) | |||
1891 | 1916 | ||
1892 | device_remove_file(&pdev->dev, &dev_attr_role); | 1917 | device_remove_file(&pdev->dev, &dev_attr_role); |
1893 | 1918 | ||
1894 | pm_runtime_put(&pdev->dev); | ||
1895 | pm_runtime_disable(&pdev->dev); | ||
1896 | |||
1897 | usb_del_gadget_udc(&usb3->gadget); | 1919 | usb_del_gadget_udc(&usb3->gadget); |
1898 | 1920 | ||
1899 | __renesas_usb3_ep_free_request(usb3->ep0_req); | 1921 | __renesas_usb3_ep_free_request(usb3->ep0_req); |
@@ -2099,9 +2121,6 @@ static int renesas_usb3_probe(struct platform_device *pdev) | |||
2099 | 2121 | ||
2100 | usb3->workaround_for_vbus = priv->workaround_for_vbus; | 2122 | usb3->workaround_for_vbus = priv->workaround_for_vbus; |
2101 | 2123 | ||
2102 | pm_runtime_enable(&pdev->dev); | ||
2103 | pm_runtime_get_sync(&pdev->dev); | ||
2104 | |||
2105 | dev_info(&pdev->dev, "probed\n"); | 2124 | dev_info(&pdev->dev, "probed\n"); |
2106 | 2125 | ||
2107 | return 0; | 2126 | return 0; |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9c7ee26ef388..bc6a9be2ccc5 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -245,6 +245,11 @@ static int dsps_check_status(struct musb *musb, void *unused) | |||
245 | dsps_mod_timer_optional(glue); | 245 | dsps_mod_timer_optional(glue); |
246 | break; | 246 | break; |
247 | case OTG_STATE_A_WAIT_BCON: | 247 | case OTG_STATE_A_WAIT_BCON: |
248 | /* keep VBUS on for host-only mode */ | ||
249 | if (musb->port_mode == MUSB_PORT_MODE_HOST) { | ||
250 | dsps_mod_timer_optional(glue); | ||
251 | break; | ||
252 | } | ||
248 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | 253 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); |
249 | skip_session = 1; | 254 | skip_session = 1; |
250 | /* fall */ | 255 | /* fall */ |