From bf46aaeacf728dad9d89ed3d604bf991035dfd77 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Sun, 15 Apr 2012 21:13:29 -0700 Subject: ARM: SAMSUNG: move clock part for common s5p into plat-samsung Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 4953d50..8315210 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -12,7 +12,6 @@ obj- := # Core files -obj-y += clock.o obj-y += irq.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c deleted file mode 100644 index f68a9bb..0000000 --- a/arch/arm/plat-s5p/clock.c +++ /dev/null @@ -1,264 +0,0 @@ -/* linux/arch/arm/plat-s5p/clock.c - * - * Copyright 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P - Common clock support - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call - * clk_ext_xtal_mux. -*/ -struct clk clk_ext_xtal_mux = { - .name = "ext_xtal", - .id = -1, -}; - -struct clk clk_xusbxti = { - .name = "xusbxti", - .id = -1, -}; - -struct clk s5p_clk_27m = { - .name = "clk_27m", - .id = -1, - .rate = 27000000, -}; - -/* 48MHz USB Phy clock output */ -struct clk clk_48m = { - .name = "clk_48m", - .id = -1, - .rate = 48000000, -}; - -/* APLL clock output - * No need .ctrlbit, this is always on -*/ -struct clk clk_fout_apll = { - .name = "fout_apll", - .id = -1, -}; - -/* BPLL clock output */ - -struct clk clk_fout_bpll = { - .name = "fout_bpll", - .id = -1, -}; - -/* CPLL clock output */ - -struct clk clk_fout_cpll = { - .name = "fout_cpll", - .id = -1, -}; - -/* MPLL clock output - * No need .ctrlbit, this is always on -*/ -struct clk clk_fout_mpll = { - .name = "fout_mpll", - .id = -1, -}; - -/* EPLL clock output */ -struct clk clk_fout_epll = { - .name = "fout_epll", - .id = -1, - .ctrlbit = (1 << 31), -}; - -/* DPLL clock output */ -struct clk clk_fout_dpll = { - .name = "fout_dpll", - .id = -1, - .ctrlbit = (1 << 31), -}; - -/* VPLL clock output */ -struct clk clk_fout_vpll = { - .name = "fout_vpll", - .id = -1, - .ctrlbit = (1 << 31), -}; - -/* Possible clock sources for APLL Mux */ -static struct clk *clk_src_apll_list[] = { - [0] = &clk_fin_apll, - [1] = &clk_fout_apll, -}; - -struct clksrc_sources clk_src_apll = { - .sources = clk_src_apll_list, - .nr_sources = ARRAY_SIZE(clk_src_apll_list), -}; - -/* Possible clock sources for BPLL Mux */ -static struct clk *clk_src_bpll_list[] = { - [0] = &clk_fin_bpll, - [1] = &clk_fout_bpll, -}; - -struct clksrc_sources clk_src_bpll = { - .sources = clk_src_bpll_list, - .nr_sources = ARRAY_SIZE(clk_src_bpll_list), -}; - -/* Possible clock sources for CPLL Mux */ -static struct clk *clk_src_cpll_list[] = { - [0] = &clk_fin_cpll, - [1] = &clk_fout_cpll, -}; - -struct clksrc_sources clk_src_cpll = { - .sources = clk_src_cpll_list, - .nr_sources = ARRAY_SIZE(clk_src_cpll_list), -}; - -/* Possible clock sources for MPLL Mux */ -static struct clk *clk_src_mpll_list[] = { - [0] = &clk_fin_mpll, - [1] = &clk_fout_mpll, -}; - -struct clksrc_sources clk_src_mpll = { - .sources = clk_src_mpll_list, - .nr_sources = ARRAY_SIZE(clk_src_mpll_list), -}; - -/* Possible clock sources for EPLL Mux */ -static struct clk *clk_src_epll_list[] = { - [0] = &clk_fin_epll, - [1] = &clk_fout_epll, -}; - -struct clksrc_sources clk_src_epll = { - .sources = clk_src_epll_list, - .nr_sources = ARRAY_SIZE(clk_src_epll_list), -}; - -/* Possible clock sources for DPLL Mux */ -static struct clk *clk_src_dpll_list[] = { - [0] = &clk_fin_dpll, - [1] = &clk_fout_dpll, -}; - -struct clksrc_sources clk_src_dpll = { - .sources = clk_src_dpll_list, - .nr_sources = ARRAY_SIZE(clk_src_dpll_list), -}; - -struct clk clk_vpll = { - .name = "vpll", - .id = -1, -}; - -int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - u32 con; - - con = __raw_readl(reg); - con = enable ? (con | ctrlbit) : (con & ~ctrlbit); - __raw_writel(con, reg); - return 0; -} - -int s5p_epll_enable(struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; - - if (enable) - __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); - else - __raw_writel(epll_con, S5P_EPLL_CON); - - return 0; -} - -unsigned long s5p_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - -int s5p_spdif_set_rate(struct clk *clk, unsigned long rate) -{ - struct clk *pclk; - int ret; - - pclk = clk_get_parent(clk); - if (IS_ERR(pclk)) - return -EINVAL; - - ret = pclk->ops->set_rate(pclk, rate); - clk_put(pclk); - - return ret; -} - -unsigned long s5p_spdif_get_rate(struct clk *clk) -{ - struct clk *pclk; - int rate; - - pclk = clk_get_parent(clk); - if (IS_ERR(pclk)) - return -EINVAL; - - rate = pclk->ops->get_rate(pclk); - clk_put(pclk); - - return rate; -} - -struct clk_ops s5p_sclk_spdif_ops = { - .set_rate = s5p_spdif_set_rate, - .get_rate = s5p_spdif_get_rate, -}; - -static struct clk *s5p_clks[] __initdata = { - &clk_ext_xtal_mux, - &clk_48m, - &s5p_clk_27m, - &clk_fout_apll, - &clk_fout_mpll, - &clk_fout_epll, - &clk_fout_dpll, - &clk_fout_vpll, - &clk_vpll, - &clk_xusbxti, -}; - -void __init s5p_register_clocks(unsigned long xtal_freq) -{ - int ret; - - clk_ext_xtal_mux.rate = xtal_freq; - - ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks)); - if (ret > 0) - printk(KERN_ERR "Failed to register s5p clocks\n"); -} diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 71553f4..3a48d9d 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -58,6 +58,11 @@ config SAMSUNG_CLKSRC Select the clock code for the clksrc implementation used by newer systems such as the S3C64XX. +config S5P_CLOCK + def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) + help + Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs + # options for IRQ support config SAMSUNG_IRQ_VIC_TIMER diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 6012366..997ce10 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -17,6 +17,7 @@ obj-y += clock.o obj-y += pwm-clock.o obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o +obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o diff --git a/arch/arm/plat-samsung/s5p-clock.c b/arch/arm/plat-samsung/s5p-clock.c new file mode 100644 index 0000000..41d3dfd --- /dev/null +++ b/arch/arm/plat-samsung/s5p-clock.c @@ -0,0 +1,263 @@ +/* + * Copyright 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Common clock support + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call + * clk_ext_xtal_mux. +*/ +struct clk clk_ext_xtal_mux = { + .name = "ext_xtal", + .id = -1, +}; + +struct clk clk_xusbxti = { + .name = "xusbxti", + .id = -1, +}; + +struct clk s5p_clk_27m = { + .name = "clk_27m", + .id = -1, + .rate = 27000000, +}; + +/* 48MHz USB Phy clock output */ +struct clk clk_48m = { + .name = "clk_48m", + .id = -1, + .rate = 48000000, +}; + +/* APLL clock output + * No need .ctrlbit, this is always on +*/ +struct clk clk_fout_apll = { + .name = "fout_apll", + .id = -1, +}; + +/* BPLL clock output */ + +struct clk clk_fout_bpll = { + .name = "fout_bpll", + .id = -1, +}; + +/* CPLL clock output */ + +struct clk clk_fout_cpll = { + .name = "fout_cpll", + .id = -1, +}; + +/* MPLL clock output + * No need .ctrlbit, this is always on +*/ +struct clk clk_fout_mpll = { + .name = "fout_mpll", + .id = -1, +}; + +/* EPLL clock output */ +struct clk clk_fout_epll = { + .name = "fout_epll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* DPLL clock output */ +struct clk clk_fout_dpll = { + .name = "fout_dpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* VPLL clock output */ +struct clk clk_fout_vpll = { + .name = "fout_vpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* Possible clock sources for APLL Mux */ +static struct clk *clk_src_apll_list[] = { + [0] = &clk_fin_apll, + [1] = &clk_fout_apll, +}; + +struct clksrc_sources clk_src_apll = { + .sources = clk_src_apll_list, + .nr_sources = ARRAY_SIZE(clk_src_apll_list), +}; + +/* Possible clock sources for BPLL Mux */ +static struct clk *clk_src_bpll_list[] = { + [0] = &clk_fin_bpll, + [1] = &clk_fout_bpll, +}; + +struct clksrc_sources clk_src_bpll = { + .sources = clk_src_bpll_list, + .nr_sources = ARRAY_SIZE(clk_src_bpll_list), +}; + +/* Possible clock sources for CPLL Mux */ +static struct clk *clk_src_cpll_list[] = { + [0] = &clk_fin_cpll, + [1] = &clk_fout_cpll, +}; + +struct clksrc_sources clk_src_cpll = { + .sources = clk_src_cpll_list, + .nr_sources = ARRAY_SIZE(clk_src_cpll_list), +}; + +/* Possible clock sources for MPLL Mux */ +static struct clk *clk_src_mpll_list[] = { + [0] = &clk_fin_mpll, + [1] = &clk_fout_mpll, +}; + +struct clksrc_sources clk_src_mpll = { + .sources = clk_src_mpll_list, + .nr_sources = ARRAY_SIZE(clk_src_mpll_list), +}; + +/* Possible clock sources for EPLL Mux */ +static struct clk *clk_src_epll_list[] = { + [0] = &clk_fin_epll, + [1] = &clk_fout_epll, +}; + +struct clksrc_sources clk_src_epll = { + .sources = clk_src_epll_list, + .nr_sources = ARRAY_SIZE(clk_src_epll_list), +}; + +/* Possible clock sources for DPLL Mux */ +static struct clk *clk_src_dpll_list[] = { + [0] = &clk_fin_dpll, + [1] = &clk_fout_dpll, +}; + +struct clksrc_sources clk_src_dpll = { + .sources = clk_src_dpll_list, + .nr_sources = ARRAY_SIZE(clk_src_dpll_list), +}; + +struct clk clk_vpll = { + .name = "vpll", + .id = -1, +}; + +int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + u32 con; + + con = __raw_readl(reg); + con = enable ? (con | ctrlbit) : (con & ~ctrlbit); + __raw_writel(con, reg); + return 0; +} + +int s5p_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); + else + __raw_writel(epll_con, S5P_EPLL_CON); + + return 0; +} + +unsigned long s5p_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +int s5p_spdif_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *pclk; + int ret; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + ret = pclk->ops->set_rate(pclk, rate); + clk_put(pclk); + + return ret; +} + +unsigned long s5p_spdif_get_rate(struct clk *clk) +{ + struct clk *pclk; + int rate; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + rate = pclk->ops->get_rate(pclk); + clk_put(pclk); + + return rate; +} + +struct clk_ops s5p_sclk_spdif_ops = { + .set_rate = s5p_spdif_set_rate, + .get_rate = s5p_spdif_get_rate, +}; + +static struct clk *s5p_clks[] __initdata = { + &clk_ext_xtal_mux, + &clk_48m, + &s5p_clk_27m, + &clk_fout_apll, + &clk_fout_mpll, + &clk_fout_epll, + &clk_fout_dpll, + &clk_fout_vpll, + &clk_vpll, + &clk_xusbxti, +}; + +void __init s5p_register_clocks(unsigned long xtal_freq) +{ + int ret; + + clk_ext_xtal_mux.rate = xtal_freq; + + ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks)); + if (ret > 0) + printk(KERN_ERR "Failed to register s5p clocks\n"); +} -- cgit v0.10.2 From 68ae89984710d2e9f3cf2005539c8f91bcce9d40 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Sun, 15 Apr 2012 21:40:33 -0700 Subject: ARM: SAMSUNG: move interrupt part for common s5p into plat-samsung Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 2c1193c..efff0a3 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -23,17 +23,6 @@ config PLAT_S5P help Base platform code for Samsung's S5P series SoC. -config S5P_EXT_INT - bool - help - Use the external interrupts (other than GPIO interrupts.) - Note: Do not choose this for S5P6440 and S5P6450. - -config S5P_GPIO_INT - bool - help - Common code for the GPIO interrupts (other than external interrupts.) - config S5P_HRT bool select SAMSUNG_DEV_PWM diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 8315210..8701c3c 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -12,9 +12,6 @@ obj- := # Core files -obj-y += irq.o -obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o -obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o obj-$(CONFIG_S5P_SLEEP) += sleep.o obj-$(CONFIG_S5P_HRT) += s5p-time.o diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c deleted file mode 100644 index 139c050..0000000 --- a/arch/arm/plat-s5p/irq-eint.c +++ /dev/null @@ -1,219 +0,0 @@ -/* linux/arch/arm/plat-s5p/irq-eint.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * S5P - IRQ EINT support - * - * 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 -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include -#include - -static inline void s5p_irq_eint_mask(struct irq_data *data) -{ - u32 mask; - - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask |= eint_irq_to_bit(data->irq); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); -} - -static void s5p_irq_eint_unmask(struct irq_data *data) -{ - u32 mask; - - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask &= ~(eint_irq_to_bit(data->irq)); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); -} - -static inline void s5p_irq_eint_ack(struct irq_data *data) -{ - __raw_writel(eint_irq_to_bit(data->irq), - S5P_EINT_PEND(EINT_REG_NR(data->irq))); -} - -static void s5p_irq_eint_maskack(struct irq_data *data) -{ - /* compiler should in-line these */ - s5p_irq_eint_mask(data); - s5p_irq_eint_ack(data); -} - -static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) -{ - int offs = EINT_OFFSET(data->irq); - int shift; - u32 ctrl, mask; - u32 newvalue = 0; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - newvalue = S5P_IRQ_TYPE_EDGE_RISING; - break; - - case IRQ_TYPE_EDGE_FALLING: - newvalue = S5P_IRQ_TYPE_EDGE_FALLING; - break; - - case IRQ_TYPE_EDGE_BOTH: - newvalue = S5P_IRQ_TYPE_EDGE_BOTH; - break; - - case IRQ_TYPE_LEVEL_LOW: - newvalue = S5P_IRQ_TYPE_LEVEL_LOW; - break; - - case IRQ_TYPE_LEVEL_HIGH: - newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; - break; - - default: - printk(KERN_ERR "No such irq type %d", type); - return -EINVAL; - } - - shift = (offs & 0x7) * 4; - mask = 0x7 << shift; - - ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); - ctrl &= ~mask; - ctrl |= newvalue << shift; - __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); - - if ((0 <= offs) && (offs < 8)) - s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); - - else if ((8 <= offs) && (offs < 16)) - s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); - - else if ((16 <= offs) && (offs < 24)) - s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); - - else if ((24 <= offs) && (offs < 32)) - s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); - - else - printk(KERN_ERR "No such irq number %d", offs); - - return 0; -} - -static struct irq_chip s5p_irq_eint = { - .name = "s5p-eint", - .irq_mask = s5p_irq_eint_mask, - .irq_unmask = s5p_irq_eint_unmask, - .irq_mask_ack = s5p_irq_eint_maskack, - .irq_ack = s5p_irq_eint_ack, - .irq_set_type = s5p_irq_eint_set_type, -#ifdef CONFIG_PM - .irq_set_wake = s3c_irqext_wake, -#endif -}; - -/* s5p_irq_demux_eint - * - * This function demuxes the IRQ from the group0 external interrupts, - * from EINTs 16 to 31. It is designed to be inlined into the specific - * handler s5p_irq_demux_eintX_Y. - * - * Each EINT pend/mask registers handle eight of them. - */ -static inline void s5p_irq_demux_eint(unsigned int start) -{ - u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); - u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); - unsigned int irq; - - status &= ~mask; - status &= 0xff; - - while (status) { - irq = fls(status) - 1; - generic_handle_irq(irq + start); - status &= ~(1 << irq); - } -} - -static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) -{ - s5p_irq_demux_eint(IRQ_EINT(16)); - s5p_irq_demux_eint(IRQ_EINT(24)); -} - -static inline void s5p_irq_vic_eint_mask(struct irq_data *data) -{ - void __iomem *base = irq_data_get_irq_chip_data(data); - - s5p_irq_eint_mask(data); - writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR); -} - -static void s5p_irq_vic_eint_unmask(struct irq_data *data) -{ - void __iomem *base = irq_data_get_irq_chip_data(data); - - s5p_irq_eint_unmask(data); - writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE); -} - -static inline void s5p_irq_vic_eint_ack(struct irq_data *data) -{ - __raw_writel(eint_irq_to_bit(data->irq), - S5P_EINT_PEND(EINT_REG_NR(data->irq))); -} - -static void s5p_irq_vic_eint_maskack(struct irq_data *data) -{ - s5p_irq_vic_eint_mask(data); - s5p_irq_vic_eint_ack(data); -} - -static struct irq_chip s5p_irq_vic_eint = { - .name = "s5p_vic_eint", - .irq_mask = s5p_irq_vic_eint_mask, - .irq_unmask = s5p_irq_vic_eint_unmask, - .irq_mask_ack = s5p_irq_vic_eint_maskack, - .irq_ack = s5p_irq_vic_eint_ack, - .irq_set_type = s5p_irq_eint_set_type, -#ifdef CONFIG_PM - .irq_set_wake = s3c_irqext_wake, -#endif -}; - -static int __init s5p_init_irq_eint(void) -{ - int irq; - - for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) - irq_set_chip(irq, &s5p_irq_vic_eint); - - for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { - irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - - irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); - return 0; -} - -arch_initcall(s5p_init_irq_eint); diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c deleted file mode 100644 index 82c7311..0000000 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ /dev/null @@ -1,216 +0,0 @@ -/* linux/arch/arm/plat-s5p/irq-gpioint.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * Author: Kyungmin Park - * Author: Joonyoung Shim - * Author: Marek Szyprowski - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) - -#define CON_OFFSET 0x700 -#define MASK_OFFSET 0x900 -#define PEND_OFFSET 0xA00 -#define REG_OFFSET(x) ((x) << 2) - -struct s5p_gpioint_bank { - struct list_head list; - int start; - int nr_groups; - int irq; - struct samsung_gpio_chip **chips; - void (*handler)(unsigned int, struct irq_desc *); -}; - -static LIST_HEAD(banks); - -static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct irq_chip_type *ct = gc->chip_types; - unsigned int shift = (d->irq - gc->irq_base) << 2; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - type = S5P_IRQ_TYPE_EDGE_RISING; - break; - case IRQ_TYPE_EDGE_FALLING: - type = S5P_IRQ_TYPE_EDGE_FALLING; - break; - case IRQ_TYPE_EDGE_BOTH: - type = S5P_IRQ_TYPE_EDGE_BOTH; - break; - case IRQ_TYPE_LEVEL_HIGH: - type = S5P_IRQ_TYPE_LEVEL_HIGH; - break; - case IRQ_TYPE_LEVEL_LOW: - type = S5P_IRQ_TYPE_LEVEL_LOW; - break; - case IRQ_TYPE_NONE: - default: - printk(KERN_WARNING "No irq type\n"); - return -EINVAL; - } - - gc->type_cache &= ~(0x7 << shift); - gc->type_cache |= type << shift; - writel(gc->type_cache, gc->reg_base + ct->regs.type); - return 0; -} - -static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) -{ - struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); - int group, pend_offset, mask_offset; - unsigned int pend, mask; - - struct irq_chip *chip = irq_get_chip(irq); - chained_irq_enter(chip, desc); - - for (group = 0; group < bank->nr_groups; group++) { - struct samsung_gpio_chip *chip = bank->chips[group]; - if (!chip) - continue; - - pend_offset = REG_OFFSET(group); - pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); - if (!pend) - continue; - - mask_offset = REG_OFFSET(group); - mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); - pend &= ~mask; - - while (pend) { - int offset = fls(pend) - 1; - int real_irq = chip->irq_base + offset; - generic_handle_irq(real_irq); - pend &= ~BIT(offset); - } - } - chained_irq_exit(chip, desc); -} - -static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip) -{ - static int used_gpioint_groups = 0; - int group = chip->group; - struct s5p_gpioint_bank *b, *bank = NULL; - struct irq_chip_generic *gc; - struct irq_chip_type *ct; - - if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) - return -ENOMEM; - - list_for_each_entry(b, &banks, list) { - if (group >= b->start && group < b->start + b->nr_groups) { - bank = b; - break; - } - } - if (!bank) - return -EINVAL; - - if (!bank->handler) { - bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) * - bank->nr_groups, GFP_KERNEL); - if (!bank->chips) - return -ENOMEM; - - irq_set_chained_handler(bank->irq, s5p_gpioint_handler); - irq_set_handler_data(bank->irq, bank); - bank->handler = s5p_gpioint_handler; - printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", - bank->irq); - } - - /* - * chained GPIO irq has been successfully registered, allocate new gpio - * int group and assign irq nubmers - */ - chip->irq_base = S5P_GPIOINT_BASE + - used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; - used_gpioint_groups++; - - bank->chips[group - bank->start] = chip; - - gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, - (void __iomem *)GPIO_BASE(chip), - handle_level_irq); - if (!gc) - return -ENOMEM; - ct = gc->chip_types; - ct->chip.irq_ack = irq_gc_ack_set_bit; - ct->chip.irq_mask = irq_gc_mask_set_bit; - ct->chip.irq_unmask = irq_gc_mask_clr_bit; - ct->chip.irq_set_type = s5p_gpioint_set_type, - ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start); - ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start); - ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start); - irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), - IRQ_GC_INIT_MASK_CACHE, - IRQ_NOREQUEST | IRQ_NOPROBE, 0); - return 0; -} - -int __init s5p_register_gpio_interrupt(int pin) -{ - struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin); - int offset, group; - int ret; - - if (!my_chip) - return -EINVAL; - - offset = pin - my_chip->chip.base; - group = my_chip->group; - - /* check if the group has been already registered */ - if (my_chip->irq_base) - return my_chip->irq_base + offset; - - /* register gpio group */ - ret = s5p_gpioint_add(my_chip); - if (ret == 0) { - my_chip->chip.to_irq = samsung_gpiolib_to_irq; - printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", - group); - return my_chip->irq_base + offset; - } - return ret; -} - -int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) -{ - struct s5p_gpioint_bank *bank; - - bank = kzalloc(sizeof(*bank), GFP_KERNEL); - if (!bank) - return -ENOMEM; - - bank->start = start; - bank->nr_groups = nr_groups; - bank->irq = chain_irq; - - list_add_tail(&bank->list, &banks); - return 0; -} diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c deleted file mode 100644 index afdaa10..0000000 --- a/arch/arm/plat-s5p/irq.c +++ /dev/null @@ -1,36 +0,0 @@ -/* arch/arm/plat-s5p/irq.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P - Interrupt handling - * - * 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 -#include -#include -#include - -#include - -#include -#include -#include -#include - -void __init s5p_init_irq(u32 *vic, u32 num_vic) -{ -#ifdef CONFIG_ARM_VIC - int irq; - - /* initialize the VICs */ - for (irq = 0; irq < num_vic; irq++) - vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); -#endif - - s3c_init_vic_timer_irq(5, IRQ_TIMER0); -} diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 3a48d9d..e09dd4f 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -70,6 +70,22 @@ config SAMSUNG_IRQ_VIC_TIMER help Internal configuration to build the VIC timer interrupt code. +config S5P_IRQ + def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) + help + Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs + +config S5P_EXT_INT + bool + help + Use the external interrupts (other than GPIO interrupts.) + Note: Do not choose this for S5P6440 and S5P6450. + +config S5P_GPIO_INT + bool + help + Common code for the GPIO interrupts (other than external interrupts.) + # options for gpio configuration support config SAMSUNG_GPIOLIB_4BIT diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 997ce10..5b65009 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -20,6 +20,9 @@ obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o +obj-$(CONFIG_S5P_IRQ) += s5p-irq.o +obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o +obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o # ADC diff --git a/arch/arm/plat-samsung/s5p-irq-eint.c b/arch/arm/plat-samsung/s5p-irq-eint.c new file mode 100644 index 0000000..33bd3f3 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-eint.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P - IRQ EINT support + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include + +static inline void s5p_irq_eint_mask(struct irq_data *data) +{ + u32 mask; + + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask |= eint_irq_to_bit(data->irq); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); +} + +static void s5p_irq_eint_unmask(struct irq_data *data) +{ + u32 mask; + + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask &= ~(eint_irq_to_bit(data->irq)); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); +} + +static inline void s5p_irq_eint_ack(struct irq_data *data) +{ + __raw_writel(eint_irq_to_bit(data->irq), + S5P_EINT_PEND(EINT_REG_NR(data->irq))); +} + +static void s5p_irq_eint_maskack(struct irq_data *data) +{ + /* compiler should in-line these */ + s5p_irq_eint_mask(data); + s5p_irq_eint_ack(data); +} + +static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) +{ + int offs = EINT_OFFSET(data->irq); + int shift; + u32 ctrl, mask; + u32 newvalue = 0; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + newvalue = S5P_IRQ_TYPE_EDGE_RISING; + break; + + case IRQ_TYPE_EDGE_FALLING: + newvalue = S5P_IRQ_TYPE_EDGE_FALLING; + break; + + case IRQ_TYPE_EDGE_BOTH: + newvalue = S5P_IRQ_TYPE_EDGE_BOTH; + break; + + case IRQ_TYPE_LEVEL_LOW: + newvalue = S5P_IRQ_TYPE_LEVEL_LOW; + break; + + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; + break; + + default: + printk(KERN_ERR "No such irq type %d", type); + return -EINVAL; + } + + shift = (offs & 0x7) * 4; + mask = 0x7 << shift; + + ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); + ctrl &= ~mask; + ctrl |= newvalue << shift; + __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); + + if ((0 <= offs) && (offs < 8)) + s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); + + else if ((8 <= offs) && (offs < 16)) + s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); + + else if ((16 <= offs) && (offs < 24)) + s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); + + else if ((24 <= offs) && (offs < 32)) + s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); + + else + printk(KERN_ERR "No such irq number %d", offs); + + return 0; +} + +static struct irq_chip s5p_irq_eint = { + .name = "s5p-eint", + .irq_mask = s5p_irq_eint_mask, + .irq_unmask = s5p_irq_eint_unmask, + .irq_mask_ack = s5p_irq_eint_maskack, + .irq_ack = s5p_irq_eint_ack, + .irq_set_type = s5p_irq_eint_set_type, +#ifdef CONFIG_PM + .irq_set_wake = s3c_irqext_wake, +#endif +}; + +/* s5p_irq_demux_eint + * + * This function demuxes the IRQ from the group0 external interrupts, + * from EINTs 16 to 31. It is designed to be inlined into the specific + * handler s5p_irq_demux_eintX_Y. + * + * Each EINT pend/mask registers handle eight of them. + */ +static inline void s5p_irq_demux_eint(unsigned int start) +{ + u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); + u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); + unsigned int irq; + + status &= ~mask; + status &= 0xff; + + while (status) { + irq = fls(status) - 1; + generic_handle_irq(irq + start); + status &= ~(1 << irq); + } +} + +static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) +{ + s5p_irq_demux_eint(IRQ_EINT(16)); + s5p_irq_demux_eint(IRQ_EINT(24)); +} + +static inline void s5p_irq_vic_eint_mask(struct irq_data *data) +{ + void __iomem *base = irq_data_get_irq_chip_data(data); + + s5p_irq_eint_mask(data); + writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR); +} + +static void s5p_irq_vic_eint_unmask(struct irq_data *data) +{ + void __iomem *base = irq_data_get_irq_chip_data(data); + + s5p_irq_eint_unmask(data); + writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE); +} + +static inline void s5p_irq_vic_eint_ack(struct irq_data *data) +{ + __raw_writel(eint_irq_to_bit(data->irq), + S5P_EINT_PEND(EINT_REG_NR(data->irq))); +} + +static void s5p_irq_vic_eint_maskack(struct irq_data *data) +{ + s5p_irq_vic_eint_mask(data); + s5p_irq_vic_eint_ack(data); +} + +static struct irq_chip s5p_irq_vic_eint = { + .name = "s5p_vic_eint", + .irq_mask = s5p_irq_vic_eint_mask, + .irq_unmask = s5p_irq_vic_eint_unmask, + .irq_mask_ack = s5p_irq_vic_eint_maskack, + .irq_ack = s5p_irq_vic_eint_ack, + .irq_set_type = s5p_irq_eint_set_type, +#ifdef CONFIG_PM + .irq_set_wake = s3c_irqext_wake, +#endif +}; + +static int __init s5p_init_irq_eint(void) +{ + int irq; + + for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) + irq_set_chip(irq, &s5p_irq_vic_eint); + + for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { + irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + + irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); + return 0; +} + +arch_initcall(s5p_init_irq_eint); diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c new file mode 100644 index 0000000..f9431fe --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * Author: Kyungmin Park + * Author: Joonyoung Shim + * Author: Marek Szyprowski + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) + +#define CON_OFFSET 0x700 +#define MASK_OFFSET 0x900 +#define PEND_OFFSET 0xA00 +#define REG_OFFSET(x) ((x) << 2) + +struct s5p_gpioint_bank { + struct list_head list; + int start; + int nr_groups; + int irq; + struct samsung_gpio_chip **chips; + void (*handler)(unsigned int, struct irq_desc *); +}; + +static LIST_HEAD(banks); + +static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct irq_chip_type *ct = gc->chip_types; + unsigned int shift = (d->irq - gc->irq_base) << 2; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + type = S5P_IRQ_TYPE_EDGE_RISING; + break; + case IRQ_TYPE_EDGE_FALLING: + type = S5P_IRQ_TYPE_EDGE_FALLING; + break; + case IRQ_TYPE_EDGE_BOTH: + type = S5P_IRQ_TYPE_EDGE_BOTH; + break; + case IRQ_TYPE_LEVEL_HIGH: + type = S5P_IRQ_TYPE_LEVEL_HIGH; + break; + case IRQ_TYPE_LEVEL_LOW: + type = S5P_IRQ_TYPE_LEVEL_LOW; + break; + case IRQ_TYPE_NONE: + default: + printk(KERN_WARNING "No irq type\n"); + return -EINVAL; + } + + gc->type_cache &= ~(0x7 << shift); + gc->type_cache |= type << shift; + writel(gc->type_cache, gc->reg_base + ct->regs.type); + return 0; +} + +static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) +{ + struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); + int group, pend_offset, mask_offset; + unsigned int pend, mask; + + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); + + for (group = 0; group < bank->nr_groups; group++) { + struct samsung_gpio_chip *chip = bank->chips[group]; + if (!chip) + continue; + + pend_offset = REG_OFFSET(group); + pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); + if (!pend) + continue; + + mask_offset = REG_OFFSET(group); + mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); + pend &= ~mask; + + while (pend) { + int offset = fls(pend) - 1; + int real_irq = chip->irq_base + offset; + generic_handle_irq(real_irq); + pend &= ~BIT(offset); + } + } + chained_irq_exit(chip, desc); +} + +static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip) +{ + static int used_gpioint_groups = 0; + int group = chip->group; + struct s5p_gpioint_bank *b, *bank = NULL; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) + return -ENOMEM; + + list_for_each_entry(b, &banks, list) { + if (group >= b->start && group < b->start + b->nr_groups) { + bank = b; + break; + } + } + if (!bank) + return -EINVAL; + + if (!bank->handler) { + bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) * + bank->nr_groups, GFP_KERNEL); + if (!bank->chips) + return -ENOMEM; + + irq_set_chained_handler(bank->irq, s5p_gpioint_handler); + irq_set_handler_data(bank->irq, bank); + bank->handler = s5p_gpioint_handler; + printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", + bank->irq); + } + + /* + * chained GPIO irq has been successfully registered, allocate new gpio + * int group and assign irq nubmers + */ + chip->irq_base = S5P_GPIOINT_BASE + + used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; + used_gpioint_groups++; + + bank->chips[group - bank->start] = chip; + + gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, + (void __iomem *)GPIO_BASE(chip), + handle_level_irq); + if (!gc) + return -ENOMEM; + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + ct->chip.irq_set_type = s5p_gpioint_set_type, + ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start); + ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start); + ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start); + irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); + return 0; +} + +int __init s5p_register_gpio_interrupt(int pin) +{ + struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin); + int offset, group; + int ret; + + if (!my_chip) + return -EINVAL; + + offset = pin - my_chip->chip.base; + group = my_chip->group; + + /* check if the group has been already registered */ + if (my_chip->irq_base) + return my_chip->irq_base + offset; + + /* register gpio group */ + ret = s5p_gpioint_add(my_chip); + if (ret == 0) { + my_chip->chip.to_irq = samsung_gpiolib_to_irq; + printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", + group); + return my_chip->irq_base + offset; + } + return ret; +} + +int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) +{ + struct s5p_gpioint_bank *bank; + + bank = kzalloc(sizeof(*bank), GFP_KERNEL); + if (!bank) + return -ENOMEM; + + bank->start = start; + bank->nr_groups = nr_groups; + bank->irq = chain_irq; + + list_add_tail(&bank->list, &banks); + return 0; +} diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c new file mode 100644 index 0000000..dfb47d6 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Interrupt handling + * + * 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 +#include +#include +#include + +#include + +#include +#include +#include +#include + +void __init s5p_init_irq(u32 *vic, u32 num_vic) +{ +#ifdef CONFIG_ARM_VIC + int irq; + + /* initialize the VICs */ + for (irq = 0; irq < num_vic; irq++) + vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); +#endif + + s3c_init_vic_timer_irq(5, IRQ_TIMER0); +} -- cgit v0.10.2 From 8eadcf74ec8285800f7f6a36a8f283932a69d17f Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Sun, 15 Apr 2012 21:57:38 -0700 Subject: ARM: SAMSUNG: move pm part for common s5p into plat-samsung Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index efff0a3..8e45c8b 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -33,18 +33,6 @@ config S5P_DEV_UART def_bool y depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) -config S5P_PM - bool - help - Common code for power management support on S5P and newer SoCs - Note: Do not select this for S5P6440 and S5P6450. - -config S5P_SLEEP - bool - help - Internal config node to apply common S5P sleep management code. - Can be selected by S5P and newer SoCs with similar sleep procedure. - config S5P_DEV_FIMC0 bool help diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 8701c3c..c81106f 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -12,8 +12,6 @@ obj- := # Core files -obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o -obj-$(CONFIG_S5P_SLEEP) += sleep.o obj-$(CONFIG_S5P_HRT) += s5p-time.o # devices diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c deleted file mode 100644 index d1bfeca..0000000 --- a/arch/arm/plat-s5p/irq-pm.c +++ /dev/null @@ -1,103 +0,0 @@ -/* linux/arch/arm/plat-s5p/irq-pm.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Based on arch/arm/plat-s3c24xx/irq-pm.c, - * Copyright (c) 2003,2004 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * 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 -#include -#include - -#include -#include -#include -#include - -#include -#include - -/* state for IRQs over sleep */ - -/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM, - * as wakeup sources - * - * set bit to 1 in allow bitfield to enable the wakeup settings on it -*/ - -unsigned long s3c_irqwake_intallow = 0x00000006L; -unsigned long s3c_irqwake_eintallow = 0xffffffffL; - -int s3c_irq_wake(struct irq_data *data, unsigned int state) -{ - unsigned long irqbit; - unsigned int irq_rtc_tic, irq_rtc_alarm; - -#ifdef CONFIG_ARCH_EXYNOS - if (soc_is_exynos5250()) { - irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC; - irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM; - } else { - irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC; - irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM; - } -#else - irq_rtc_tic = IRQ_RTC_TIC; - irq_rtc_alarm = IRQ_RTC_ALARM; -#endif - - if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) { - irqbit = 1 << (data->irq + 1 - irq_rtc_alarm); - - if (!state) - s3c_irqwake_intmask |= irqbit; - else - s3c_irqwake_intmask &= ~irqbit; - } else { - return -ENOENT; - } - - return 0; -} - -static struct sleep_save eint_save[] = { - SAVE_ITEM(S5P_EINT_CON(0)), - SAVE_ITEM(S5P_EINT_CON(1)), - SAVE_ITEM(S5P_EINT_CON(2)), - SAVE_ITEM(S5P_EINT_CON(3)), - - SAVE_ITEM(S5P_EINT_FLTCON(0)), - SAVE_ITEM(S5P_EINT_FLTCON(1)), - SAVE_ITEM(S5P_EINT_FLTCON(2)), - SAVE_ITEM(S5P_EINT_FLTCON(3)), - SAVE_ITEM(S5P_EINT_FLTCON(4)), - SAVE_ITEM(S5P_EINT_FLTCON(5)), - SAVE_ITEM(S5P_EINT_FLTCON(6)), - SAVE_ITEM(S5P_EINT_FLTCON(7)), - - SAVE_ITEM(S5P_EINT_MASK(0)), - SAVE_ITEM(S5P_EINT_MASK(1)), - SAVE_ITEM(S5P_EINT_MASK(2)), - SAVE_ITEM(S5P_EINT_MASK(3)), -}; - -int s3c24xx_irq_suspend(void) -{ - s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save)); - - return 0; -} - -void s3c24xx_irq_resume(void) -{ - s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save)); -} - diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c deleted file mode 100644 index d15dc47..0000000 --- a/arch/arm/plat-s5p/pm.c +++ /dev/null @@ -1,41 +0,0 @@ -/* linux/arch/arm/plat-s5p/pm.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * S5P Power Manager (Suspend-To-RAM) support - * - * Based on arch/arm/plat-s3c24xx/pm.c - * Copyright (c) 2004,2006 Simtec Electronics - * Ben Dooks - * - * 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 -#include - -#define PFX "s5p pm: " - -/* s3c_pm_configure_extint - * - * configure all external interrupt pins -*/ - -void s3c_pm_configure_extint(void) -{ - /* nothing here yet */ -} - -void s3c_pm_restore_core(void) -{ - /* nothing here yet */ -} - -void s3c_pm_save_core(void) -{ - /* nothing here yet */ -} - diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S deleted file mode 100644 index 006bd01..0000000 --- a/arch/arm/plat-s5p/sleep.S +++ /dev/null @@ -1,81 +0,0 @@ -/* linux/arch/arm/plat-s5p/sleep.S - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Common S5P Sleep Code - * Based on S3C64XX sleep code by: - * Ben Dooks, (c) 2008 Simtec Electronics - * - * 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 -*/ - -#include -#include -#include - -/* - * The following code is located into the .data section. This is to - * allow l2x0_regs_phys to be accessed with a relative load while we - * can't rely on any MMU translation. We could have put l2x0_regs_phys - * in the .text section as well, but some setups might insist on it to - * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) - */ - .data - .align - - /* - * sleep magic, to allow the bootloader to check for an valid - * image to resume to. Must be the first word before the - * s3c_cpu_resume entry. - */ - - .word 0x2bedf00d - - /* - * s3c_cpu_resume - * - * resume code entry for bootloader to call - */ - -ENTRY(s3c_cpu_resume) -#ifdef CONFIG_CACHE_L2X0 - adr r0, l2x0_regs_phys - ldr r0, [r0] - ldr r1, [r0, #L2X0_R_PHY_BASE] - ldr r2, [r1, #L2X0_CTRL] - tst r2, #0x1 - bne resume_l2on - ldr r2, [r0, #L2X0_R_AUX_CTRL] - str r2, [r1, #L2X0_AUX_CTRL] - ldr r2, [r0, #L2X0_R_TAG_LATENCY] - str r2, [r1, #L2X0_TAG_LATENCY_CTRL] - ldr r2, [r0, #L2X0_R_DATA_LATENCY] - str r2, [r1, #L2X0_DATA_LATENCY_CTRL] - ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] - str r2, [r1, #L2X0_PREFETCH_CTRL] - ldr r2, [r0, #L2X0_R_PWR_CTRL] - str r2, [r1, #L2X0_POWER_CTRL] - mov r2, #1 - str r2, [r1, #L2X0_CTRL] -resume_l2on: -#endif - b cpu_resume -ENDPROC(s3c_cpu_resume) -#ifdef CONFIG_CACHE_L2X0 - .globl l2x0_regs_phys -l2x0_regs_phys: - .long 0 -#endif diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index e09dd4f..2184623 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -371,6 +371,18 @@ config SAMSUNG_WAKEMASK and above. This code allows a set of interrupt to wakeup-mask mappings. See +config S5P_PM + bool + help + Common code for power management support on S5P and newer SoCs + Note: Do not select this for S5P6440 and S5P6450. + +config S5P_SLEEP + bool + help + Internal config node to apply common S5P sleep management code. + Can be selected by S5P and newer SoCs with similar sleep procedure. + comment "Power Domain" config SAMSUNG_PD diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 5b65009..caa6f9a 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -51,6 +51,9 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o +obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o +obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o + # PD support obj-$(CONFIG_SAMSUNG_PD) += pd.o diff --git a/arch/arm/plat-samsung/s5p-irq-pm.c b/arch/arm/plat-samsung/s5p-irq-pm.c new file mode 100644 index 0000000..7c1e3b7 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-pm.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on arch/arm/plat-s3c24xx/irq-pm.c, + * Copyright (c) 2003,2004 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * 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 +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* state for IRQs over sleep */ + +/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM, + * as wakeup sources + * + * set bit to 1 in allow bitfield to enable the wakeup settings on it +*/ + +unsigned long s3c_irqwake_intallow = 0x00000006L; +unsigned long s3c_irqwake_eintallow = 0xffffffffL; + +int s3c_irq_wake(struct irq_data *data, unsigned int state) +{ + unsigned long irqbit; + unsigned int irq_rtc_tic, irq_rtc_alarm; + +#ifdef CONFIG_ARCH_EXYNOS + if (soc_is_exynos5250()) { + irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC; + irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM; + } else { + irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC; + irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM; + } +#else + irq_rtc_tic = IRQ_RTC_TIC; + irq_rtc_alarm = IRQ_RTC_ALARM; +#endif + + if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) { + irqbit = 1 << (data->irq + 1 - irq_rtc_alarm); + + if (!state) + s3c_irqwake_intmask |= irqbit; + else + s3c_irqwake_intmask &= ~irqbit; + } else { + return -ENOENT; + } + + return 0; +} + +static struct sleep_save eint_save[] = { + SAVE_ITEM(S5P_EINT_CON(0)), + SAVE_ITEM(S5P_EINT_CON(1)), + SAVE_ITEM(S5P_EINT_CON(2)), + SAVE_ITEM(S5P_EINT_CON(3)), + + SAVE_ITEM(S5P_EINT_FLTCON(0)), + SAVE_ITEM(S5P_EINT_FLTCON(1)), + SAVE_ITEM(S5P_EINT_FLTCON(2)), + SAVE_ITEM(S5P_EINT_FLTCON(3)), + SAVE_ITEM(S5P_EINT_FLTCON(4)), + SAVE_ITEM(S5P_EINT_FLTCON(5)), + SAVE_ITEM(S5P_EINT_FLTCON(6)), + SAVE_ITEM(S5P_EINT_FLTCON(7)), + + SAVE_ITEM(S5P_EINT_MASK(0)), + SAVE_ITEM(S5P_EINT_MASK(1)), + SAVE_ITEM(S5P_EINT_MASK(2)), + SAVE_ITEM(S5P_EINT_MASK(3)), +}; + +int s3c24xx_irq_suspend(void) +{ + s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save)); + + return 0; +} + +void s3c24xx_irq_resume(void) +{ + s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save)); +} + diff --git a/arch/arm/plat-samsung/s5p-pm.c b/arch/arm/plat-samsung/s5p-pm.c new file mode 100644 index 0000000..0747468 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-pm.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P Power Manager (Suspend-To-RAM) support + * + * Based on arch/arm/plat-s3c24xx/pm.c + * Copyright (c) 2004,2006 Simtec Electronics + * Ben Dooks + * + * 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 +#include + +#define PFX "s5p pm: " + +/* s3c_pm_configure_extint + * + * configure all external interrupt pins +*/ + +void s3c_pm_configure_extint(void) +{ + /* nothing here yet */ +} + +void s3c_pm_restore_core(void) +{ + /* nothing here yet */ +} + +void s3c_pm_save_core(void) +{ + /* nothing here yet */ +} + diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S new file mode 100644 index 0000000..bdf6dad --- /dev/null +++ b/arch/arm/plat-samsung/s5p-sleep.S @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Common S5P Sleep Code + * Based on S3C64XX sleep code by: + * Ben Dooks, (c) 2008 Simtec Electronics + * + * 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 +*/ + +#include +#include +#include + +/* + * The following code is located into the .data section. This is to + * allow l2x0_regs_phys to be accessed with a relative load while we + * can't rely on any MMU translation. We could have put l2x0_regs_phys + * in the .text section as well, but some setups might insist on it to + * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) + */ + .data + .align + + /* + * sleep magic, to allow the bootloader to check for an valid + * image to resume to. Must be the first word before the + * s3c_cpu_resume entry. + */ + + .word 0x2bedf00d + + /* + * s3c_cpu_resume + * + * resume code entry for bootloader to call + */ + +ENTRY(s3c_cpu_resume) +#ifdef CONFIG_CACHE_L2X0 + adr r0, l2x0_regs_phys + ldr r0, [r0] + ldr r1, [r0, #L2X0_R_PHY_BASE] + ldr r2, [r1, #L2X0_CTRL] + tst r2, #0x1 + bne resume_l2on + ldr r2, [r0, #L2X0_R_AUX_CTRL] + str r2, [r1, #L2X0_AUX_CTRL] + ldr r2, [r0, #L2X0_R_TAG_LATENCY] + str r2, [r1, #L2X0_TAG_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_DATA_LATENCY] + str r2, [r1, #L2X0_DATA_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] + str r2, [r1, #L2X0_PREFETCH_CTRL] + ldr r2, [r0, #L2X0_R_PWR_CTRL] + str r2, [r1, #L2X0_POWER_CTRL] + mov r2, #1 + str r2, [r1, #L2X0_CTRL] +resume_l2on: +#endif + b cpu_resume +ENDPROC(s3c_cpu_resume) +#ifdef CONFIG_CACHE_L2X0 + .globl l2x0_regs_phys +l2x0_regs_phys: + .long 0 +#endif -- cgit v0.10.2 From 33bf33278fa608428c46d4fab58ae5bc3e3acfde Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 17 Apr 2012 11:20:49 -0700 Subject: ARM: SAMSUNG: move hr timer for common s5p into plat-samsung Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 8e45c8b..795790d 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -23,12 +23,6 @@ config PLAT_S5P help Base platform code for Samsung's S5P series SoC. -config S5P_HRT - bool - select SAMSUNG_DEV_PWM - help - Use the High Resolution timer support - config S5P_DEV_UART def_bool y depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index c81106f..0a2ce38 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -10,10 +10,6 @@ obj-m := obj-n := dummy.o obj- := -# Core files - -obj-$(CONFIG_S5P_HRT) += s5p-time.o - # devices obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c deleted file mode 100644 index 17c0a2c..0000000 --- a/arch/arm/plat-s5p/s5p-time.c +++ /dev/null @@ -1,406 +0,0 @@ -/* linux/arch/arm/plat-s5p/s5p-time.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P - Common hr-timer support - * - * 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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static struct clk *tin_event; -static struct clk *tin_source; -static struct clk *tdiv_event; -static struct clk *tdiv_source; -static struct clk *timerclk; -static struct s5p_timer_source timer_source; -static unsigned long clock_count_per_tick; -static void s5p_timer_resume(void); - -static void s5p_time_stop(enum s5p_timer_mode mode) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - switch (mode) { - case S5P_PWM0: - tcon &= ~S3C2410_TCON_T0START; - break; - - case S5P_PWM1: - tcon &= ~S3C2410_TCON_T1START; - break; - - case S5P_PWM2: - tcon &= ~S3C2410_TCON_T2START; - break; - - case S5P_PWM3: - tcon &= ~S3C2410_TCON_T3START; - break; - - case S5P_PWM4: - tcon &= ~S3C2410_TCON_T4START; - break; - - default: - printk(KERN_ERR "Invalid Timer %d\n", mode); - break; - } - __raw_writel(tcon, S3C2410_TCON); -} - -static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - tcnt--; - - switch (mode) { - case S5P_PWM0: - tcon &= ~(0x0f << 0); - tcon |= S3C2410_TCON_T0MANUALUPD; - break; - - case S5P_PWM1: - tcon &= ~(0x0f << 8); - tcon |= S3C2410_TCON_T1MANUALUPD; - break; - - case S5P_PWM2: - tcon &= ~(0x0f << 12); - tcon |= S3C2410_TCON_T2MANUALUPD; - break; - - case S5P_PWM3: - tcon &= ~(0x0f << 16); - tcon |= S3C2410_TCON_T3MANUALUPD; - break; - - case S5P_PWM4: - tcon &= ~(0x07 << 20); - tcon |= S3C2410_TCON_T4MANUALUPD; - break; - - default: - printk(KERN_ERR "Invalid Timer %d\n", mode); - break; - } - - __raw_writel(tcnt, S3C2410_TCNTB(mode)); - __raw_writel(tcnt, S3C2410_TCMPB(mode)); - __raw_writel(tcon, S3C2410_TCON); -} - -static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - switch (mode) { - case S5P_PWM0: - tcon |= S3C2410_TCON_T0START; - tcon &= ~S3C2410_TCON_T0MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T0RELOAD; - else - tcon &= ~S3C2410_TCON_T0RELOAD; - break; - - case S5P_PWM1: - tcon |= S3C2410_TCON_T1START; - tcon &= ~S3C2410_TCON_T1MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T1RELOAD; - else - tcon &= ~S3C2410_TCON_T1RELOAD; - break; - - case S5P_PWM2: - tcon |= S3C2410_TCON_T2START; - tcon &= ~S3C2410_TCON_T2MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T2RELOAD; - else - tcon &= ~S3C2410_TCON_T2RELOAD; - break; - - case S5P_PWM3: - tcon |= S3C2410_TCON_T3START; - tcon &= ~S3C2410_TCON_T3MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T3RELOAD; - else - tcon &= ~S3C2410_TCON_T3RELOAD; - break; - - case S5P_PWM4: - tcon |= S3C2410_TCON_T4START; - tcon &= ~S3C2410_TCON_T4MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T4RELOAD; - else - tcon &= ~S3C2410_TCON_T4RELOAD; - break; - - default: - printk(KERN_ERR "Invalid Timer %d\n", mode); - break; - } - __raw_writel(tcon, S3C2410_TCON); -} - -static int s5p_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - s5p_time_setup(timer_source.event_id, cycles); - s5p_time_start(timer_source.event_id, NON_PERIODIC); - - return 0; -} - -static void s5p_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - s5p_time_stop(timer_source.event_id); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - s5p_time_setup(timer_source.event_id, clock_count_per_tick); - s5p_time_start(timer_source.event_id, PERIODIC); - break; - - case CLOCK_EVT_MODE_ONESHOT: - break; - - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - break; - - case CLOCK_EVT_MODE_RESUME: - s5p_timer_resume(); - break; - } -} - -static void s5p_timer_resume(void) -{ - /* event timer restart */ - s5p_time_setup(timer_source.event_id, clock_count_per_tick); - s5p_time_start(timer_source.event_id, PERIODIC); - - /* source timer restart */ - s5p_time_setup(timer_source.source_id, TCNT_MAX); - s5p_time_start(timer_source.source_id, PERIODIC); -} - -void __init s5p_set_timer_source(enum s5p_timer_mode event, - enum s5p_timer_mode source) -{ - s3c_device_timer[event].dev.bus = &platform_bus_type; - s3c_device_timer[source].dev.bus = &platform_bus_type; - - timer_source.event_id = event; - timer_source.source_id = source; -} - -static struct clock_event_device time_event_device = { - .name = "s5p_event_timer", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .rating = 200, - .set_next_event = s5p_set_next_event, - .set_mode = s5p_set_mode, -}; - -static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) -{ - struct clock_event_device *evt = dev_id; - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction s5p_clock_event_irq = { - .name = "s5p_time_irq", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = s5p_clock_event_isr, - .dev_id = &time_event_device, -}; - -static void __init s5p_clockevent_init(void) -{ - unsigned long pclk; - unsigned long clock_rate; - unsigned int irq_number; - struct clk *tscaler; - - pclk = clk_get_rate(timerclk); - - tscaler = clk_get_parent(tdiv_event); - - clk_set_rate(tscaler, pclk / 2); - clk_set_rate(tdiv_event, pclk / 2); - clk_set_parent(tin_event, tdiv_event); - - clock_rate = clk_get_rate(tin_event); - clock_count_per_tick = clock_rate / HZ; - - clockevents_calc_mult_shift(&time_event_device, - clock_rate, S5PTIMER_MIN_RANGE); - time_event_device.max_delta_ns = - clockevent_delta2ns(-1, &time_event_device); - time_event_device.min_delta_ns = - clockevent_delta2ns(1, &time_event_device); - - time_event_device.cpumask = cpumask_of(0); - clockevents_register_device(&time_event_device); - - irq_number = timer_source.event_id + IRQ_TIMER0; - setup_irq(irq_number, &s5p_clock_event_irq); -} - -static void __iomem *s5p_timer_reg(void) -{ - unsigned long offset = 0; - - switch (timer_source.source_id) { - case S5P_PWM0: - case S5P_PWM1: - case S5P_PWM2: - case S5P_PWM3: - offset = (timer_source.source_id * 0x0c) + 0x14; - break; - - case S5P_PWM4: - offset = 0x40; - break; - - default: - printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id); - return NULL; - } - - return S3C_TIMERREG(offset); -} - -/* - * Override the global weak sched_clock symbol with this - * local implementation which uses the clocksource to get some - * better resolution when scheduling the kernel. We accept that - * this wraps around for now, since it is just a relative time - * stamp. (Inspired by U300 implementation.) - */ -static u32 notrace s5p_read_sched_clock(void) -{ - void __iomem *reg = s5p_timer_reg(); - - if (!reg) - return 0; - - return ~__raw_readl(reg); -} - -static void __init s5p_clocksource_init(void) -{ - unsigned long pclk; - unsigned long clock_rate; - - pclk = clk_get_rate(timerclk); - - clk_set_rate(tdiv_source, pclk / 2); - clk_set_parent(tin_source, tdiv_source); - - clock_rate = clk_get_rate(tin_source); - - s5p_time_setup(timer_source.source_id, TCNT_MAX); - s5p_time_start(timer_source.source_id, PERIODIC); - - setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); - - if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", - clock_rate, 250, 32, clocksource_mmio_readl_down)) - panic("s5p_clocksource_timer: can't register clocksource\n"); -} - -static void __init s5p_timer_resources(void) -{ - - unsigned long event_id = timer_source.event_id; - unsigned long source_id = timer_source.source_id; - char devname[15]; - - timerclk = clk_get(NULL, "timers"); - if (IS_ERR(timerclk)) - panic("failed to get timers clock for timer"); - - clk_enable(timerclk); - - sprintf(devname, "s3c24xx-pwm.%lu", event_id); - s3c_device_timer[event_id].id = event_id; - s3c_device_timer[event_id].dev.init_name = devname; - - tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin"); - if (IS_ERR(tin_event)) - panic("failed to get pwm-tin clock for event timer"); - - tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv"); - if (IS_ERR(tdiv_event)) - panic("failed to get pwm-tdiv clock for event timer"); - - clk_enable(tin_event); - - sprintf(devname, "s3c24xx-pwm.%lu", source_id); - s3c_device_timer[source_id].id = source_id; - s3c_device_timer[source_id].dev.init_name = devname; - - tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin"); - if (IS_ERR(tin_source)) - panic("failed to get pwm-tin clock for source timer"); - - tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv"); - if (IS_ERR(tdiv_source)) - panic("failed to get pwm-tdiv clock for source timer"); - - clk_enable(tin_source); -} - -static void __init s5p_timer_init(void) -{ - s5p_timer_resources(); - s5p_clockevent_init(); - s5p_clocksource_init(); -} - -struct sys_timer s5p_timer = { - .init = s5p_timer_init, -}; diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 2184623..1922413 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -50,6 +50,14 @@ config S3C_LOWLEVEL_UART_PORT this configuration should be between zero and two. The port must have been initialised by the boot-loader before use. +# timer options + +config S5P_HRT + bool + select SAMSUNG_DEV_PWM + help + Use the High Resolution timer support + # clock options config SAMSUNG_CLKSRC diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index caa6f9a..6217c41 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -13,6 +13,8 @@ obj- := obj-y += init.o cpu.o obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o +obj-$(CONFIG_S5P_HRT) += s5p-time.o + obj-y += clock.o obj-y += pwm-clock.o diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/s5p-time.c new file mode 100644 index 0000000..028b6e8 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-time.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Common hr-timer support + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct clk *tin_event; +static struct clk *tin_source; +static struct clk *tdiv_event; +static struct clk *tdiv_source; +static struct clk *timerclk; +static struct s5p_timer_source timer_source; +static unsigned long clock_count_per_tick; +static void s5p_timer_resume(void); + +static void s5p_time_stop(enum s5p_timer_mode mode) +{ + unsigned long tcon; + + tcon = __raw_readl(S3C2410_TCON); + + switch (mode) { + case S5P_PWM0: + tcon &= ~S3C2410_TCON_T0START; + break; + + case S5P_PWM1: + tcon &= ~S3C2410_TCON_T1START; + break; + + case S5P_PWM2: + tcon &= ~S3C2410_TCON_T2START; + break; + + case S5P_PWM3: + tcon &= ~S3C2410_TCON_T3START; + break; + + case S5P_PWM4: + tcon &= ~S3C2410_TCON_T4START; + break; + + default: + printk(KERN_ERR "Invalid Timer %d\n", mode); + break; + } + __raw_writel(tcon, S3C2410_TCON); +} + +static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) +{ + unsigned long tcon; + + tcon = __raw_readl(S3C2410_TCON); + + tcnt--; + + switch (mode) { + case S5P_PWM0: + tcon &= ~(0x0f << 0); + tcon |= S3C2410_TCON_T0MANUALUPD; + break; + + case S5P_PWM1: + tcon &= ~(0x0f << 8); + tcon |= S3C2410_TCON_T1MANUALUPD; + break; + + case S5P_PWM2: + tcon &= ~(0x0f << 12); + tcon |= S3C2410_TCON_T2MANUALUPD; + break; + + case S5P_PWM3: + tcon &= ~(0x0f << 16); + tcon |= S3C2410_TCON_T3MANUALUPD; + break; + + case S5P_PWM4: + tcon &= ~(0x07 << 20); + tcon |= S3C2410_TCON_T4MANUALUPD; + break; + + default: + printk(KERN_ERR "Invalid Timer %d\n", mode); + break; + } + + __raw_writel(tcnt, S3C2410_TCNTB(mode)); + __raw_writel(tcnt, S3C2410_TCMPB(mode)); + __raw_writel(tcon, S3C2410_TCON); +} + +static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) +{ + unsigned long tcon; + + tcon = __raw_readl(S3C2410_TCON); + + switch (mode) { + case S5P_PWM0: + tcon |= S3C2410_TCON_T0START; + tcon &= ~S3C2410_TCON_T0MANUALUPD; + + if (periodic) + tcon |= S3C2410_TCON_T0RELOAD; + else + tcon &= ~S3C2410_TCON_T0RELOAD; + break; + + case S5P_PWM1: + tcon |= S3C2410_TCON_T1START; + tcon &= ~S3C2410_TCON_T1MANUALUPD; + + if (periodic) + tcon |= S3C2410_TCON_T1RELOAD; + else + tcon &= ~S3C2410_TCON_T1RELOAD; + break; + + case S5P_PWM2: + tcon |= S3C2410_TCON_T2START; + tcon &= ~S3C2410_TCON_T2MANUALUPD; + + if (periodic) + tcon |= S3C2410_TCON_T2RELOAD; + else + tcon &= ~S3C2410_TCON_T2RELOAD; + break; + + case S5P_PWM3: + tcon |= S3C2410_TCON_T3START; + tcon &= ~S3C2410_TCON_T3MANUALUPD; + + if (periodic) + tcon |= S3C2410_TCON_T3RELOAD; + else + tcon &= ~S3C2410_TCON_T3RELOAD; + break; + + case S5P_PWM4: + tcon |= S3C2410_TCON_T4START; + tcon &= ~S3C2410_TCON_T4MANUALUPD; + + if (periodic) + tcon |= S3C2410_TCON_T4RELOAD; + else + tcon &= ~S3C2410_TCON_T4RELOAD; + break; + + default: + printk(KERN_ERR "Invalid Timer %d\n", mode); + break; + } + __raw_writel(tcon, S3C2410_TCON); +} + +static int s5p_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + s5p_time_setup(timer_source.event_id, cycles); + s5p_time_start(timer_source.event_id, NON_PERIODIC); + + return 0; +} + +static void s5p_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + s5p_time_stop(timer_source.event_id); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + s5p_time_setup(timer_source.event_id, clock_count_per_tick); + s5p_time_start(timer_source.event_id, PERIODIC); + break; + + case CLOCK_EVT_MODE_ONESHOT: + break; + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + + case CLOCK_EVT_MODE_RESUME: + s5p_timer_resume(); + break; + } +} + +static void s5p_timer_resume(void) +{ + /* event timer restart */ + s5p_time_setup(timer_source.event_id, clock_count_per_tick); + s5p_time_start(timer_source.event_id, PERIODIC); + + /* source timer restart */ + s5p_time_setup(timer_source.source_id, TCNT_MAX); + s5p_time_start(timer_source.source_id, PERIODIC); +} + +void __init s5p_set_timer_source(enum s5p_timer_mode event, + enum s5p_timer_mode source) +{ + s3c_device_timer[event].dev.bus = &platform_bus_type; + s3c_device_timer[source].dev.bus = &platform_bus_type; + + timer_source.event_id = event; + timer_source.source_id = source; +} + +static struct clock_event_device time_event_device = { + .name = "s5p_event_timer", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .rating = 200, + .set_next_event = s5p_set_next_event, + .set_mode = s5p_set_mode, +}; + +static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction s5p_clock_event_irq = { + .name = "s5p_time_irq", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = s5p_clock_event_isr, + .dev_id = &time_event_device, +}; + +static void __init s5p_clockevent_init(void) +{ + unsigned long pclk; + unsigned long clock_rate; + unsigned int irq_number; + struct clk *tscaler; + + pclk = clk_get_rate(timerclk); + + tscaler = clk_get_parent(tdiv_event); + + clk_set_rate(tscaler, pclk / 2); + clk_set_rate(tdiv_event, pclk / 2); + clk_set_parent(tin_event, tdiv_event); + + clock_rate = clk_get_rate(tin_event); + clock_count_per_tick = clock_rate / HZ; + + clockevents_calc_mult_shift(&time_event_device, + clock_rate, S5PTIMER_MIN_RANGE); + time_event_device.max_delta_ns = + clockevent_delta2ns(-1, &time_event_device); + time_event_device.min_delta_ns = + clockevent_delta2ns(1, &time_event_device); + + time_event_device.cpumask = cpumask_of(0); + clockevents_register_device(&time_event_device); + + irq_number = timer_source.event_id + IRQ_TIMER0; + setup_irq(irq_number, &s5p_clock_event_irq); +} + +static void __iomem *s5p_timer_reg(void) +{ + unsigned long offset = 0; + + switch (timer_source.source_id) { + case S5P_PWM0: + case S5P_PWM1: + case S5P_PWM2: + case S5P_PWM3: + offset = (timer_source.source_id * 0x0c) + 0x14; + break; + + case S5P_PWM4: + offset = 0x40; + break; + + default: + printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id); + return NULL; + } + + return S3C_TIMERREG(offset); +} + +/* + * Override the global weak sched_clock symbol with this + * local implementation which uses the clocksource to get some + * better resolution when scheduling the kernel. We accept that + * this wraps around for now, since it is just a relative time + * stamp. (Inspired by U300 implementation.) + */ +static u32 notrace s5p_read_sched_clock(void) +{ + void __iomem *reg = s5p_timer_reg(); + + if (!reg) + return 0; + + return ~__raw_readl(reg); +} + +static void __init s5p_clocksource_init(void) +{ + unsigned long pclk; + unsigned long clock_rate; + + pclk = clk_get_rate(timerclk); + + clk_set_rate(tdiv_source, pclk / 2); + clk_set_parent(tin_source, tdiv_source); + + clock_rate = clk_get_rate(tin_source); + + s5p_time_setup(timer_source.source_id, TCNT_MAX); + s5p_time_start(timer_source.source_id, PERIODIC); + + setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); + + if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", + clock_rate, 250, 32, clocksource_mmio_readl_down)) + panic("s5p_clocksource_timer: can't register clocksource\n"); +} + +static void __init s5p_timer_resources(void) +{ + + unsigned long event_id = timer_source.event_id; + unsigned long source_id = timer_source.source_id; + char devname[15]; + + timerclk = clk_get(NULL, "timers"); + if (IS_ERR(timerclk)) + panic("failed to get timers clock for timer"); + + clk_enable(timerclk); + + sprintf(devname, "s3c24xx-pwm.%lu", event_id); + s3c_device_timer[event_id].id = event_id; + s3c_device_timer[event_id].dev.init_name = devname; + + tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin"); + if (IS_ERR(tin_event)) + panic("failed to get pwm-tin clock for event timer"); + + tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv"); + if (IS_ERR(tdiv_event)) + panic("failed to get pwm-tdiv clock for event timer"); + + clk_enable(tin_event); + + sprintf(devname, "s3c24xx-pwm.%lu", source_id); + s3c_device_timer[source_id].id = source_id; + s3c_device_timer[source_id].dev.init_name = devname; + + tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin"); + if (IS_ERR(tin_source)) + panic("failed to get pwm-tin clock for source timer"); + + tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv"); + if (IS_ERR(tdiv_source)) + panic("failed to get pwm-tdiv clock for source timer"); + + clk_enable(tin_source); +} + +static void __init s5p_timer_init(void) +{ + s5p_timer_resources(); + s5p_clockevent_init(); + s5p_clocksource_init(); +} + +struct sys_timer s5p_timer = { + .init = s5p_timer_init, +}; -- cgit v0.10.2 From cfe370f876407735041f8e02ec31ffa922cd8e45 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 17 Apr 2012 20:05:19 -0700 Subject: ARM: SAMSUNG: move platform device for s5p uart into plat-samsung Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 795790d..33d9bc8 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -23,10 +23,6 @@ config PLAT_S5P help Base platform code for Samsung's S5P series SoC. -config S5P_DEV_UART - def_bool y - depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) - config S5P_DEV_FIMC0 bool help diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 0a2ce38..1dc6b1c 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -12,6 +12,5 @@ obj- := # devices -obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c deleted file mode 100644 index c9308db..0000000 --- a/arch/arm/plat-s5p/dev-uart.c +++ /dev/null @@ -1,137 +0,0 @@ -/* linux/arch/arm/plat-s5p/dev-uart.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Base S5P UART resource and device definitions - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - /* Serial port registrations */ - -static struct resource s5p_uart0_resource[] = { - [0] = { - .start = S5P_PA_UART0, - .end = S5P_PA_UART0 + S5P_SZ_UART - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART0, - .end = IRQ_UART0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource s5p_uart1_resource[] = { - [0] = { - .start = S5P_PA_UART1, - .end = S5P_PA_UART1 + S5P_SZ_UART - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART1, - .end = IRQ_UART1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource s5p_uart2_resource[] = { - [0] = { - .start = S5P_PA_UART2, - .end = S5P_PA_UART2 + S5P_SZ_UART - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART2, - .end = IRQ_UART2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource s5p_uart3_resource[] = { -#if CONFIG_SERIAL_SAMSUNG_UARTS > 3 - [0] = { - .start = S5P_PA_UART3, - .end = S5P_PA_UART3 + S5P_SZ_UART - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART3, - .end = IRQ_UART3, - .flags = IORESOURCE_IRQ, - }, -#endif -}; - -static struct resource s5p_uart4_resource[] = { -#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 - [0] = { - .start = S5P_PA_UART4, - .end = S5P_PA_UART4 + S5P_SZ_UART - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART4, - .end = IRQ_UART4, - .flags = IORESOURCE_IRQ, - }, -#endif -}; - -static struct resource s5p_uart5_resource[] = { -#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 - [0] = { - .start = S5P_PA_UART5, - .end = S5P_PA_UART5 + S5P_SZ_UART - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART5, - .end = IRQ_UART5, - .flags = IORESOURCE_IRQ, - }, -#endif -}; - -struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { - [0] = { - .resources = s5p_uart0_resource, - .nr_resources = ARRAY_SIZE(s5p_uart0_resource), - }, - [1] = { - .resources = s5p_uart1_resource, - .nr_resources = ARRAY_SIZE(s5p_uart1_resource), - }, - [2] = { - .resources = s5p_uart2_resource, - .nr_resources = ARRAY_SIZE(s5p_uart2_resource), - }, - [3] = { - .resources = s5p_uart3_resource, - .nr_resources = ARRAY_SIZE(s5p_uart3_resource), - }, - [4] = { - .resources = s5p_uart4_resource, - .nr_resources = ARRAY_SIZE(s5p_uart4_resource), - }, - [5] = { - .resources = s5p_uart5_resource, - .nr_resources = ARRAY_SIZE(s5p_uart5_resource), - }, -}; diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 1922413..5ce6bc8 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -146,6 +146,12 @@ config S3C_GPIO_TRACK Internal configuration option to enable the s3c specific gpio chip tracking if the platform requires it. +# uart options + +config S5P_DEV_UART + def_bool y + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) + # ADC driver config S3C_ADC diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 6217c41..b20047b 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -36,6 +36,7 @@ obj-y += platformdata.o obj-y += devs.o obj-y += dev-uart.o +obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o diff --git a/arch/arm/plat-samsung/s5p-dev-uart.c b/arch/arm/plat-samsung/s5p-dev-uart.c new file mode 100644 index 0000000..cafa3de --- /dev/null +++ b/arch/arm/plat-samsung/s5p-dev-uart.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009,2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Base S5P UART resource and device definitions + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + /* Serial port registrations */ + +static struct resource s5p_uart0_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_UART0, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART0), +}; + +static struct resource s5p_uart1_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_UART1, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART1), +}; + +static struct resource s5p_uart2_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_UART2, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART2), +}; + +static struct resource s5p_uart3_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 3 + [0] = DEFINE_RES_MEM(S5P_PA_UART3, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART3), +#endif +}; + +static struct resource s5p_uart4_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 + [0] = DEFINE_RES_MEM(S5P_PA_UART4, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART4), +#endif +}; + +static struct resource s5p_uart5_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 + [0] = DEFINE_RES_MEM(S5P_PA_UART5, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART5), +#endif +}; + +struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { + [0] = { + .resources = s5p_uart0_resource, + .nr_resources = ARRAY_SIZE(s5p_uart0_resource), + }, + [1] = { + .resources = s5p_uart1_resource, + .nr_resources = ARRAY_SIZE(s5p_uart1_resource), + }, + [2] = { + .resources = s5p_uart2_resource, + .nr_resources = ARRAY_SIZE(s5p_uart2_resource), + }, + [3] = { + .resources = s5p_uart3_resource, + .nr_resources = ARRAY_SIZE(s5p_uart3_resource), + }, + [4] = { + .resources = s5p_uart4_resource, + .nr_resources = ARRAY_SIZE(s5p_uart4_resource), + }, + [5] = { + .resources = s5p_uart5_resource, + .nr_resources = ARRAY_SIZE(s5p_uart5_resource), + }, +}; -- cgit v0.10.2 From d9c452f4b4042baaa24fb91bf0c847813ff3645d Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 17 Apr 2012 20:21:30 -0700 Subject: ARM: SAMSUNG: move setup code for s5p mfc and mipiphy into plat-samsung Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 33d9bc8..4ff6d7e 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -63,11 +63,6 @@ config S5P_DEV_I2C_HDMIPHY help Compile in platform device definitions for I2C HDMIPHY controller -config S5P_DEV_MFC - bool - help - Compile in platform device definitions for MFC - config S5P_DEV_ONENAND bool help @@ -92,8 +87,3 @@ config S5P_DEV_USB_EHCI bool help Compile in platform device definition for USB EHCI - -config S5P_SETUP_MIPIPHY - bool - help - Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 1dc6b1c..884b9a1 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -9,8 +9,3 @@ obj-y := obj-m := obj-n := dummy.o obj- := - -# devices - -obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o -obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c deleted file mode 100644 index a30d36b..0000000 --- a/arch/arm/plat-s5p/dev-mfc.c +++ /dev/null @@ -1,73 +0,0 @@ -/* linux/arch/arm/plat-s5p/dev-mfc.c - * - * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd - * - * Base S5P MFC resource and device definitions - * - * 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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -struct s5p_mfc_reserved_mem { - phys_addr_t base; - unsigned long size; - struct device *dev; -}; - -static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata; - -void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, - phys_addr_t lbase, unsigned int lsize) -{ - int i; - - s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev; - s5p_mfc_mem[0].base = rbase; - s5p_mfc_mem[0].size = rsize; - - s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev; - s5p_mfc_mem[1].base = lbase; - s5p_mfc_mem[1].size = lsize; - - for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { - struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; - if (memblock_remove(area->base, area->size)) { - printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n", - area->size, (unsigned long) area->base); - area->base = 0; - } - } -} - -static int __init s5p_mfc_memory_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { - struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; - if (!area->base) - continue; - - if (dma_declare_coherent_memory(area->dev, area->base, - area->base, area->size, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) - printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n", - area->size, (unsigned long) area->base); - } - return 0; -} -device_initcall(s5p_mfc_memory_init); diff --git a/arch/arm/plat-s5p/setup-mipiphy.c b/arch/arm/plat-s5p/setup-mipiphy.c deleted file mode 100644 index 683c466..0000000 --- a/arch/arm/plat-s5p/setup-mipiphy.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control - * - * 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 -#include -#include -#include -#include - -static int __s5p_mipi_phy_control(struct platform_device *pdev, - bool on, u32 reset) -{ - static DEFINE_SPINLOCK(lock); - void __iomem *addr; - unsigned long flags; - int pid; - u32 cfg; - - if (!pdev) - return -EINVAL; - - pid = (pdev->id == -1) ? 0 : pdev->id; - - if (pid != 0 && pid != 1) - return -EINVAL; - - addr = S5P_MIPI_DPHY_CONTROL(pid); - - spin_lock_irqsave(&lock, flags); - - cfg = __raw_readl(addr); - cfg = on ? (cfg | reset) : (cfg & ~reset); - __raw_writel(cfg, addr); - - if (on) { - cfg |= S5P_MIPI_DPHY_ENABLE; - } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN | - S5P_MIPI_DPHY_MRESETN) & ~reset)) { - cfg &= ~S5P_MIPI_DPHY_ENABLE; - } - - __raw_writel(cfg, addr); - spin_unlock_irqrestore(&lock, flags); - - return 0; -} - -int s5p_csis_phy_enable(struct platform_device *pdev, bool on) -{ - return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN); -} - -int s5p_dsim_phy_enable(struct platform_device *pdev, bool on) -{ - return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN); -} diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 5ce6bc8..7fec2e9 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -309,6 +309,11 @@ config SAMSUNG_DEV_BACKLIGHT help Compile in platform device definition LCD backlight with PWM Timer +config S5P_DEV_MFC + bool + help + Compile in setup memory (init) code for MFC + config S3C24XX_PWM bool "PWM device support" select HAVE_PWM @@ -316,6 +321,11 @@ config S3C24XX_PWM Support for exporting the PWM timer blocks via the pwm device system +config S5P_SETUP_MIPIPHY + bool + help + Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices + # DMA config S3C_DMA diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index b20047b..860b2db 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -36,10 +36,13 @@ obj-y += platformdata.o obj-y += devs.o obj-y += dev-uart.o +obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o +obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o + # DMA support obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c new file mode 100644 index 0000000..ad60894 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-dev-mfc.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd + * + * Base S5P MFC resource and device definitions + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct s5p_mfc_reserved_mem { + phys_addr_t base; + unsigned long size; + struct device *dev; +}; + +static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata; + +void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, + phys_addr_t lbase, unsigned int lsize) +{ + int i; + + s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev; + s5p_mfc_mem[0].base = rbase; + s5p_mfc_mem[0].size = rsize; + + s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev; + s5p_mfc_mem[1].base = lbase; + s5p_mfc_mem[1].size = lsize; + + for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { + struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; + if (memblock_remove(area->base, area->size)) { + printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n", + area->size, (unsigned long) area->base); + area->base = 0; + } + } +} + +static int __init s5p_mfc_memory_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { + struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; + if (!area->base) + continue; + + if (dma_declare_coherent_memory(area->dev, area->base, + area->base, area->size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) + printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n", + area->size, (unsigned long) area->base); + } + return 0; +} +device_initcall(s5p_mfc_memory_init); diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c new file mode 100644 index 0000000..683c466 --- /dev/null +++ b/arch/arm/plat-samsung/setup-mipiphy.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co., Ltd. + * + * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control + * + * 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 +#include +#include +#include +#include + +static int __s5p_mipi_phy_control(struct platform_device *pdev, + bool on, u32 reset) +{ + static DEFINE_SPINLOCK(lock); + void __iomem *addr; + unsigned long flags; + int pid; + u32 cfg; + + if (!pdev) + return -EINVAL; + + pid = (pdev->id == -1) ? 0 : pdev->id; + + if (pid != 0 && pid != 1) + return -EINVAL; + + addr = S5P_MIPI_DPHY_CONTROL(pid); + + spin_lock_irqsave(&lock, flags); + + cfg = __raw_readl(addr); + cfg = on ? (cfg | reset) : (cfg & ~reset); + __raw_writel(cfg, addr); + + if (on) { + cfg |= S5P_MIPI_DPHY_ENABLE; + } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN | + S5P_MIPI_DPHY_MRESETN) & ~reset)) { + cfg &= ~S5P_MIPI_DPHY_ENABLE; + } + + __raw_writel(cfg, addr); + spin_unlock_irqrestore(&lock, flags); + + return 0; +} + +int s5p_csis_phy_enable(struct platform_device *pdev, bool on) +{ + return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN); +} + +int s5p_dsim_phy_enable(struct platform_device *pdev, bool on) +{ + return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN); +} -- cgit v0.10.2 From e033ca9bfa0831889d7b8fdad516c771ad200e41 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 17 Apr 2012 20:39:10 -0700 Subject: ARM: SAMSUNG: move options for common s5p into plat-samsung/Kconfig Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 4ff6d7e..e7d5d77 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -22,68 +22,3 @@ config PLAT_S5P select SAMSUNG_IRQ_VIC_TIMER help Base platform code for Samsung's S5P series SoC. - -config S5P_DEV_FIMC0 - bool - help - Compile in platform device definitions for FIMC controller 0 - -config S5P_DEV_FIMC1 - bool - help - Compile in platform device definitions for FIMC controller 1 - -config S5P_DEV_FIMC2 - bool - help - Compile in platform device definitions for FIMC controller 2 - -config S5P_DEV_FIMC3 - bool - help - Compile in platform device definitions for FIMC controller 3 - -config S5P_DEV_JPEG - bool - help - Compile in platform device definitions for JPEG codec - -config S5P_DEV_G2D - bool - help - Compile in platform device definitions for G2D device - -config S5P_DEV_FIMD0 - bool - help - Compile in platform device definitions for FIMD controller 0 - -config S5P_DEV_I2C_HDMIPHY - bool - help - Compile in platform device definitions for I2C HDMIPHY controller - -config S5P_DEV_ONENAND - bool - help - Compile in platform device definition for OneNAND controller - -config S5P_DEV_CSIS0 - bool - help - Compile in platform device definitions for MIPI-CSIS channel 0 - -config S5P_DEV_CSIS1 - bool - help - Compile in platform device definitions for MIPI-CSIS channel 1 - -config S5P_DEV_TV - bool - help - Compile in platform device definition for TV interface - -config S5P_DEV_USB_EHCI - bool - help - Compile in platform device definition for USB EHCI diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 7fec2e9..8381d47 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -309,11 +309,76 @@ config SAMSUNG_DEV_BACKLIGHT help Compile in platform device definition LCD backlight with PWM Timer +config S5P_DEV_CSIS0 + bool + help + Compile in platform device definitions for MIPI-CSIS channel 0 + +config S5P_DEV_CSIS1 + bool + help + Compile in platform device definitions for MIPI-CSIS channel 1 + +config S5P_DEV_FIMC0 + bool + help + Compile in platform device definitions for FIMC controller 0 + +config S5P_DEV_FIMC1 + bool + help + Compile in platform device definitions for FIMC controller 1 + +config S5P_DEV_FIMC2 + bool + help + Compile in platform device definitions for FIMC controller 2 + +config S5P_DEV_FIMC3 + bool + help + Compile in platform device definitions for FIMC controller 3 + +config S5P_DEV_FIMD0 + bool + help + Compile in platform device definitions for FIMD controller 0 + +config S5P_DEV_G2D + bool + help + Compile in platform device definitions for G2D device + +config S5P_DEV_I2C_HDMIPHY + bool + help + Compile in platform device definitions for I2C HDMIPHY controller + +config S5P_DEV_JPEG + bool + help + Compile in platform device definitions for JPEG codec + config S5P_DEV_MFC bool help Compile in setup memory (init) code for MFC +config S5P_DEV_ONENAND + bool + help + Compile in platform device definition for OneNAND controller + +config S5P_DEV_TV + bool + help + Compile in platform device definition for TV interface + +config S5P_DEV_USB_EHCI + bool + help + Compile in platform device definition for USB EHCI + config S3C24XX_PWM bool "PWM device support" select HAVE_PWM -- cgit v0.10.2 From 199642bfe107c411f25fbfc16c9fd49cfef9785d Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Sun, 13 May 2012 07:11:38 +0900 Subject: ARM: SAMSUNG: merge plat-s5p into plat-samsung Since just plat-samsung can support all of Samsung stuff so that there is no more need to keep the plat-s5p for S5P SoCs. Signed-off-by: Kukjin Kim diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9318084..60c2f9c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1087,7 +1087,6 @@ source "arch/arm/mach-sa1100/Kconfig" source "arch/arm/plat-samsung/Kconfig" source "arch/arm/plat-s3c24xx/Kconfig" -source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-spear/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 047a207..f55b509 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -209,7 +209,7 @@ plat-$(CONFIG_PLAT_NOMADIK) := nomadik plat-$(CONFIG_PLAT_ORION) := orion plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung -plat-$(CONFIG_PLAT_S5P) := s5p samsung +plat-$(CONFIG_PLAT_S5P) := samsung plat-$(CONFIG_PLAT_SPEAR) := spear plat-$(CONFIG_PLAT_VERSATILE) := versatile diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig deleted file mode 100644 index e7d5d77..0000000 --- a/arch/arm/plat-s5p/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -# arch/arm/plat-s5p/Kconfig -# -# Copyright (c) 2009 Samsung Electronics Co., Ltd. -# http://www.samsung.com/ -# -# Licensed under GPLv2 - -config PLAT_S5P - bool - depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) - default y - select ARM_VIC if !ARCH_EXYNOS - select ARM_GIC if ARCH_EXYNOS - select GIC_NON_BANKED if ARCH_EXYNOS4 - select NO_IOPORT - select ARCH_REQUIRE_GPIOLIB - select S3C_GPIO_TRACK - select S5P_GPIO_DRVSTR - select SAMSUNG_GPIOLIB_4BIT - select PLAT_SAMSUNG - select SAMSUNG_CLKSRC - select SAMSUNG_IRQ_VIC_TIMER - help - Base platform code for Samsung's S5P series SoC. diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile deleted file mode 100644 index 884b9a1..0000000 --- a/arch/arm/plat-s5p/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# arch/arm/plat-s5p/Makefile -# -# Copyright (c) 2009 Samsung Electronics Co., Ltd. -# http://www.samsung.com/ -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := dummy.o -obj- := diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 8381d47..b54e13d 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -13,6 +13,24 @@ config PLAT_SAMSUNG help Base platform code for all Samsung SoC based systems +config PLAT_S5P + bool + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) + default y + select ARM_VIC if !ARCH_EXYNOS + select ARM_GIC if ARCH_EXYNOS + select GIC_NON_BANKED if ARCH_EXYNOS4 + select NO_IOPORT + select ARCH_REQUIRE_GPIOLIB + select S3C_GPIO_TRACK + select S5P_GPIO_DRVSTR + select SAMSUNG_GPIOLIB_4BIT + select PLAT_SAMSUNG + select SAMSUNG_CLKSRC + select SAMSUNG_IRQ_VIC_TIMER + help + Base platform code for Samsung's S5P series SoC. + if PLAT_SAMSUNG # boot configurations -- cgit v0.10.2 From d36bcd0790b331116cb877774dc975abf0eaa40c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 24 Apr 2012 14:03:05 -0700 Subject: ARM: EXYNOS: Add watchdog timer clock instance Add watchdog timer clock instance for EXYNOS5 watchdog controller. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 9f87a07..84ef35a 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -474,6 +474,11 @@ static struct clk exynos5_init_clocks_off[] = { .enable = exynos5_clk_ip_peris_ctrl, .ctrlbit = (1 << 20), }, { + .name = "watchdog", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peris_ctrl, + .ctrlbit = (1 << 19), + }, { .name = "hsmmc", .devname = "exynos4-sdhci.0", .parent = &exynos5_clk_aclk_200.clk, -- cgit v0.10.2 From c9ce7dbdbf25d7245ead1923c11620d4c8013592 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 24 Apr 2012 14:31:11 -0700 Subject: ARM: EXYNOS: Modify the GIC physical address for static io-mapping Adapt to changes in GIC physical address in rev1 of EXYNOS5. Signed-off-by: Changhwan Youn Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 5ccd6e8..eff4446 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -265,12 +265,12 @@ static struct map_desc exynos5_iodesc[] __initdata = { }, { .virtual = (unsigned long)S5P_VA_GIC_CPU, .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU), - .length = SZ_64K, + .length = SZ_8K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_GIC_DIST, .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST), - .length = SZ_64K, + .length = SZ_4K, .type = MT_DEVICE, }, }; diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 0e2292d..648d59b 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -78,8 +78,8 @@ #define EXYNOS4_PA_GIC_CPU 0x10480000 #define EXYNOS4_PA_GIC_DIST 0x10490000 -#define EXYNOS5_PA_GIC_CPU 0x10480000 -#define EXYNOS5_PA_GIC_DIST 0x10490000 +#define EXYNOS5_PA_GIC_CPU 0x10482000 +#define EXYNOS5_PA_GIC_DIST 0x10481000 #define EXYNOS4_PA_COREPERI 0x10500000 #define EXYNOS4_PA_TWD 0x10500600 -- cgit v0.10.2 From eeed66e3a50f4d23d542498b17861ffadcdaf8ec Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 24 Apr 2012 14:33:14 -0700 Subject: ARM: EXYNOS: Redefine IRQ_MCT_L0,1 definition Redefine IRQ_MCT_L0,1 irq definition as it is changed in rev1 of EXYNOS5. Signed-off-by: Changhwan Youn Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index 1161675..86e75f5 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -320,6 +320,8 @@ #define EXYNOS5_IRQ_SATA IRQ_SPI(115) #define EXYNOS5_IRQ_NFCON IRQ_SPI(116) +#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120) +#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121) #define EXYNOS5_IRQ_MMC44 IRQ_SPI(123) #define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124) #define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125) @@ -399,8 +401,6 @@ #define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6) #define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) -#define EXYNOS5_IRQ_MCT_L0 COMBINER_IRQ(23, 1) -#define EXYNOS5_IRQ_MCT_L1 COMBINER_IRQ(23, 2) #define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) #define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4) #define EXYNOS5_IRQ_MCT_G2 COMBINER_IRQ(23, 5) diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c index 897d9a9..b601fb8 100644 --- a/arch/arm/mach-exynos/mct.c +++ b/arch/arm/mach-exynos/mct.c @@ -388,6 +388,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) { struct mct_clock_event_device *mevt; unsigned int cpu = smp_processor_id(); + int mct_lx_irq; mevt = this_cpu_ptr(&percpu_mct_tick); mevt->evt = evt; @@ -414,14 +415,18 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) if (mct_int_type == MCT_INT_SPI) { if (cpu == 0) { + mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L0 : + EXYNOS5_IRQ_MCT_L0; mct_tick0_event_irq.dev_id = mevt; - evt->irq = EXYNOS4_IRQ_MCT_L0; - setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq); + evt->irq = mct_lx_irq; + setup_irq(mct_lx_irq, &mct_tick0_event_irq); } else { + mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L1 : + EXYNOS5_IRQ_MCT_L1; mct_tick1_event_irq.dev_id = mevt; - evt->irq = EXYNOS4_IRQ_MCT_L1; - setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq); - irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1)); + evt->irq = mct_lx_irq; + setup_irq(mct_lx_irq, &mct_tick1_event_irq); + irq_set_affinity(mct_lx_irq, cpumask_of(1)); } } else { enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0); @@ -473,7 +478,7 @@ static void __init exynos4_timer_resources(void) static void __init exynos4_timer_init(void) { - if (soc_is_exynos4210()) + if ((soc_is_exynos4210()) || (soc_is_exynos5250())) mct_int_type = MCT_INT_SPI; else mct_int_type = MCT_INT_PPI; -- cgit v0.10.2 From f10590c9836c9fc595d1dafff965b280029d4f16 Mon Sep 17 00:00:00 2001 From: Sangsu Park Date: Tue, 24 Apr 2012 14:44:58 -0700 Subject: ARM: EXYNOS: add GPC4 bank instance Add GPC4 bank instance which is included in rev1 of EXYNOS5. Signed-off-by: Sangsu Park Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h index d7498af..eb24f1e 100644 --- a/arch/arm/mach-exynos/include/mach/gpio.h +++ b/arch/arm/mach-exynos/include/mach/gpio.h @@ -153,10 +153,11 @@ enum exynos4_gpio_number { #define EXYNOS5_GPIO_B2_NR (4) #define EXYNOS5_GPIO_B3_NR (4) #define EXYNOS5_GPIO_C0_NR (7) -#define EXYNOS5_GPIO_C1_NR (7) +#define EXYNOS5_GPIO_C1_NR (4) #define EXYNOS5_GPIO_C2_NR (7) #define EXYNOS5_GPIO_C3_NR (7) -#define EXYNOS5_GPIO_D0_NR (8) +#define EXYNOS5_GPIO_C4_NR (7) +#define EXYNOS5_GPIO_D0_NR (4) #define EXYNOS5_GPIO_D1_NR (8) #define EXYNOS5_GPIO_Y0_NR (6) #define EXYNOS5_GPIO_Y1_NR (4) @@ -199,7 +200,8 @@ enum exynos5_gpio_number { EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0), EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1), EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2), - EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3), + EXYNOS5_GPIO_C4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3), + EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C4), EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0), EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1), EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0), @@ -242,6 +244,7 @@ enum exynos5_gpio_number { #define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr)) #define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr)) #define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr)) +#define EXYNOS5_GPC4(_nr) (EXYNOS5_GPIO_C4_START + (_nr)) #define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr)) #define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr)) #define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr)) diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index 86e75f5..b1d3b68 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -435,7 +435,7 @@ #define EXYNOS5_MAX_COMBINER_NR 32 -#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 13 +#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 14 #define EXYNOS5_IRQ_GPIO2_NR_GROUPS 9 #define EXYNOS5_IRQ_GPIO3_NR_GROUPS 5 #define EXYNOS5_IRQ_GPIO4_NR_GROUPS 1 diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index e991d91..f88bb9f 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -2454,6 +2454,12 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { }, }, { .chip = { + .base = EXYNOS5_GPC4(0), + .ngpio = EXYNOS5_GPIO_C4_NR, + .label = "GPC4", + }, + }, { + .chip = { .base = EXYNOS5_GPD0(0), .ngpio = EXYNOS5_GPIO_D0_NR, .label = "GPD0", @@ -2878,8 +2884,11 @@ static __init int samsung_gpiolib_init(void) goto err_ioremap1; } + /* need to set base address for gpc4 */ + exynos5_gpios_1[11].base = gpio_base1 + 0x2E0; + /* need to set base address for gpx */ - chip = &exynos5_gpios_1[20]; + chip = &exynos5_gpios_1[21]; gpx_base = gpio_base1 + 0xC00; for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) chip->base = gpx_base; -- cgit v0.10.2 From 57b317f912b3f4b05c834818c73d7c8ea22642f7 Mon Sep 17 00:00:00 2001 From: Kisoo Yu Date: Tue, 24 Apr 2012 14:54:15 -0700 Subject: ARM: EXYNOS: Add pre-divider and fout mux clocks for bpll and mpll The fout clock of BPLL and MPLL have a selectable source on EXYNOS5250. The clock options are a fixed divided by 2 clock and the output of the PLL itself. Add support for these new clock instances. Signed-off-by: Kisoo Yu Signed-off-by: Thomas Abraham [kgene.kim@samsung.com: moved common pll stuff into s5p-clock.c] Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 84ef35a..5aa460b 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -165,11 +165,29 @@ static struct clksrc_clk exynos5_clk_sclk_apll = { .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 }, }; +static struct clksrc_clk exynos5_clk_mout_bpll_fout = { + .clk = { + .name = "mout_bpll_fout", + }, + .sources = &clk_src_bpll_fout, + .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos5_clk_src_bpll_list[] = { + [0] = &clk_fin_bpll, + [1] = &exynos5_clk_mout_bpll_fout.clk, +}; + +static struct clksrc_sources exynos5_clk_src_bpll = { + .sources = exynos5_clk_src_bpll_list, + .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_list), +}; + static struct clksrc_clk exynos5_clk_mout_bpll = { .clk = { .name = "mout_bpll", }, - .sources = &clk_src_bpll, + .sources = &exynos5_clk_src_bpll, .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 }, }; @@ -207,11 +225,29 @@ static struct clksrc_clk exynos5_clk_mout_epll = { .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 }, }; +static struct clksrc_clk exynos5_clk_mout_mpll_fout = { + .clk = { + .name = "mout_mpll_fout", + }, + .sources = &clk_src_mpll_fout, + .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 4, .size = 1 }, +}; + +static struct clk *exynos5_clk_src_mpll_list[] = { + [0] = &clk_fin_mpll, + [1] = &exynos5_clk_mout_mpll_fout.clk, +}; + +static struct clksrc_sources exynos5_clk_src_mpll = { + .sources = exynos5_clk_src_mpll_list, + .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_list), +}; + struct clksrc_clk exynos5_clk_mout_mpll = { .clk = { .name = "mout_mpll", }, - .sources = &clk_src_mpll, + .sources = &exynos5_clk_src_mpll, .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 }, }; @@ -1036,10 +1072,12 @@ static struct clksrc_clk *exynos5_sysclks[] = { &exynos5_clk_mout_apll, &exynos5_clk_sclk_apll, &exynos5_clk_mout_bpll, + &exynos5_clk_mout_bpll_fout, &exynos5_clk_mout_bpll_user, &exynos5_clk_mout_cpll, &exynos5_clk_mout_epll, &exynos5_clk_mout_mpll, + &exynos5_clk_mout_mpll_fout, &exynos5_clk_mout_mpll_user, &exynos5_clk_vpllsrc, &exynos5_clk_sclk_vpll, @@ -1103,7 +1141,9 @@ static struct clk *exynos5_clks[] __initdata = { &exynos5_clk_sclk_hdmi27m, &exynos5_clk_sclk_hdmiphy, &clk_fout_bpll, + &clk_fout_bpll_div2, &clk_fout_cpll, + &clk_fout_mpll_div2, &exynos5_clk_armclk, }; @@ -1268,8 +1308,10 @@ void __init_or_cpufreq exynos5_setup_clocks(void) clk_fout_apll.ops = &exynos5_fout_apll_ops; clk_fout_bpll.rate = bpll; + clk_fout_bpll_div2.rate = bpll >> 1; clk_fout_cpll.rate = cpll; clk_fout_mpll.rate = mpll; + clk_fout_mpll_div2.rate = mpll >> 1; clk_fout_epll.rate = epll; clk_fout_vpll.rate = vpll; diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index dba83e9..b78b5f3 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -322,6 +322,8 @@ #define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200) #define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500) +#define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24) + #define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030) #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h index 1de4b32..8364b4b 100644 --- a/arch/arm/plat-samsung/include/plat/s5p-clock.h +++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h @@ -32,8 +32,10 @@ extern struct clk clk_48m; extern struct clk s5p_clk_27m; extern struct clk clk_fout_apll; extern struct clk clk_fout_bpll; +extern struct clk clk_fout_bpll_div2; extern struct clk clk_fout_cpll; extern struct clk clk_fout_mpll; +extern struct clk clk_fout_mpll_div2; extern struct clk clk_fout_epll; extern struct clk clk_fout_dpll; extern struct clk clk_fout_vpll; @@ -42,8 +44,10 @@ extern struct clk clk_vpll; extern struct clksrc_sources clk_src_apll; extern struct clksrc_sources clk_src_bpll; +extern struct clksrc_sources clk_src_bpll_fout; extern struct clksrc_sources clk_src_cpll; extern struct clksrc_sources clk_src_mpll; +extern struct clksrc_sources clk_src_mpll_fout; extern struct clksrc_sources clk_src_epll; extern struct clksrc_sources clk_src_dpll; diff --git a/arch/arm/plat-samsung/s5p-clock.c b/arch/arm/plat-samsung/s5p-clock.c index 41d3dfd..031a618 100644 --- a/arch/arm/plat-samsung/s5p-clock.c +++ b/arch/arm/plat-samsung/s5p-clock.c @@ -67,6 +67,11 @@ struct clk clk_fout_bpll = { .id = -1, }; +struct clk clk_fout_bpll_div2 = { + .name = "fout_bpll_div2", + .id = -1, +}; + /* CPLL clock output */ struct clk clk_fout_cpll = { @@ -82,6 +87,11 @@ struct clk clk_fout_mpll = { .id = -1, }; +struct clk clk_fout_mpll_div2 = { + .name = "fout_mpll_div2", + .id = -1, +}; + /* EPLL clock output */ struct clk clk_fout_epll = { .name = "fout_epll", @@ -125,6 +135,16 @@ struct clksrc_sources clk_src_bpll = { .nr_sources = ARRAY_SIZE(clk_src_bpll_list), }; +static struct clk *clk_src_bpll_fout_list[] = { + [0] = &clk_fout_bpll_div2, + [1] = &clk_fout_bpll, +}; + +struct clksrc_sources clk_src_bpll_fout = { + .sources = clk_src_bpll_fout_list, + .nr_sources = ARRAY_SIZE(clk_src_bpll_fout_list), +}; + /* Possible clock sources for CPLL Mux */ static struct clk *clk_src_cpll_list[] = { [0] = &clk_fin_cpll, @@ -147,6 +167,16 @@ struct clksrc_sources clk_src_mpll = { .nr_sources = ARRAY_SIZE(clk_src_mpll_list), }; +static struct clk *clk_src_mpll_fout_list[] = { + [0] = &clk_fout_mpll_div2, + [1] = &clk_fout_mpll, +}; + +struct clksrc_sources clk_src_mpll_fout = { + .sources = clk_src_mpll_fout_list, + .nr_sources = ARRAY_SIZE(clk_src_mpll_fout_list), +}; + /* Possible clock sources for EPLL Mux */ static struct clk *clk_src_epll_list[] = { [0] = &clk_fin_epll, -- cgit v0.10.2 From 3a08f7f85a885da15d47ad92464f829535aff7cb Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 24 Apr 2012 15:33:32 -0700 Subject: ARM: EXYNOS: update irqs for EXYNOS5250 SoC Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index b1d3b68..561553a 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -286,6 +286,7 @@ #define EXYNOS5_IRQ_MIPICSI1 IRQ_SPI(80) #define EXYNOS5_IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81) #define EXYNOS5_IRQ_MIPIDSI0 IRQ_SPI(82) +#define EXYNOS5_IRQ_WDT_IOP IRQ_SPI(83) #define EXYNOS5_IRQ_ROTATOR IRQ_SPI(84) #define EXYNOS5_IRQ_GSC0 IRQ_SPI(85) #define EXYNOS5_IRQ_GSC1 IRQ_SPI(86) @@ -294,8 +295,8 @@ #define EXYNOS5_IRQ_JPEG IRQ_SPI(89) #define EXYNOS5_IRQ_EFNFCON_DMA IRQ_SPI(90) #define EXYNOS5_IRQ_2D IRQ_SPI(91) -#define EXYNOS5_IRQ_SFMC0 IRQ_SPI(92) -#define EXYNOS5_IRQ_SFMC1 IRQ_SPI(93) +#define EXYNOS5_IRQ_EFNFCON_0 IRQ_SPI(92) +#define EXYNOS5_IRQ_EFNFCON_1 IRQ_SPI(93) #define EXYNOS5_IRQ_MIXER IRQ_SPI(94) #define EXYNOS5_IRQ_HDMI IRQ_SPI(95) #define EXYNOS5_IRQ_MFC IRQ_SPI(96) @@ -309,7 +310,7 @@ #define EXYNOS5_IRQ_PCM2 IRQ_SPI(104) #define EXYNOS5_IRQ_SPDIF IRQ_SPI(105) #define EXYNOS5_IRQ_ADC0 IRQ_SPI(106) - +#define EXYNOS5_IRQ_ADC1 IRQ_SPI(107) #define EXYNOS5_IRQ_SATA_PHY IRQ_SPI(108) #define EXYNOS5_IRQ_SATA_PMEMREQ IRQ_SPI(109) #define EXYNOS5_IRQ_CAM_C IRQ_SPI(110) @@ -318,7 +319,6 @@ #define EXYNOS5_IRQ_DP1_INTP1 IRQ_SPI(113) #define EXYNOS5_IRQ_CEC IRQ_SPI(114) #define EXYNOS5_IRQ_SATA IRQ_SPI(115) -#define EXYNOS5_IRQ_NFCON IRQ_SPI(116) #define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120) #define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121) @@ -329,7 +329,6 @@ #define EXYNOS5_IRQ_RP_TIMER IRQ_SPI(127) #define EXYNOS5_IRQ_PMU COMBINER_IRQ(1, 2) -#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(1, 6) #define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0) #define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1) @@ -340,6 +339,8 @@ #define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6) #define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7) +#define EXYNOS5_IRQ_SYSMMU_LITE2_0 COMBINER_IRQ(3, 0) +#define EXYNOS5_IRQ_SYSMMU_LITE2_1 COMBINER_IRQ(3, 1) #define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2) #define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3) #define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4) @@ -363,8 +364,8 @@ #define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0) #define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1) -#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(6, 2) -#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(6, 3) +#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(6, 2) +#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(6, 3) #define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4) #define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5) #define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6) @@ -376,11 +377,9 @@ #define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3) #define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4) #define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5) -#define EXYNOS5_IRQ_SYSMMU_GPSX_0 COMBINER_IRQ(7, 6) -#define EXYNOS5_IRQ_SYSMMU_GPSX_1 COMBINER_IRQ(7, 7) -#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(8, 5) -#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(8, 6) +#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(8, 5) +#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(8, 6) #define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4) #define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5) @@ -396,15 +395,24 @@ #define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6) #define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7) +#define EXYNOS5_IRQ_MDMA1_ABORT COMBINER_IRQ(13, 1) + +#define EXYNOS5_IRQ_MDMA0_ABORT COMBINER_IRQ(15, 3) + #define EXYNOS5_IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4) #define EXYNOS5_IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5) #define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6) +#define EXYNOS5_IRQ_ARMIOP_GIC COMBINER_IRQ(19, 0) +#define EXYNOS5_IRQ_ARMISP_GIC COMBINER_IRQ(19, 1) +#define EXYNOS5_IRQ_IOP_GIC COMBINER_IRQ(19, 3) +#define EXYNOS5_IRQ_ISP_GIC COMBINER_IRQ(19, 4) + +#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4) + #define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) #define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) #define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4) -#define EXYNOS5_IRQ_MCT_G2 COMBINER_IRQ(23, 5) -#define EXYNOS5_IRQ_MCT_G3 COMBINER_IRQ(23, 6) #define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0) #define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1) -- cgit v0.10.2 From 9ee6af9c3fad48cddc0684d0c77d3ea1329e10a1 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 15 May 2012 15:47:40 +0900 Subject: ARM: EXYNOS: Remove a new bus_type instance for EXYNOS5 A seperate bus_type instance is not required for EXYNOS5. The existing bus_type instance used with EXYNOS4 is sufficient for both EXYNOS4 and EXYNOS5. This also solves issue of uninitialized usage of exynos4_subsys in EXYNOS4 power management code that is reused for EXYNOS5 also. In addition to that, the existing exynos4_subsys bus_type is renamed to exynos_subsys to indicate that it is reused on both EXYNOS4 and EXYNOS5 platforms. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index eff4446..3302a8d 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -565,30 +565,18 @@ void __init exynos5_init_irq(void) s5p_init_irq(NULL, 0); } -struct bus_type exynos4_subsys = { - .name = "exynos4-core", - .dev_name = "exynos4-core", -}; - -struct bus_type exynos5_subsys = { - .name = "exynos5-core", - .dev_name = "exynos5-core", +struct bus_type exynos_subsys = { + .name = "exynos-core", + .dev_name = "exynos-core", }; static struct device exynos4_dev = { - .bus = &exynos4_subsys, -}; - -static struct device exynos5_dev = { - .bus = &exynos5_subsys, + .bus = &exynos_subsys, }; static int __init exynos_core_init(void) { - if (soc_is_exynos5250()) - return subsys_system_register(&exynos5_subsys, NULL); - else - return subsys_system_register(&exynos4_subsys, NULL); + return subsys_system_register(&exynos_subsys, NULL); } core_initcall(exynos_core_init); @@ -675,10 +663,7 @@ static int __init exynos_init(void) { printk(KERN_INFO "EXYNOS: Initializing architecture\n"); - if (soc_is_exynos5250()) - return device_register(&exynos5_dev); - else - return device_register(&exynos4_dev); + return device_register(&exynos4_dev); } /* uart registration process */ diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 428cfeb..7164aa9 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -275,7 +275,7 @@ static void exynos4_restore_pll(void) static struct subsys_interface exynos4_pm_interface = { .name = "exynos4_pm", - .subsys = &exynos4_subsys, + .subsys = &exynos_subsys, .add_dev = exynos4_pm_add, }; diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 787ceac..0721293 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -202,7 +202,7 @@ extern struct bus_type s3c2443_subsys; extern struct bus_type s3c6410_subsys; extern struct bus_type s5p64x0_subsys; extern struct bus_type s5pv210_subsys; -extern struct bus_type exynos4_subsys; +extern struct bus_type exynos_subsys; extern void (*s5pc1xx_idle)(void); -- cgit v0.10.2 From 1e60bc0b5f488c8acde22adeb62118ccfdb49062 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 15 May 2012 16:18:35 +0900 Subject: ARM: EXYNOS: Add irq_domain support for interrupt combiner Add irq_domain support for hardware interrupts of the interrupt combiner. The hardware interrupts of all the instances of the combiner are grouped in a single irq_domain. Cc: Grant Likely Signed-off-by: Thomas Abraham Acked-by: Rob Herring Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 3302a8d..a688c17 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -399,6 +401,7 @@ struct combiner_chip_data { void __iomem *base; }; +static struct irq_domain *combiner_irq_domain; static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; static inline void __iomem *combiner_base(struct irq_data *data) @@ -411,14 +414,14 @@ static inline void __iomem *combiner_base(struct irq_data *data) static void combiner_mask_irq(struct irq_data *data) { - u32 mask = 1 << (data->irq % 32); + u32 mask = 1 << (data->hwirq % 32); __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR); } static void combiner_unmask_irq(struct irq_data *data) { - u32 mask = 1 << (data->irq % 32); + u32 mask = 1 << (data->hwirq % 32); __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); } @@ -474,36 +477,58 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i irq_set_chained_handler(irq, combiner_handle_cascade_irq); } -static void __init combiner_init(unsigned int combiner_nr, void __iomem *base, - unsigned int irq_start) +static void __init combiner_init_one(unsigned int combiner_nr, + void __iomem *base) { - unsigned int i; - unsigned int max_nr; - - if (soc_is_exynos5250()) - max_nr = EXYNOS5_MAX_COMBINER_NR; - else - max_nr = EXYNOS4_MAX_COMBINER_NR; - - if (combiner_nr >= max_nr) - BUG(); - combiner_data[combiner_nr].base = base; - combiner_data[combiner_nr].irq_offset = irq_start; + combiner_data[combiner_nr].irq_offset = irq_find_mapping( + combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER); combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); /* Disable all interrupts */ - __raw_writel(combiner_data[combiner_nr].irq_mask, base + COMBINER_ENABLE_CLEAR); +} + +static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq); + irq_set_chip_data(irq, &combiner_data[hw >> 3]); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + + return 0; +} + +static struct irq_domain_ops combiner_irq_domain_ops = { + .map = combiner_irq_domain_map, +}; + +void __init combiner_init(void __iomem *combiner_base, struct device_node *np) +{ + int i, irq_base; + unsigned int max_nr, nr_irq; + + max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR : + EXYNOS4_MAX_COMBINER_NR; + nr_irq = max_nr * MAX_IRQ_IN_COMBINER; + + irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0); + if (IS_ERR_VALUE(irq_base)) { + irq_base = COMBINER_IRQ(0, 0); + pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base); + } - /* Setup the Linux IRQ subsystem */ + combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0, + &combiner_irq_domain_ops, &combiner_data); + if (WARN_ON(!combiner_irq_domain)) { + pr_warning("%s: irq domain init failed\n", __func__); + return; + } - for (i = irq_start; i < combiner_data[combiner_nr].irq_offset - + MAX_IRQ_IN_COMBINER; i++) { - irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq); - irq_set_chip_data(i, &combiner_data[combiner_nr]); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + for (i = 0; i < max_nr; i++) { + combiner_init_one(i, combiner_base + (i >> 2) * 0x10); + combiner_cascade_irq(i, IRQ_SPI(i)); } } @@ -516,7 +541,6 @@ static const struct of_device_id exynos4_dt_irq_match[] = { void __init exynos4_init_irq(void) { - int irq; unsigned int gic_bank_offset; gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; @@ -528,12 +552,7 @@ void __init exynos4_init_irq(void) of_irq_init(exynos4_dt_irq_match); #endif - for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) { - - combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), - COMBINER_IRQ(irq, 0)); - combiner_cascade_irq(irq, IRQ_SPI(irq)); - } + combiner_init(S5P_VA_COMBINER_BASE, NULL); /* * The parameters of s5p_init_irq() are for VIC init. @@ -545,17 +564,10 @@ void __init exynos4_init_irq(void) void __init exynos5_init_irq(void) { - int irq; - #ifdef CONFIG_OF of_irq_init(exynos4_dt_irq_match); #endif - - for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) { - combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), - COMBINER_IRQ(irq, 0)); - combiner_cascade_irq(irq, IRQ_SPI(irq)); - } + combiner_init(S5P_VA_COMBINER_BASE, NULL); /* * The parameters of s5p_init_irq() are for VIC init. -- cgit v0.10.2 From e873a47c4ef3fbb2e439a6b674e73b0c40dd8248 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 15 May 2012 16:25:23 +0900 Subject: ARM: EXYNOS: Add device tree support for interrupt combiner Add device tree based instantiation of the interrupt combiner controller. Signed-off-by: Thomas Abraham Acked-by: Rob Herring Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt b/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file mode 100644 index 0000000..f2f2171 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt @@ -0,0 +1,52 @@ +* Samsung Exynos Interrupt Combiner Controller + +Samsung's Exynos4 architecture includes a interrupt combiner controller which +can combine interrupt sources as a group and provide a single interrupt request +for the group. The interrupt request from each group are connected to a parent +interrupt controller, such as GIC in case of Exynos4210. + +The interrupt combiner controller consists of multiple combiners. Upto eight +interrupt sources can be connected to a combiner. The combiner outputs one +combined interrupt for its eight interrupt sources. The combined interrupt +is usually connected to a parent interrupt controller. + +A single node in the device tree is used to describe the interrupt combiner +controller module (which includes multiple combiners). A combiner in the +interrupt controller module shares config/control registers with other +combiners. For example, a 32-bit interrupt enable/disable config register +can accommodate upto 4 interrupt combiners (with each combiner supporting +upto 8 interrupt sources). + +Required properties: +- compatible: should be "samsung,exynos4210-combiner". +- interrupt-controller: Identifies the node as an interrupt controller. +- #interrupt-cells: should be <2>. The meaning of the cells are + * First Cell: Combiner Group Number. + * Second Cell: Interrupt number within the group. +- reg: Base address and size of interrupt combiner registers. +- interrupts: The list of interrupts generated by the combiners which are then + connected to a parent interrupt controller. The format of the interrupt + specifier depends in the interrupt parent controller. + +Optional properties: +- samsung,combiner-nr: The number of interrupt combiners supported. If this + property is not specified, the default number of combiners is assumed + to be 16. +- interrupt-parent: pHandle of the parent interrupt controller, if not + inherited from the parent node. + + +Example: + + The following is a an example from the Exynos4210 SoC dtsi file. + + combiner:interrupt-controller@10440000 { + compatible = "samsung,exynos4210-combiner"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x10440000 0x1000>; + interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, + <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, + <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, + <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>; + }; diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index a688c17..9900158 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -490,6 +491,35 @@ static void __init combiner_init_one(unsigned int combiner_nr, base + COMBINER_ENABLE_CLEAR); } +#ifdef CONFIG_OF +static int combiner_irq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (d->of_node != controller) + return -EINVAL; + + if (intsize < 2) + return -EINVAL; + + *out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1]; + *out_type = 0; + + return 0; +} +#else +static int combiner_irq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + return -EINVAL; +} +#endif + static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { @@ -501,16 +531,26 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, } static struct irq_domain_ops combiner_irq_domain_ops = { + .xlate = combiner_irq_domain_xlate, .map = combiner_irq_domain_map, }; void __init combiner_init(void __iomem *combiner_base, struct device_node *np) { - int i, irq_base; + int i, irq, irq_base; unsigned int max_nr, nr_irq; - max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR : - EXYNOS4_MAX_COMBINER_NR; + if (np) { + if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) { + pr_warning("%s: number of combiners not specified, " + "setting default as %d.\n", + __func__, EXYNOS4_MAX_COMBINER_NR); + max_nr = EXYNOS4_MAX_COMBINER_NR; + } + } else { + max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR : + EXYNOS4_MAX_COMBINER_NR; + } nr_irq = max_nr * MAX_IRQ_IN_COMBINER; irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0); @@ -528,13 +568,31 @@ void __init combiner_init(void __iomem *combiner_base, struct device_node *np) for (i = 0; i < max_nr; i++) { combiner_init_one(i, combiner_base + (i >> 2) * 0x10); - combiner_cascade_irq(i, IRQ_SPI(i)); + irq = np ? irq_of_parse_and_map(np, i) : IRQ_SPI(i); + combiner_cascade_irq(i, irq); } } #ifdef CONFIG_OF +int __init combiner_of_init(struct device_node *np, struct device_node *parent) +{ + void __iomem *combiner_base; + + combiner_base = of_iomap(np, 0); + if (!combiner_base) { + pr_err("%s: failed to map combiner registers\n", __func__); + return -ENXIO; + } + + combiner_init(combiner_base, np); + + return 0; +} + static const struct of_device_id exynos4_dt_irq_match[] = { { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + { .compatible = "samsung,exynos4210-combiner", + .data = combiner_of_init, }, {}, }; #endif @@ -552,7 +610,8 @@ void __init exynos4_init_irq(void) of_irq_init(exynos4_dt_irq_match); #endif - combiner_init(S5P_VA_COMBINER_BASE, NULL); + if (!of_have_populated_dt()) + combiner_init(S5P_VA_COMBINER_BASE, NULL); /* * The parameters of s5p_init_irq() are for VIC init. @@ -567,8 +626,6 @@ void __init exynos5_init_irq(void) #ifdef CONFIG_OF of_irq_init(exynos4_dt_irq_match); #endif - combiner_init(S5P_VA_COMBINER_BASE, NULL); - /* * The parameters of s5p_init_irq() are for VIC init. * Theses parameters should be NULL and 0 because EXYNOS4 -- cgit v0.10.2 From 009f7c9f567d58d874b46deacafac8e8b34cf931 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 15 May 2012 23:47:53 +0900 Subject: ARM: dts: Update device tree source files for EXYNOS5250 Update EXYNOS5 device tree source files for EXYNOS5250 SoC. This includes new additions to the EXYNOS5 dtsi and SMDK5250 dts files and few minor fixes. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 399d17b..49945cc 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -23,4 +23,52 @@ chosen { bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200"; }; + + i2c@12C60000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <20000>; + gpios = <&gpb3 0 2 3 0>, + <&gpb3 1 2 3 0>; + + eeprom@50 { + compatible = "samsung,s524ad0xd1"; + reg = <0x50>; + }; + }; + + i2c@12C70000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <20000>; + gpios = <&gpb3 2 2 3 0>, + <&gpb3 3 2 3 0>; + + eeprom@51 { + compatible = "samsung,s524ad0xd1"; + reg = <0x51>; + }; + }; + + i2c@12C80000 { + status = "disabled"; + }; + + i2c@12C90000 { + status = "disabled"; + }; + + i2c@12CA0000 { + status = "disabled"; + }; + + i2c@12CB0000 { + status = "disabled"; + }; + + i2c@12CC0000 { + status = "disabled"; + }; + + i2c@12CD0000 { + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index dfc4335..5ca0cdb 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -23,11 +23,11 @@ compatible = "samsung,exynos5250"; interrupt-parent = <&gic>; - gic:interrupt-controller@10490000 { + gic:interrupt-controller@10481000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x10490000 0x1000>, <0x10480000 0x100>; + reg = <0x10481000 0x1000>, <0x10482000 0x2000>; }; watchdog { @@ -42,30 +42,6 @@ interrupts = <0 43 0>, <0 44 0>; }; - sdhci@12200000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12200000 0x100>; - interrupts = <0 75 0>; - }; - - sdhci@12210000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12210000 0x100>; - interrupts = <0 76 0>; - }; - - sdhci@12220000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12220000 0x100>; - interrupts = <0 77 0>; - }; - - sdhci@12230000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12230000 0x100>; - interrupts = <0 78 0>; - }; - serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; @@ -94,48 +70,64 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x12C60000 0x100>; interrupts = <0 56 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12C70000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C70000 0x100>; interrupts = <0 57 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12C80000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C80000 0x100>; interrupts = <0 58 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12C90000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C90000 0x100>; interrupts = <0 59 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CA0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CA0000 0x100>; interrupts = <0 60 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CB0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CB0000 0x100>; interrupts = <0 61 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CC0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CC0000 0x100>; interrupts = <0 62 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CD0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CD0000 0x100>; interrupts = <0 63 0>; + #address-cells = <1>; + #size-cells = <0>; }; amba { @@ -157,13 +149,13 @@ interrupts = <0 35 0>; }; - mdma0: pdma@10800000 { + mdma0: mdma@10800000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x10800000 0x1000>; interrupts = <0 33 0>; }; - mdma1: pdma@11C10000 { + mdma1: mdma@11C10000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x11C10000 0x1000>; interrupts = <0 124 0>; @@ -242,6 +234,12 @@ #gpio-cells = <4>; }; + gpc4: gpio-controller@114002E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114002E0 0x20>; + #gpio-cells = <4>; + }; + gpd0: gpio-controller@11400160 { compatible = "samsung,exynos4-gpio"; reg = <0x11400160 0x20>; @@ -388,19 +386,19 @@ gpv2: gpio-controller@10D10040 { compatible = "samsung,exynos4-gpio"; - reg = <0x10D10040 0x20>; + reg = <0x10D10060 0x20>; #gpio-cells = <4>; }; gpv3: gpio-controller@10D10060 { compatible = "samsung,exynos4-gpio"; - reg = <0x10D10060 0x20>; + reg = <0x10D10080 0x20>; #gpio-cells = <4>; }; gpv4: gpio-controller@10D10080 { compatible = "samsung,exynos4-gpio"; - reg = <0x10D10080 0x20>; + reg = <0x10D100C0 0x20>; #gpio-cells = <4>; }; -- cgit v0.10.2 From 380c3a545f7de096c0f84344ba70ea4cfd1a059f Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 15 May 2012 15:56:57 +0900 Subject: ARM: EXYNOS: Add AUXDATA for i2c controllers Use AUXDATA to set the device names for controller instances discovered from device tree. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 4711c89..cf5d222 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -43,6 +43,10 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { "exynos4210-uart.2", NULL), OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3, "exynos4210-uart.3", NULL), + OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0), + "s3c2440-i2c.0", NULL), + OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1), + "s3c2440-i2c.1", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), -- cgit v0.10.2