Skip to content

Commit 379c9a2

Browse files
aford173abelvesa
authored andcommitted
clk: imx: Fix reparenting of UARTs not associated with stdout
Most if not all i.MX SoC's call a function which enables all UARTS. This is a problem for users who need to re-parent the clock source, because any attempt to change the parent results in an busy error due to the fact that the clocks have been enabled already. clk: failed to reparent uart1 to sys_pll1_80m: -16 Instead of pre-initializing all UARTS, scan the device tree to see which UART clocks are associated to stdout, and only enable those UART clocks if it's needed early. This will move initialization of the remaining clocks until after the parenting of the clocks. When the clocks are shutdown, this mechanism will also disable any clocks that were pre-initialized. Fixes: 9461f7b ("clk: fix CLK_SET_RATE_GATE with clock rate protection") Suggested-by: Aisheng Dong <[email protected]> Signed-off-by: Adam Ford <[email protected]> Reviewed-by: Abel Vesa <[email protected]> Tested-by: Ahmad Fatoum <[email protected]> Signed-off-by: Abel Vesa <[email protected]>
1 parent a38fd87 commit 379c9a2

16 files changed

+54
-252
lines changed

drivers/clk/imx/clk-imx25.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,6 @@ enum mx25_clks {
7373

7474
static struct clk *clk[clk_max];
7575

76-
static struct clk ** const uart_clks[] __initconst = {
77-
&clk[uart_ipg_per],
78-
&clk[uart1_ipg],
79-
&clk[uart2_ipg],
80-
&clk[uart3_ipg],
81-
&clk[uart4_ipg],
82-
&clk[uart5_ipg],
83-
NULL
84-
};
85-
8676
static int __init __mx25_clocks_init(void __iomem *ccm_base)
8777
{
8878
BUG_ON(!ccm_base);
@@ -228,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem *ccm_base)
228218
*/
229219
clk_set_parent(clk[cko_sel], clk[ipg]);
230220

231-
imx_register_uart_clocks(uart_clks);
221+
imx_register_uart_clocks(6);
232222

233223
return 0;
234224
}

drivers/clk/imx/clk-imx27.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,6 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
4949
static struct clk *clk[IMX27_CLK_MAX];
5050
static struct clk_onecell_data clk_data;
5151

52-
static struct clk ** const uart_clks[] __initconst = {
53-
&clk[IMX27_CLK_PER1_GATE],
54-
&clk[IMX27_CLK_UART1_IPG_GATE],
55-
&clk[IMX27_CLK_UART2_IPG_GATE],
56-
&clk[IMX27_CLK_UART3_IPG_GATE],
57-
&clk[IMX27_CLK_UART4_IPG_GATE],
58-
&clk[IMX27_CLK_UART5_IPG_GATE],
59-
&clk[IMX27_CLK_UART6_IPG_GATE],
60-
NULL
61-
};
62-
6352
static void __init _mx27_clocks_init(unsigned long fref)
6453
{
6554
BUG_ON(!ccm);
@@ -176,7 +165,7 @@ static void __init _mx27_clocks_init(unsigned long fref)
176165

177166
clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
178167

179-
imx_register_uart_clocks(uart_clks);
168+
imx_register_uart_clocks(7);
180169

181170
imx_print_silicon_rev("i.MX27", mx27_revision());
182171
}

