Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: fix clk-gpio.c with optional clock= DT property

When the clock DT property is not given, of_clk_get_parent_count()
returns -ENOENT, which then tries to allocate -2 x 4 bytes of memory,
which of course fails, causing the whole driver to fail to create
the clock.

This causes the SolidRun platforms to fail probing the SDHCI1 interface
which is connected to the WiFi.

Fix this by detecting errno codes, skipping the allocation, and fixing
of_clk_gpio_gate_delayed_register_get() to handle a NULL parent_names
array.

Fixes: 80eeb1f0f757 ("clk: add gpio controlled clock multiplexer")
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>

authored by

Russell King and committed by
Michael Turquette
7ed88aa2 49dea76a

+13 -9
+13 -9
drivers/clk/clk-gpio.c
··· 264 264 const char * const *parent_names, u8 num_parents, 265 265 unsigned gpio, bool active_low) 266 266 { 267 - return clk_register_gpio_gate(NULL, name, parent_names[0], 268 - gpio, active_low, 0); 267 + return clk_register_gpio_gate(NULL, name, parent_names ? 268 + parent_names[0] : NULL, gpio, active_low, 0); 269 269 } 270 270 271 271 static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name, ··· 295 295 if (!data) 296 296 return; 297 297 298 - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); 299 - if (!parent_names) { 300 - kfree(data); 301 - return; 302 - } 298 + if (num_parents) { 299 + parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); 300 + if (!parent_names) { 301 + kfree(data); 302 + return; 303 + } 303 304 304 - for (i = 0; i < num_parents; i++) 305 - parent_names[i] = of_clk_get_parent_name(node, i); 305 + for (i = 0; i < num_parents; i++) 306 + parent_names[i] = of_clk_get_parent_name(node, i); 307 + } else { 308 + parent_names = NULL; 309 + } 306 310 307 311 data->num_parents = num_parents; 308 312 data->parent_names = parent_names;