From e3c83c2db458f1e040c5b4bb19773c458e0240a8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 25 Apr 2012 13:05:24 +1000 Subject: ARM: OMAP2+: INTC: fix suspend abort, set IRQCHIP_SKIP_SET_WAKE Without an ->irq_set_wake() method in an irq_chip, calls to enable_irq_wake() will fail. This also causes these interrupts to not be able to abort suspend (via check_wakeup_irqs() in late suspend.) Currently, we don't implement ->irq_set_wake() for INTC interrupts because they default to be wakeup enabled by setting the GRPSEL bits in PM init. Even though there is no ->irq_set_wake(), we want enable_irq_wake() to succeed so these interrupts can abort suspend when necessary. To fix, set IRQCHIP_SKIP_SET_WAKE flag for all the INTC interrupts which avoids trying to check irq_chip->irq_set_wake() and failing when it doesn't exist. Longer term, we need to implement ->irq_set_wake() for the INTC which can manage the appropriate GRPSEL bits. Signed-off-by: NeilBrown [khilman@ti.com: rework changelog] Acked-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/irq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 65f0d2571c9a..b0790a995dc9 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -148,6 +148,7 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) ct->chip.irq_ack = omap_mask_ack_irq; ct->chip.irq_mask = irq_gc_mask_disable_reg; ct->chip.irq_unmask = irq_gc_unmask_enable_reg; + ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE; ct->regs.ack = INTC_CONTROL; ct->regs.enable = INTC_MIR_CLEAR0; -- cgit v1.2.3 From 99b59df04899a048d1a3ed8bc2b1263779816868 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 27 Apr 2012 16:05:51 -0700 Subject: ARM: OMAP3: PM: fix shared PRCM interrupts: leave disabled at boot By default, request_irq() will auto-enable the requested IRQ. For PRCM interrupts, we may want to avoid that until the PM core code is fully ready to handle the interrupts. This is particularily true for IO pad interrupts on OMAP3, which are shared between the hwmod core and the PRM core. In order to avoid PRCM IO-chain interrupts until the PM core is ready to handle them, ready, set the IRQ_NOAUTOEN flag for the PRCM IO-chain interrupt, which means it will remain disabled after request_irq(). Then, explicitly enable the PRCM interrupts after the request_irq() in the PM core (but not in the hwmod core.) Special thanks to Tero Kristo for suggesting to isolate the fix to only the IO-chain interrupt on OMAP3 instead of all PRCM interrupts. Cc: Tero Kristo Acked-by: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 1 + arch/arm/mach-omap2/prm2xxx_3xxx.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 703bd1099259..4f44ee517f78 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -729,6 +729,7 @@ static int __init omap3_pm_init(void) ret = request_irq(omap_prcm_event_to_irq("io"), _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io", omap3_pm_init); + enable_irq(omap_prcm_event_to_irq("io")); if (ret) { pr_err("pm: Failed to request pm_io irq\n"); diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 9ce765407ad5..21cb74003a56 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "common.h" #include @@ -303,8 +304,15 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask) static int __init omap3xxx_prcm_init(void) { - if (cpu_is_omap34xx()) - return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); - return 0; + int ret = 0; + + if (cpu_is_omap34xx()) { + ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + if (!ret) + irq_set_status_flags(omap_prcm_event_to_irq("io"), + IRQ_NOAUTOEN); + } + + return ret; } subsys_initcall(omap3xxx_prcm_init); -- cgit v1.2.3 From 1ce029968718477149e7f1fb245a8e82c690cc4a Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 30 Apr 2012 16:57:09 -0700 Subject: arm: omap3: am35x: Don't mark missing features as present The Chip Identification register on the am35x family of SoCs has bits 12, 7:5, and 3:2 marked as reserved and are read as zeroes. Unfortunately, on other omap SoCs, a 0 bit means a feature is "Full Use" so the OMAP3_CHECK_FEATURE() macro called by omap3_check_features() will incorrectly interpret those zeroes to mean that a feature is present even though it isn't. To fix that, the feature bits that are incorrectly set (namely, OMAP3_HAS_IVA and OMAP3_HAS_ISP) need to be cleared after all of the calls to OMAP3_CHECK_FEATURE() in omap3_check_features() are made. Signed-off-by: Mark A. Greer [khilman@ti.com: use soc_is_am35xx() instead of cpu_is_am35xx()] Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/id.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index f611e3097157..38ae74f8e77a 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -246,6 +246,17 @@ void __init omap3xxx_check_features(void) omap_features |= OMAP3_HAS_SDRC; + /* + * am35x fixups: + * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as + * reserved and therefore return 0 when read. Unfortunately, + * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to + * mean that a feature is present even though it isn't so clear + * the incorrectly set feature bits. + */ + if (soc_is_am35xx()) + omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP); + /* * TODO: Get additional info (where applicable) * e.g. Size of L2 cache. -- cgit v1.2.3 From c040be003f16a1bdd7997cc4ab7fc5fd43acb03b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 May 2012 12:01:40 +0200 Subject: ARM i.MX5: fix gpt peripheral clock path - The gpt peripheral clk parent is per_root, not ipg - The register for selectin per_lp_apm and per_root is MXC_CCM_CBCMR, not MXC_CCM_CBCDR Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx51-imx53.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index b8a382defb23..1e7828d6be95 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -94,12 +94,12 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, main_bus_sel, ARRAY_SIZE(main_bus_sel)); - clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCDR, 1, 1, + clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); - clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCDR, 1, 0, + clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, per_root_sel, ARRAY_SIZE(per_root_sel)); clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); @@ -162,7 +162,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12); clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16); - clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", MXC_CCM_CCGR2, 18); + clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per_root", MXC_CCM_CCGR2, 18); clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); -- cgit v1.2.3 From 1f152b48eaaf4918047e84777b01a6d687f066e9 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Tue, 15 May 2012 15:34:40 +0800 Subject: ARM: i.MX: change timer clock from ipg to perclk Contrary to the ipg clock the perclk rate is not changed or gated in low power mode, so we choose perclk for gpt. With the port to the common clock framework as a side effect the timer used the rate returned from the peripheral clock but the hardware was still programmed to use the ipg clock, so this patch only changes the hardware to really use the clock it already assumed. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 99f958ca6cb8..d865f7960baf 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -58,6 +58,7 @@ /* MX31, MX35, MX25, MX5 */ #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ #define V2_TCTL_CLK_IPG (1 << 6) +#define V2_TCTL_CLK_PER (2 << 6) #define V2_TCTL_FRR (1 << 9) #define V2_IR 0x0c #define V2_TSTAT 0x08 @@ -309,7 +310,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ if (timer_is_v2()) - tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; + tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; else tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; -- cgit v1.2.3 From 2cfb45188a997ba4c3348e98a999b36663a4646f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 May 2012 12:29:53 +0200 Subject: ARM i.MX: remove now unnecessary argument from mxc_timer_init As the timer code now does a clk_get to get its clock we don't need the struct clk argument anymore. This also changes the alternative EPIT timer to do a clk_get. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx1.c | 3 +-- arch/arm/mach-imx/clk-imx21.c | 4 ++-- arch/arm/mach-imx/clk-imx25.c | 2 +- arch/arm/mach-imx/clk-imx27.c | 3 +-- arch/arm/mach-imx/clk-imx31.c | 3 +-- arch/arm/mach-imx/clk-imx35.c | 6 ++---- arch/arm/mach-imx/clk-imx51-imx53.c | 6 ++---- arch/arm/mach-imx/clk-imx6q.c | 2 +- arch/arm/plat-mxc/epit.c | 11 ++++++++++- arch/arm/plat-mxc/include/mach/common.h | 4 ++-- arch/arm/plat-mxc/time.c | 21 ++++++++++----------- 11 files changed, 33 insertions(+), 32 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index 0f0beb580b73..516ddee1948e 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -108,8 +108,7 @@ int __init mx1_clocks_init(unsigned long fref) clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0"); clk_register_clkdev(clk[clko], "clko", NULL); - mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), - MX1_TIM1_INT); + mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); return 0; } diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index 4e4f384ee8dd..ea13e61bd5f3 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -180,7 +180,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL); clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL); - mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), - MX21_INT_GPT1); + mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); + return 0; } diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index d9833bb5fd61..fdd8cc87c9fe 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -243,6 +243,6 @@ int __init mx25_clocks_init(void) clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma"); clk_register_clkdev(clk[iim_ipg], "iim", NULL); - mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); + mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); return 0; } diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 50a7ebd8d1b2..295cbd7c08dc 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -263,8 +263,7 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0"); clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1"); - mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), - MX27_INT_GPT1); + mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); clk_prepare_enable(clk[emi_ahb_gate]); diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index a854b9cae5ea..c9a06d800f8e 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -175,8 +175,7 @@ int __init mx31_clocks_init(unsigned long fref) mx31_revision(); clk_disable_unprepare(clk[iim_gate]); - mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), - MX31_INT_GPT); + mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); return 0; } diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index a9e60bf7dd75..920a8cc42726 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -267,11 +267,9 @@ int __init mx35_clocks_init() imx_print_silicon_rev("i.MX35", mx35_revision()); #ifdef CONFIG_MXC_USE_EPIT - epit_timer_init(&epit1_clk, - MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); + epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); #else - mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), - MX35_INT_GPT); + mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); #endif return 0; diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 1e7828d6be95..c1739f6078d5 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -329,8 +329,7 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_b_podf], 166250000); /* System timer */ - mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), - MX51_INT_GPT); + mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT); clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX51", mx51_revision()); @@ -412,8 +411,7 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_b_podf], 200000000); /* System timer */ - mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), - MX53_INT_GPT); + mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT); clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX53", mx53_revision()); diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index f40a35da2e5c..24324f2dac95 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -433,7 +433,7 @@ int __init mx6q_clocks_init(void) base = of_iomap(np, 0); WARN_ON(!base); irq = irq_of_parse_and_map(np, 0); - mxc_timer_init(NULL, base, irq); + mxc_timer_init(base, irq); return 0; } diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c index 9129c9e7d532..88726f4dbbfa 100644 --- a/arch/arm/plat-mxc/epit.c +++ b/arch/arm/plat-mxc/epit.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -201,8 +202,16 @@ static int __init epit_clockevent_init(struct clk *timer_clk) return 0; } -void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +void __init epit_timer_init(void __iomem *base, int irq) { + struct clk *timer_clk; + + timer_clk = clk_get_sys("imx-epit.0", NULL); + if (IS_ERR(timer_clk)) { + pr_err("i.MX epit: unable to get clk\n"); + return; + } + clk_prepare_enable(timer_clk); timer_base = base; diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 0319c4a0cafa..da02540f4bd4 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -53,8 +53,8 @@ extern void imx35_soc_init(void); extern void imx50_soc_init(void); extern void imx51_soc_init(void); extern void imx53_soc_init(void); -extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); -extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); +extern void epit_timer_init(void __iomem *base, int irq); +extern void mxc_timer_init(void __iomem *, int); extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx25_clocks_init(void); diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index d865f7960baf..00e8e659e667 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -281,23 +281,22 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) return 0; } -void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +void __init mxc_timer_init(void __iomem *base, int irq) { uint32_t tctl_val; + struct clk *timer_clk; struct clk *timer_ipg_clk; - if (!timer_clk) { - timer_clk = clk_get_sys("imx-gpt.0", "per"); - if (IS_ERR(timer_clk)) { - pr_err("i.MX timer: unable to get clk\n"); - return; - } - - timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg"); - if (!IS_ERR(timer_ipg_clk)) - clk_prepare_enable(timer_ipg_clk); + timer_clk = clk_get_sys("imx-gpt.0", "per"); + if (IS_ERR(timer_clk)) { + pr_err("i.MX timer: unable to get clk\n"); + return; } + timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg"); + if (!IS_ERR(timer_ipg_clk)) + clk_prepare_enable(timer_ipg_clk); + clk_prepare_enable(timer_clk); timer_base = base; -- cgit v1.2.3 From b0286f20c36d0c1e7537489daddaf574abf403dd Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Mon, 14 May 2012 13:04:47 +0800 Subject: ARM: imx6q: prepare and enable init on clks directly instead of clk_get first This also removes the usboh3 clk from the initially turned on clocks which leaked in from an internal development tree. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx6q.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 24324f2dac95..7b4751dbe749 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -122,10 +122,6 @@ static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; -static const char * const clks_init_on[] __initconst = { - "mmdc_ch0_axi", "mmdc_ch1_axi", "usboh3", -}; - enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, pll3_pfd0_720m, pll3_pfd1_540m, pll3_pfd2_508m, pll3_pfd3_454m, @@ -160,11 +156,14 @@ enum mx6q_clks { static struct clk *clk[clk_max]; +static enum mx6q_clks const clks_init_on[] __initconst = { + mmdc_ch0_axi, mmdc_ch1_axi, +}; + int __init mx6q_clocks_init(void) { struct device_node *np; void __iomem *base; - struct clk *c; int i, irq; clk[dummy] = imx_clk_fixed("dummy", 0); @@ -419,15 +418,8 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[dummy], NULL, "20bc000.wdog"); clk_register_clkdev(clk[dummy], NULL, "20c0000.wdog"); - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) { - c = clk_get_sys(clks_init_on[i], NULL); - if (IS_ERR(c)) { - pr_err("%s: failed to get clk %s", __func__, - clks_init_on[i]); - return PTR_ERR(c); - } - clk_prepare_enable(c); - } + for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) + clk_prepare_enable(clk[clks_init_on[i]]); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); -- cgit v1.2.3 From 00633d7c7a0243940fc616bee573bcf497db79b9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 4 Jan 2012 15:33:17 -0800 Subject: ARM: OMAP3: clock data: cleanup AM3[35]x SoC detection Use the more generic SoC family soc_is_am35xx() instead of the specific cpu_is_omap3517() (which is being removed.) Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Tested-by: Mark A. Greer Cc: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 4e1a3b0e8cc8..1efdec236ae8 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3514,7 +3514,7 @@ int __init omap3xxx_clk_init(void) struct omap_clk *c; u32 cpu_clkflg = 0; - if (cpu_is_omap3517()) { + if (soc_is_am35xx()) { cpu_mask = RATE_IN_34XX; cpu_clkflg = CK_AM35XX; } else if (cpu_is_omap3630()) { -- cgit v1.2.3 From 96f3994929c05a21d757a83613d2710b780ea2b4 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 11 May 2012 16:38:11 -0700 Subject: ARM: OMAP: SoC detection: remove unused cpu_is macros Remove multiple unused cpu_is_omap35xx macros. In particular, the cpu_is_omap35* macros for 3503, 3515, 3525 are removed because they are using omap_has_* feature checks and we want to remove specific feature detection from SoC family detection. There are no longer any cpu_is_* checks that depend on specific IP detection. Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Tested-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/include/plat/cpu.h | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 4bdf14ec6747..0f8a201cee68 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -250,8 +250,6 @@ IS_AM_SUBCLASS(335x, 0x335) * cpu_is_omap2423(): True for OMAP2423 * cpu_is_omap2430(): True for OMAP2430 * cpu_is_omap3430(): True for OMAP3430 - * cpu_is_omap3505(): True for OMAP3505 - * cpu_is_omap3517(): True for OMAP3517 */ #define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff) @@ -275,8 +273,6 @@ IS_OMAP_TYPE(2422, 0x2422) IS_OMAP_TYPE(2423, 0x2423) IS_OMAP_TYPE(2430, 0x2430) IS_OMAP_TYPE(3430, 0x3430) -IS_OMAP_TYPE(3505, 0x3517) -IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap310() 0 #define cpu_is_omap730() 0 @@ -291,12 +287,6 @@ IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap2422() 0 #define cpu_is_omap2423() 0 #define cpu_is_omap2430() 0 -#define cpu_is_omap3503() 0 -#define cpu_is_omap3515() 0 -#define cpu_is_omap3525() 0 -#define cpu_is_omap3530() 0 -#define cpu_is_omap3505() 0 -#define cpu_is_omap3517() 0 #define cpu_is_omap3430() 0 #define cpu_is_omap3630() 0 @@ -348,31 +338,12 @@ IS_OMAP_TYPE(3517, 0x3517) #if defined(CONFIG_ARCH_OMAP3) # undef cpu_is_omap3430 -# undef cpu_is_omap3503 -# undef cpu_is_omap3515 -# undef cpu_is_omap3525 -# undef cpu_is_omap3530 -# undef cpu_is_omap3505 -# undef cpu_is_omap3517 # undef cpu_is_ti81xx # undef cpu_is_ti816x # undef cpu_is_ti814x # undef cpu_is_am33xx # undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() -# define cpu_is_omap3503() (cpu_is_omap3430() && \ - (!omap3_has_iva()) && \ - (!omap3_has_sgx())) -# define cpu_is_omap3515() (cpu_is_omap3430() && \ - (!omap3_has_iva()) && \ - (omap3_has_sgx())) -# define cpu_is_omap3525() (cpu_is_omap3430() && \ - (!omap3_has_sgx()) && \ - (omap3_has_iva())) -# define cpu_is_omap3530() (cpu_is_omap3430()) -# define cpu_is_omap3517() is_omap3517() -# define cpu_is_omap3505() (cpu_is_omap3517() && \ - !omap3_has_sgx()) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti81xx() is_ti81xx() @@ -420,10 +391,6 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8)) #define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8)) -#define OMAP3517_CLASS 0x35170034 -#define OMAP3517_REV_ES1_0 OMAP3517_CLASS -#define OMAP3517_REV_ES1_1 (OMAP3517_CLASS | (0x1 << 8)) - #define TI816X_CLASS 0x81600034 #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) -- cgit v1.2.3 From 3ef7cf1839061b275ee1fc59c042194dc452b7e2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 May 2012 16:09:06 -0300 Subject: ARM: mx31_3ds: Fix build due to missing IMX_HAVE_PLATFORM_IMX_SSI commit 5fb86e5 (ARM: mx31_3ds: Add sound support) missed to select IMX_HAVE_PLATFORM_IMX_SSI, which causes the following build error when only mx31_3ds is selected: arch/arm/mach-imx/built-in.o: In function `mx31_3ds_init': mach-mx31_3ds.c:(.init.text+0x15dc): undefined reference to `imx_add_imx_ssi' mach-mx31_3ds.c:(.init.text+0x16b8): undefined reference to `imx31_imx_ssi_data' Select IMX_HAVE_PLATFORM_IMX_SSI to fix it. Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 7561eca131b0..8abcee3c34d0 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -467,6 +467,7 @@ config MACH_MX31_3DS select IMX_HAVE_PLATFORM_IMX2_WDT select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_KEYPAD + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_IPU_CORE select IMX_HAVE_PLATFORM_MXC_EHCI -- cgit v1.2.3 From 1064f8893ee1d16178d983928912057352362dc2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 2 May 2012 22:08:07 +0200 Subject: ARM: imx: only specify i2c device type once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first argument of I2C_BOARD_INFO is used to assign .type, so drop second assignment. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mach-cpuimx35.c | 1 - arch/arm/mach-imx/mach-cpuimx51sd.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 8ecc872b2547..b1a4796548b5 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -70,7 +70,6 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x48), - .type = "tsc2007", .platform_data = &tsc2007_info, .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), }, diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index 9fbe923c8b08..89eb93cec601 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -124,7 +124,6 @@ static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x49), - .type = "tsc2007", .platform_data = &tsc2007_info, .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), }, -- cgit v1.2.3 From f90da3c7a52ac0c8f07f4d6cd0a7f7677e831916 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 May 2012 16:58:03 +0200 Subject: ARM: imx: only call l2x0_init if it's available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a build failure with CONFIG_CACHE_L2X0=n: arch/arm/mach-imx/built-in.o: In function `imx3_init_l2x0': imx53-dt.c:(.init.text+0x190): undefined reference to `l2x0_init' make[2]: *** [.tmp_vmlinux1] Error 1 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 When the l2 cache isn't enabled the quirk introduced in 9524705 (MX35: Fix bogus L2 cache settings) doesn't need to be done either. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mm-imx3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 74127389e7ab..6a80496d72dc 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -81,6 +81,7 @@ static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size, void __init imx3_init_l2x0(void) { +#ifdef CONFIG_CACHE_L2X0 void __iomem *l2x0_base; void __iomem *clkctl_base; @@ -110,6 +111,7 @@ void __init imx3_init_l2x0(void) } l2x0_init(l2x0_base, 0x00030024, 0x00000000); +#endif } #ifdef CONFIG_SOC_IMX31 -- cgit v1.2.3 From 4d04317f6efab7359ae56e50cc9c60e9804b5015 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 4 Jun 2012 00:13:25 -0700 Subject: ARM: OMAP: Fix lis3lv02d accelerometer to use gpio_to_irq Commit 3b511201 (ARM: OMAP: rx51: Platform support for lis3lv02d accelerometer) added support for lis3lv02d accelerometer. The patch was still using OMAP_GPIO_IRQ which no longer exists. Fix it by using gpio_to_irq(). Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-peripherals.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index ff53deccecab..df2534de3361 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -144,7 +144,6 @@ static struct lis3lv02d_platform_data rx51_lis3lv02d_data = { .release_resources = lis302_release, .st_min_limits = {-32, 3, 3}, .st_max_limits = {-3, 32, 32}, - .irq2 = OMAP_GPIO_IRQ(LIS302_IRQ2_GPIO), }; #endif @@ -1030,7 +1029,6 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = { { I2C_BOARD_INFO("lis3lv02d", 0x1d), .platform_data = &rx51_lis3lv02d_data, - .irq = OMAP_GPIO_IRQ(LIS302_IRQ1_GPIO), }, #endif }; @@ -1056,6 +1054,10 @@ static int __init rx51_i2c_init(void) omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata); omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); +#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) + rx51_lis3lv02d_data.irq2 = gpio_to_irq(LIS302_IRQ2_GPIO); + rx51_peripherals_i2c_board_info_3[0].irq = gpio_to_irq(LIS302_IRQ1_GPIO); +#endif omap_register_i2c_bus(3, 400, rx51_peripherals_i2c_board_info_3, ARRAY_SIZE(rx51_peripherals_i2c_board_info_3)); return 0; -- cgit v1.2.3 From 6cc90d6de16532fe68b54ee6967894f7ca83affa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Jun 2012 12:21:21 +0200 Subject: ARM i.MX pllv2: use standard register set unconditionally The i.MX5 PLL has two different register sets for setting the rate. One is used for the standard case and and is used for DVFS. Which one of them is used depends on a hardware input of the PLL. Current implementation reads back from the hardware which setting is used. This is bogus: If we ever want to implement DVFS we have to program both register sets and not only the one which happens to be used at the moment. For now, just use the standard register set uncondionally. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-pllv2.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index 4685919deb63..1b0307195a6e 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c @@ -78,7 +78,7 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; + unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, dbl; void __iomem *pllbase; s64 temp; struct clk_pllv2 *pll = to_clk_pllv2(hw); @@ -86,18 +86,12 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, pllbase = pll->base; dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; - if (pll_hfsm == 0) { - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - } else { - dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); - } + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; mfi = (mfi <= 5) ? 5 : mfi; @@ -132,7 +126,7 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, long mfi, pdf, mfn, mfd = 999999; s64 temp64; unsigned long quad_parent_rate; - unsigned long pll_hfsm, dp_ctl; + unsigned long dp_ctl; pllbase = pll->base; @@ -151,18 +145,11 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); /* use dpdck0_2 */ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; - if (pll_hfsm == 0) { - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); - } else { - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); - } + + reg = mfi << 4 | pdf; + __raw_writel(reg, pllbase + MXC_PLL_DP_OP); + __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); return 0; } -- cgit v1.2.3 From 9ca41bccc39f5ebbbb515dfadb2e0f912168c8bd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Jun 2012 14:51:32 +0200 Subject: ARM i.MX pllv2: make round_rate accurate in round_rate we made the assumption that we can set arbitrary frequencies and thus returned the input rate. This is not correct, for certain frequencies after setting a frequency with set_rate, recalc_rate will return different values. To fix this, introduce set_rate/recalc_rate functions which work on variables instead of registers directly. This way we can call these in round_rate to get the exact rate which we would get if we call set_rate with this value. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-pllv2.c | 78 ++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index 1b0307195a6e..0440379e3628 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c @@ -74,24 +74,15 @@ struct clk_pllv2 { void __iomem *base; }; -static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) +static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, + u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) { long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, dbl; - void __iomem *pllbase; + unsigned long dbl; s64 temp; - struct clk_pllv2 *pll = to_clk_pllv2(hw); - - pllbase = pll->base; - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; mfi = (mfi <= 5) ? 5 : mfi; @@ -117,18 +108,30 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, return temp; } -static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, +static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { + u32 dp_op, dp_mfd, dp_mfn, dp_ctl; + void __iomem *pllbase; struct clk_pllv2 *pll = to_clk_pllv2(hw); + + pllbase = pll->base; + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + + return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn); +} + +static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, + u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn) +{ u32 reg; - void __iomem *pllbase; long mfi, pdf, mfn, mfd = 999999; s64 temp64; unsigned long quad_parent_rate; - unsigned long dp_ctl; - - pllbase = pll->base; quad_parent_rate = 4 * parent_rate; pdf = mfi = -1; @@ -138,18 +141,41 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; pdf--; - temp64 = rate * (pdf+1) - quad_parent_rate * mfi; - do_div(temp64, quad_parent_rate/1000000); + temp64 = rate * (pdf + 1) - quad_parent_rate * mfi; + do_div(temp64, quad_parent_rate / 1000000); mfn = (long)temp64; + reg = mfi << 4 | pdf; + + *dp_op = reg; + *dp_mfd = mfd; + *dp_mfn = mfn; + + return 0; +} + +static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv2 *pll = to_clk_pllv2(hw); + void __iomem *pllbase; + u32 dp_ctl, dp_op, dp_mfd, dp_mfn; + int ret; + + pllbase = pll->base; + + + ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn); + if (ret) + return ret; + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); /* use dpdck0_2 */ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); + __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP); + __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN); return 0; } @@ -157,7 +183,11 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { - return rate; + u32 dp_op, dp_mfd, dp_mfn; + + __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); + return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, + dp_op, dp_mfd, dp_mfn); } static int clk_pllv2_prepare(struct clk_hw *hw) -- cgit v1.2.3 From cdd781ab1906d039c2a93078385645d2d5af8491 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Jun 2012 14:58:07 +0200 Subject: ARM i.MX53: Fix PLL4 base address MX53_DPLL4_BASE accidently returned the base address of PLL3. Fix this. Signed-off-by: Sascha Hauer Cc: stable@vger.kernel.org --- arch/arm/mach-imx/crm-regs-imx5.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/crm-regs-imx5.h b/arch/arm/mach-imx/crm-regs-imx5.h index 5e11ba7daee2..5e3f1f0f4cab 100644 --- a/arch/arm/mach-imx/crm-regs-imx5.h +++ b/arch/arm/mach-imx/crm-regs-imx5.h @@ -23,7 +23,7 @@ #define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) #define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) #define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) -#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) +#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR) /* PLL Register Offsets */ #define MXC_PLL_DP_CTL 0x00 -- cgit v1.2.3 From 18847b42f8d157201550015296a222a9009a04da Mon Sep 17 00:00:00 2001 From: Javier Martin Date: Fri, 1 Jun 2012 09:45:33 +0200 Subject: ARM i.MX27 Visstrim M10: fix gpio handling. Some GPIOs in Visstrim M10 are used without being registered. This leads to USB and video malfunctions. This patch registers those GPIOs to solve the issue. Signed-off-by: Javier Martin Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mach-imx27_visstrim_m10.c | 36 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index f7b074f496f0..2c6a783d4c04 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -107,6 +107,8 @@ static const int visstrim_m10_pins[] __initconst = { PB23_PF_USB_PWR, PB24_PF_USB_OC, /* CSI */ + TVP5150_RSTN | GPIO_GPIO | GPIO_OUT, + TVP5150_PWDN | GPIO_GPIO | GPIO_OUT, PB10_PF_CSI_D0, PB11_PF_CSI_D1, PB12_PF_CSI_D2, @@ -121,6 +123,24 @@ static const int visstrim_m10_pins[] __initconst = { PB21_PF_CSI_HSYNC, }; +static const struct gpio visstrim_m10_gpios[] __initconst = { + { + .gpio = TVP5150_RSTN, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH, + .label = "tvp5150_rstn", + }, + { + .gpio = TVP5150_PWDN, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, + .label = "tvp5150_pwdn", + }, + { + .gpio = OTG_PHY_CS_GPIO, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, + .label = "usbotg_cs", + }, +}; + /* Camera */ static int visstrim_camera_power(struct device *dev, int on) { @@ -164,13 +184,6 @@ static void __init visstrim_camera_init(void) struct platform_device *pdev; int dma; - /* Initialize tvp5150 gpios */ - mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT); - mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT); - gpio_set_value(TVP5150_RSTN, 1); - gpio_set_value(TVP5150_PWDN, 0); - ndelay(1); - gpio_set_value(TVP5150_PWDN, 1); ndelay(1); gpio_set_value(TVP5150_RSTN, 0); @@ -351,10 +364,6 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { /* USB OTG */ static int otg_phy_init(struct platform_device *pdev) { - gpio_set_value(OTG_PHY_CS_GPIO, 0); - - mdelay(10); - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); } @@ -380,6 +389,11 @@ static void __init visstrim_m10_board_init(void) if (ret) pr_err("Failed to setup pins (%d)\n", ret); + ret = gpio_request_array(visstrim_m10_gpios, + ARRAY_SIZE(visstrim_m10_gpios)); + if (ret) + pr_err("Failed to request gpios (%d)\n", ret); + imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata); imx27_add_imx_uart0(&uart_pdata); -- cgit v1.2.3 From 51ce29196dee3084387aa4448d75edc282a91685 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 5 Jun 2012 16:42:38 +0800 Subject: ARM: dts: update memory size on brownstone The memory size on brownstone should be 128MB, not 64MB. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/mmp2-brownstone.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts index 153a4b2d12b5..c9b4f27d191e 100644 --- a/arch/arm/boot/dts/mmp2-brownstone.dts +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -11,7 +11,7 @@ /include/ "mmp2.dtsi" / { - model = "Marvell MMP2 Aspenite Development Board"; + model = "Marvell MMP2 Brownstone Development Board"; compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; chosen { @@ -19,7 +19,7 @@ }; memory { - reg = <0x00000000 0x04000000>; + reg = <0x00000000 0x08000000>; }; soc { -- cgit v1.2.3 From 10bd21c0547ba2834374ccdddbc6a984eeed432c Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 5 Jun 2012 17:42:23 +0800 Subject: ARM: mmp: fix missing cascade_irq in irq handler While supporting board in non-DT mode, icu_data[i]->cascade_irq isn't assigned with correct value. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/irq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c index fcfe0e3bd701..e60c7d98922b 100644 --- a/arch/arm/mach-mmp/irq.c +++ b/arch/arm/mach-mmp/irq.c @@ -241,6 +241,7 @@ void __init mmp2_init_icu(void) icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE; icu_data[1].nr_irqs = 2; + icu_data[1].cascade_irq = 4; icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs, icu_data[1].virq_base, 0, @@ -249,6 +250,7 @@ void __init mmp2_init_icu(void) icu_data[2].reg_status = mmp_icu_base + 0x154; icu_data[2].reg_mask = mmp_icu_base + 0x16c; icu_data[2].nr_irqs = 2; + icu_data[2].cascade_irq = 5; icu_data[2].virq_base = IRQ_MMP2_RTC_BASE; icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs, icu_data[2].virq_base, 0, @@ -257,6 +259,7 @@ void __init mmp2_init_icu(void) icu_data[3].reg_status = mmp_icu_base + 0x180; icu_data[3].reg_mask = mmp_icu_base + 0x17c; icu_data[3].nr_irqs = 3; + icu_data[3].cascade_irq = 9; icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE; icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs, icu_data[3].virq_base, 0, @@ -265,6 +268,7 @@ void __init mmp2_init_icu(void) icu_data[4].reg_status = mmp_icu_base + 0x158; icu_data[4].reg_mask = mmp_icu_base + 0x170; icu_data[4].nr_irqs = 5; + icu_data[4].cascade_irq = 17; icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE; icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs, icu_data[4].virq_base, 0, @@ -273,6 +277,7 @@ void __init mmp2_init_icu(void) icu_data[5].reg_status = mmp_icu_base + 0x15c; icu_data[5].reg_mask = mmp_icu_base + 0x174; icu_data[5].nr_irqs = 15; + icu_data[5].cascade_irq = 35; icu_data[5].virq_base = IRQ_MMP2_MISC_BASE; icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs, icu_data[5].virq_base, 0, @@ -281,6 +286,7 @@ void __init mmp2_init_icu(void) icu_data[6].reg_status = mmp_icu_base + 0x160; icu_data[6].reg_mask = mmp_icu_base + 0x178; icu_data[6].nr_irqs = 2; + icu_data[6].cascade_irq = 51; icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE; icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs, icu_data[6].virq_base, 0, @@ -289,6 +295,7 @@ void __init mmp2_init_icu(void) icu_data[7].reg_status = mmp_icu_base + 0x188; icu_data[7].reg_mask = mmp_icu_base + 0x184; icu_data[7].nr_irqs = 2; + icu_data[7].cascade_irq = 55; icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE; icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs, icu_data[7].virq_base, 0, -- cgit v1.2.3 From 91930652a23de0873a157aa1d9962cb878d64451 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 5 Jun 2012 04:04:11 -0700 Subject: OMAP2+: UART: Add mechanism to probe uart pins and configure rx wakeup The commit (bce492c0 ARM: OMAP2+: UART: Fix incorrect population of default uart pads) removed default uart pads that where getting populated and which was making rx pin wakeup capable. If uart pads were used in different mode by any other module then it would fail since the default pads took over all the uart pins forcefully. With removal of default pads the rx_pad wakeup for console uart while waking up from off mode is broken. Utilise the mux api available to probe the availability of mux pins in uart mode and probe for availability of uart pin in mux mode0 if uart is available as uart pin itself then configure rx pin as wakeup capable. This patch itself doesn't cater to all boards. Boards using uart rx wakeup mechanism should ensure the usage of omap_serial_init_port by configuring required uart ports and pass necessary mux data, till then this probing of uart pins can cater to enabling of rx pad wakeup to most of the boards. This patch can also throw some boot warning from _omap_mux_get_by_name if pin is requested for availability is not present while dynamically probing the uart pins availability such boot warnings can be addressed only when board files are patched with omap_serial_init_port calls passing the right pads needed for a given port. Discussion Threads for reference: http://www.spinics.net/lists/linux-omap/msg69859.html http://www.spinics.net/lists/linux-omap/msg68659.html Cc: Felipe Balbi Cc: Kevin Hilman Cc: Russ Dill Cc: Paul Walmsley Cc: Ameya Palande Signed-off-by: Govindraj.R [tony@atomide.com: updated to fix compile when CONFIG_OMAP_MUX is not set] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/mux.c | 3 +- arch/arm/mach-omap2/mux.h | 11 ++++++++ arch/arm/mach-omap2/serial.c | 67 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 80e55c5c9998..4b46b91cca5c 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -217,8 +217,7 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, return -ENODEV; } -static int __init -omap_mux_get_by_name(const char *muxname, +int __init omap_mux_get_by_name(const char *muxname, struct omap_mux_partition **found_partition, struct omap_mux **found_mux) { diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 69fe060a0b75..471e62a74a16 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -59,6 +59,7 @@ #define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN #define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4) +#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0) /* Flags for omapX_mux_init */ #define OMAP_PACKAGE_MASK 0xffff @@ -225,8 +226,18 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads); */ void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state); +int omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux); #else +static inline int omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux) +{ + return 0; +} + static inline int omap_mux_init_gpio(int gpio, int val) { return 0; diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 292d4aaca068..c1b93c752d70 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -57,6 +57,7 @@ struct omap_uart_state { struct list_head node; struct omap_hwmod *oh; + struct omap_device_pad default_omap_uart_pads[2]; }; static LIST_HEAD(uart_list); @@ -126,11 +127,70 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX -static void omap_serial_fill_default_pads(struct omap_board_data *bdata) + +#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28 +static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN], + tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata; + +static void __init +omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata, + struct omap_uart_state *uart) +{ + uart->default_omap_uart_pads[0].name = rx_pad_name; + uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX | + OMAP_DEVICE_PAD_WAKEUP; + uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT | + OMAP_MUX_MODE0; + uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0; + uart->default_omap_uart_pads[1].name = tx_pad_name; + uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT | + OMAP_MUX_MODE0; + bdata->pads = uart->default_omap_uart_pads; + bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads); +} + +static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, + struct omap_uart_state *uart) { + struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL; + struct omap_mux *rx_mux = NULL, *tx_mux = NULL; + char *rx_fmt, *tx_fmt; + int uart_nr = bdata->id + 1; + + if (bdata->id != 2) { + rx_fmt = "uart%d_rx.uart%d_rx"; + tx_fmt = "uart%d_tx.uart%d_tx"; + } else { + rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx"; + tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx"; + } + + snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt, + uart_nr, uart_nr); + snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt, + uart_nr, uart_nr); + + if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 && + omap_mux_get_by_name + (tx_pad_name, &tx_partition, &tx_mux) >= 0) { + u16 tx_mode, rx_mode; + + tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset); + rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset); + + /* + * Check if uart is used in default tx/rx mode i.e. in mux mode0 + * if yes then configure rx pin for wake up capability + */ + if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode)) + omap_serial_fill_uart_tx_rx_pads(bdata, uart); + } } #else -static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} +static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, + struct omap_uart_state *uart) +{ +} #endif static char *cmdline_find_option(char *str) @@ -287,8 +347,7 @@ void __init omap_serial_board_init(struct omap_uart_port_info *info) bdata.pads = NULL; bdata.pads_cnt = 0; - if (cpu_is_omap44xx() || cpu_is_omap34xx()) - omap_serial_fill_default_pads(&bdata); + omap_serial_check_wakeup(&bdata, uart); if (!info) omap_serial_init_port(&bdata, NULL); -- cgit v1.2.3 From f968cabcb1cd0c253fa25850970e5376f9eef065 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 01:42:20 -0700 Subject: ARM: OMAP: Fix MMC_OMAP build when only MMC_OMAP_HS is selected If CONFIG_MMC_OMAP is not set and CONFIG_MMC_OMAP_HS is set, we can get error: redefinition of `omap242x_init_mmc' error. Fix it by removing MMC_OMAP_HS from MMC_OMAP ifdefs as they do not depend on each other. While at it, also prettify the formatting a bit. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/mmc.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index a7754a886d42..5493bd95da5e 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -172,8 +172,7 @@ struct omap_mmc_platform_data { extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ - defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); @@ -185,7 +184,6 @@ static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) { } - #endif extern int omap_msdi_reset(struct omap_hwmod *oh); -- cgit v1.2.3 From 00d6bfaf20e723e3f4c9aa6bc0fb6636785a0701 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 01:42:20 -0700 Subject: ARM: OMAP3: Fix omap3_l3_block_irq warning when CONFIG_BUG is not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we will get: arch/arm/mach-omap2/omap_l3_smx.c: In function ‘omap3_l3_block_irq’: arch/arm/mach-omap2/omap_l3_smx.c:156: warning: unused variable ‘address’ arch/arm/mach-omap2/omap_l3_smx.c:155: warning: unused variable ‘multi’ arch/arm/mach-omap2/omap_l3_smx.c:154: warning: unused variable ‘initid’ arch/arm/mach-omap2/omap_l3_smx.c:153: warning: unused variable ‘code’ arch/arm/mach-omap2/omap_l3_smx.c: At top level: arch/arm/mach-omap2/omap_l3_smx.c:68: warning: ‘omap3_l3_code_string’ defined but not used arch/arm/mach-omap2/omap_l3_smx.c:90: warning: ‘omap3_l3_initiator_string’ defined but not used Fix it by always showing the L3 error. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_l3_smx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c index a05a62f9ee5b..acc216491b8a 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.c +++ b/arch/arm/mach-omap2/omap_l3_smx.c @@ -155,10 +155,11 @@ static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3, u8 multi = error & L3_ERROR_LOG_MULTI; u32 address = omap3_l3_decode_addr(error_addr); - WARN(true, "%s seen by %s %s at address %x\n", + pr_err("%s seen by %s %s at address %x\n", omap3_l3_code_string(code), omap3_l3_initiator_string(initid), multi ? "Multiple Errors" : "", address); + WARN_ON(1); return IRQ_HANDLED; } -- cgit v1.2.3 From febe9e02d63ed8a42e7e9c75ea16117821f90f07 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 01:42:20 -0700 Subject: ARM: OMAP2+: Fix compile for CONFIG_TIDSPBRIDGE platform init code Commit 7f28427b (ARM: OMAP2+: Move omap_dsp_reserve_sdram_memblock() to mach-omap2) moved DSP platform init code, but failed to include memblock.h causing: arch/arm/mach-omap2/dsp.c: In function 'omap_dsp_reserve_sdram_memblock': arch/arm/mach-omap2/dsp.c:58: error: implicit declaration of function 'arm_memblock_steal' Reported-by: Russell King Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/dsp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c index 845309f146fe..88ffa1e645cd 100644 --- a/arch/arm/mach-omap2/dsp.c +++ b/arch/arm/mach-omap2/dsp.c @@ -20,6 +20,9 @@ #include #include + +#include + #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #ifdef CONFIG_BRIDGE_DVFS -- cgit v1.2.3 From aa29cab3f12b14020011bcad28cc11f50725d68f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 20 May 2012 14:11:24 -0300 Subject: ARM: mx31: Add pinctrl_provide_dummies() commit a2aa65a (ARM: imx: enable pinctrl dummy states) missed to add pinctrl_provide_dummies() for mx31. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mm-imx3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 967ed5b35a45..0b211f63981f 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -179,6 +179,8 @@ void __init imx31_soc_init(void) mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); + pinctrl_provide_dummies(); + if (to_version == 1) { strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin", strlen(imx31_sdma_pdata.fw_name)); -- cgit v1.2.3 From eb5558dd46dab1e3023f052f99979b0e2bfd1b19 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 20 May 2012 14:21:09 -0300 Subject: ARM: mx51: Add pinctrl_provide_dummies() commit a2aa65a (ARM: imx: enable pinctrl dummy states) missed to add pinctrl_provide_dummies() for mx51. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mm-imx5.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index feeee17da96b..1d003053d562 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -202,6 +202,8 @@ void __init imx51_soc_init(void) mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); + pinctrl_provide_dummies(); + /* i.mx51 has the i.mx35 type sdma */ imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); -- cgit v1.2.3 From 602bf40971d7f9a1ec0b7ba2b7e6427849828651 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 22 May 2012 22:13:46 +0800 Subject: ARM: imx6: exit coherency when shutting down a cpu There is a system hang issue on imx6q which can easily be seen with running a cpu hotplug stress testing (hotplug secondary cores from user space via sysfs interface for thousands iterations). It turns out that the issue is caused by coherency of the cpu that is being shut down. When shutting down a cpu, we need to have the cpu exit coherency to prevent it from receiving cache, TLB, or BTB maintenance operations broadcast by other CPUs in the cluster. Copy cpu_enter_lowpower() and cpu_leave_lowpower() from mach-vexpress to have coherency properly handled in platform_cpu_die(), thus fix the issue. Signed-off-by: Shawn Guo Cc: stable@kernel.org --- arch/arm/mach-imx/hotplug.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 89493abd497c..20ed2d56c1af 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -12,6 +12,7 @@ #include #include +#include #include int platform_cpu_kill(unsigned int cpu) @@ -19,6 +20,44 @@ int platform_cpu_kill(unsigned int cpu) return 1; } +static inline void cpu_enter_lowpower(void) +{ + unsigned int v; + + flush_cache_all(); + asm volatile( + "mcr p15, 0, %1, c7, c5, 0\n" + " mcr p15, 0, %1, c7, c10, 4\n" + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %3\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0), "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} + +static inline void cpu_leave_lowpower(void) +{ + unsigned int v; + + asm volatile( + "mrc p15, 0, %0, c1, c0, 0\n" + " orr %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + " mrc p15, 0, %0, c1, c0, 1\n" + " orr %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} + /* * platform-specific code to shutdown a CPU * @@ -26,9 +65,10 @@ int platform_cpu_kill(unsigned int cpu) */ void platform_cpu_die(unsigned int cpu) { - flush_cache_all(); + cpu_enter_lowpower(); imx_enable_cpu(cpu, false); cpu_do_idle(); + cpu_leave_lowpower(); /* We should never return from idle */ panic("cpu %d unexpectedly exit from shutdown\n", cpu); -- cgit v1.2.3 From 350ab15bb2ffe7103bc6bf6c634f3c5b286eaf2a Mon Sep 17 00:00:00 2001 From: Jaccon Bastiaansen Date: Mon, 30 Apr 2012 11:53:43 +0200 Subject: ARM i.MX imx21ads: Fix overlapping static i/o mappings The statically defined I/O memory regions for the i.MX21 on chip peripherals and the on board I/O peripherals of the i.MX21ADS board overlap. This results in a kernel crash during startup. This is fixed by reducing the memory range for the on board I/O peripherals to the actually required range. Signed-off-by: Jaccon Bastiaansen Signed-off-by: Sascha Hauer Cc: stable --- arch/arm/mach-imx/mach-mx21ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index e432d4acee1f..4460d25faae1 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -32,7 +32,7 @@ * Memory-mapped I/O on MX21ADS base board */ #define MX21ADS_MMIO_BASE_ADDR 0xf5000000 -#define MX21ADS_MMIO_SIZE SZ_16M +#define MX21ADS_MMIO_SIZE 0xc00000 #define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \ (MX21ADS_MMIO_BASE_ADDR + (offset)) -- cgit v1.2.3 From 8e56130dcbcc0608c2531c61f93175e36a300e58 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 6 Jun 2012 17:20:10 -0500 Subject: ARM: highbank: Add smc calls to enable/disable the L2 Linux runs in non-secure mode on highbank, so we need secure monitor calls to enable and disable the PL310. Rather than invent new smc calls, the same calling convention used by OMAP is used here. Signed-off-by: Rob Herring Signed-off-by: Olof Johansson --- arch/arm/mach-highbank/Makefile | 6 +++++- arch/arm/mach-highbank/core.h | 1 + arch/arm/mach-highbank/highbank.c | 14 ++++++++++++++ arch/arm/mach-highbank/smc.S | 27 +++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-highbank/smc.S diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile index f8437dd238c2..ded4652ada80 100644 --- a/arch/arm/mach-highbank/Makefile +++ b/arch/arm/mach-highbank/Makefile @@ -1,4 +1,8 @@ -obj-y := clock.o highbank.o system.o +obj-y := clock.o highbank.o system.o smc.o + +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) + obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h index d8e2d0be64ac..141ed5171826 100644 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@ -8,3 +8,4 @@ extern void highbank_lluart_map_io(void); static inline void highbank_lluart_map_io(void) {} #endif +extern void highbank_smc1(int fn, int arg); diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 410a112bb52e..8777612b1a42 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -85,10 +85,24 @@ const static struct of_device_id irq_match[] = { {} }; +#ifdef CONFIG_CACHE_L2X0 +static void highbank_l2x0_disable(void) +{ + /* Disable PL310 L2 Cache controller */ + highbank_smc1(0x102, 0x0); +} +#endif + static void __init highbank_init_irq(void) { of_irq_init(irq_match); + +#ifdef CONFIG_CACHE_L2X0 + /* Enable PL310 L2 Cache controller */ + highbank_smc1(0x102, 0x1); l2x0_of_init(0, ~0UL); + outer_cache.disable = highbank_l2x0_disable; +#endif } static void __init highbank_timer_init(void) diff --git a/arch/arm/mach-highbank/smc.S b/arch/arm/mach-highbank/smc.S new file mode 100644 index 000000000000..407d17baaaa9 --- /dev/null +++ b/arch/arm/mach-highbank/smc.S @@ -0,0 +1,27 @@ +/* + * Copied from omap44xx-smc.S Copyright (C) 2010 Texas Instruments, Inc. + * Copyright 2012 Calxeda, Inc. + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. + * Function signature : void highbank_smc1(u32 fn, u32 arg) + */ + +ENTRY(highbank_smc1) + stmfd sp!, {r4-r11, lr} + mov r12, r0 + mov r0, r1 + dsb + smc #0 + ldmfd sp!, {r4-r11, pc} +ENDPROC(highbank_smc1) -- cgit v1.2.3 From 9b0f7e399238c61f28539daeb65d72a8d7f91966 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 11 Jun 2012 09:03:58 -0500 Subject: arm: versatile: fix and enable PCI I/O space With commit 4d5fc58dbe34b (ARM: remove bunch of now unused mach/io.h files), the I/O space setup was completely broken on versatile. This patch fixes that and prepares for further I/O space clean-up. I/O space handling on the versatile platform is currently broken in multiple ways. Most importantly, the ports do not get mapped into the virtual address space at all. Also, there is some amount of confusion between PCI I/O space and other statically mapped MMIO registers in the platform code: * The __io_address() macro that is used to access the platform register maps to the same __io macro that gets used for I/O space. * The IO_SPACE_LIMIT is set to a value that is much larger than the total available space. * The I/O resource of the PCI bus is set to the physical address of the mapping, which is way outside of the actual I/O space limit as well as the address range that gets decoded by traditional PCI cards. * No attempt is made to stay outside of the ISA port range that some device drivers try access. * No resource gets requested as a child of ioport_resource, but an IORESOURCE_IO type mapping gets requested as a child of iomem_resource. This patch attempts to correct all of the above. This makes it possible to use virtio-pci based virtual devices as well as actual PCI cards including those with legacy ISA port ranges like VGA. Some of the issues seem to be duplicated on other platforms. Signed-off-by: Arnd Bergmann [rob: update to 3.5-rc2 and io.h cleanup related changes] Signed-off-by: Rob Herring Tested-by: Robert Schwebel Signed-off-by: Olof Johansson --- arch/arm/Kconfig | 1 + arch/arm/mach-versatile/core.c | 19 +++-------------- arch/arm/mach-versatile/include/mach/hardware.h | 3 ++- arch/arm/mach-versatile/include/mach/io.h | 27 +++++++++++++++++++++++++ arch/arm/mach-versatile/pci.c | 18 +++++++++++++++-- 5 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 arch/arm/mach-versatile/include/mach/io.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b649c5904a4f..567b4323c9e6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -294,6 +294,7 @@ config ARCH_VERSATILE select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select NEED_MACH_IO_H if PCI select PLAT_VERSATILE select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_FPGA_IRQ diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index cf4687ee2a7b..cd8ea3588f93 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -169,26 +169,13 @@ static struct map_desc versatile_io_desc[] __initdata = { .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), .length = VERSATILE_PCI_CFG_BASE_SIZE, .type = MT_DEVICE - }, -#if 0 - { - .virtual = VERSATILE_PCI_VIRT_MEM_BASE0, - .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), - .length = SZ_16M, - .type = MT_DEVICE }, { - .virtual = VERSATILE_PCI_VIRT_MEM_BASE1, - .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), - .length = SZ_16M, - .type = MT_DEVICE - }, { - .virtual = VERSATILE_PCI_VIRT_MEM_BASE2, - .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2), - .length = SZ_16M, + .virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), + .length = IO_SPACE_LIMIT, .type = MT_DEVICE }, #endif -#endif }; void __init versatile_map_io(void) diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h index 4d4973dd8fba..408e58da46c6 100644 --- a/arch/arm/mach-versatile/include/mach/hardware.h +++ b/arch/arm/mach-versatile/include/mach/hardware.h @@ -29,8 +29,9 @@ */ #define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul #define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul +#define VERSATILE_PCI_VIRT_MEM_BASE0 (void __iomem *)PCIO_BASE -/* macro to get at IO space when running virtually */ +/* macro to get at MMIO space when running virtually */ #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) #define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n)) diff --git a/arch/arm/mach-versatile/include/mach/io.h b/arch/arm/mach-versatile/include/mach/io.h new file mode 100644 index 000000000000..0406513be7d8 --- /dev/null +++ b/arch/arm/mach-versatile/include/mach/io.h @@ -0,0 +1,27 @@ +/* + * arch/arm/mach-versatile/include/mach/io.h + * + * Copyright (C) 2003 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define PCIO_BASE 0xeb000000ul + +#define __io(a) ((a) + PCIO_BASE) + +#endif diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 15c6a00000ec..bec933b04ef0 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -169,11 +169,18 @@ static struct pci_ops pci_versatile_ops = { .write = versatile_write_config, }; +static struct resource io_port = { + .name = "PCI", + .start = 0, + .end = IO_SPACE_LIMIT, + .flags = IORESOURCE_IO, +}; + static struct resource io_mem = { .name = "PCI I/O space", .start = VERSATILE_PCI_MEM_BASE0, .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_MEM, }; static struct resource non_mem = { @@ -200,6 +207,12 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) "memory region (%d)\n", ret); goto out; } + ret = request_resource(&ioport_resource, &io_port); + if (ret) { + printk(KERN_ERR "PCI: unable to allocate I/O " + "port region (%d)\n", ret); + goto out; + } ret = request_resource(&iomem_resource, &non_mem); if (ret) { printk(KERN_ERR "PCI: unable to allocate non-prefetchable " @@ -218,7 +231,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); + pci_add_resource_offset(&sys->resources, &io_port, sys->io_offset); pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); @@ -249,6 +262,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) if (nr == 0) { sys->mem_offset = 0; + sys->io_offset = 0; ret = pci_versatile_setup_resources(sys); if (ret < 0) { printk("pci_versatile_setup: resources... oops?\n"); -- cgit v1.2.3 From 128789a8293653a4f889f2b1601eea07c00ff65e Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 13 Jun 2012 14:52:45 +0200 Subject: ARM: Kirkwood: Fix clk problems modular ethernet driver When the ethernet driver was built as a module, it would lock the machine when loaded. At boot the ethernet clks are unused, so get turned off. Later, when the module is loaded, the probe function would access the hardware before the clock was restarted, and the machine would lock. It has also been determined that when the clk is turned off, the interface forgets its MAC address, which for most systems, is set by the boot loader. When the machine setup file creates a platform device for the interface, prepare and enable the clock for the interface. This will ensure it is not turned off. However, if the setup file only instantiates one platform device, the other will have its clk disabled, thus maybe saving a little power. Report-by: Simon Baatz Signed-off-by: Andrew Lunn Tested-by: Simon Baatz Signed-off-by: Olof Johansson --- arch/arm/mach-kirkwood/common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 25fb3fd418ef..e1d2c6def5e6 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -193,9 +193,11 @@ static struct clk __init *kirkwood_register_gate_fn(const char *name, bit_idx, 0, &gating_lock, fn); } +static struct clk *ge0, *ge1; + void __init kirkwood_clk_init(void) { - struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; + struct clk *runit, *sata0, *sata1, *usb0, *sdio; struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, @@ -257,6 +259,9 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) orion_ge00_init(eth_data, GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, IRQ_KIRKWOOD_GE00_ERR); + /* The interface forgets the MAC address assigned by u-boot if + the clock is turned off, so claim the clk now. */ + clk_prepare_enable(ge0); } @@ -268,6 +273,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) orion_ge01_init(eth_data, GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, IRQ_KIRKWOOD_GE01_ERR); + clk_prepare_enable(ge1); } -- cgit v1.2.3