From ad3e6c0b1fad31282a8384903ed811671d840a9c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 19 Jan 2010 16:42:12 +0100 Subject: ARM: 5885/1: arm: Flush TLB entries in setup_mm_for_reboot() We need to do that if we tinker with the MMU entries. This fixes the occasional bug with kexec where the new fails to uncompress with "crc error". Most likely at least kexec on v6 and v7 need this fix. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 1708da82da96..761ffede6a23 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1067,4 +1067,6 @@ void setup_mm_for_reboot(char mode) pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); flush_pmd_entry(pmd); } + + local_flush_tlb_all(); } -- cgit v1.2.3 From 1f667c690be3ab71036c436d8391105eee23f65b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 19 Jan 2010 17:01:33 +0100 Subject: ARM: 5886/1: arm: Fix cpu_proc_fin() for proc-v7.S and make kexec work The comments in arm_machine_restart() suggest that cpu_proc_fin() will clean and disable cache and turn off interrupts. This does not seem to be implemented for proc-v7.S, implement it the same way as for proc-v6.S. This also makes kexec work for v7. Note that a related TLB and branch traget flush patch is also needed to avoid kexec "crc error". Note that there are still some issues that seem to be related to L2 cache being on and causing occasional uncompress "crc error" with kexec. Anyways, this gets kexec mostly working on V7 for now. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mm/proc-v7.S | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 3a285218fd15..d2a80747c6fe 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -45,7 +45,14 @@ ENTRY(cpu_v7_proc_init) ENDPROC(cpu_v7_proc_init) ENTRY(cpu_v7_proc_fin) - mov pc, lr + stmfd sp!, {lr} + cpsid if @ disable interrupts + bl v7_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x0006 @ .............ca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} ENDPROC(cpu_v7_proc_fin) /* -- cgit v1.2.3 From 2045124ffd1a5e46d157349016a2c50f19c8c91d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 19 Jan 2010 23:42:08 +0100 Subject: ARM: 5888/1: arm: Update comments in cacheflush.h and remove unnecessary V6 and V7 comments The comments in cacheflush.h should follow what's in struct cpu_cache_fns. The comments for V6 and V7 are unnecessary. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/include/asm/cacheflush.h | 20 +++++++++++++++++--- arch/arm/mm/proc-v6.S | 2 -- arch/arm/mm/proc-v7.S | 2 -- 3 files changed, 17 insertions(+), 7 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 730aefcfbee3..c77d2fa1f6e5 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -154,16 +154,16 @@ * Please note that the implementation of these, and the required * effects are cache-type (VIVT/VIPT/PIPT) specific. * - * flush_cache_kern_all() + * flush_kern_all() * * Unconditionally clean and invalidate the entire cache. * - * flush_cache_user_mm(mm) + * flush_user_all() * * Clean and invalidate all user space cache entries * before a change of page tables. * - * flush_cache_user_range(start, end, flags) + * flush_user_range(start, end, flags) * * Clean and invalidate a range of cache entries in the * specified address space before a change of page tables. @@ -179,6 +179,20 @@ * - start - virtual start address * - end - virtual end address * + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * - start - virtual start address + * - end - virtual end address + * + * flush_kern_dcache_area(kaddr, size) + * + * Ensure that the data held in page is written back. + * - kaddr - page address + * - size - region size + * * DMA Cache Coherency * =================== * diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 395cc90c6613..7a5337ed7d68 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -59,8 +59,6 @@ ENTRY(cpu_v6_proc_fin) * to what would be the reset vector. * * - loc - location to jump to for soft reset - * - * It is assumed that: */ .align 5 ENTRY(cpu_v6_reset) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index d2a80747c6fe..7aaf88a3b7aa 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -63,8 +63,6 @@ ENDPROC(cpu_v7_proc_fin) * to what would be the reset vector. * * - loc - location to jump to for soft reset - * - * It is assumed that: */ .align 5 ENTRY(cpu_v7_reset) -- cgit v1.2.3 From 0a0300dc8c4b3f3ce5c9ef5a0a4be5442590398f Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 12 Jan 2010 12:28:00 +0000 Subject: ARM: Consolidate clks_register() and similar Most machine classes want some way to register a block of clk_lookup structures, and most do it by implementing a clks_register() type function which walks an array, or by open-coding a loop. Consolidate all this into clkdev_add_table(). Acked-by: H Hartley Sweeten Reviewed-by: Kevin Hilman Acked-by: Eric Miao Signed-off-by: Russell King --- arch/arm/common/clkdev.c | 10 ++++++++++ arch/arm/include/asm/clkdev.h | 3 +++ arch/arm/mach-bcmring/core.c | 3 +-- arch/arm/mach-ep93xx/clock.c | 4 +--- arch/arm/mach-integrator/core.c | 3 +-- arch/arm/mach-integrator/integrator_cp.c | 4 +--- arch/arm/mach-mmp/clock.c | 8 -------- arch/arm/mach-mmp/clock.h | 2 -- arch/arm/mach-mmp/pxa168.c | 2 +- arch/arm/mach-mmp/pxa910.c | 2 +- arch/arm/mach-mx1/clock.c | 4 +--- arch/arm/mach-mx2/clock_imx21.c | 4 +--- arch/arm/mach-mx2/clock_imx27.c | 4 +--- arch/arm/mach-mx25/clock.c | 6 +----- arch/arm/mach-mx3/clock-imx35.c | 4 +--- arch/arm/mach-mx3/clock.c | 4 +--- arch/arm/mach-mxc91231/clock.c | 4 +--- arch/arm/mach-pxa/clock.c | 8 -------- arch/arm/mach-pxa/clock.h | 4 ---- arch/arm/mach-pxa/eseries.c | 2 +- arch/arm/mach-pxa/pxa25x.c | 4 ++-- arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/pxa300.c | 4 ++-- arch/arm/mach-pxa/pxa320.c | 2 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- arch/arm/mach-realview/core.c | 5 +---- arch/arm/mach-u300/clock.c | 5 +---- arch/arm/mach-ux500/clock.c | 5 +---- arch/arm/mach-versatile/core.c | 3 +-- arch/arm/mach-w90x900/clock.c | 9 --------- arch/arm/mach-w90x900/clock.h | 1 - arch/arm/mach-w90x900/cpu.c | 2 +- arch/arm/plat-stmp3xxx/clock.c | 3 +-- 33 files changed, 40 insertions(+), 92 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c index aae5bc01acc8..446b696196e3 100644 --- a/arch/arm/common/clkdev.c +++ b/arch/arm/common/clkdev.c @@ -99,6 +99,16 @@ void clkdev_add(struct clk_lookup *cl) } EXPORT_SYMBOL(clkdev_add); +void __init clkdev_add_table(struct clk_lookup *cl, size_t num) +{ + mutex_lock(&clocks_mutex); + while (num--) { + list_add_tail(&cl->node, &clocks); + cl++; + } + mutex_unlock(&clocks_mutex); +} + #define MAX_DEV_ID 20 #define MAX_CON_ID 16 diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h index b6ec7c627b39..7a0690da5e63 100644 --- a/arch/arm/include/asm/clkdev.h +++ b/arch/arm/include/asm/clkdev.h @@ -27,4 +27,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, void clkdev_add(struct clk_lookup *cl); void clkdev_drop(struct clk_lookup *cl); +void clkdev_add_table(struct clk_lookup *, size_t); +int clk_add_alias(const char *, const char *, char *, struct device *); + #endif diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c index e590bbe0a7b4..72e405df0fb0 100644 --- a/arch/arm/mach-bcmring/core.c +++ b/arch/arm/mach-bcmring/core.c @@ -142,8 +142,7 @@ void __init bcmring_amba_init(void) chipcHw_busInterfaceClockEnable(bus_clock); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 1d0f9d8aff2e..bb3c62196442 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -445,7 +445,6 @@ static void __init ep93xx_dma_clock_init(void) static int __init ep93xx_clock_init(void) { u32 value; - int i; value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); if (!(value & 0x00800000)) { /* PLL1 bypassed? */ @@ -474,8 +473,7 @@ static int __init ep93xx_clock_init(void) clk_f.rate / 1000000, clk_h.rate / 1000000, clk_p.rate / 1000000); - for (i = 0; i < ARRAY_SIZE(clocks); i++) - clkdev_add(&clocks[i]); + clkdev_add_table(clocks, ARRAY_SIZE(clocks)); return 0; } arch_initcall(ep93xx_clock_init); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index a0f60e55da6a..8b390e36ba69 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -144,8 +144,7 @@ static int __init integrator_init(void) { int i; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 3f35293d457a..66ef86d6d9e3 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -558,9 +558,7 @@ static void __init intcp_init(void) { int i; - for (i = 0; i < ARRAY_SIZE(cp_lookups); i++) - clkdev_add(&cp_lookups[i]); - + clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups)); platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c index 2a46ed5cc2a2..886e05648f08 100644 --- a/arch/arm/mach-mmp/clock.c +++ b/arch/arm/mach-mmp/clock.c @@ -88,11 +88,3 @@ unsigned long clk_get_rate(struct clk *clk) return rate; } EXPORT_SYMBOL(clk_get_rate); - -void clks_register(struct clk_lookup *clks, size_t num) -{ - int i; - - for (i = 0; i < num; i++) - clkdev_add(&clks[i]); -} diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h index eefffbe683b0..016ae94691c0 100644 --- a/arch/arm/mach-mmp/clock.h +++ b/arch/arm/mach-mmp/clock.h @@ -68,5 +68,3 @@ struct clk clk_##_name = { \ extern struct clk clk_pxa168_gpio; extern struct clk clk_pxa168_timers; - -extern void clks_register(struct clk_lookup *, size_t); diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index 37dbdde17fac..1873c821df90 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -94,7 +94,7 @@ static int __init pxa168_init(void) mfp_init_base(MFPR_VIRT_BASE); mfp_init_addr(pxa168_mfp_addr_map); pxa_init_dma(IRQ_PXA168_DMA_INT0, 32); - clks_register(ARRAY_AND_SIZE(pxa168_clkregs)); + clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs)); } return 0; diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index d4049508a4df..46f2d69bef3c 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -131,7 +131,7 @@ static int __init pxa910_init(void) mfp_init_base(MFPR_VIRT_BASE); mfp_init_addr(pxa910_mfp_addr_map); pxa_init_dma(IRQ_PXA910_DMA_INT0, 32); - clks_register(ARRAY_AND_SIZE(pxa910_clkregs)); + clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs)); } return 0; diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c index d1b588519ad2..6cf2d4a7511d 100644 --- a/arch/arm/mach-mx1/clock.c +++ b/arch/arm/mach-mx1/clock.c @@ -570,7 +570,6 @@ static struct clk_lookup lookups[] __initdata = { int __init mx1_clocks_init(unsigned long fref) { unsigned int reg; - int i; /* disable clocks we are able to */ __raw_writel(0, SCM_GCCR); @@ -592,8 +591,7 @@ int __init mx1_clocks_init(unsigned long fref) reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET; clko_clk.parent = (struct clk *)clko_clocks[reg]; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); clk_enable(&hclk); clk_enable(&fclk); diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c index 91901b5d56c2..e82b489d1215 100644 --- a/arch/arm/mach-mx2/clock_imx21.c +++ b/arch/arm/mach-mx2/clock_imx21.c @@ -968,7 +968,6 @@ static struct clk_lookup lookups[] = { */ int __init mx21_clocks_init(unsigned long lref, unsigned long href) { - int i; u32 cscr; external_low_reference = lref; @@ -986,8 +985,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) else spll_clk.parent = &fpm_clk; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); /* Turn off all clock gates */ __raw_writel(0, CCM_PCCR0); diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index b010bf9ceaab..18c53a6487fa 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -719,7 +719,6 @@ static void __init to2_adjust_clocks(void) int __init mx27_clocks_init(unsigned long fref) { u32 cscr = __raw_readl(CCM_CSCR); - int i; external_high_reference = fref; @@ -736,8 +735,7 @@ int __init mx27_clocks_init(unsigned long fref) to2_adjust_clocks(); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); /* Turn off all clocks we do not need */ __raw_writel(0, CCM_PCCR0); diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c index 6e838b857712..66916f104812 100644 --- a/arch/arm/mach-mx25/clock.c +++ b/arch/arm/mach-mx25/clock.c @@ -210,11 +210,7 @@ static struct clk_lookup lookups[] = { int __init mx25_clocks_init(unsigned long fref) { - int i; - - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); - + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); return 0; diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index 7584b4c6c556..f3f41fa4f21b 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c @@ -485,15 +485,13 @@ static struct clk_lookup lookups[] = { int __init mx35_clocks_init() { - int i; unsigned int ll = 0; #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) ll = (3 << 16); #endif - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); /* Turn off all clocks except the ones we need to survive, namely: * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index 27a318af0d20..b5c39a016db7 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -578,12 +578,10 @@ static struct clk_lookup lookups[] = { int __init mx31_clocks_init(unsigned long fref) { u32 reg; - int i; ckih_rate = fref; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); /* change the csi_clk parent if necessary */ reg = __raw_readl(MXC_CCM_CCMR); diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c index ecfa37fef8ad..5c85075d8a56 100644 --- a/arch/arm/mach-mxc91231/clock.c +++ b/arch/arm/mach-mxc91231/clock.c @@ -624,7 +624,6 @@ static struct clk_lookup lookups[] = { int __init mxc91231_clocks_init(unsigned long fref) { void __iomem *gpt_base; - int i; ckih_rate = fref; @@ -632,8 +631,7 @@ int __init mxc91231_clocks_init(unsigned long fref) sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]); sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR); mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT); diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index 49ae38292310..abba0089a2ae 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -78,11 +78,3 @@ const struct clkops clk_cken_ops = { .enable = clk_cken_enable, .disable = clk_cken_disable, }; - -void clks_register(struct clk_lookup *clks, size_t num) -{ - int i; - - for (i = 0; i < num; i++) - clkdev_add(&clks[i]); -} diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index 978a3667e90d..d8488742b807 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -67,7 +67,3 @@ extern void clk_pxa3xx_cken_enable(struct clk *); extern void clk_pxa3xx_cken_disable(struct clk *); #endif -void clks_register(struct clk_lookup *clks, size_t num); -int clk_add_alias(const char *alias, const char *alias_name, char *id, - struct device *dev); - diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 91417f035069..96ed13081639 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -128,6 +128,6 @@ static struct clk_lookup eseries_clkregs[] = { void eseries_register_clks(void) { - clks_register(eseries_clkregs, ARRAY_SIZE(eseries_clkregs)); + clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs)); } diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 2c1b0b70d01d..0b9ad30bfd51 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -349,7 +349,7 @@ static int __init pxa25x_init(void) reset_status = RCSR; - clks_register(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs)); + clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs)); if ((ret = pxa_init_dma(IRQ_DMA, 16))) return ret; @@ -370,7 +370,7 @@ static int __init pxa25x_init(void) /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */ if (cpu_is_pxa255()) - clks_register(&pxa25x_hwuart_clkreg, 1); + clkdev_add(&pxa25x_hwuart_clkreg); return ret; } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 6a0b73167e03..d783123e2d48 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -392,7 +392,7 @@ static int __init pxa27x_init(void) reset_status = RCSR; - clks_register(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs)); + clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs)); if ((ret = pxa_init_dma(IRQ_DMA, 32))) return ret; diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index f4af6e2bef89..40bb16501d86 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c @@ -102,12 +102,12 @@ static int __init pxa300_init(void) if (cpu_is_pxa300() || cpu_is_pxa310()) { mfp_init_base(io_p2v(MFPR_BASE)); mfp_init_addr(pxa300_mfp_addr_map); - clks_register(ARRAY_AND_SIZE(common_clkregs)); + clkdev_add_table(ARRAY_AND_SIZE(common_clkregs)); } if (cpu_is_pxa310()) { mfp_init_addr(pxa310_mfp_addr_map); - clks_register(ARRAY_AND_SIZE(pxa310_clkregs)); + clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs)); } return 0; diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c index c7373e74a109..8d614ecd8e99 100644 --- a/arch/arm/mach-pxa/pxa320.c +++ b/arch/arm/mach-pxa/pxa320.c @@ -90,7 +90,7 @@ static int __init pxa320_init(void) if (cpu_is_pxa320()) { mfp_init_base(io_p2v(MFPR_BASE)); mfp_init_addr(pxa320_mfp_addr_map); - clks_register(ARRAY_AND_SIZE(pxa320_clkregs)); + clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs)); } return 0; diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index fcb0721f4669..4d7c03e72504 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -634,7 +634,7 @@ static int __init pxa3xx_init(void) */ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); - clks_register(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs)); + clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs)); if ((ret = pxa_init_dma(IRQ_DMA, 32))) return ret; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 9f293438e020..90bd4ef71b2c 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -346,10 +346,7 @@ static struct clk_lookup lookups[] = { static int __init clk_init(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); return 0; } arch_initcall(clk_init); diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c index 111f7ea32b38..c174ed1f3691 100644 --- a/arch/arm/mach-u300/clock.c +++ b/arch/arm/mach-u300/clock.c @@ -1276,11 +1276,8 @@ static struct clk_lookup lookups[] = { static void __init clk_register(void) { - int i; - /* Register the lookups */ - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); } /* diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 20b6ebb6783a..8359a73d0041 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -85,11 +85,8 @@ static struct clk_lookup lookups[] = { static int __init clk_init(void) { - int i; - /* register the clock lookups */ - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); return 0; } arch_initcall(clk_init); diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index e13be7c444ca..9ddb49b1cb71 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -851,8 +851,7 @@ void __init versatile_init(void) { int i; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); platform_device_register(&versatile_flash_device); platform_device_register(&versatile_i2c_device); diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c index b785994bab0a..2c371ff22e51 100644 --- a/arch/arm/mach-w90x900/clock.c +++ b/arch/arm/mach-w90x900/clock.c @@ -90,12 +90,3 @@ void nuc900_subclk_enable(struct clk *clk, int enable) __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK); } - - -void clks_register(struct clk_lookup *clks, size_t num) -{ - int i; - - for (i = 0; i < num; i++) - clkdev_add(&clks[i]); -} diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h index f5816a06eed6..c56ddab3d912 100644 --- a/arch/arm/mach-w90x900/clock.h +++ b/arch/arm/mach-w90x900/clock.h @@ -14,7 +14,6 @@ void nuc900_clk_enable(struct clk *clk, int enable); void nuc900_subclk_enable(struct clk *clk, int enable); -void clks_register(struct clk_lookup *clks, size_t num); struct clk { unsigned long cken; diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c index 20dc0c96214d..6f5ca532883f 100644 --- a/arch/arm/mach-w90x900/cpu.c +++ b/arch/arm/mach-w90x900/cpu.c @@ -208,6 +208,6 @@ void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size) void __init nuc900_init_clocks(void) { - clks_register(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs)); + clkdev_add_table(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs)); } diff --git a/arch/arm/plat-stmp3xxx/clock.c b/arch/arm/plat-stmp3xxx/clock.c index 5d2f19a09e44..e593a2a801c6 100644 --- a/arch/arm/plat-stmp3xxx/clock.c +++ b/arch/arm/plat-stmp3xxx/clock.c @@ -1126,9 +1126,8 @@ static int __init clk_init(void) if (ops && ops->set_parent) ops->set_parent(cl->clk, cl->clk->parent); } - - clkdev_add(cl); } + clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks)); return 0; } -- cgit v1.2.3 From 6985a5ad0d719d8c8d584a69f6e5d7138a2e19ab Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 10:32:41 +0000 Subject: ARM: PNX4008: convert to clkdev Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-pnx4008/clock.c | 66 +++++++++++++++-------------- arch/arm/mach-pnx4008/clock.h | 2 - arch/arm/mach-pnx4008/include/mach/clkdev.h | 7 +++ 4 files changed, 43 insertions(+), 33 deletions(-) create mode 100644 arch/arm/mach-pnx4008/include/mach/clkdev.h (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4c33ca82f9b1..fb2a51b0ec15 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -554,6 +554,7 @@ config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T select HAVE_CLK + select COMMON_CLKDEV help This enables support for Philips PNX4008 mobile platform. diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 898c0e88acbc..6f5d2e502654 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -22,8 +22,9 @@ #include #include -#include +#include +#include #include #include "clock.h" @@ -747,7 +748,7 @@ static struct clk wdt_ck = { /* These clocks are visible outside this module * and can be initialized */ -static struct clk *onchip_clks[] = { +static struct clk *onchip_clks[] __initdata = { &ck_13MHz, &ck_pll1, &ck_pll4, @@ -777,6 +778,36 @@ static struct clk *onchip_clks[] = { &wdt_ck, }; +static struct clk_lookup onchip_clkreg[] = { + { .clk = &ck_13MHz, .con_id = "ck_13MHz" }, + { .clk = &ck_pll1, .con_id = "ck_pll1" }, + { .clk = &ck_pll4, .con_id = "ck_pll4" }, + { .clk = &ck_pll5, .con_id = "ck_pll5" }, + { .clk = &ck_pll3, .con_id = "ck_pll3" }, + { .clk = &vfp9_ck, .con_id = "vfp9_ck" }, + { .clk = &m2hclk_ck, .con_id = "m2hclk_ck" }, + { .clk = &hclk_ck, .con_id = "hclk_ck" }, + { .clk = &dma_ck, .con_id = "dma_ck" }, + { .clk = &flash_ck, .con_id = "flash_ck" }, + { .clk = &dum_ck, .con_id = "dum_ck" }, + { .clk = &keyscan_ck, .con_id = "keyscan_ck" }, + { .clk = &pwm1_ck, .con_id = "pwm1_ck" }, + { .clk = &pwm2_ck, .con_id = "pwm2_ck" }, + { .clk = &jpeg_ck, .con_id = "jpeg_ck" }, + { .clk = &ms_ck, .con_id = "ms_ck" }, + { .clk = &touch_ck, .con_id = "touch_ck" }, + { .clk = &i2c0_ck, .con_id = "i2c0_ck" }, + { .clk = &i2c1_ck, .con_id = "i2c1_ck" }, + { .clk = &i2c2_ck, .con_id = "i2c2_ck" }, + { .clk = &spi0_ck, .con_id = "spi0_ck" }, + { .clk = &spi1_ck, .con_id = "spi1_ck" }, + { .clk = &uart3_ck, .con_id = "uart3_ck" }, + { .clk = &uart4_ck, .con_id = "uart4_ck" }, + { .clk = &uart5_ck, .con_id = "uart5_ck" }, + { .clk = &uart6_ck, .con_id = "uart6_ck" }, + { .clk = &wdt_ck, .con_id = "wdt_ck" }, +}; + static int local_clk_enable(struct clk *clk) { int ret = 0; @@ -866,35 +897,6 @@ out: EXPORT_SYMBOL(clk_set_rate); -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *clk = ERR_PTR(-ENOENT); - struct clk **clkp; - - clock_lock(); - for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); - clkp++) { - if (strcmp(id, (*clkp)->name) == 0 - && try_module_get((*clkp)->owner)) { - clk = (*clkp); - break; - } - } - clock_unlock(); - - return clk; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ - clock_lock(); - if (clk && !IS_ERR(clk)) - module_put(clk->owner); - clock_unlock(); -} -EXPORT_SYMBOL(clk_put); - unsigned long clk_get_rate(struct clk *clk) { unsigned long ret; @@ -987,6 +989,8 @@ static int __init clk_init(void) /* Disable autoclocking */ __raw_writeb(0xff, AUTOCLK_CTRL); + clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg)); + return 0; } diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h index cd58f372cfd0..933e18133b96 100644 --- a/arch/arm/mach-pnx4008/clock.h +++ b/arch/arm/mach-pnx4008/clock.h @@ -14,8 +14,6 @@ #define __ARCH_ARM_PNX4008_CLOCK_H__ struct clk { - struct list_head node; - struct module *owner; const char *name; struct clk *parent; struct clk *propagate_next; diff --git a/arch/arm/mach-pnx4008/include/mach/clkdev.h b/arch/arm/mach-pnx4008/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/mach-pnx4008/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif -- cgit v1.2.3 From 5413f7464e976e2c2ddb20686fc2e66ae8795b6e Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 11:25:44 +0000 Subject: ARM: PNX4008: simplify clk enable/disable paths Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 55 ++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 6f5d2e502654..f0cc91909090 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -808,49 +808,40 @@ static struct clk_lookup onchip_clkreg[] = { { .clk = &wdt_ck, .con_id = "wdt_ck" }, }; -static int local_clk_enable(struct clk *clk) -{ - int ret = 0; - - if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate - && clk->user_rate) - ret = clk->set_rate(clk, clk->user_rate); - return ret; -} - static void local_clk_disable(struct clk *clk) { - if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) - clk->set_rate(clk, 0); -} + if (WARN_ON(clk->usecount == 0)) + return; -static void local_clk_unuse(struct clk *clk) -{ - if (clk->usecount > 0 && !(--clk->usecount)) { - local_clk_disable(clk); + if (!(--clk->usecount)) { + if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) + clk->set_rate(clk, 0); if (clk->parent) - local_clk_unuse(clk->parent); + local_clk_disable(clk->parent); } } -static int local_clk_use(struct clk *clk) +static int local_clk_enable(struct clk *clk) { int ret = 0; - if (clk->usecount++ == 0) { - if (clk->parent) - ret = local_clk_use(clk->parent); - if (ret != 0) { - clk->usecount--; - goto out; + if (clk->usecount == 0) { + if (clk->parent) { + ret = local_clk_enable(clk->parent); + if (ret != 0) + goto out; } - ret = local_clk_enable(clk); + if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate + && clk->user_rate) + ret = clk->set_rate(clk, clk->user_rate); if (ret != 0 && clk->parent) { - local_clk_unuse(clk->parent); - clk->usecount--; + local_clk_disable(clk->parent); + goto out; } + + clk->usecount++; } out: return ret; @@ -909,10 +900,10 @@ EXPORT_SYMBOL(clk_get_rate); int clk_enable(struct clk *clk) { - int ret = 0; + int ret; clock_lock(); - ret = local_clk_use(clk); + ret = local_clk_enable(clk); clock_unlock(); return ret; } @@ -922,7 +913,7 @@ EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { clock_lock(); - local_clk_unuse(clk); + local_clk_disable(clk); clock_unlock(); } @@ -980,7 +971,7 @@ static int __init clk_init(void) __func__, (*clkp)->name, (*clkp)->rate); } - local_clk_use(&ck_pll4); + local_clk_enable(&ck_pll4); /* if ck_13MHz is not used, disable it. */ if (ck_13MHz.usecount == 0) -- cgit v1.2.3 From 0c452df9f08d4f0b829802cec3501d987390ada2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 11:28:59 +0000 Subject: ARM: PNX4008: provide clock enable/disable methods and initialization Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 35 +++++++++++++++++++++++------------ arch/arm/mach-pnx4008/clock.h | 4 +++- 2 files changed, 26 insertions(+), 13 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index f0cc91909090..3ad694e15968 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -57,18 +57,19 @@ static void propagate_rate(struct clk *clk) } } -static inline void clk_reg_disable(struct clk *clk) +static void clk_reg_disable(struct clk *clk) { if (clk->enable_reg) __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_shift), clk->enable_reg); } -static inline void clk_reg_enable(struct clk *clk) +static int clk_reg_enable(struct clk *clk) { if (clk->enable_reg) __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_shift), clk->enable_reg); + return 0; } static inline void clk_reg_disable1(struct clk *clk) @@ -814,7 +815,9 @@ static void local_clk_disable(struct clk *clk) return; if (!(--clk->usecount)) { - if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) + if (clk->disable) + clk->disable(clk); + else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) clk->set_rate(clk, 0); if (clk->parent) local_clk_disable(clk->parent); @@ -832,8 +835,10 @@ static int local_clk_enable(struct clk *clk) goto out; } - if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate - && clk->user_rate) + if (clk->enable) + ret = clk->enable(clk); + else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate + && clk->user_rate) ret = clk->set_rate(clk, clk->user_rate); if (ret != 0 && clk->parent) { @@ -960,15 +965,21 @@ static int __init clk_init(void) for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); clkp++) { - if (((*clkp)->flags & NEEDS_INITIALIZATION) - && ((*clkp)->set_rate)) { - (*clkp)->user_rate = (*clkp)->rate; - local_set_rate((*clkp), (*clkp)->user_rate); - if ((*clkp)->set_parent) - (*clkp)->set_parent((*clkp), (*clkp)->parent); + struct clk *clk = *clkp; + if (clk->flags & NEEDS_INITIALIZATION) { + if (clk->set_rate) { + clk->user_rate = clk->rate; + local_set_rate(clk, clk->user_rate); + if (clk->set_parent) + clk->set_parent(clk, clk->parent); + } + if (clk->enable && clk->usecount) + clk->enable(clk); + if (clk->disable && !clk->usecount) + clk->disable(clk); } pr_debug("%s: clock %s, rate %ld\n", - __func__, (*clkp)->name, (*clkp)->rate); + __func__, clk->name, clk->rate); } local_clk_enable(&ck_pll4); diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h index 933e18133b96..39720d6c0d01 100644 --- a/arch/arm/mach-pnx4008/clock.h +++ b/arch/arm/mach-pnx4008/clock.h @@ -27,9 +27,11 @@ struct clk { u8 enable_shift1; u32 enable_reg1; u32 parent_switch_reg; - u32(*round_rate) (struct clk *, u32); + u32(*round_rate) (struct clk *, u32); int (*set_rate) (struct clk *, u32); int (*set_parent) (struct clk * clk, struct clk * parent); + int (*enable)(struct clk *); + void (*disable)(struct clk *); }; /* Flags */ -- cgit v1.2.3 From 9bb787f435c86ffed079b66efa3ef6a8c577568c Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 13:07:28 +0000 Subject: ARM: PNX4008: convert watchdog clocks to match by device only Acked-by: Wim Van Sebroeck Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 2 +- drivers/watchdog/pnx4008_wdt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 3ad694e15968..e5140237fb15 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -806,7 +806,7 @@ static struct clk_lookup onchip_clkreg[] = { { .clk = &uart4_ck, .con_id = "uart4_ck" }, { .clk = &uart5_ck, .con_id = "uart5_ck" }, { .clk = &uart6_ck, .con_id = "uart6_ck" }, - { .clk = &wdt_ck, .con_id = "wdt_ck" }, + { .clk = &wdt_ck, .dev_id = "pnx4008-watchdog" }, }; static void local_clk_disable(struct clk *clk) diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 430a5848a9a5..8c5367fc4e50 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -273,7 +273,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) } wdt_base = (void __iomem *)IO_ADDRESS(res->start); - wdt_clk = clk_get(&pdev->dev, "wdt_ck"); + wdt_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(wdt_clk)) { ret = PTR_ERR(wdt_clk); release_resource(wdt_mem); -- cgit v1.2.3 From 24fd1edaac79fe9554c557f9f93b3197c136c236 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 13:04:14 +0000 Subject: ARM: PNX4008: convert watchdog to use clk API enable/disable calls clk_set_rate() is not supposed to be used to turn clocks on and off. That's what clk_enable/clk_disable is for. Acked-by: Wim Van Sebroeck Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 4 ++-- drivers/watchdog/pnx4008_wdt.c | 37 ++++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 15 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index e5140237fb15..944ffa94d325 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -740,10 +740,10 @@ static struct clk wdt_ck = { .name = "wdt_ck", .parent = &per_ck, .flags = NEEDS_INITIALIZATION, - .round_rate = &on_off_round_rate, - .set_rate = &on_off_set_rate, .enable_shift = 0, .enable_reg = TIMCLKCTRL_REG, + .enable = clk_reg_enable, + .disable = clk_reg_disable, }; /* These clocks are visible outside this module diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 8c5367fc4e50..c7a9479934af 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -96,9 +96,6 @@ static void wdt_enable(void) { spin_lock(&io_lock); - if (wdt_clk) - clk_set_rate(wdt_clk, 1); - /* stop counter, initiate counter reset */ __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); /*wait for reset to complete. 100% guarantee event */ @@ -125,19 +122,25 @@ static void wdt_disable(void) spin_lock(&io_lock); __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ - if (wdt_clk) - clk_set_rate(wdt_clk, 0); spin_unlock(&io_lock); } static int pnx4008_wdt_open(struct inode *inode, struct file *file) { + int ret; + if (test_and_set_bit(WDT_IN_USE, &wdt_status)) return -EBUSY; clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + ret = clk_enable(wdt_clk); + if (ret) { + clear_bit(WDT_IN_USE, &wdt_status); + return ret; + } + wdt_enable(); return nonseekable_open(inode, file); @@ -225,6 +228,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file) printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); wdt_disable(); + clk_disable(wdt_clk); clear_bit(WDT_IN_USE, &wdt_status); clear_bit(WDT_OK_TO_CLOSE, &wdt_status); @@ -279,19 +283,27 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) release_resource(wdt_mem); kfree(wdt_mem); goto out; - } else - clk_set_rate(wdt_clk, 1); + } + + ret = clk_enable(wdt_clk); + if (ret) { + release_resource(wdt_mem); + kfree(wdt_mem); + goto out; + } ret = misc_register(&pnx4008_wdt_miscdev); if (ret < 0) { printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); release_resource(wdt_mem); kfree(wdt_mem); - clk_set_rate(wdt_clk, 0); + clk_disable(wdt_clk); + clk_put(wdt_clk); } else { boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? WDIOF_CARDRESET : 0; wdt_disable(); /*disable for now */ + clk_disable(wdt_clk); set_bit(WDT_DEVICE_INITED, &wdt_status); } @@ -302,11 +314,10 @@ out: static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) { misc_deregister(&pnx4008_wdt_miscdev); - if (wdt_clk) { - clk_set_rate(wdt_clk, 0); - clk_put(wdt_clk); - wdt_clk = NULL; - } + + clk_disable(wdt_clk); + clk_put(wdt_clk); + if (wdt_mem) { release_resource(wdt_mem); kfree(wdt_mem); -- cgit v1.2.3 From bba2be480b981bc1e7bea24c2a2552b0ad7e9774 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 10:46:24 +0000 Subject: ARM: PNX4008: convert i2c clocks to match by device only Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 6 +++--- arch/arm/mach-pnx4008/i2c.c | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 944ffa94d325..5a1515210969 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -797,9 +797,9 @@ static struct clk_lookup onchip_clkreg[] = { { .clk = &jpeg_ck, .con_id = "jpeg_ck" }, { .clk = &ms_ck, .con_id = "ms_ck" }, { .clk = &touch_ck, .con_id = "touch_ck" }, - { .clk = &i2c0_ck, .con_id = "i2c0_ck" }, - { .clk = &i2c1_ck, .con_id = "i2c1_ck" }, - { .clk = &i2c2_ck, .con_id = "i2c2_ck" }, + { .clk = &i2c0_ck, .dev_id = "pnx-i2c.0" }, + { .clk = &i2c1_ck, .dev_id = "pnx-i2c.1" }, + { .clk = &i2c2_ck, .dev_id = "pnx-i2c.2" }, { .clk = &spi0_ck, .con_id = "spi0_ck" }, { .clk = &spi1_ck, .con_id = "spi1_ck" }, { .clk = &uart3_ck, .con_id = "uart3_ck" }, diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index f3fea29c00d3..c986b3a61311 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c @@ -21,11 +21,9 @@ static int set_clock_run(struct platform_device *pdev) { struct clk *clk; - char name[10]; int retval = 0; - snprintf(name, 10, "i2c%d_ck", pdev->id); - clk = clk_get(&pdev->dev, name); + clk = clk_get(&pdev->dev, NULL); if (!IS_ERR(clk)) { clk_set_rate(clk, 1); clk_put(clk); @@ -38,11 +36,9 @@ static int set_clock_run(struct platform_device *pdev) static int set_clock_stop(struct platform_device *pdev) { struct clk *clk; - char name[10]; int retval = 0; - snprintf(name, 10, "i2c%d_ck", pdev->id); - clk = clk_get(&pdev->dev, name); + clk = clk_get(&pdev->dev, NULL); if (!IS_ERR(clk)) { clk_set_rate(clk, 0); clk_put(clk); -- cgit v1.2.3 From a0dcf19f59d4f37150a6b7e115925d72aca15293 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 10:50:34 +0000 Subject: ARM: PNX4008: move i2c suspend/resume callbacks into driver Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/i2c.c | 24 ------------------------ drivers/i2c/busses/i2c-pnx.c | 9 +++++++-- include/linux/i2c-pnx.h | 4 ---- 3 files changed, 7 insertions(+), 30 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index c986b3a61311..707d819f1280 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c @@ -48,24 +48,6 @@ static int set_clock_stop(struct platform_device *pdev) return retval; } -static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state) -{ - int retval = 0; -#ifdef CONFIG_PM - retval = set_clock_run(pdev); -#endif - return retval; -} - -static int i2c_pnx_resume(struct platform_device *pdev) -{ - int retval = 0; -#ifdef CONFIG_PM - retval = set_clock_run(pdev); -#endif - return retval; -} - static u32 calculate_input_freq(struct platform_device *pdev) { return HCLK_MHZ; @@ -102,8 +84,6 @@ static struct i2c_adapter pnx_adapter2 = { }; static struct i2c_pnx_data i2c0_data = { - .suspend = i2c_pnx_suspend, - .resume = i2c_pnx_resume, .calculate_input_freq = calculate_input_freq, .set_clock_run = set_clock_run, .set_clock_stop = set_clock_stop, @@ -111,8 +91,6 @@ static struct i2c_pnx_data i2c0_data = { }; static struct i2c_pnx_data i2c1_data = { - .suspend = i2c_pnx_suspend, - .resume = i2c_pnx_resume, .calculate_input_freq = calculate_input_freq, .set_clock_run = set_clock_run, .set_clock_stop = set_clock_stop, @@ -120,8 +98,6 @@ static struct i2c_pnx_data i2c1_data = { }; static struct i2c_pnx_data i2c2_data = { - .suspend = i2c_pnx_suspend, - .resume = i2c_pnx_resume, .calculate_input_freq = calculate_input_freq, .set_clock_run = set_clock_run, .set_clock_stop = set_clock_stop, diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d1c2603a130..bc8075514e53 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -545,18 +545,23 @@ static struct i2c_algorithm pnx_algorithm = { .functionality = i2c_pnx_func, }; +#ifdef CONFIG_PM static int i2c_pnx_controller_suspend(struct platform_device *pdev, pm_message_t state) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->suspend(pdev, state); + return i2c_pnx->set_clock_run(pdev); } static int i2c_pnx_controller_resume(struct platform_device *pdev) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->resume(pdev); + return i2c_pnx->set_clock_run(pdev); } +#else +#define i2c_pnx_controller_suspend NULL +#define i2c_pnx_controller_resume NULL +#endif static int __devinit i2c_pnx_probe(struct platform_device *pdev) { diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 9eb07bbc6522..71de7f976adf 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h @@ -12,8 +12,6 @@ #ifndef __I2C_PNX_H__ #define __I2C_PNX_H__ -#include - struct platform_device; struct i2c_pnx_mif { @@ -34,8 +32,6 @@ struct i2c_pnx_algo_data { }; struct i2c_pnx_data { - int (*suspend) (struct platform_device *pdev, pm_message_t state); - int (*resume) (struct platform_device *pdev); u32 (*calculate_input_freq) (struct platform_device *pdev); int (*set_clock_run) (struct platform_device *pdev); int (*set_clock_stop) (struct platform_device *pdev); -- cgit v1.2.3 From 0321cb83e1c3f3a4282bd620c6cec78c5b80b572 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 11:12:26 +0000 Subject: ARM: PNX4008: move i2c clock start/stop into driver Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/i2c.c | 36 ------------------------------------ drivers/i2c/busses/i2c-pnx.c | 39 ++++++++++++++++++++++++++++++--------- include/linux/i2c-pnx.h | 4 ++-- 3 files changed, 32 insertions(+), 47 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index 707d819f1280..14b4906bec2f 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c @@ -18,36 +18,6 @@ #include #include -static int set_clock_run(struct platform_device *pdev) -{ - struct clk *clk; - int retval = 0; - - clk = clk_get(&pdev->dev, NULL); - if (!IS_ERR(clk)) { - clk_set_rate(clk, 1); - clk_put(clk); - } else - retval = -ENOENT; - - return retval; -} - -static int set_clock_stop(struct platform_device *pdev) -{ - struct clk *clk; - int retval = 0; - - clk = clk_get(&pdev->dev, NULL); - if (!IS_ERR(clk)) { - clk_set_rate(clk, 0); - clk_put(clk); - } else - retval = -ENOENT; - - return retval; -} - static u32 calculate_input_freq(struct platform_device *pdev) { return HCLK_MHZ; @@ -85,22 +55,16 @@ static struct i2c_adapter pnx_adapter2 = { static struct i2c_pnx_data i2c0_data = { .calculate_input_freq = calculate_input_freq, - .set_clock_run = set_clock_run, - .set_clock_stop = set_clock_stop, .adapter = &pnx_adapter0, }; static struct i2c_pnx_data i2c1_data = { .calculate_input_freq = calculate_input_freq, - .set_clock_run = set_clock_run, - .set_clock_stop = set_clock_stop, .adapter = &pnx_adapter1, }; static struct i2c_pnx_data i2c2_data = { .calculate_input_freq = calculate_input_freq, - .set_clock_run = set_clock_run, - .set_clock_stop = set_clock_stop, .adapter = &pnx_adapter2, }; diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index bc8075514e53..98462671cdf7 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include + #include #include #include @@ -550,13 +553,22 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, pm_message_t state) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->set_clock_run(pdev); + struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + + /* FIXME: disable clock? */ + clk_set_rate(alg_data->clk, 1); + + return 0; } static int i2c_pnx_controller_resume(struct platform_device *pdev) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->set_clock_run(pdev); + struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + + clk_set_rate(alg_data->clk, 1); + + return 0; } #else #define i2c_pnx_controller_suspend NULL @@ -580,6 +592,15 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c_pnx); + i2c_pnx->adapter->algo = &pnx_algorithm; + alg_data = i2c_pnx->adapter->algo_data; + + alg_data->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(alg_data->clk)) { + ret = PTR_ERR(alg_data->clk); + goto out_drvdata; + } + if (i2c_pnx->calculate_input_freq) freq_mhz = i2c_pnx->calculate_input_freq(pdev); else { @@ -588,9 +609,6 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) "%d MHz\n", freq_mhz); } - i2c_pnx->adapter->algo = &pnx_algorithm; - - alg_data = i2c_pnx->adapter->algo_data; init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; @@ -602,7 +620,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) "I/O region 0x%08x for I2C already in use.\n", alg_data->base); ret = -ENODEV; - goto out_drvdata; + goto out_clkget; } if (!(alg_data->ioaddr = @@ -612,7 +630,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_release; } - i2c_pnx->set_clock_run(pdev); + clk_set_rate(alg_data->clk, 1); /* * Clock Divisor High This value is the number of system clocks @@ -658,11 +676,13 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) out_irq: free_irq(alg_data->irq, i2c_pnx->adapter); out_clock: - i2c_pnx->set_clock_stop(pdev); + clk_set_rate(alg_data->clk, 0); out_unmap: iounmap((void *)alg_data->ioaddr); out_release: release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); +out_clkget: + clk_put(alg_data->clk); out_drvdata: platform_set_drvdata(pdev, NULL); out: @@ -677,9 +697,10 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) free_irq(alg_data->irq, i2c_pnx->adapter); i2c_del_adapter(adap); - i2c_pnx->set_clock_stop(pdev); + clk_set_rate(alg_data->clk, 0); iounmap((void *)alg_data->ioaddr); release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); + clk_put(alg_data->clk); platform_set_drvdata(pdev, NULL); return 0; diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 71de7f976adf..688e29262a43 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h @@ -13,6 +13,7 @@ #define __I2C_PNX_H__ struct platform_device; +struct clk; struct i2c_pnx_mif { int ret; /* Return value */ @@ -29,12 +30,11 @@ struct i2c_pnx_algo_data { int irq; struct i2c_pnx_mif mif; int last; + struct clk *clk; }; struct i2c_pnx_data { u32 (*calculate_input_freq) (struct platform_device *pdev); - int (*set_clock_run) (struct platform_device *pdev); - int (*set_clock_stop) (struct platform_device *pdev); struct i2c_adapter *adapter; }; -- cgit v1.2.3 From ebdbbf2003ae2342147c87c2a6c6ed8984b9cede Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 11:44:46 +0000 Subject: ARM: PNX4008: convert i2c-pnx to use clk API enable/disable calls clk_set_rate() is not supposed to be used to turn clocks on and off. That's what clk_enable/clk_disable is for. Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 12 ++++++------ drivers/i2c/busses/i2c-pnx.c | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 5a1515210969..692625cd2001 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -639,30 +639,30 @@ static struct clk i2c0_ck = { .name = "i2c0_ck", .parent = &per_ck, .flags = NEEDS_INITIALIZATION, - .round_rate = &on_off_round_rate, - .set_rate = &on_off_set_rate, .enable_shift = 0, .enable_reg = I2CCLKCTRL_REG, + .enable = clk_reg_enable, + .disable = clk_reg_disable, }; static struct clk i2c1_ck = { .name = "i2c1_ck", .parent = &per_ck, .flags = NEEDS_INITIALIZATION, - .round_rate = &on_off_round_rate, - .set_rate = &on_off_set_rate, .enable_shift = 1, .enable_reg = I2CCLKCTRL_REG, + .enable = clk_reg_enable, + .disable = clk_reg_disable, }; static struct clk i2c2_ck = { .name = "i2c2_ck", .parent = &per_ck, .flags = NEEDS_INITIALIZATION, - .round_rate = &on_off_round_rate, - .set_rate = &on_off_set_rate, .enable_shift = 2, .enable_reg = USB_OTG_CLKCTRL_REG, + .enable = clk_reg_enable, + .disable = clk_reg_disable, }; static struct clk spi0_ck = { diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 98462671cdf7..29f91774c4df 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -555,8 +555,8 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; - /* FIXME: disable clock? */ - clk_set_rate(alg_data->clk, 1); + /* FIXME: shouldn't this be clk_disable? */ + clk_enable(alg_data->clk); return 0; } @@ -566,9 +566,7 @@ static int i2c_pnx_controller_resume(struct platform_device *pdev) struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; - clk_set_rate(alg_data->clk, 1); - - return 0; + return clk_enable(alg_data->clk); } #else #define i2c_pnx_controller_suspend NULL @@ -630,7 +628,9 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_release; } - clk_set_rate(alg_data->clk, 1); + ret = clk_enable(alg_data->clk); + if (ret) + goto out_unmap; /* * Clock Divisor High This value is the number of system clocks @@ -650,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { ret = -ENODEV; - goto out_unmap; + goto out_clock; } init_completion(&alg_data->mif.complete); @@ -676,7 +676,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) out_irq: free_irq(alg_data->irq, i2c_pnx->adapter); out_clock: - clk_set_rate(alg_data->clk, 0); + clk_disable(alg_data->clk); out_unmap: iounmap((void *)alg_data->ioaddr); out_release: @@ -697,7 +697,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) free_irq(alg_data->irq, i2c_pnx->adapter); i2c_del_adapter(adap); - clk_set_rate(alg_data->clk, 0); + clk_disable(alg_data->clk); iounmap((void *)alg_data->ioaddr); release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); clk_put(alg_data->clk); -- cgit v1.2.3 From 6fff3da998ac3cc9ed8a84bf4f19911bd63c8c32 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 12:46:07 +0000 Subject: ARM: PNX4008: get i2c clock rate from clk API Acked-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/clock.c | 9 ++++++--- arch/arm/mach-pnx4008/i2c.c | 9 --------- drivers/i2c/busses/i2c-pnx.c | 15 ++++----------- include/linux/i2c-pnx.h | 1 - 4 files changed, 10 insertions(+), 24 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 692625cd2001..9d1975fa4d9f 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -638,9 +638,10 @@ static struct clk flash_ck = { static struct clk i2c0_ck = { .name = "i2c0_ck", .parent = &per_ck, - .flags = NEEDS_INITIALIZATION, + .flags = NEEDS_INITIALIZATION | FIXED_RATE, .enable_shift = 0, .enable_reg = I2CCLKCTRL_REG, + .rate = 13000000, .enable = clk_reg_enable, .disable = clk_reg_disable, }; @@ -648,9 +649,10 @@ static struct clk i2c0_ck = { static struct clk i2c1_ck = { .name = "i2c1_ck", .parent = &per_ck, - .flags = NEEDS_INITIALIZATION, + .flags = NEEDS_INITIALIZATION | FIXED_RATE, .enable_shift = 1, .enable_reg = I2CCLKCTRL_REG, + .rate = 13000000, .enable = clk_reg_enable, .disable = clk_reg_disable, }; @@ -658,9 +660,10 @@ static struct clk i2c1_ck = { static struct clk i2c2_ck = { .name = "i2c2_ck", .parent = &per_ck, - .flags = NEEDS_INITIALIZATION, + .flags = NEEDS_INITIALIZATION | FIXED_RATE, .enable_shift = 2, .enable_reg = USB_OTG_CLKCTRL_REG, + .rate = 13000000, .enable = clk_reg_enable, .disable = clk_reg_disable, }; diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index 14b4906bec2f..23ec335a4bc0 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c @@ -18,12 +18,6 @@ #include #include -static u32 calculate_input_freq(struct platform_device *pdev) -{ - return HCLK_MHZ; -} - - static struct i2c_pnx_algo_data pnx_algo_data0 = { .base = PNX4008_I2C1_BASE, .irq = I2C_1_INT, @@ -54,17 +48,14 @@ static struct i2c_adapter pnx_adapter2 = { }; static struct i2c_pnx_data i2c0_data = { - .calculate_input_freq = calculate_input_freq, .adapter = &pnx_adapter0, }; static struct i2c_pnx_data i2c1_data = { - .calculate_input_freq = calculate_input_freq, .adapter = &pnx_adapter1, }; static struct i2c_pnx_data i2c2_data = { - .calculate_input_freq = calculate_input_freq, .adapter = &pnx_adapter2, }; diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 29f91774c4df..bfcd079e885c 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -31,7 +31,6 @@ #define I2C_PNX_TIMEOUT 10 /* msec */ #define I2C_PNX_SPEED_KHZ 100 #define I2C_PNX_REGION_SIZE 0x100 -#define PNX_DEFAULT_FREQ 13 /* MHz */ static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data) { @@ -578,7 +577,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) unsigned long tmp; int ret = 0; struct i2c_pnx_algo_data *alg_data; - int freq_mhz; + unsigned long freq; struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; if (!i2c_pnx || !i2c_pnx->adapter) { @@ -599,14 +598,6 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_drvdata; } - if (i2c_pnx->calculate_input_freq) - freq_mhz = i2c_pnx->calculate_input_freq(pdev); - else { - freq_mhz = PNX_DEFAULT_FREQ; - dev_info(&pdev->dev, "Setting bus frequency to default value: " - "%d MHz\n", freq_mhz); - } - init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; @@ -632,6 +623,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) if (ret) goto out_unmap; + freq = clk_get_rate(alg_data->clk); + /* * Clock Divisor High This value is the number of system clocks * the serial clock (SCL) will be high. @@ -643,7 +636,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) * the deglitching filter length. */ - tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; + tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; iowrite32(tmp, I2C_REG_CKH(alg_data)); iowrite32(tmp, I2C_REG_CKL(alg_data)); diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 688e29262a43..9035711cb3b1 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h @@ -34,7 +34,6 @@ struct i2c_pnx_algo_data { }; struct i2c_pnx_data { - u32 (*calculate_input_freq) (struct platform_device *pdev); struct i2c_adapter *adapter; }; -- cgit v1.2.3 From 2781681ea6629ac0a685f5afe2011f916ab3c8ba Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 11:43:33 +0000 Subject: ARM: PNX4008: remove platform definitions from mach/timex.h mach/timex.h is only supposed to contain a definition for CLOCK_TICK_RATE. Remove additional includes, and move private definitions to a private header file. Signed-off-by: Russell King --- arch/arm/mach-pnx4008/include/mach/timex.h | 54 ----------------------- arch/arm/mach-pnx4008/pm.c | 2 + arch/arm/mach-pnx4008/time.c | 2 + arch/arm/mach-pnx4008/time.h | 70 ++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 54 deletions(-) create mode 100644 arch/arm/mach-pnx4008/time.h (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/include/mach/timex.h b/arch/arm/mach-pnx4008/include/mach/timex.h index 5ff0196c0f16..b383c7de7ab4 100644 --- a/arch/arm/mach-pnx4008/include/mach/timex.h +++ b/arch/arm/mach-pnx4008/include/mach/timex.h @@ -14,60 +14,6 @@ #ifndef __PNX4008_TIMEX_H #define __PNX4008_TIMEX_H -#include -#include - #define CLOCK_TICK_RATE 1000000 -#define TICKS2USECS(x) (x) - -/* MilliSecond Timer - Chapter 21 Page 202 */ - -#define MSTIM_INT IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0)) -#define MSTIM_CTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4)) -#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8)) -#define MSTIM_MCTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14)) -#define MSTIM_MATCH0 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18)) -#define MSTIM_MATCH1 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c)) - -/* High Speed Timer - Chpater 22, Page 205 */ - -#define HSTIM_INT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0)) -#define HSTIM_CTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4)) -#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8)) -#define HSTIM_PMATCH IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC)) -#define HSTIM_PCOUNT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10)) -#define HSTIM_MCTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14)) -#define HSTIM_MATCH0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18)) -#define HSTIM_MATCH1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c)) -#define HSTIM_MATCH2 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20)) -#define HSTIM_CCR IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28)) -#define HSTIM_CR0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C)) -#define HSTIM_CR1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30)) - -/* IMPORTANT: both timers are UPCOUNTING */ - -/* xSTIM_MCTRL bit definitions */ -#define MR0_INT 1 -#define RESET_COUNT0 (1<<1) -#define STOP_COUNT0 (1<<2) -#define MR1_INT (1<<3) -#define RESET_COUNT1 (1<<4) -#define STOP_COUNT1 (1<<5) -#define MR2_INT (1<<6) -#define RESET_COUNT2 (1<<7) -#define STOP_COUNT2 (1<<8) - -/* xSTIM_CTRL bit definitions */ -#define COUNT_ENAB 1 -#define RESET_COUNT (1<<1) -#define DEBUG_EN (1<<2) - -/* xSTIM_INT bit definitions */ -#define MATCH0_INT 1 -#define MATCH1_INT (1<<1) -#define MATCH2_INT (1<<2) -#define RTC_TICK0 (1<<4) -#define RTC_TICK1 (1<<5) - #endif diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c index b3d8d53e32ef..1f0585329be4 100644 --- a/arch/arm/mach-pnx4008/pm.c +++ b/arch/arm/mach-pnx4008/pm.c @@ -21,6 +21,8 @@ #include #include + +#include #include #include diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c index fc0ba183fe12..0c8aad4bb0dc 100644 --- a/arch/arm/mach-pnx4008/time.c +++ b/arch/arm/mach-pnx4008/time.c @@ -30,6 +30,8 @@ #include #include +#include "time.h" + /*! Note: all timers are UPCOUNTING */ /*! diff --git a/arch/arm/mach-pnx4008/time.h b/arch/arm/mach-pnx4008/time.h new file mode 100644 index 000000000000..75e88c570aa7 --- /dev/null +++ b/arch/arm/mach-pnx4008/time.h @@ -0,0 +1,70 @@ +/* + * arch/arm/mach-pnx4008/include/mach/timex.h + * + * PNX4008 timers header file + * + * Author: Dmitry Chigirev + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef PNX_TIME_H +#define PNX_TIME_H + +#include +#include + +#define TICKS2USECS(x) (x) + +/* MilliSecond Timer - Chapter 21 Page 202 */ + +#define MSTIM_INT IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0)) +#define MSTIM_CTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4)) +#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8)) +#define MSTIM_MCTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14)) +#define MSTIM_MATCH0 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18)) +#define MSTIM_MATCH1 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c)) + +/* High Speed Timer - Chpater 22, Page 205 */ + +#define HSTIM_INT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0)) +#define HSTIM_CTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4)) +#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8)) +#define HSTIM_PMATCH IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC)) +#define HSTIM_PCOUNT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10)) +#define HSTIM_MCTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14)) +#define HSTIM_MATCH0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18)) +#define HSTIM_MATCH1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c)) +#define HSTIM_MATCH2 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20)) +#define HSTIM_CCR IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28)) +#define HSTIM_CR0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C)) +#define HSTIM_CR1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30)) + +/* IMPORTANT: both timers are UPCOUNTING */ + +/* xSTIM_MCTRL bit definitions */ +#define MR0_INT 1 +#define RESET_COUNT0 (1<<1) +#define STOP_COUNT0 (1<<2) +#define MR1_INT (1<<3) +#define RESET_COUNT1 (1<<4) +#define STOP_COUNT1 (1<<5) +#define MR2_INT (1<<6) +#define RESET_COUNT2 (1<<7) +#define STOP_COUNT2 (1<<8) + +/* xSTIM_CTRL bit definitions */ +#define COUNT_ENAB 1 +#define RESET_COUNT (1<<1) +#define DEBUG_EN (1<<2) + +/* xSTIM_INT bit definitions */ +#define MATCH0_INT 1 +#define MATCH1_INT (1<<1) +#define MATCH2_INT (1<<2) +#define RTC_TICK0 (1<<4) +#define RTC_TICK1 (1<<5) + +#endif -- cgit v1.2.3 From 44c5d739181886cff8e3903dfa38cd704f3d9640 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:10:54 +0000 Subject: ARM: PNX4008: kzalloc i2c drivers internal data Signed-off-by: Russell King --- arch/arm/mach-pnx4008/i2c.c | 25 +++++++------------------ drivers/i2c/busses/i2c-pnx.c | 29 +++++++++++++++++++---------- include/linux/i2c-pnx.h | 4 ++-- 3 files changed, 28 insertions(+), 30 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index 23ec335a4bc0..33146e832dd7 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c @@ -18,45 +18,34 @@ #include #include -static struct i2c_pnx_algo_data pnx_algo_data0 = { - .base = PNX4008_I2C1_BASE, - .irq = I2C_1_INT, -}; - -static struct i2c_pnx_algo_data pnx_algo_data1 = { - .base = PNX4008_I2C2_BASE, - .irq = I2C_2_INT, -}; - -static struct i2c_pnx_algo_data pnx_algo_data2 = { - .base = (PNX4008_USB_CONFIG_BASE + 0x300), - .irq = USB_I2C_INT, -}; - static struct i2c_adapter pnx_adapter0 = { .name = I2C_CHIP_NAME "0", - .algo_data = &pnx_algo_data0, }; + static struct i2c_adapter pnx_adapter1 = { .name = I2C_CHIP_NAME "1", - .algo_data = &pnx_algo_data1, }; static struct i2c_adapter pnx_adapter2 = { .name = "USB-I2C", - .algo_data = &pnx_algo_data2, }; static struct i2c_pnx_data i2c0_data = { .adapter = &pnx_adapter0, + .base = PNX4008_I2C1_BASE, + .irq = I2C_1_INT, }; static struct i2c_pnx_data i2c1_data = { .adapter = &pnx_adapter1, + .base = PNX4008_I2C2_BASE, + .irq = I2C_2_INT, }; static struct i2c_pnx_data i2c2_data = { .adapter = &pnx_adapter2, + .base = (PNX4008_USB_CONFIG_BASE + 0x300), + .irq = USB_I2C_INT, }; static struct platform_device i2c0_device = { diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 882579e64111..1d66856a22fd 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -587,10 +587,16 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out; } + alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); + if (!alg_data) { + ret = -ENOMEM; + goto err_kzalloc; + } + platform_set_drvdata(pdev, i2c_pnx); i2c_pnx->adapter->algo = &pnx_algorithm; - alg_data = i2c_pnx->adapter->algo_data; + i2c_pnx->adapter->algo_data = alg_data; alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { @@ -603,16 +609,16 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; /* Register I/O resource */ - if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE, + if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, pdev->name)) { dev_err(&pdev->dev, "I/O region 0x%08x for I2C already in use.\n", - alg_data->base); + i2c_pnx->base); ret = -ENODEV; goto out_clkget; } - alg_data->ioaddr = ioremap(alg_data->base, I2C_PNX_REGION_SIZE); + alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); if (!alg_data->ioaddr) { dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); ret = -ENOMEM; @@ -647,7 +653,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) } init_completion(&alg_data->mif.complete); - ret = request_irq(alg_data->irq, i2c_pnx_interrupt, + ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, 0, pdev->name, i2c_pnx->adapter); if (ret) goto out_clock; @@ -662,21 +668,23 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) } dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", - i2c_pnx->adapter->name, alg_data->base, alg_data->irq); + i2c_pnx->adapter->name, i2c_pnx->base, i2c_pnx->irq); return 0; out_irq: - free_irq(alg_data->irq, i2c_pnx->adapter); + free_irq(i2c_pnx->irq, i2c_pnx->adapter); out_clock: clk_disable(alg_data->clk); out_unmap: iounmap(alg_data->ioaddr); out_release: - release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); + release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); out_clkget: clk_put(alg_data->clk); out_drvdata: + kfree(alg_data); +err_kzalloc: platform_set_drvdata(pdev, NULL); out: return ret; @@ -688,12 +696,13 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) struct i2c_adapter *adap = i2c_pnx->adapter; struct i2c_pnx_algo_data *alg_data = adap->algo_data; - free_irq(alg_data->irq, i2c_pnx->adapter); + free_irq(i2c_pnx->irq, i2c_pnx->adapter); i2c_del_adapter(adap); clk_disable(alg_data->clk); iounmap(alg_data->ioaddr); - release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); + release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); clk_put(alg_data->clk); + kfree(alg_data); platform_set_drvdata(pdev, NULL); return 0; diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 5a48f33046fb..9ebdf882d032 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h @@ -25,9 +25,7 @@ struct i2c_pnx_mif { }; struct i2c_pnx_algo_data { - u32 base; void __iomem *ioaddr; - int irq; struct i2c_pnx_mif mif; int last; struct clk *clk; @@ -35,6 +33,8 @@ struct i2c_pnx_algo_data { struct i2c_pnx_data { struct i2c_adapter *adapter; + u32 base; + int irq; }; #endif /* __I2C_PNX_H__ */ -- cgit v1.2.3 From 9d7f73632c87ef1b6187eb539d1efd63c3cf0e36 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:25:27 +0000 Subject: ARM: PNX4008: move i2c_adapter structure inside the drivers private data Signed-off-by: Russell King --- arch/arm/mach-pnx4008/i2c.c | 18 +++--------------- drivers/i2c/busses/i2c-pnx.c | 40 ++++++++++++++++++++-------------------- include/linux/i2c-pnx.h | 4 +++- 3 files changed, 26 insertions(+), 36 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c index 33146e832dd7..8103f9644e2d 100644 --- a/arch/arm/mach-pnx4008/i2c.c +++ b/arch/arm/mach-pnx4008/i2c.c @@ -18,32 +18,20 @@ #include #include -static struct i2c_adapter pnx_adapter0 = { - .name = I2C_CHIP_NAME "0", -}; - -static struct i2c_adapter pnx_adapter1 = { - .name = I2C_CHIP_NAME "1", -}; - -static struct i2c_adapter pnx_adapter2 = { - .name = "USB-I2C", -}; - static struct i2c_pnx_data i2c0_data = { - .adapter = &pnx_adapter0, + .name = I2C_CHIP_NAME "0", .base = PNX4008_I2C1_BASE, .irq = I2C_1_INT, }; static struct i2c_pnx_data i2c1_data = { - .adapter = &pnx_adapter1, + .name = I2C_CHIP_NAME "1", .base = PNX4008_I2C2_BASE, .irq = I2C_2_INT, }; static struct i2c_pnx_data i2c2_data = { - .adapter = &pnx_adapter2, + .name = "USB-I2C", .base = (PNX4008_USB_CONFIG_BASE + 0x300), .irq = USB_I2C_INT, }; diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 1d66856a22fd..6b413c5300d3 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -551,8 +551,7 @@ static struct i2c_algorithm pnx_algorithm = { static int i2c_pnx_controller_suspend(struct platform_device *pdev, pm_message_t state) { - struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); /* FIXME: shouldn't this be clk_disable? */ clk_enable(alg_data->clk); @@ -562,8 +561,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, static int i2c_pnx_controller_resume(struct platform_device *pdev) { - struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); return clk_enable(alg_data->clk); } @@ -580,7 +578,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) unsigned long freq; struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; - if (!i2c_pnx || !i2c_pnx->adapter) { + if (!i2c_pnx || !i2c_pnx->name) { dev_err(&pdev->dev, "%s: no platform data supplied\n", __func__); ret = -EINVAL; @@ -593,10 +591,15 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto err_kzalloc; } - platform_set_drvdata(pdev, i2c_pnx); + platform_set_drvdata(pdev, alg_data); - i2c_pnx->adapter->algo = &pnx_algorithm; - i2c_pnx->adapter->algo_data = alg_data; + strlcpy(alg_data->adapter.name, i2c_pnx->name, + sizeof(alg_data->adapter.name)); + alg_data->adapter.dev.parent = &pdev->dev; + alg_data->adapter.algo = &pnx_algorithm; + alg_data->adapter.algo_data = alg_data; + alg_data->adapter.nr = pdev->id; + alg_data->i2c_pnx = i2c_pnx; alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { @@ -606,7 +609,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; - alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; + alg_data->mif.timer.data = (unsigned long)&alg_data->adapter; /* Register I/O resource */ if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, @@ -654,26 +657,24 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) init_completion(&alg_data->mif.complete); ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, - 0, pdev->name, i2c_pnx->adapter); + 0, pdev->name, &alg_data->adapter); if (ret) goto out_clock; /* Register this adapter with the I2C subsystem */ - i2c_pnx->adapter->dev.parent = &pdev->dev; - i2c_pnx->adapter->nr = pdev->id; - ret = i2c_add_numbered_adapter(i2c_pnx->adapter); + ret = i2c_add_numbered_adapter(&alg_data->adapter); if (ret < 0) { dev_err(&pdev->dev, "I2C: Failed to add bus\n"); goto out_irq; } dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", - i2c_pnx->adapter->name, i2c_pnx->base, i2c_pnx->irq); + alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq); return 0; out_irq: - free_irq(i2c_pnx->irq, i2c_pnx->adapter); + free_irq(i2c_pnx->irq, &alg_data->adapter); out_clock: clk_disable(alg_data->clk); out_unmap: @@ -692,12 +693,11 @@ out: static int __devexit i2c_pnx_remove(struct platform_device *pdev) { - struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - struct i2c_adapter *adap = i2c_pnx->adapter; - struct i2c_pnx_algo_data *alg_data = adap->algo_data; + struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); + struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx; - free_irq(i2c_pnx->irq, i2c_pnx->adapter); - i2c_del_adapter(adap); + free_irq(i2c_pnx->irq, &alg_data->adapter); + i2c_del_adapter(&alg_data->adapter); clk_disable(alg_data->clk); iounmap(alg_data->ioaddr); release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 9ebdf882d032..a87124d4d533 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h @@ -29,10 +29,12 @@ struct i2c_pnx_algo_data { struct i2c_pnx_mif mif; int last; struct clk *clk; + struct i2c_pnx_data *i2c_pnx; + struct i2c_adapter adapter; }; struct i2c_pnx_data { - struct i2c_adapter *adapter; + const char *name; u32 base; int irq; }; -- cgit v1.2.3