drivers/clk/imx/clk-imx35.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,6 @@ enum mx35_clks {
8282

8383
static struct clk *clk[clk_max];
8484

85-
static struct clk ** const uart_clks[] __initconst = {
86-
&clk[ipg],
87-
&clk[uart1_gate],
88-
&clk[uart2_gate],
89-
&clk[uart3_gate],
90-
NULL
91-
};
92-
9385
static void __init _mx35_clocks_init(void)
9486
{
9587
void __iomem *base;
@@ -243,7 +235,7 @@ static void __init _mx35_clocks_init(void)
243235
*/
244236
clk_prepare_enable(clk[scc_gate]);
245237

246-
imx_register_uart_clocks(uart_clks);
238+
imx_register_uart_clocks(4);
247239

248240
imx_print_silicon_rev("i.MX35", mx35_revision());
249241
}

drivers/clk/imx/clk-imx5.c

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -128,30 +128,6 @@ static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_
128128
static struct clk *clk[IMX5_CLK_END];
129129
static struct clk_onecell_data clk_data;
130130

131-
static struct clk ** const uart_clks_mx51[] __initconst = {
132-
&clk[IMX5_CLK_UART1_IPG_GATE],
133-
&clk[IMX5_CLK_UART1_PER_GATE],
134-
&clk[IMX5_CLK_UART2_IPG_GATE],
135-
&clk[IMX5_CLK_UART2_PER_GATE],
136-
&clk[IMX5_CLK_UART3_IPG_GATE],
137-
&clk[IMX5_CLK_UART3_PER_GATE],
138-
NULL
139-
};
140-
141-
static struct clk ** const uart_clks_mx50_mx53[] __initconst = {
142-
&clk[IMX5_CLK_UART1_IPG_GATE],
143-
&clk[IMX5_CLK_UART1_PER_GATE],
144-
&clk[IMX5_CLK_UART2_IPG_GATE],
145-
&clk[IMX5_CLK_UART2_PER_GATE],
146-
&clk[IMX5_CLK_UART3_IPG_GATE],
147-
&clk[IMX5_CLK_UART3_PER_GATE],
148-
&clk[IMX5_CLK_UART4_IPG_GATE],
149-
&clk[IMX5_CLK_UART4_PER_GATE],
150-
&clk[IMX5_CLK_UART5_IPG_GATE],
151-
&clk[IMX5_CLK_UART5_PER_GATE],
152-
NULL
153-
};
154-
155131
static void __init mx5_clocks_common_init(void __iomem *ccm_base)
156132
{
157133
clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
@@ -382,7 +358,7 @@ static void __init mx50_clocks_init(struct device_node *np)
382358
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
383359
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
384360

385-
imx_register_uart_clocks(uart_clks_mx50_mx53);
361+
imx_register_uart_clocks(5);
386362
}
387363
CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
388364

@@ -488,7 +464,7 @@ static void __init mx51_clocks_init(struct device_node *np)
488464
val |= 1 << 23;
489465
writel(val, MXC_CCM_CLPCR);
490466

491-
imx_register_uart_clocks(uart_clks_mx51);
467+
imx_register_uart_clocks(3);
492468
}
493469
CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
494470

@@ -633,6 +609,6 @@ static void __init mx53_clocks_init(struct device_node *np)
633609
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
634610
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
635611

636-
imx_register_uart_clocks(uart_clks_mx50_mx53);
612+
imx_register_uart_clocks(5);
637613
}
638614
CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);

drivers/clk/imx/clk-imx6q.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,6 @@ static inline int clk_on_imx6dl(void)
140140
return of_machine_is_compatible("fsl,imx6dl");
141141
}
142142

143-
static const int uart_clk_ids[] __initconst = {
144-
IMX6QDL_CLK_UART_IPG,
145-
IMX6QDL_CLK_UART_SERIAL,
146-
};
147-
148-
static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata;
149-
150143
static int ldb_di_sel_by_clock_id(int clock_id)
151144
{
152145
switch (clock_id) {
@@ -440,7 +433,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
440433
struct device_node *np;
441434
void __iomem *anatop_base, *base;
442435
int ret;
443-
int i;
444436

445437
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
446438
IMX6QDL_CLK_END), GFP_KERNEL);
@@ -982,12 +974,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
982974
hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk);
983975
}
984976

985-
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
986-
int index = uart_clk_ids[i];
987-
988-
uart_clks[i] = &hws[index]->clk;
989-
}
990-
991-
imx_register_uart_clocks(uart_clks);
977+
imx_register_uart_clocks(1);
992978
}
993979
CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);

