aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-14 19:43:09 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-14 19:43:09 -0400
commit37a842d36f63a047d94be2603d40d4407c949f1b (patch)
tree6aed94775f66f7198130b725bb5c7eae98faacdb
parenta3fbedf98fe9909cb2e406e2018ec437d64806f6 (diff)
parent96625eadca1bb8832fb502f0899a543695f1ba35 (diff)
Merge tag 'usb-ci-v4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb into usb-next
Peter writes: USB: chipidea updates for v4.3-rc1 The main changes are adding several system interfaces for tuning performance, and each vendors can adjust them according to their design configurations. Others are tiny improvements, like more well siTD supports, USB_DEVICE_A_HNP_SUPPORT supports, etc.
-rw-r--r--Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt20
-rw-r--r--drivers/usb/chipidea/bits.h12
-rw-r--r--drivers/usb/chipidea/ci.h4
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c17
-rw-r--r--drivers/usb/chipidea/core.c113
-rw-r--r--drivers/usb/chipidea/debug.c6
-rw-r--r--drivers/usb/chipidea/host.c26
-rw-r--r--drivers/usb/chipidea/otg_fsm.c1
-rw-r--r--drivers/usb/chipidea/udc.c9
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c12
-rw-r--r--include/linux/usb/chipidea.h14
11 files changed, 202 insertions, 32 deletions
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index 553e2fae3a76..d71ef07bca5d 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -30,6 +30,21 @@ Optional properties:
30 argument that indicate usb controller index 30 argument that indicate usb controller index
31- disable-over-current: (FSL only) disable over current detect 31- disable-over-current: (FSL only) disable over current detect
32- external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus 32- external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
33- itc-setting: interrupt threshold control register control, the setting
34 should be aligned with ITC bits at register USBCMD.
35- ahb-burst-config: it is vendor dependent, the required value should be
36 aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7. This
37 property is used to change AHB burst configuration, check the chipidea
38 spec for meaning of each value. If this property is not existed, it
39 will use the reset value.
40- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
41 (4 bytes), This register represents the maximum length of a the burst
42 in 32-bit words while moving data from system memory to the USB
43 bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
44- rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
45 (4 bytes), This register represents the maximum length of a the burst
46 in 32-bit words while moving data from the USB bus to system memory,
47 changing this value takes effect only the SBUSCFG.AHBBRST is 0.
33 48
34Example: 49Example:
35 50
@@ -41,4 +56,9 @@ Example:
41 phys = <&usb_phy0>; 56 phys = <&usb_phy0>;
42 phy-names = "usb-phy"; 57 phy-names = "usb-phy";
43 vbus-supply = <&reg_usb0_vbus>; 58 vbus-supply = <&reg_usb0_vbus>;
59 gadget-itc-setting = <0x4>; /* 4 micro-frames */
60 /* Incremental burst of unspecified length */
61 ahb-burst-config = <0x0>;
62 tx-burst-size-dword = <0x10>; /* 64 bytes */
63 rx-burst-size-dword = <0x10>;
44 }; 64 };
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 3cb9bda51ddf..e462f55c8b99 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -25,6 +25,9 @@
25#define VERSION (0xF << 25) 25#define VERSION (0xF << 25)
26#define CIVERSION (0x7 << 29) 26#define CIVERSION (0x7 << 29)
27 27
28/* SBUSCFG */
29#define AHBBRST_MASK 0x7
30
28/* HCCPARAMS */ 31/* HCCPARAMS */
29#define HCCPARAMS_LEN BIT(17) 32#define HCCPARAMS_LEN BIT(17)
30 33
@@ -53,6 +56,15 @@
53#define DEVICEADDR_USBADRA BIT(24) 56#define DEVICEADDR_USBADRA BIT(24)
54#define DEVICEADDR_USBADR (0x7FUL << 25) 57#define DEVICEADDR_USBADR (0x7FUL << 25)
55 58
59/* TTCTRL */
60#define TTCTRL_TTHA_MASK (0x7fUL << 24)
61/* Set non-zero value for internal TT Hub address representation */
62#define TTCTRL_TTHA (0x7fUL << 24)
63
64/* BURSTSIZE */
65#define RX_BURST_MASK 0xff
66#define TX_BURST_MASK 0xff00
67
56/* PORTSC */ 68/* PORTSC */
57#define PORTSC_CCS BIT(0) 69#define PORTSC_CCS BIT(0)
58#define PORTSC_CSC BIT(1) 70#define PORTSC_CSC BIT(1)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f243f0b431c3..41d7cf6d63ba 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -50,6 +50,8 @@ enum ci_hw_regs {
50 OP_USBINTR, 50 OP_USBINTR,
51 OP_DEVICEADDR, 51 OP_DEVICEADDR,
52 OP_ENDPTLISTADDR, 52 OP_ENDPTLISTADDR,
53 OP_TTCTRL,
54 OP_BURSTSIZE,
53 OP_PORTSC, 55 OP_PORTSC,
54 OP_DEVLC, 56 OP_DEVLC,
55 OP_OTGSC, 57 OP_OTGSC,
@@ -429,4 +431,6 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
429int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, 431int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
430 u32 value, unsigned int timeout_ms); 432 u32 value, unsigned int timeout_ms);
431 433
434void ci_platform_configure(struct ci_hdrc *ci);
435
432#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ 436#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 389f0e034259..867e9f3f3859 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -29,26 +29,31 @@ struct ci_hdrc_imx_platform_flag {
29}; 29};
30 30
31static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { 31static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
32 CI_HDRC_DISABLE_STREAMING,
32}; 33};
33 34
34static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { 35static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
35 .flags = CI_HDRC_IMX28_WRITE_FIX | 36 .flags = CI_HDRC_IMX28_WRITE_FIX |
36 CI_HDRC_TURN_VBUS_EARLY_ON, 37 CI_HDRC_TURN_VBUS_EARLY_ON |
38 CI_HDRC_DISABLE_STREAMING,
37}; 39};
38 40
39static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = { 41static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
40 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 42 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
41 CI_HDRC_TURN_VBUS_EARLY_ON, 43 CI_HDRC_TURN_VBUS_EARLY_ON |
44 CI_HDRC_DISABLE_STREAMING,
42}; 45};
43 46
44static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = { 47static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
45 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 48 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
46 CI_HDRC_TURN_VBUS_EARLY_ON, 49 CI_HDRC_TURN_VBUS_EARLY_ON |
50 CI_HDRC_DISABLE_HOST_STREAMING,
47}; 51};
48 52
49static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = { 53static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
50 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 54 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
51 CI_HDRC_TURN_VBUS_EARLY_ON, 55 CI_HDRC_TURN_VBUS_EARLY_ON |
56 CI_HDRC_DISABLE_HOST_STREAMING,
52}; 57};
53 58
54static const struct of_device_id ci_hdrc_imx_dt_ids[] = { 59static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
@@ -104,7 +109,7 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
104 misc_pdev = of_find_device_by_node(args.np); 109 misc_pdev = of_find_device_by_node(args.np);
105 of_node_put(args.np); 110 of_node_put(args.np);
106 111
107 if (!misc_pdev) 112 if (!misc_pdev || !platform_get_drvdata(misc_pdev))
108 return ERR_PTR(-EPROBE_DEFER); 113 return ERR_PTR(-EPROBE_DEFER);
109 114
110 data->dev = &misc_pdev->dev; 115 data->dev = &misc_pdev->dev;
@@ -126,7 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
126 struct ci_hdrc_platform_data pdata = { 131 struct ci_hdrc_platform_data pdata = {
127 .name = dev_name(&pdev->dev), 132 .name = dev_name(&pdev->dev),
128 .capoffset = DEF_CAPOFFSET, 133 .capoffset = DEF_CAPOFFSET,
129 .flags = CI_HDRC_DISABLE_STREAMING, 134 .flags = CI_HDRC_SET_NON_ZERO_TTHA,
130 }; 135 };
131 int ret; 136 int ret;
132 const struct of_device_id *of_id = 137 const struct of_device_id *of_id =
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index ab6212e888e1..3feebf7f31f0 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -64,6 +64,7 @@
64#include <linux/of.h> 64#include <linux/of.h>
65#include <linux/phy.h> 65#include <linux/phy.h>
66#include <linux/regulator/consumer.h> 66#include <linux/regulator/consumer.h>
67#include <linux/usb/ehci_def.h>
67 68
68#include "ci.h" 69#include "ci.h"
69#include "udc.h" 70#include "udc.h"
@@ -84,6 +85,8 @@ static const u8 ci_regs_nolpm[] = {
84 [OP_USBINTR] = 0x08U, 85 [OP_USBINTR] = 0x08U,
85 [OP_DEVICEADDR] = 0x14U, 86 [OP_DEVICEADDR] = 0x14U,
86 [OP_ENDPTLISTADDR] = 0x18U, 87 [OP_ENDPTLISTADDR] = 0x18U,
88 [OP_TTCTRL] = 0x1CU,
89 [OP_BURSTSIZE] = 0x20U,
87 [OP_PORTSC] = 0x44U, 90 [OP_PORTSC] = 0x44U,
88 [OP_DEVLC] = 0x84U, 91 [OP_DEVLC] = 0x84U,
89 [OP_OTGSC] = 0x64U, 92 [OP_OTGSC] = 0x64U,
@@ -106,6 +109,8 @@ static const u8 ci_regs_lpm[] = {
106 [OP_USBINTR] = 0x08U, 109 [OP_USBINTR] = 0x08U,
107 [OP_DEVICEADDR] = 0x14U, 110 [OP_DEVICEADDR] = 0x14U,
108 [OP_ENDPTLISTADDR] = 0x18U, 111 [OP_ENDPTLISTADDR] = 0x18U,
112 [OP_TTCTRL] = 0x1CU,
113 [OP_BURSTSIZE] = 0x20U,
109 [OP_PORTSC] = 0x44U, 114 [OP_PORTSC] = 0x44U,
110 [OP_DEVLC] = 0x84U, 115 [OP_DEVLC] = 0x84U,
111 [OP_OTGSC] = 0xC4U, 116 [OP_OTGSC] = 0xC4U,
@@ -118,7 +123,7 @@ static const u8 ci_regs_lpm[] = {
118 [OP_ENDPTCTRL] = 0xECU, 123 [OP_ENDPTCTRL] = 0xECU,
119}; 124};
120 125
121static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm) 126static void hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm)
122{ 127{
123 int i; 128 int i;
124 129
@@ -134,7 +139,6 @@ static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm)
134 ? ci_regs_lpm[OP_ENDPTCTRL] 139 ? ci_regs_lpm[OP_ENDPTCTRL]
135 : ci_regs_nolpm[OP_ENDPTCTRL]); 140 : ci_regs_nolpm[OP_ENDPTCTRL]);
136 141
137 return 0;
138} 142}
139 143
140static enum ci_revision ci_get_revision(struct ci_hdrc *ci) 144static enum ci_revision ci_get_revision(struct ci_hdrc *ci)
@@ -403,6 +407,55 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
403 return ret; 407 return ret;
404} 408}
405 409
410
411/**
412 * ci_platform_configure: do controller configure
413 * @ci: the controller
414 *
415 */
416void ci_platform_configure(struct ci_hdrc *ci)
417{
418 bool is_device_mode, is_host_mode;
419
420 is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
421 is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
422
423 if (is_device_mode &&
424 (ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING))
425 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
426
427 if (is_host_mode &&
428 (ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING))
429 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
430
431 if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
432 if (ci->hw_bank.lpm)
433 hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC);
434 else
435 hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
436 }
437
438 if (ci->platdata->flags & CI_HDRC_SET_NON_ZERO_TTHA)
439 hw_write(ci, OP_TTCTRL, TTCTRL_TTHA_MASK, TTCTRL_TTHA);
440
441 hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
442
443 if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
444 hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
445 ci->platdata->ahb_burst_config);
446
447 /* override burst size, take effect only when ahb_burst_config is 0 */
448 if (!hw_read_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK)) {
449 if (ci->platdata->flags & CI_HDRC_OVERRIDE_TX_BURST)
450 hw_write(ci, OP_BURSTSIZE, TX_BURST_MASK,
451 ci->platdata->tx_burst_size << __ffs(TX_BURST_MASK));
452
453 if (ci->platdata->flags & CI_HDRC_OVERRIDE_RX_BURST)
454 hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
455 ci->platdata->rx_burst_size);
456 }
457}
458
406/** 459/**
407 * hw_controller_reset: do controller reset 460 * hw_controller_reset: do controller reset
408 * @ci: the controller 461 * @ci: the controller
@@ -447,16 +500,6 @@ int hw_device_reset(struct ci_hdrc *ci)
447 ci->platdata->notify_event(ci, 500 ci->platdata->notify_event(ci,
448 CI_HDRC_CONTROLLER_RESET_EVENT); 501 CI_HDRC_CONTROLLER_RESET_EVENT);
449 502
450 if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
451 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
452
453 if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
454 if (ci->hw_bank.lpm)
455 hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC);
456 else
457 hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
458 }
459
460 /* USBMODE should be configured step by step */ 503 /* USBMODE should be configured step by step */
461 hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); 504 hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
462 hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC); 505 hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC);
@@ -469,6 +512,8 @@ int hw_device_reset(struct ci_hdrc *ci)
469 return -ENODEV; 512 return -ENODEV;
470 } 513 }
471 514
515 ci_platform_configure(ci);
516
472 return 0; 517 return 0;
473} 518}
474 519
@@ -606,6 +651,50 @@ static int ci_get_platdata(struct device *dev,
606 if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) 651 if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL)
607 platdata->flags |= CI_HDRC_FORCE_FULLSPEED; 652 platdata->flags |= CI_HDRC_FORCE_FULLSPEED;
608 653
654 platdata->itc_setting = 1;
655 if (of_find_property(dev->of_node, "itc-setting", NULL)) {
656 ret = of_property_read_u32(dev->of_node, "itc-setting",
657 &platdata->itc_setting);
658 if (ret) {
659 dev_err(dev,
660 "failed to get itc-setting\n");
661 return ret;
662 }
663 }
664
665 if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
666 ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
667 &platdata->ahb_burst_config);
668 if (ret) {
669 dev_err(dev,
670 "failed to get ahb-burst-config\n");
671 return ret;
672 }
673 platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
674 }
675
676 if (of_find_property(dev->of_node, "tx-burst-size-dword", NULL)) {
677 ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword",
678 &platdata->tx_burst_size);
679 if (ret) {
680 dev_err(dev,
681 "failed to get tx-burst-size-dword\n");
682 return ret;
683 }
684 platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST;
685 }
686
687 if (of_find_property(dev->of_node, "rx-burst-size-dword", NULL)) {
688 ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword",
689 &platdata->rx_burst_size);
690 if (ret) {
691 dev_err(dev,
692 "failed to get rx-burst-size-dword\n");
693 return ret;
694 }
695 platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
696 }
697
609 return 0; 698 return 0;
610} 699}
611 700
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
index 3869c6d75515..080b7be3daf0 100644
--- a/drivers/usb/chipidea/debug.c
+++ b/drivers/usb/chipidea/debug.c
@@ -67,9 +67,11 @@ static int ci_port_test_show(struct seq_file *s, void *data)
67 unsigned long flags; 67 unsigned long flags;
68 unsigned mode; 68 unsigned mode;
69 69
70 pm_runtime_get_sync(ci->dev);
70 spin_lock_irqsave(&ci->lock, flags); 71 spin_lock_irqsave(&ci->lock, flags);
71 mode = hw_port_test_get(ci); 72 mode = hw_port_test_get(ci);
72 spin_unlock_irqrestore(&ci->lock, flags); 73 spin_unlock_irqrestore(&ci->lock, flags);
74 pm_runtime_put_sync(ci->dev);
73 75
74 seq_printf(s, "mode = %u\n", mode); 76 seq_printf(s, "mode = %u\n", mode);
75 77
@@ -99,9 +101,11 @@ static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf,
99 if (sscanf(buf, "%u", &mode) != 1) 101 if (sscanf(buf, "%u", &mode) != 1)
100 return -EINVAL; 102 return -EINVAL;
101 103
104 pm_runtime_get_sync(ci->dev);
102 spin_lock_irqsave(&ci->lock, flags); 105 spin_lock_irqsave(&ci->lock, flags);
103 ret = hw_port_test_set(ci, mode); 106 ret = hw_port_test_set(ci, mode);
104 spin_unlock_irqrestore(&ci->lock, flags); 107 spin_unlock_irqrestore(&ci->lock, flags);
108 pm_runtime_put_sync(ci->dev);
105 109
106 return ret ? ret : count; 110 return ret ? ret : count;
107} 111}
@@ -317,8 +321,10 @@ static ssize_t ci_role_write(struct file *file, const char __user *ubuf,
317 if (role == CI_ROLE_END || role == ci->role) 321 if (role == CI_ROLE_END || role == ci->role)
318 return -EINVAL; 322 return -EINVAL;
319 323
324 pm_runtime_get_sync(ci->dev);
320 ci_role_stop(ci); 325 ci_role_stop(ci);
321 ret = ci_role_start(ci, role); 326 ret = ci_role_start(ci, role);
327 pm_runtime_put_sync(ci->dev);
322 328
323 return ret ? ret : count; 329 return ret ? ret : count;
324} 330}
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 7161439def19..3d24304405b3 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -37,15 +37,14 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd);
37 37
38struct ehci_ci_priv { 38struct ehci_ci_priv {
39 struct regulator *reg_vbus; 39 struct regulator *reg_vbus;
40 struct ci_hdrc *ci;
41}; 40};
42 41
43static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) 42static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
44{ 43{
45 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 44 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
46 struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; 45 struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
47 struct ci_hdrc *ci = priv->ci;
48 struct device *dev = hcd->self.controller; 46 struct device *dev = hcd->self.controller;
47 struct ci_hdrc *ci = dev_get_drvdata(dev);
49 int ret = 0; 48 int ret = 0;
50 int port = HCS_N_PORTS(ehci->hcs_params); 49 int port = HCS_N_PORTS(ehci->hcs_params);
51 50
@@ -78,9 +77,25 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
78 return 0; 77 return 0;
79}; 78};
80 79
80static int ehci_ci_reset(struct usb_hcd *hcd)
81{
82 struct device *dev = hcd->self.controller;
83 struct ci_hdrc *ci = dev_get_drvdata(dev);
84 int ret;
85
86 ret = ehci_setup(hcd);
87 if (ret)
88 return ret;
89
90 ci_platform_configure(ci);
91
92 return ret;
93}
94
81static const struct ehci_driver_overrides ehci_ci_overrides = { 95static const struct ehci_driver_overrides ehci_ci_overrides = {
82 .extra_priv_size = sizeof(struct ehci_ci_priv), 96 .extra_priv_size = sizeof(struct ehci_ci_priv),
83 .port_power = ehci_ci_portpower, 97 .port_power = ehci_ci_portpower,
98 .reset = ehci_ci_reset,
84}; 99};
85 100
86static irqreturn_t host_irq(struct ci_hdrc *ci) 101static irqreturn_t host_irq(struct ci_hdrc *ci)
@@ -123,7 +138,6 @@ static int host_start(struct ci_hdrc *ci)
123 138
124 priv = (struct ehci_ci_priv *)ehci->priv; 139 priv = (struct ehci_ci_priv *)ehci->priv;
125 priv->reg_vbus = NULL; 140 priv->reg_vbus = NULL;
126 priv->ci = ci;
127 141
128 if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { 142 if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
129 if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) { 143 if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
@@ -153,12 +167,6 @@ static int host_start(struct ci_hdrc *ci)
153 } 167 }
154 } 168 }
155 169
156 if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
157 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
158
159 if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED)
160 hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
161
162 return ret; 170 return ret;
163 171
164disable_reg: 172disable_reg:
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index 19d655a743b5..00ab59d45da1 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -525,7 +525,6 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on)
525 ci_role_start(ci, CI_ROLE_HOST); 525 ci_role_start(ci, CI_ROLE_HOST);
526 } else { 526 } else {
527 ci_role_stop(ci); 527 ci_role_stop(ci);
528 hw_device_reset(ci);
529 ci_role_start(ci, CI_ROLE_GADGET); 528 ci_role_start(ci, CI_ROLE_GADGET);
530 } 529 }
531 return 0; 530 return 0;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c592b6f0fe21..a637da25dda0 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -445,7 +445,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
445 rest -= count; 445 rest -= count;
446 } 446 }
447 447
448 if (hwreq->req.zero && hwreq->req.length 448 if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX
449 && (hwreq->req.length % hwep->ep.maxpacket == 0)) 449 && (hwreq->req.length % hwep->ep.maxpacket == 0))
450 add_td_to_list(hwep, hwreq, 0); 450 add_td_to_list(hwep, hwreq, 0);
451 451
@@ -1090,6 +1090,13 @@ __acquires(ci->lock)
1090 if (ci_otg_is_fsm_mode(ci)) 1090 if (ci_otg_is_fsm_mode(ci))
1091 err = otg_a_alt_hnp_support(ci); 1091 err = otg_a_alt_hnp_support(ci);
1092 break; 1092 break;
1093 case USB_DEVICE_A_HNP_SUPPORT:
1094 if (ci_otg_is_fsm_mode(ci)) {
1095 ci->gadget.a_hnp_support = 1;
1096 err = isr_setup_status_phase(
1097 ci);
1098 }
1099 break;
1093 default: 1100 default:
1094 goto delegate; 1101 goto delegate;
1095 } 1102 }
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 3cefd49ddb00..5ddab30ee240 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -54,6 +54,7 @@
54#define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 54#define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3
55#define MX53_USB_PLL_DIV_24_MHZ 0x01 55#define MX53_USB_PLL_DIV_24_MHZ 0x01
56 56
57#define MX6_BM_NON_BURST_SETTING BIT(1)
57#define MX6_BM_OVER_CUR_DIS BIT(7) 58#define MX6_BM_OVER_CUR_DIS BIT(7)
58#define MX6_BM_WAKEUP_ENABLE BIT(10) 59#define MX6_BM_WAKEUP_ENABLE BIT(10)
59#define MX6_BM_ID_WAKEUP BIT(16) 60#define MX6_BM_ID_WAKEUP BIT(16)
@@ -255,14 +256,21 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
255 if (data->index > 3) 256 if (data->index > 3)
256 return -EINVAL; 257 return -EINVAL;
257 258
259 spin_lock_irqsave(&usbmisc->lock, flags);
260
258 if (data->disable_oc) { 261 if (data->disable_oc) {
259 spin_lock_irqsave(&usbmisc->lock, flags);
260 reg = readl(usbmisc->base + data->index * 4); 262 reg = readl(usbmisc->base + data->index * 4);
261 writel(reg | MX6_BM_OVER_CUR_DIS, 263 writel(reg | MX6_BM_OVER_CUR_DIS,
262 usbmisc->base + data->index * 4); 264 usbmisc->base + data->index * 4);
263 spin_unlock_irqrestore(&usbmisc->lock, flags);
264 } 265 }
265 266
267 /* SoC non-burst setting */
268 reg = readl(usbmisc->base + data->index * 4);
269 writel(reg | MX6_BM_NON_BURST_SETTING,
270 usbmisc->base + data->index * 4);
271
272 spin_unlock_irqrestore(&usbmisc->lock, flags);
273
266 usbmisc_imx6q_set_wakeup(data, false); 274 usbmisc_imx6q_set_wakeup(data, false);
267 275
268 return 0; 276 return 0;
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index e10cefc721ad..a41833cd184c 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -19,8 +19,11 @@ struct ci_hdrc_platform_data {
19 enum usb_phy_interface phy_mode; 19 enum usb_phy_interface phy_mode;
20 unsigned long flags; 20 unsigned long flags;
21#define CI_HDRC_REGS_SHARED BIT(0) 21#define CI_HDRC_REGS_SHARED BIT(0)
22#define CI_HDRC_DISABLE_DEVICE_STREAMING BIT(1)
22#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2) 23#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
23#define CI_HDRC_DISABLE_STREAMING BIT(3) 24#define CI_HDRC_DISABLE_HOST_STREAMING BIT(3)
25#define CI_HDRC_DISABLE_STREAMING (CI_HDRC_DISABLE_DEVICE_STREAMING | \
26 CI_HDRC_DISABLE_HOST_STREAMING)
24 /* 27 /*
25 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, 28 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
26 * but otg is not supported (no register otgsc). 29 * but otg is not supported (no register otgsc).
@@ -29,6 +32,10 @@ struct ci_hdrc_platform_data {
29#define CI_HDRC_IMX28_WRITE_FIX BIT(5) 32#define CI_HDRC_IMX28_WRITE_FIX BIT(5)
30#define CI_HDRC_FORCE_FULLSPEED BIT(6) 33#define CI_HDRC_FORCE_FULLSPEED BIT(6)
31#define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7) 34#define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7)
35#define CI_HDRC_SET_NON_ZERO_TTHA BIT(8)
36#define CI_HDRC_OVERRIDE_AHB_BURST BIT(9)
37#define CI_HDRC_OVERRIDE_TX_BURST BIT(10)
38#define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
32 enum usb_dr_mode dr_mode; 39 enum usb_dr_mode dr_mode;
33#define CI_HDRC_CONTROLLER_RESET_EVENT 0 40#define CI_HDRC_CONTROLLER_RESET_EVENT 0
34#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 41#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
@@ -36,6 +43,11 @@ struct ci_hdrc_platform_data {
36 struct regulator *reg_vbus; 43 struct regulator *reg_vbus;
37 struct usb_otg_caps ci_otg_caps; 44 struct usb_otg_caps ci_otg_caps;
38 bool tpl_support; 45 bool tpl_support;
46 /* interrupt threshold setting */
47 u32 itc_setting;
48 u32 ahb_burst_config;
49 u32 tx_burst_size;
50 u32 rx_burst_size;
39}; 51};
40 52
41/* Default offset of capability registers */ 53/* Default offset of capability registers */