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

ARM: integrator: switch to fetch clocks from device tree

This atomic commit changes the Integrator clock implementation
and the machines to register clocks from the device tree and
use these instead of the previous hard-coded clocks.

In the clock implementation all hard-coded clocks and the
special initialization function call goes away, and is
replaced by two compatible strings for the two clocks
available on the core module.

Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+80 -60
+34
Documentation/devicetree/bindings/clock/arm-integrator.txt
··· 1 + Clock bindings for ARM Integrator Core Module clocks 2 + 3 + Auxilary Oscillator Clock 4 + 5 + This is a configurable clock fed from a 24 MHz chrystal, 6 + used for generating e.g. video clocks. It is located on the 7 + core module and there is only one of these. 8 + 9 + This clock node *must* be a subnode of the core module, since 10 + it obtains the base address for it's address range from its 11 + parent node. 12 + 13 + 14 + Required properties: 15 + - compatible: must be "arm,integrator-cm-auxosc" 16 + - #clock-cells: must be <0> 17 + 18 + Optional properties: 19 + - clocks: parent clock(s) 20 + 21 + Example: 22 + 23 + core-module@10000000 { 24 + xtal24mhz: xtal24mhz@24M { 25 + #clock-cells = <0>; 26 + compatible = "fixed-clock"; 27 + clock-frequency = <24000000>; 28 + }; 29 + auxosc: cm_aux_osc@25M { 30 + #clock-cells = <0>; 31 + compatible = "arm,integrator-cm-auxosc"; 32 + clocks = <&xtal24mhz>; 33 + }; 34 + };
+14 -5
arch/arm/mach-integrator/integrator_ap.c
··· 42 42 #include <linux/sys_soc.h> 43 43 #include <linux/termios.h> 44 44 #include <linux/sched_clock.h> 45 + #include <linux/clk-provider.h> 45 46 46 47 #include <mach/hardware.h> 47 48 #include <mach/platform.h> ··· 403 402 struct clk *clk; 404 403 unsigned long rate; 405 404 406 - clk = clk_get_sys("ap_timer", NULL); 407 - BUG_ON(IS_ERR(clk)); 408 - clk_prepare_enable(clk); 409 - rate = clk_get_rate(clk); 405 + of_clk_init(NULL); 410 406 411 407 err = of_property_read_string(of_aliases, 412 408 "arm,timer-primary", &path); ··· 413 415 base = of_iomap(node, 0); 414 416 if (WARN_ON(!base)) 415 417 return; 418 + 419 + clk = of_clk_get(node, 0); 420 + BUG_ON(IS_ERR(clk)); 421 + clk_prepare_enable(clk); 422 + rate = clk_get_rate(clk); 423 + 416 424 writel(0, base + TIMER_CTRL); 417 425 integrator_clocksource_init(rate, base); 418 426 ··· 431 427 if (WARN_ON(!base)) 432 428 return; 433 429 irq = irq_of_parse_and_map(node, 0); 430 + 431 + clk = of_clk_get(node, 0); 432 + BUG_ON(IS_ERR(clk)); 433 + clk_prepare_enable(clk); 434 + rate = clk_get_rate(clk); 435 + 434 436 writel(0, base + TIMER_CTRL); 435 437 integrator_clockevent_init(rate, base, irq); 436 438 } ··· 450 440 { 451 441 cm_init(); 452 442 of_irq_init(fpga_irq_of_match); 453 - integrator_clk_init(false); 454 443 } 455 444 456 445 /* For the Device Tree, add in the UART callbacks as AUXDATA */
-6
arch/arm/mach-integrator/integrator_cp.c
··· 23 23 #include <linux/irqchip/versatile-fpga.h> 24 24 #include <linux/gfp.h> 25 25 #include <linux/mtd/physmap.h> 26 - #include <linux/platform_data/clk-integrator.h> 27 26 #include <linux/of_irq.h> 28 27 #include <linux/of_address.h> 29 28 #include <linux/of_platform.h> ··· 32 33 #include <mach/platform.h> 33 34 #include <asm/setup.h> 34 35 #include <asm/mach-types.h> 35 - #include <asm/hardware/arm_timer.h> 36 - #include <asm/hardware/icst.h> 37 36 38 37 #include <mach/lm.h> 39 38 ··· 39 42 #include <asm/mach/irq.h> 40 43 #include <asm/mach/map.h> 41 44 #include <asm/mach/time.h> 42 - 43 - #include <asm/hardware/timer-sp.h> 44 45 45 46 #include <plat/clcd.h> 46 47 #include <plat/sched_clock.h> ··· 245 250 { 246 251 cm_init(); 247 252 of_irq_init(fpga_irq_of_match); 248 - integrator_clk_init(true); 249 253 } 250 254 251 255 /*
+32 -48
drivers/clk/versatile/clk-integrator.c
··· 10 10 #include <linux/clk.h> 11 11 #include <linux/clkdev.h> 12 12 #include <linux/err.h> 13 - #include <linux/platform_data/clk-integrator.h> 14 - 15 - #include <mach/hardware.h> 16 - #include <mach/platform.h> 13 + #include <linux/of.h> 14 + #include <linux/of_address.h> 17 15 18 16 #include "clk-icst.h" 19 17 20 - /* 21 - * Implementation of the ARM Integrator/AP and Integrator/CP clock tree. 22 - * Inspired by portions of: 23 - * plat-versatile/clock.c and plat-versatile/include/plat/clock.h 24 - */ 18 + #define INTEGRATOR_HDR_LOCK_OFFSET 0x14 25 19 26 - static const struct icst_params cp_auxvco_params = { 20 + /* Base offset for the core module */ 21 + static void __iomem *cm_base; 22 + 23 + static const struct icst_params cp_auxosc_params = { 27 24 .ref = 24000000, 28 25 .vco_max = ICST525_VCO_MAX_5V, 29 26 .vco_min = ICST525_VCO_MIN, ··· 32 35 .idx2s = icst525_idx2s, 33 36 }; 34 37 35 - static const struct clk_icst_desc __initdata cp_icst_desc = { 36 - .params = &cp_auxvco_params, 38 + static const struct clk_icst_desc __initdata cm_auxosc_desc = { 39 + .params = &cp_auxosc_params, 37 40 .vco_offset = 0x1c, 38 41 .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, 39 42 }; 40 43 41 - /* 42 - * integrator_clk_init() - set up the integrator clock tree 43 - * @is_cp: pass true if it's the Integrator/CP else AP is assumed 44 - */ 45 - void __init integrator_clk_init(bool is_cp) 44 + static void __init of_integrator_cm_osc_setup(struct device_node *np) 46 45 { 47 - struct clk *clk; 46 + struct clk *clk = ERR_PTR(-EINVAL); 47 + const char *clk_name = np->name; 48 + const struct clk_icst_desc *desc = &cm_auxosc_desc; 48 49 49 - /* APB clock dummy */ 50 - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); 51 - clk_register_clkdev(clk, "apb_pclk", NULL); 50 + if (!cm_base) { 51 + /* Remap the core module base if not done yet */ 52 + struct device_node *parent; 52 53 53 - /* UART reference clock */ 54 - clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, 55 - 14745600); 56 - clk_register_clkdev(clk, NULL, "uart0"); 57 - clk_register_clkdev(clk, NULL, "uart1"); 58 - if (is_cp) 59 - clk_register_clkdev(clk, NULL, "mmci"); 54 + parent = of_get_parent(np); 55 + if (!np) { 56 + pr_err("no parent on core module clock\n"); 57 + return; 58 + } 59 + cm_base = of_iomap(parent, 0); 60 + if (!cm_base) { 61 + pr_err("could not remap core module base\n"); 62 + return; 63 + } 64 + } 60 65 61 - /* 24 MHz clock */ 62 - clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, 63 - 24000000); 64 - clk_register_clkdev(clk, NULL, "kmi0"); 65 - clk_register_clkdev(clk, NULL, "kmi1"); 66 - if (!is_cp) 67 - clk_register_clkdev(clk, NULL, "ap_timer"); 68 - 69 - if (!is_cp) 70 - return; 71 - 72 - /* 1 MHz clock */ 73 - clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, 74 - 1000000); 75 - clk_register_clkdev(clk, NULL, "sp804"); 76 - 77 - /* ICST VCO clock used on the Integrator/CP CLCD */ 78 - clk = icst_clk_register(NULL, &cp_icst_desc, "icst", 79 - __io_address(INTEGRATOR_HDR_BASE)); 80 - clk_register_clkdev(clk, NULL, "clcd"); 66 + clk = icst_clk_register(NULL, desc, clk_name, cm_base); 67 + if (!IS_ERR(clk)) 68 + of_clk_add_provider(np, of_clk_src_simple_get, clk); 81 69 } 70 + CLK_OF_DECLARE(integrator_cm_auxosc_clk, 71 + "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);
-1
include/linux/platform_data/clk-integrator.h
··· 1 - void integrator_clk_init(bool is_cp); 2 1 void integrator_impd1_clk_init(void __iomem *base, unsigned int id); 3 2 void integrator_impd1_clk_exit(unsigned int id);