drivers/clk/imx/clk-imx6sl.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -179,19 +179,11 @@ void imx6sl_set_wait_clk(bool enter)
179179
imx6sl_enable_pll_arm(false);
180180
}
181181

182-
static const int uart_clk_ids[] __initconst = {
183-
IMX6SL_CLK_UART,
184-
IMX6SL_CLK_UART_SERIAL,
185-
};
186-
187-
static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata;
188-
189182
static void __init imx6sl_clocks_init(struct device_node *ccm_node)
190183
{
191184
struct device_node *np;
192185
void __iomem *base;
193186
int ret;
194-
int i;
195187

196188
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
197189
IMX6SL_CLK_END), GFP_KERNEL);
@@ -448,12 +440,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
448440
clk_set_parent(hws[IMX6SL_CLK_LCDIF_AXI_SEL]->clk,
449441
hws[IMX6SL_CLK_PLL2_PFD2]->clk);
450442

451-
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
452-
int index = uart_clk_ids[i];
453-
454-
uart_clks[i] = &hws[index]->clk;
455-
}
456-
457-
imx_register_uart_clocks(uart_clks);
443+
imx_register_uart_clocks(2);
458444
}
459445
CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);

drivers/clk/imx/clk-imx6sll.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,10 @@ static u32 share_count_ssi1;
7676
static u32 share_count_ssi2;
7777
static u32 share_count_ssi3;
7878

79-
static const int uart_clk_ids[] __initconst = {
80-
IMX6SLL_CLK_UART1_IPG,
81-
IMX6SLL_CLK_UART1_SERIAL,
82-
IMX6SLL_CLK_UART2_IPG,
83-
IMX6SLL_CLK_UART2_SERIAL,
84-
IMX6SLL_CLK_UART3_IPG,
85-
IMX6SLL_CLK_UART3_SERIAL,
86-
IMX6SLL_CLK_UART4_IPG,
87-
IMX6SLL_CLK_UART4_SERIAL,
88-
IMX6SLL_CLK_UART5_IPG,
89-
IMX6SLL_CLK_UART5_SERIAL,
90-
};
91-
92-
static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata;
93-
9479
static void __init imx6sll_clocks_init(struct device_node *ccm_node)
9580
{
9681
struct device_node *np;
9782
void __iomem *base;
98-
int i;
9983

10084
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
10185
IMX6SLL_CLK_END), GFP_KERNEL);
@@ -356,13 +340,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
356340

357341
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
358342

359-
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
360-
int index = uart_clk_ids[i];
361-
362-
uart_clks[i] = &hws[index]->clk;
363-
}
364-
365-
imx_register_uart_clocks(uart_clks);
343+
imx_register_uart_clocks(5);
366344

367345
/* Lower the AHB clock rate before changing the clock source. */
368346
clk_set_rate(hws[IMX6SLL_CLK_AHB]->clk, 99000000);

drivers/clk/imx/clk-imx6sx.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,10 @@ static u32 share_count_ssi3;
117117
static u32 share_count_sai1;
118118
static u32 share_count_sai2;
119119

120-
static const int uart_clk_ids[] __initconst = {
121-
IMX6SX_CLK_UART_IPG,
122-
IMX6SX_CLK_UART_SERIAL,
123-
};
124-
125-
static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata;
126-
127120
static void __init imx6sx_clocks_init(struct device_node *ccm_node)
128121
{
129122
struct device_node *np;
130123
void __iomem *base;
131-
int i;
132124

133125
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
134126
IMX6SX_CLK_CLK_END), GFP_KERNEL);
@@ -556,12 +548,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
556548
clk_set_parent(hws[IMX6SX_CLK_QSPI1_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
557549
clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
558550

559-
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
560-
int index = uart_clk_ids[i];
561-
562-
uart_clks[i] = &hws[index]->clk;
563-
}
564-
565-
imx_register_uart_clocks(uart_clks);
551+
imx_register_uart_clocks(2);
566552
}
567553
CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);

drivers/clk/imx/clk-imx7d.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -377,23 +377,10 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_
377377
static struct clk_hw **hws;
378378
static struct clk_hw_onecell_data *clk_hw_data;
379379

