kernel: bump 4.14 to 4.14.125 (FS#2305 FS#2297)
[oweals/openwrt.git] / target / linux / mediatek / patches-4.14 / 0104-usb-mtu3-support-option-to-disable-usb3-ports.patch
1 From 7a46c3488c48a0fbe313ed25c12af3fb3af48a01 Mon Sep 17 00:00:00 2001
2 From: Chunfeng Yun <chunfeng.yun@mediatek.com>
3 Date: Fri, 13 Oct 2017 17:10:38 +0800
4 Subject: [PATCH 104/224] usb: mtu3: support option to disable usb3 ports
5
6 Add support to disable specific usb3 ports, it's useful when
7 usb3 phy is shared with PCIe or SATA, because we should disable
8 the corresponding usb3 port if the phy is used by PCIe or SATA.
9
10 Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
11 Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
12 ---
13  drivers/usb/mtu3/mtu3.h      |  3 +++
14  drivers/usb/mtu3/mtu3_host.c | 16 +++++++++++++---
15  drivers/usb/mtu3/mtu3_plat.c |  8 ++++++--
16  3 files changed, 22 insertions(+), 5 deletions(-)
17
18 --- a/drivers/usb/mtu3/mtu3.h
19 +++ b/drivers/usb/mtu3/mtu3.h
20 @@ -210,6 +210,8 @@ struct otg_switch_mtk {
21   *             host only, device only or dual-role mode
22   * @u2_ports: number of usb2.0 host ports
23   * @u3_ports: number of usb3.0 host ports
24 + * @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to
25 + *             disable u3port0, bit1==1 to disable u3port1,... etc
26   * @dbgfs_root: only used when supports manual dual-role switch via debugfs
27   * @wakeup_en: it's true when supports remote wakeup in host mode
28   * @wk_deb_p0: port0's wakeup debounce clock
29 @@ -232,6 +234,7 @@ struct ssusb_mtk {
30         bool is_host;
31         int u2_ports;
32         int u3_ports;
33 +       int u3p_dis_msk;
34         struct dentry *dbgfs_root;
35         /* usb wakeup for host mode */
36         bool wakeup_en;
37 --- a/drivers/usb/mtu3/mtu3_host.c
38 +++ b/drivers/usb/mtu3/mtu3_host.c
39 @@ -151,6 +151,7 @@ int ssusb_host_enable(struct ssusb_mtk *
40         void __iomem *ibase = ssusb->ippc_base;
41         int num_u3p = ssusb->u3_ports;
42         int num_u2p = ssusb->u2_ports;
43 +       int u3_ports_disabed;
44         u32 check_clk;
45         u32 value;
46         int i;
47 @@ -158,8 +159,14 @@ int ssusb_host_enable(struct ssusb_mtk *
48         /* power on host ip */
49         mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
50  
51 -       /* power on and enable all u3 ports */
52 +       /* power on and enable u3 ports except skipped ones */
53 +       u3_ports_disabed = 0;
54         for (i = 0; i < num_u3p; i++) {
55 +               if ((0x1 << i) & ssusb->u3p_dis_msk) {
56 +                       u3_ports_disabed++;
57 +                       continue;
58 +               }
59 +
60                 value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
61                 value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
62                 value |= SSUSB_U3_PORT_HOST_SEL;
63 @@ -175,7 +182,7 @@ int ssusb_host_enable(struct ssusb_mtk *
64         }
65  
66         check_clk = SSUSB_XHCI_RST_B_STS;
67 -       if (num_u3p)
68 +       if (num_u3p > u3_ports_disabed)
69                 check_clk = SSUSB_U3_MAC_RST_B_STS;
70  
71         return ssusb_check_clocks(ssusb, check_clk);
72 @@ -190,8 +197,11 @@ int ssusb_host_disable(struct ssusb_mtk
73         int ret;
74         int i;
75  
76 -       /* power down and disable all u3 ports */
77 +       /* power down and disable u3 ports except skipped ones */
78         for (i = 0; i < num_u3p; i++) {
79 +               if ((0x1 << i) & ssusb->u3p_dis_msk)
80 +                       continue;
81 +
82                 value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
83                 value |= SSUSB_U3_PORT_PDN;
84                 value |= suspend ? 0 : SSUSB_U3_PORT_DIS;
85 --- a/drivers/usb/mtu3/mtu3_plat.c
86 +++ b/drivers/usb/mtu3/mtu3_plat.c
87 @@ -276,6 +276,10 @@ static int get_ssusb_rscs(struct platfor
88         if (ret)
89                 return ret;
90  
91 +       /* optional property, ignore the error if it does not exist */
92 +       of_property_read_u32(node, "mediatek,u3p-dis-msk",
93 +                            &ssusb->u3p_dis_msk);
94 +
95         if (ssusb->dr_mode != USB_DR_MODE_OTG)
96                 return 0;
97  
98 @@ -304,8 +308,8 @@ static int get_ssusb_rscs(struct platfor
99                 }
100         }
101  
102 -       dev_info(dev, "dr_mode: %d, is_u3_dr: %d\n",
103 -               ssusb->dr_mode, otg_sx->is_u3_drd);
104 +       dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk:%x\n",
105 +               ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk);
106  
107         return 0;
108  }