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

ARM i.MX25: Add devicetree support

This adds a i.MX25 dt machine descriptor and changes the clock
support to optionally initialize from dt.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Shawn Guo <shawn.guo@linaro.org>

+109 -4
+7
arch/arm/mach-imx/Kconfig
··· 272 272 273 273 endchoice 274 274 275 + config MACH_IMX25_DT 276 + bool "Support i.MX25 platforms from device tree" 277 + select SOC_IMX25 278 + help 279 + Include support for Freescale i.MX25 based platforms 280 + using the device tree for discovery 281 + 275 282 comment "MX27 platforms:" 276 283 277 284 config MACH_MX27ADS
+1
arch/arm/mach-imx/Makefile
··· 50 50 obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o 51 51 obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o 52 52 obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o 53 + obj-$(CONFIG_MACH_IMX25_DT) += imx25-dt.o 53 54 54 55 # i.MX27 based machines 55 56 obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
+52 -4
arch/arm/mach-imx/clk-imx25.c
··· 23 23 #include <linux/io.h> 24 24 #include <linux/clkdev.h> 25 25 #include <linux/err.h> 26 + #include <linux/of.h> 27 + #include <linux/of_address.h> 28 + #include <linux/of_irq.h> 26 29 27 30 #include "clk.h" 28 31 #include "common.h" ··· 58 55 59 56 #define ccm(x) (CRM_BASE + (x)) 60 57 58 + static struct clk_onecell_data clk_data; 59 + 61 60 static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", }; 62 61 static const char *per_sel_clks[] = { "ahb", "upll", }; 63 62 ··· 87 82 88 83 static struct clk *clk[clk_max]; 89 84 90 - int __init mx25_clocks_init(void) 85 + static int __init __mx25_clocks_init(unsigned long osc_rate) 91 86 { 92 87 int i; 93 88 94 89 clk[dummy] = imx_clk_fixed("dummy", 0); 95 - clk[osc] = imx_clk_fixed("osc", 24000000); 90 + clk[osc] = imx_clk_fixed("osc", osc_rate); 96 91 clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL)); 97 92 clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL)); 98 93 clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); ··· 224 219 225 220 clk_prepare_enable(clk[emi_ahb]); 226 221 222 + clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); 223 + clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); 224 + 225 + return 0; 226 + } 227 + 228 + int __init mx25_clocks_init(void) 229 + { 230 + __mx25_clocks_init(24000000); 231 + 227 232 /* i.mx25 has the i.mx21 type uart */ 228 233 clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0"); 229 234 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0"); ··· 245 230 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3"); 246 231 clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4"); 247 232 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4"); 248 - clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); 249 - clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); 250 233 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); 251 234 clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0"); 252 235 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); ··· 302 289 clk_register_clkdev(clk[iim_ipg], "iim", NULL); 303 290 304 291 mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1); 292 + 293 + return 0; 294 + } 295 + 296 + int __init mx25_clocks_init_dt(void) 297 + { 298 + struct device_node *np; 299 + void __iomem *base; 300 + int irq; 301 + unsigned long osc_rate = 24000000; 302 + 303 + /* retrieve the freqency of fixed clocks from device tree */ 304 + for_each_compatible_node(np, NULL, "fixed-clock") { 305 + u32 rate; 306 + if (of_property_read_u32(np, "clock-frequency", &rate)) 307 + continue; 308 + 309 + if (of_device_is_compatible(np, "fsl,imx-osc")) 310 + osc_rate = rate; 311 + } 312 + 313 + np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm"); 314 + clk_data.clks = clk; 315 + clk_data.clk_num = ARRAY_SIZE(clk); 316 + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 317 + 318 + __mx25_clocks_init(osc_rate); 319 + 320 + np = of_find_compatible_node(NULL, NULL, "fsl,imx25-gpt"); 321 + base = of_iomap(np, 0); 322 + WARN_ON(!base); 323 + irq = irq_of_parse_and_map(np, 0); 324 + 325 + mxc_timer_init(base, irq); 326 + 305 327 return 0; 306 328 }
+1
arch/arm/mach-imx/common.h
··· 66 66 unsigned long ckih1, unsigned long ckih2); 67 67 extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, 68 68 unsigned long ckih1, unsigned long ckih2); 69 + extern int mx25_clocks_init_dt(void); 69 70 extern int mx27_clocks_init_dt(void); 70 71 extern int mx31_clocks_init_dt(void); 71 72 extern int mx51_clocks_init_dt(void);
+48
arch/arm/mach-imx/imx25-dt.c
··· 1 + /* 2 + * Copyright 2012 Sascha Hauer, Pengutronix 3 + * 4 + * The code contained herein is licensed under the GNU General Public 5 + * License. You may obtain a copy of the GNU General Public License 6 + * Version 2 or later at the following locations: 7 + * 8 + * http://www.opensource.org/licenses/gpl-license.html 9 + * http://www.gnu.org/copyleft/gpl.html 10 + */ 11 + 12 + #include <linux/irq.h> 13 + #include <linux/of_irq.h> 14 + #include <linux/of_platform.h> 15 + #include <asm/mach/arch.h> 16 + #include <asm/mach/time.h> 17 + #include "common.h" 18 + #include "mx25.h" 19 + 20 + static void __init imx25_dt_init(void) 21 + { 22 + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 23 + } 24 + 25 + static void __init imx25_timer_init(void) 26 + { 27 + mx25_clocks_init_dt(); 28 + } 29 + 30 + static struct sys_timer imx25_timer = { 31 + .init = imx25_timer_init, 32 + }; 33 + 34 + static const char * const imx25_dt_board_compat[] __initconst = { 35 + "fsl,imx25", 36 + NULL 37 + }; 38 + 39 + DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") 40 + .map_io = mx25_map_io, 41 + .init_early = imx25_init_early, 42 + .init_irq = mx25_init_irq, 43 + .handle_irq = imx25_handle_irq, 44 + .timer = &imx25_timer, 45 + .init_machine = imx25_dt_init, 46 + .dt_compat = imx25_dt_board_compat, 47 + .restart = mxc_restart, 48 + MACHINE_END