Commit 9d6623f13fe58edb5c773c8915ec610b37bb8774

Authored by Luo Ji
Committed by Ji Luo
1 parent dfdf60c69c

MA-14379 [coverity] Resource leak (RESOURCE_LEAK)

Fix coverity issue: CID 2970630: Resource leak (RESOURCE_LEAK)
leaked_storage: Variable cdns going out of scope leaks the storage
it points to.

Memory allocated by devm_kzalloc() won't be freed automatically in
u-boot, free the memory manually here.

Test: Coverity scan pass.

Change-Id: I3000a2385941cef3b8b7e01611cfdc999971a4ca
Signed-off-by: Luo Ji <ji.luo@nxp.com>

Showing 1 changed file with 5 additions and 0 deletions Inline Diff

drivers/usb/cdns3/core.c
1 /* 1 /*
2 * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com/ 2 * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com/
3 * Copyright 2018 NXP 3 * Copyright 2018 NXP
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0 5 * SPDX-License-Identifier: GPL-2.0
6 */ 6 */
7 #include <common.h> 7 #include <common.h>
8 #include <malloc.h> 8 #include <malloc.h>
9 #include <asm/dma-mapping.h> 9 #include <asm/dma-mapping.h>
10 #include <asm/io.h> 10 #include <asm/io.h>
11 #include <linux/bug.h> 11 #include <linux/bug.h>
12 #include <linux/list.h> 12 #include <linux/list.h>
13 #include <linux/compat.h> 13 #include <linux/compat.h>
14 #include <cdns3-uboot.h> 14 #include <cdns3-uboot.h>
15 15
16 #include "linux-compat.h" 16 #include "linux-compat.h"
17 #include "cdns3-nxp-reg-def.h" 17 #include "cdns3-nxp-reg-def.h"
18 #include "core.h" 18 #include "core.h"
19 #include "gadget-export.h" 19 #include "gadget-export.h"
20 20
21 static LIST_HEAD(cdns3_list); 21 static LIST_HEAD(cdns3_list);
22 22
23 /* Need SoC level to implement the clock */ 23 /* Need SoC level to implement the clock */
24 __weak int cdns3_enable_clks(int index) 24 __weak int cdns3_enable_clks(int index)
25 { 25 {
26 return 0; 26 return 0;
27 } 27 }
28 28
29 __weak int cdns3_disable_clks(int index) 29 __weak int cdns3_disable_clks(int index)
30 { 30 {
31 return 0; 31 return 0;
32 } 32 }
33 33
34 static void cdns3_usb_phy_init(void __iomem *regs) 34 static void cdns3_usb_phy_init(void __iomem *regs)
35 { 35 {
36 u32 value; 36 u32 value;
37 37
38 pr_debug("begin of %s\n", __func__); 38 pr_debug("begin of %s\n", __func__);
39 39
40 writel(0x0830, regs + PHY_PMA_CMN_CTRL1); 40 writel(0x0830, regs + PHY_PMA_CMN_CTRL1);
41 writel(0x10, regs + TB_ADDR_CMN_DIAG_HSCLK_SEL); 41 writel(0x10, regs + TB_ADDR_CMN_DIAG_HSCLK_SEL);
42 writel(0x00F0, regs + TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR); 42 writel(0x00F0, regs + TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR);
43 writel(0x0018, regs + TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR); 43 writel(0x0018, regs + TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR);
44 writel(0x00D0, regs + TB_ADDR_CMN_PLL0_INTDIV); 44 writel(0x00D0, regs + TB_ADDR_CMN_PLL0_INTDIV);
45 writel(0x4aaa, regs + TB_ADDR_CMN_PLL0_FRACDIV); 45 writel(0x4aaa, regs + TB_ADDR_CMN_PLL0_FRACDIV);
46 writel(0x0034, regs + TB_ADDR_CMN_PLL0_HIGH_THR); 46 writel(0x0034, regs + TB_ADDR_CMN_PLL0_HIGH_THR);
47 writel(0x1ee, regs + TB_ADDR_CMN_PLL0_SS_CTRL1); 47 writel(0x1ee, regs + TB_ADDR_CMN_PLL0_SS_CTRL1);
48 writel(0x7F03, regs + TB_ADDR_CMN_PLL0_SS_CTRL2); 48 writel(0x7F03, regs + TB_ADDR_CMN_PLL0_SS_CTRL2);
49 writel(0x0020, regs + TB_ADDR_CMN_PLL0_DSM_DIAG); 49 writel(0x0020, regs + TB_ADDR_CMN_PLL0_DSM_DIAG);
50 writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_OVRD); 50 writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_OVRD);
51 writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD); 51 writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD);
52 writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD); 52 writel(0x0000, regs + TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD);
53 writel(0x0007, regs + TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE); 53 writel(0x0007, regs + TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE);
54 writel(0x0027, regs + TB_ADDR_CMN_DIAG_PLL0_CP_TUNE); 54 writel(0x0027, regs + TB_ADDR_CMN_DIAG_PLL0_CP_TUNE);
55 writel(0x0008, regs + TB_ADDR_CMN_DIAG_PLL0_LF_PROG); 55 writel(0x0008, regs + TB_ADDR_CMN_DIAG_PLL0_LF_PROG);
56 writel(0x0022, regs + TB_ADDR_CMN_DIAG_PLL0_TEST_MODE); 56 writel(0x0022, regs + TB_ADDR_CMN_DIAG_PLL0_TEST_MODE);
57 writel(0x000a, regs + TB_ADDR_CMN_PSM_CLK_CTRL); 57 writel(0x000a, regs + TB_ADDR_CMN_PSM_CLK_CTRL);
58 writel(0x139, regs + TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR); 58 writel(0x139, regs + TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR);
59 writel(0xbefc, regs + TB_ADDR_XCVR_PSM_RCTRL); 59 writel(0xbefc, regs + TB_ADDR_XCVR_PSM_RCTRL);
60 60
61 writel(0x7799, regs + TB_ADDR_TX_PSC_A0); 61 writel(0x7799, regs + TB_ADDR_TX_PSC_A0);
62 writel(0x7798, regs + TB_ADDR_TX_PSC_A1); 62 writel(0x7798, regs + TB_ADDR_TX_PSC_A1);
63 writel(0x509b, regs + TB_ADDR_TX_PSC_A2); 63 writel(0x509b, regs + TB_ADDR_TX_PSC_A2);
64 writel(0x3, regs + TB_ADDR_TX_DIAG_ECTRL_OVRD); 64 writel(0x3, regs + TB_ADDR_TX_DIAG_ECTRL_OVRD);
65 writel(0x509b, regs + TB_ADDR_TX_PSC_A3); 65 writel(0x509b, regs + TB_ADDR_TX_PSC_A3);
66 writel(0x2090, regs + TB_ADDR_TX_PSC_CAL); 66 writel(0x2090, regs + TB_ADDR_TX_PSC_CAL);
67 writel(0x2090, regs + TB_ADDR_TX_PSC_RDY); 67 writel(0x2090, regs + TB_ADDR_TX_PSC_RDY);
68 68
69 writel(0xA6FD, regs + TB_ADDR_RX_PSC_A0); 69 writel(0xA6FD, regs + TB_ADDR_RX_PSC_A0);
70 writel(0xA6FD, regs + TB_ADDR_RX_PSC_A1); 70 writel(0xA6FD, regs + TB_ADDR_RX_PSC_A1);
71 writel(0xA410, regs + TB_ADDR_RX_PSC_A2); 71 writel(0xA410, regs + TB_ADDR_RX_PSC_A2);
72 writel(0x2410, regs + TB_ADDR_RX_PSC_A3); 72 writel(0x2410, regs + TB_ADDR_RX_PSC_A3);
73 73
74 writel(0x23FF, regs + TB_ADDR_RX_PSC_CAL); 74 writel(0x23FF, regs + TB_ADDR_RX_PSC_CAL);
75 writel(0x2010, regs + TB_ADDR_RX_PSC_RDY); 75 writel(0x2010, regs + TB_ADDR_RX_PSC_RDY);
76 76
77 writel(0x0020, regs + TB_ADDR_TX_TXCC_MGNLS_MULT_000); 77 writel(0x0020, regs + TB_ADDR_TX_TXCC_MGNLS_MULT_000);
78 writel(0x00ff, regs + TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY); 78 writel(0x00ff, regs + TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY);
79 writel(0x0002, regs + TB_ADDR_RX_SLC_CU_ITER_TMR); 79 writel(0x0002, regs + TB_ADDR_RX_SLC_CU_ITER_TMR);
80 writel(0x0013, regs + TB_ADDR_RX_SIGDET_HL_FILT_TMR); 80 writel(0x0013, regs + TB_ADDR_RX_SIGDET_HL_FILT_TMR);
81 writel(0x0000, regs + TB_ADDR_RX_SAMP_DAC_CTRL); 81 writel(0x0000, regs + TB_ADDR_RX_SAMP_DAC_CTRL);
82 writel(0x1004, regs + TB_ADDR_RX_DIAG_SIGDET_TUNE); 82 writel(0x1004, regs + TB_ADDR_RX_DIAG_SIGDET_TUNE);
83 writel(0x4041, regs + TB_ADDR_RX_DIAG_LFPSDET_TUNE2); 83 writel(0x4041, regs + TB_ADDR_RX_DIAG_LFPSDET_TUNE2);
84 writel(0x0480, regs + TB_ADDR_RX_DIAG_BS_TM); 84 writel(0x0480, regs + TB_ADDR_RX_DIAG_BS_TM);
85 writel(0x8006, regs + TB_ADDR_RX_DIAG_DFE_CTRL1); 85 writel(0x8006, regs + TB_ADDR_RX_DIAG_DFE_CTRL1);
86 writel(0x003f, regs + TB_ADDR_RX_DIAG_ILL_IQE_TRIM4); 86 writel(0x003f, regs + TB_ADDR_RX_DIAG_ILL_IQE_TRIM4);
87 writel(0x543f, regs + TB_ADDR_RX_DIAG_ILL_E_TRIM0); 87 writel(0x543f, regs + TB_ADDR_RX_DIAG_ILL_E_TRIM0);
88 writel(0x543f, regs + TB_ADDR_RX_DIAG_ILL_IQ_TRIM0); 88 writel(0x543f, regs + TB_ADDR_RX_DIAG_ILL_IQ_TRIM0);
89 writel(0x0000, regs + TB_ADDR_RX_DIAG_ILL_IQE_TRIM6); 89 writel(0x0000, regs + TB_ADDR_RX_DIAG_ILL_IQE_TRIM6);
90 writel(0x8000, regs + TB_ADDR_RX_DIAG_RXFE_TM3); 90 writel(0x8000, regs + TB_ADDR_RX_DIAG_RXFE_TM3);
91 writel(0x0003, regs + TB_ADDR_RX_DIAG_RXFE_TM4); 91 writel(0x0003, regs + TB_ADDR_RX_DIAG_RXFE_TM4);
92 writel(0x2408, regs + TB_ADDR_RX_DIAG_LFPSDET_TUNE); 92 writel(0x2408, regs + TB_ADDR_RX_DIAG_LFPSDET_TUNE);
93 writel(0x05ca, regs + TB_ADDR_RX_DIAG_DFE_CTRL3); 93 writel(0x05ca, regs + TB_ADDR_RX_DIAG_DFE_CTRL3);
94 writel(0x0258, regs + TB_ADDR_RX_DIAG_SC2C_DELAY); 94 writel(0x0258, regs + TB_ADDR_RX_DIAG_SC2C_DELAY);
95 writel(0x1fff, regs + TB_ADDR_RX_REE_VGA_GAIN_NODFE); 95 writel(0x1fff, regs + TB_ADDR_RX_REE_VGA_GAIN_NODFE);
96 96
97 writel(0x02c6, regs + TB_ADDR_XCVR_PSM_CAL_TMR); 97 writel(0x02c6, regs + TB_ADDR_XCVR_PSM_CAL_TMR);
98 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A0BYP_TMR); 98 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A0BYP_TMR);
99 writel(0x02c6, regs + TB_ADDR_XCVR_PSM_A0IN_TMR); 99 writel(0x02c6, regs + TB_ADDR_XCVR_PSM_A0IN_TMR);
100 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A1IN_TMR); 100 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A1IN_TMR);
101 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A2IN_TMR); 101 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A2IN_TMR);
102 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A3IN_TMR); 102 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A3IN_TMR);
103 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A4IN_TMR); 103 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A4IN_TMR);
104 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A5IN_TMR); 104 writel(0x0010, regs + TB_ADDR_XCVR_PSM_A5IN_TMR);
105 105
106 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A0OUT_TMR); 106 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A0OUT_TMR);
107 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A1OUT_TMR); 107 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A1OUT_TMR);
108 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A2OUT_TMR); 108 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A2OUT_TMR);
109 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A3OUT_TMR); 109 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A3OUT_TMR);
110 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A4OUT_TMR); 110 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A4OUT_TMR);
111 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A5OUT_TMR); 111 writel(0x0002, regs + TB_ADDR_XCVR_PSM_A5OUT_TMR);
112 112
113 /* Change rx detect parameter */ 113 /* Change rx detect parameter */
114 writel(0x960, regs + TB_ADDR_TX_RCVDET_EN_TMR); 114 writel(0x960, regs + TB_ADDR_TX_RCVDET_EN_TMR);
115 writel(0x01e0, regs + TB_ADDR_TX_RCVDET_ST_TMR); 115 writel(0x01e0, regs + TB_ADDR_TX_RCVDET_ST_TMR);
116 writel(0x0090, regs + TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR); 116 writel(0x0090, regs + TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR);
117 117
118 /* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */ 118 /* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */
119 value = readl(regs + TB_ADDR_TX_RCVDETSC_CTRL); 119 value = readl(regs + TB_ADDR_TX_RCVDETSC_CTRL);
120 value |= RXDET_IN_P3_32KHZ; 120 value |= RXDET_IN_P3_32KHZ;
121 writel(value, regs + TB_ADDR_TX_RCVDETSC_CTRL); 121 writel(value, regs + TB_ADDR_TX_RCVDETSC_CTRL);
122 122
123 udelay(10); 123 udelay(10);
124 124
125 pr_debug("end of %s\n", __func__); 125 pr_debug("end of %s\n", __func__);
126 } 126 }
127 127
128 static void cdns3_reset_core(struct cdns3 *cdns) 128 static void cdns3_reset_core(struct cdns3 *cdns)
129 { 129 {
130 u32 value; 130 u32 value;
131 131
132 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1); 132 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
133 value |= ALL_SW_RESET; 133 value |= ALL_SW_RESET;
134 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 134 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
135 udelay(1); 135 udelay(1);
136 } 136 }
137 137
138 static void cdns3_set_role(struct cdns3 *cdns, enum cdns3_roles role) 138 static void cdns3_set_role(struct cdns3 *cdns, enum cdns3_roles role)
139 { 139 {
140 u32 value; 140 u32 value;
141 int timeout_us = 100000; 141 int timeout_us = 100000;
142 142
143 if (role == CDNS3_ROLE_END) 143 if (role == CDNS3_ROLE_END)
144 return; 144 return;
145 145
146 /* Wait clk value */ 146 /* Wait clk value */
147 value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS); 147 value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS);
148 writel(value, cdns->none_core_regs + USB3_SSPHY_STATUS); 148 writel(value, cdns->none_core_regs + USB3_SSPHY_STATUS);
149 udelay(1); 149 udelay(1);
150 value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS); 150 value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS);
151 while ((value & 0xf0000000) != 0xf0000000 && timeout_us-- > 0) { 151 while ((value & 0xf0000000) != 0xf0000000 && timeout_us-- > 0) {
152 value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS); 152 value = readl(cdns->none_core_regs + USB3_SSPHY_STATUS);
153 dev_dbg(cdns->dev, "clkvld:0x%x\n", value); 153 dev_dbg(cdns->dev, "clkvld:0x%x\n", value);
154 udelay(1); 154 udelay(1);
155 } 155 }
156 156
157 if (timeout_us <= 0) 157 if (timeout_us <= 0)
158 dev_err(cdns->dev, "wait clkvld timeout\n"); 158 dev_err(cdns->dev, "wait clkvld timeout\n");
159 159
160 /* Set all Reset bits */ 160 /* Set all Reset bits */
161 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1); 161 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
162 value |= ALL_SW_RESET; 162 value |= ALL_SW_RESET;
163 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 163 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
164 udelay(1); 164 udelay(1);
165 165
166 if (role == CDNS3_ROLE_HOST) { 166 if (role == CDNS3_ROLE_HOST) {
167 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1); 167 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
168 value = (value & ~MODE_STRAP_MASK) | HOST_MODE | OC_DISABLE; 168 value = (value & ~MODE_STRAP_MASK) | HOST_MODE | OC_DISABLE;
169 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 169 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
170 value &= ~PHYAHB_SW_RESET; 170 value &= ~PHYAHB_SW_RESET;
171 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 171 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
172 mdelay(1); 172 mdelay(1);
173 cdns3_usb_phy_init(cdns->phy_regs); 173 cdns3_usb_phy_init(cdns->phy_regs);
174 /* Force B Session Valid as 1 */ 174 /* Force B Session Valid as 1 */
175 writel(0x0060, cdns->phy_regs + 0x380a4); 175 writel(0x0060, cdns->phy_regs + 0x380a4);
176 mdelay(1); 176 mdelay(1);
177 177
178 value = readl(cdns->none_core_regs + USB3_INT_REG); 178 value = readl(cdns->none_core_regs + USB3_INT_REG);
179 value |= HOST_INT1_EN; 179 value |= HOST_INT1_EN;
180 writel(value, cdns->none_core_regs + USB3_INT_REG); 180 writel(value, cdns->none_core_regs + USB3_INT_REG);
181 181
182 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1); 182 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
183 value &= ~ALL_SW_RESET; 183 value &= ~ALL_SW_RESET;
184 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 184 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
185 185
186 dev_dbg(cdns->dev, "wait xhci_power_on_ready\n"); 186 dev_dbg(cdns->dev, "wait xhci_power_on_ready\n");
187 187
188 value = readl(cdns->none_core_regs + USB3_CORE_STATUS); 188 value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
189 timeout_us = 100000; 189 timeout_us = 100000;
190 while (!(value & HOST_POWER_ON_READY) && timeout_us-- > 0) { 190 while (!(value & HOST_POWER_ON_READY) && timeout_us-- > 0) {
191 value = readl(cdns->none_core_regs + USB3_CORE_STATUS); 191 value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
192 udelay(1); 192 udelay(1);
193 } 193 }
194 194
195 if (timeout_us <= 0) 195 if (timeout_us <= 0)
196 dev_err(cdns->dev, "wait xhci_power_on_ready timeout\n"); 196 dev_err(cdns->dev, "wait xhci_power_on_ready timeout\n");
197 197
198 mdelay(1); 198 mdelay(1);
199 199
200 dev_dbg(cdns->dev, "switch to host role successfully\n"); 200 dev_dbg(cdns->dev, "switch to host role successfully\n");
201 } else { /* gadget mode */ 201 } else { /* gadget mode */
202 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1); 202 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
203 value = (value & ~MODE_STRAP_MASK) | DEV_MODE; 203 value = (value & ~MODE_STRAP_MASK) | DEV_MODE;
204 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 204 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
205 value &= ~PHYAHB_SW_RESET; 205 value &= ~PHYAHB_SW_RESET;
206 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 206 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
207 207
208 cdns3_usb_phy_init(cdns->phy_regs); 208 cdns3_usb_phy_init(cdns->phy_regs);
209 /* Force B Session Valid as 1 */ 209 /* Force B Session Valid as 1 */
210 writel(0x0060, cdns->phy_regs + 0x380a4); 210 writel(0x0060, cdns->phy_regs + 0x380a4);
211 value = readl(cdns->none_core_regs + USB3_INT_REG); 211 value = readl(cdns->none_core_regs + USB3_INT_REG);
212 value |= DEV_INT_EN; 212 value |= DEV_INT_EN;
213 writel(value, cdns->none_core_regs + USB3_INT_REG); 213 writel(value, cdns->none_core_regs + USB3_INT_REG);
214 214
215 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1); 215 value = readl(cdns->none_core_regs + USB3_CORE_CTRL1);
216 value &= ~ALL_SW_RESET; 216 value &= ~ALL_SW_RESET;
217 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1); 217 writel(value, cdns->none_core_regs + USB3_CORE_CTRL1);
218 218
219 dev_dbg(cdns->dev, "wait gadget_power_on_ready\n"); 219 dev_dbg(cdns->dev, "wait gadget_power_on_ready\n");
220 220
221 value = readl(cdns->none_core_regs + USB3_CORE_STATUS); 221 value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
222 timeout_us = 100000; 222 timeout_us = 100000;
223 while (!(value & DEV_POWER_ON_READY) && timeout_us-- > 0) { 223 while (!(value & DEV_POWER_ON_READY) && timeout_us-- > 0) {
224 value = readl(cdns->none_core_regs + USB3_CORE_STATUS); 224 value = readl(cdns->none_core_regs + USB3_CORE_STATUS);
225 udelay(1); 225 udelay(1);
226 } 226 }
227 227
228 if (timeout_us <= 0) 228 if (timeout_us <= 0)
229 dev_err(cdns->dev, 229 dev_err(cdns->dev,
230 "wait gadget_power_on_ready timeout\n"); 230 "wait gadget_power_on_ready timeout\n");
231 231
232 mdelay(1); 232 mdelay(1);
233 233
234 dev_dbg(cdns->dev, "switch to gadget role successfully\n"); 234 dev_dbg(cdns->dev, "switch to gadget role successfully\n");
235 } 235 }
236 } 236 }
237 237
238 static enum cdns3_roles cdns3_get_role(struct cdns3 *cdns) 238 static enum cdns3_roles cdns3_get_role(struct cdns3 *cdns)
239 { 239 {
240 return cdns->roles[CDNS3_ROLE_HOST] 240 return cdns->roles[CDNS3_ROLE_HOST]
241 ? CDNS3_ROLE_HOST 241 ? CDNS3_ROLE_HOST
242 : CDNS3_ROLE_GADGET; 242 : CDNS3_ROLE_GADGET;
243 } 243 }
244 244
245 /** 245 /**
246 * cdns3_core_init_role - initialize role of operation 246 * cdns3_core_init_role - initialize role of operation
247 * @cdns: Pointer to cdns3 structure 247 * @cdns: Pointer to cdns3 structure
248 * 248 *
249 * Returns 0 on success otherwise negative errno 249 * Returns 0 on success otherwise negative errno
250 */ 250 */
251 static int cdns3_core_init_role(struct cdns3 *cdns, enum usb_dr_mode dr_mode) 251 static int cdns3_core_init_role(struct cdns3 *cdns, enum usb_dr_mode dr_mode)
252 { 252 {
253 cdns->role = CDNS3_ROLE_END; 253 cdns->role = CDNS3_ROLE_END;
254 if (dr_mode == USB_DR_MODE_UNKNOWN) 254 if (dr_mode == USB_DR_MODE_UNKNOWN)
255 dr_mode = USB_DR_MODE_OTG; 255 dr_mode = USB_DR_MODE_OTG;
256 256
257 /* Currently, only support gadget mode */ 257 /* Currently, only support gadget mode */
258 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) { 258 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
259 dev_err(cdns->dev, "doesn't support host and OTG, only for gadget\n"); 259 dev_err(cdns->dev, "doesn't support host and OTG, only for gadget\n");
260 return -EPERM; 260 return -EPERM;
261 } 261 }
262 262
263 if (dr_mode == USB_DR_MODE_PERIPHERAL) { 263 if (dr_mode == USB_DR_MODE_PERIPHERAL) {
264 if (cdns3_gadget_init(cdns)) 264 if (cdns3_gadget_init(cdns))
265 dev_info(cdns->dev, "doesn't support gadget\n"); 265 dev_info(cdns->dev, "doesn't support gadget\n");
266 } 266 }
267 267
268 if (!cdns->roles[CDNS3_ROLE_HOST] && !cdns->roles[CDNS3_ROLE_GADGET]) { 268 if (!cdns->roles[CDNS3_ROLE_HOST] && !cdns->roles[CDNS3_ROLE_GADGET]) {
269 dev_err(cdns->dev, "no supported roles\n"); 269 dev_err(cdns->dev, "no supported roles\n");
270 return -ENODEV; 270 return -ENODEV;
271 } 271 }
272 272
273 return 0; 273 return 0;
274 } 274 }
275 275
276 static void cdns3_remove_roles(struct cdns3 *cdns) 276 static void cdns3_remove_roles(struct cdns3 *cdns)
277 { 277 {
278 /* Only support gadget */ 278 /* Only support gadget */
279 cdns3_gadget_remove(cdns); 279 cdns3_gadget_remove(cdns);
280 } 280 }
281 281
282 int cdns3_uboot_init(struct cdns3_device *cdns3_dev) 282 int cdns3_uboot_init(struct cdns3_device *cdns3_dev)
283 { 283 {
284 struct device *dev = NULL; 284 struct device *dev = NULL;
285 struct cdns3 *cdns; 285 struct cdns3 *cdns;
286 int ret; 286 int ret;
287 287
288 cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL); 288 cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
289 if (!cdns) 289 if (!cdns)
290 return -ENOMEM; 290 return -ENOMEM;
291 291
292 cdns->dev = dev; 292 cdns->dev = dev;
293 293
294 /* 294 /*
295 * Request memory region 295 * Request memory region
296 * region-0: nxp wrap registers 296 * region-0: nxp wrap registers
297 * region-1: xHCI 297 * region-1: xHCI
298 * region-2: Peripheral 298 * region-2: Peripheral
299 * region-3: PHY registers 299 * region-3: PHY registers
300 * region-4: OTG registers 300 * region-4: OTG registers
301 */ 301 */
302 cdns->none_core_regs = (void __iomem *)cdns3_dev->none_core_base; 302 cdns->none_core_regs = (void __iomem *)cdns3_dev->none_core_base;
303 cdns->xhci_regs = (void __iomem *)cdns3_dev->xhci_base; 303 cdns->xhci_regs = (void __iomem *)cdns3_dev->xhci_base;
304 cdns->dev_regs = (void __iomem *)cdns3_dev->dev_base; 304 cdns->dev_regs = (void __iomem *)cdns3_dev->dev_base;
305 cdns->phy_regs = (void __iomem *)cdns3_dev->phy_base; 305 cdns->phy_regs = (void __iomem *)cdns3_dev->phy_base;
306 cdns->otg_regs = (void __iomem *)cdns3_dev->otg_base; 306 cdns->otg_regs = (void __iomem *)cdns3_dev->otg_base;
307 cdns->index = cdns3_dev->index; 307 cdns->index = cdns3_dev->index;
308 308
309 ret = cdns3_enable_clks(cdns->index); 309 ret = cdns3_enable_clks(cdns->index);
310 if (ret) 310 if (ret)
311 return ret; 311 return ret;
312 312
313 ret = cdns3_core_init_role(cdns, cdns3_dev->dr_mode); 313 ret = cdns3_core_init_role(cdns, cdns3_dev->dr_mode);
314 if (ret) 314 if (ret)
315 goto err1; 315 goto err1;
316 316
317 cdns->role = cdns3_get_role(cdns); 317 cdns->role = cdns3_get_role(cdns);
318 dev_dbg(dev, "the init role is %d\n", cdns->role); 318 dev_dbg(dev, "the init role is %d\n", cdns->role);
319 cdns3_set_role(cdns, cdns->role); 319 cdns3_set_role(cdns, cdns->role);
320 ret = cdns3_role_start(cdns, cdns->role); 320 ret = cdns3_role_start(cdns, cdns->role);
321 if (ret) { 321 if (ret) {
322 dev_err(dev, "can't start %s role\n", cdns3_role(cdns)->name); 322 dev_err(dev, "can't start %s role\n", cdns3_role(cdns)->name);
323 goto err2; 323 goto err2;
324 } 324 }
325 325
326 dev_dbg(dev, "Cadence USB3 core: probe succeed\n"); 326 dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
327 327
328 list_add_tail(&cdns->list, &cdns3_list); 328 list_add_tail(&cdns->list, &cdns3_list);
329 329
330 return 0; 330 return 0;
331 331
332 err2: 332 err2:
333 cdns3_remove_roles(cdns); 333 cdns3_remove_roles(cdns);
334 err1: 334 err1:
335 cdns3_disable_clks(cdns->index); 335 cdns3_disable_clks(cdns->index);
336
337 /* For u-boot, need to free the memory manually here. */
338 if (cdns != NULL)
339 free(cdns);
340
336 return ret; 341 return ret;
337 } 342 }
338 343
339 void cdns3_uboot_exit(int index) 344 void cdns3_uboot_exit(int index)
340 { 345 {
341 struct cdns3 *cdns; 346 struct cdns3 *cdns;
342 347
343 list_for_each_entry(cdns, &cdns3_list, list) { 348 list_for_each_entry(cdns, &cdns3_list, list) {
344 if (cdns->index != index) 349 if (cdns->index != index)
345 continue; 350 continue;
346 351
347 cdns3_role_stop(cdns); 352 cdns3_role_stop(cdns);
348 cdns3_remove_roles(cdns); 353 cdns3_remove_roles(cdns);
349 cdns3_reset_core(cdns); 354 cdns3_reset_core(cdns);
350 cdns3_disable_clks(index); 355 cdns3_disable_clks(index);
351 356
352 list_del(&cdns->list); 357 list_del(&cdns->list);
353 kfree(cdns); 358 kfree(cdns);
354 break; 359 break;
355 } 360 }
356 } 361 }
357 362
358 void cdns3_uboot_handle_interrupt(int index) 363 void cdns3_uboot_handle_interrupt(int index)
359 { 364 {
360 struct cdns3 *cdns = NULL; 365 struct cdns3 *cdns = NULL;
361 366
362 list_for_each_entry(cdns, &cdns3_list, list) { 367 list_for_each_entry(cdns, &cdns3_list, list) {
363 if (cdns->index != index) 368 if (cdns->index != index)
364 continue; 369 continue;
365 370
366 cdns3_role_irq_handler(cdns); 371 cdns3_role_irq_handler(cdns);
367 break; 372 break;
368 } 373 }
369 } 374 }
370 375