380-
static const int uart_clk_ids[] __initconst = {
381-
IMX7D_UART1_ROOT_CLK,
382-
IMX7D_UART2_ROOT_CLK,
383-
IMX7D_UART3_ROOT_CLK,
384-
IMX7D_UART4_ROOT_CLK,
385-
IMX7D_UART5_ROOT_CLK,
386-
IMX7D_UART6_ROOT_CLK,
387-
IMX7D_UART7_ROOT_CLK,
388-
};
389-
390-
static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata;
391-
392380
static void __init imx7d_clocks_init(struct device_node *ccm_node)
393381
{
394382
struct device_node *np;
395383
void __iomem *base;
396-
int i;
397384

398385
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
399386
IMX7D_CLK_END), GFP_KERNEL);
@@ -897,14 +884,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
897884
hws[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_hw_fixed_factor("pll_usb1_main_clk", "osc", 20, 1);
898885
hws[IMX7D_USB_MAIN_480M_CLK] = imx_clk_hw_fixed_factor("pll_usb_main_clk", "osc", 20, 1);
899886

900-
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
901-
int index = uart_clk_ids[i];
902-
903-
uart_clks[i] = &hws[index]->clk;
904-
}
905-
906-
907-
imx_register_uart_clocks(uart_clks);
887+
imx_register_uart_clocks(7);
908888

909889
}
910890
CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);

drivers/clk/imx/clk-imx7ulp.c

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,6 @@ static const struct clk_div_table ulp_div_table[] = {
4343
{ /* sentinel */ },
4444
};
4545

46-
static const int pcc2_uart_clk_ids[] __initconst = {
47-
IMX7ULP_CLK_LPUART4,
48-
IMX7ULP_CLK_LPUART5,
49-
};
50-
51-
static const int pcc3_uart_clk_ids[] __initconst = {
52-
IMX7ULP_CLK_LPUART6,
53-
IMX7ULP_CLK_LPUART7,
54-
};
55-
56-
static struct clk **pcc2_uart_clks[ARRAY_SIZE(pcc2_uart_clk_ids) + 1] __initdata;
57-
static struct clk **pcc3_uart_clks[ARRAY_SIZE(pcc3_uart_clk_ids) + 1] __initdata;
58-
5946
static void __init imx7ulp_clk_scg1_init(struct device_node *np)
6047
{
6148
struct clk_hw_onecell_data *clk_data;
@@ -150,7 +137,6 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
150137
struct clk_hw_onecell_data *clk_data;
151138
struct clk_hw **hws;
152139
void __iomem *base;
153-
int i;
154140

155141
clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC2_END),
156142
GFP_KERNEL);
@@ -190,13 +176,7 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
190176

191177
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
192178

193-
for (i = 0; i < ARRAY_SIZE(pcc2_uart_clk_ids); i++) {
194-
int index = pcc2_uart_clk_ids[i];
195-
196-
pcc2_uart_clks[i] = &hws[index]->clk;
197-
}
198-
199-
imx_register_uart_clocks(pcc2_uart_clks);
179+
imx_register_uart_clocks(2);
200180
}
201181
CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init);
202182

@@ -205,7 +185,6 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
205185
struct clk_hw_onecell_data *clk_data;
206186
struct clk_hw **hws;
207187
void __iomem *base;
208-
int i;
209188

210189
clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC3_END),
211190
GFP_KERNEL);
@@ -244,13 +223,7 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
244223

245224
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
246225

247-
for (i = 0; i < ARRAY_SIZE(pcc3_uart_clk_ids); i++) {
248-
int index = pcc3_uart_clk_ids[i];
249-
250-
pcc3_uart_clks[i] = &hws[index]->clk;
251-
}
252-
253-
imx_register_uart_clocks(pcc3_uart_clks);
226+
imx_register_uart_clocks(7);
254227
}
255228
CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init);
256229

0 commit comments

Comments
 (0)