* [PATCH v2 6/9] arm: samsung: register uart clocks to clock lookup list
From: Thomas Abraham @ 2011-10-10 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
Samsung uart driver lookups the clock using the connection id 'clk_uart_baud'.
The uart clocks for all Samsung platforms are reorganized to register them
with the lookup name as required by the uart driver.
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos4/clock.c | 106 ++++++++++++++++++++------------
arch/arm/mach-exynos4/init.c | 2 +-
arch/arm/mach-s3c2410/s3c2410.c | 6 ++
arch/arm/mach-s3c2412/clock.c | 7 ++
arch/arm/mach-s3c2440/clock.c | 7 ++
arch/arm/mach-s3c64xx/clock.c | 37 ++++++++---
arch/arm/mach-s5p64x0/clock-s5p6440.c | 32 +++++++---
arch/arm/mach-s5p64x0/clock-s5p6450.c | 32 +++++++---
arch/arm/mach-s5pc100/clock.c | 33 +++++++---
arch/arm/mach-s5pv210/clock.c | 107 ++++++++++++++++++++------------
arch/arm/plat-s3c24xx/s3c2443-clock.c | 23 +++++--
11 files changed, 266 insertions(+), 126 deletions(-)
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index db61691..9f50e33 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -1014,46 +1014,6 @@ static struct clksrc_clk clk_dout_mmc4 = {
static struct clksrc_clk clksrcs[] = {
{
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.0",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.1",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.2",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.3",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
- }, {
.clk = {
.name = "sclk_pwm",
.enable = exynos4_clksrc_mask_peril0_ctrl,
@@ -1242,6 +1202,54 @@ static struct clksrc_clk clksrcs[] = {
}
};
+static struct clksrc_clk clk_sclk_uart0 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.0",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uart1 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.1",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uart2 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.2",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uart3 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.3",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
+};
+
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -1276,6 +1284,20 @@ static struct clksrc_clk *sysclks[] = {
&clk_mout_mfc1,
};
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uart0,
+ &clk_sclk_uart1,
+ &clk_sclk_uart2,
+ &clk_sclk_uart3,
+};
+
+static struct clk_lookup exynos4_clk_lookup[] = {
+ CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk),
+ CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
+ CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
+ CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
+};
+
static int xtal_rate;
static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
@@ -1483,11 +1505,15 @@ void __init exynos4_register_clocks(void)
for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
s3c_register_clksrc(sclk_tv[ptr], 1);
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
+
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
register_syscore_ops(&exynos4_clock_syscore_ops);
s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c
index 3c9590b..5b35978 100644
--- a/arch/arm/mach-exynos4/init.c
+++ b/arch/arm/mach-exynos4/init.c
@@ -23,5 +23,5 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
tcfg->has_fracval = 1;
- s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+ s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
}
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index a99c2f4..ffec01c 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -123,12 +123,18 @@ static struct clk s3c2410_armclk = {
.id = -1,
};
+static struct clk_lookup s3c2410_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
+ CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+};
+
void __init s3c2410_init_clocks(int xtal)
{
s3c24xx_register_baseclocks(xtal);
s3c2410_setup_clocks();
s3c2410_baseclk_add();
s3c24xx_register_clock(&s3c2410_armclk);
+ clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
}
struct sysdev_class s3c2410_sysclass = {
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 140711d..cd50291 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -659,6 +659,12 @@ static struct clk *clks[] __initdata = {
&clk_armclk,
};
+static struct clk_lookup s3c2412_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk),
+};
+
int __init s3c2412_baseclk_add(void)
{
unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
@@ -751,6 +757,7 @@ int __init s3c2412_baseclk_add(void)
s3c2412_clkcon_enable(clkp, 0);
}
+ clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
s3c_pwmclk_init();
return 0;
}
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index f85853c..c9879af 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -144,6 +144,12 @@ static struct clk s3c2440_clk_fclk_n = {
},
};
+static struct clk_lookup s3c2440_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
+};
+
static int s3c2440_clk_add(struct sys_device *sysdev)
{
struct clk *clock_upll;
@@ -167,6 +173,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
s3c24xx_register_clock(&s3c2440_clk_ac97);
s3c24xx_register_clock(&s3c2440_clk_cam);
s3c24xx_register_clock(&s3c2440_clk_cam_upll);
+ clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
clk_disable(&s3c2440_clk_ac97);
clk_disable(&s3c2440_clk_cam);
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 39c238d..2addd98 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -617,16 +617,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_uhost,
}, {
.clk = {
- .name = "uclk1",
- .ctrlbit = S3C_CLKCON_SCLK_UART,
- .enable = s3c64xx_sclk_ctrl,
- },
- .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
- .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
- .sources = &clkset_uart,
- }, {
-/* Where does UCLK0 come from? */
- .clk = {
.name = "spi-bus",
.devname = "s3c64xx-spi.0",
.ctrlbit = S3C_CLKCON_SCLK_SPI0,
@@ -695,6 +685,18 @@ static struct clksrc_clk clksrcs[] = {
},
};
+/* Where does UCLK0 come from? */
+static struct clksrc_clk clk_sclk_uclk = {
+ .clk = {
+ .name = "uclk1",
+ .ctrlbit = S3C_CLKCON_SCLK_UART,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
+ .sources = &clkset_uart,
+};
+
/* Clock initialisation code */
static struct clksrc_clk *init_parents[] = {
@@ -703,6 +705,15 @@ static struct clksrc_clk *init_parents[] = {
&clk_mout_mpll,
};
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uclk,
+};
+
+static struct clk_lookup s3c64xx_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
+};
+
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
void __init_or_cpufreq s3c6400_setup_clocks(void)
@@ -811,6 +822,8 @@ static struct clk *clks[] __initdata = {
void __init s3c64xx_register_clocks(unsigned long xtal,
unsigned armclk_divlimit)
{
+ unsigned int cnt;
+
armclk_mask = armclk_divlimit;
s3c24xx_register_baseclocks(xtal);
@@ -823,5 +836,9 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
+ s3c_register_clksrc(clksrc_cdev[cnt], 1);
+ clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
+
s3c_pwmclk_init();
}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index c54c65d..bfb1917 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -421,15 +421,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
}, {
.clk = {
- .name = "uclk1",
- .ctrlbit = (1 << 5),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
- }, {
- .clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 20),
@@ -487,6 +478,17 @@ static struct clksrc_clk clksrcs[] = {
},
};
+static struct clksrc_clk clk_sclk_uclk = {
+ .clk = {
+ .name = "uclk1",
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+};
+
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -505,6 +507,15 @@ static struct clk dummy_apb_pclk = {
.id = -1,
};
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uclk,
+};
+
+static struct clk_lookup s5p6440_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
+};
+
void __init_or_cpufreq s5p6440_setup_clocks(void)
{
struct clk *xtal_clk;
@@ -583,9 +594,12 @@ void __init s5p6440_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 2d04abf..d132638 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -443,15 +443,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
}, {
.clk = {
- .name = "uclk1",
- .ctrlbit = (1 << 5),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
- }, {
- .clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 20),
@@ -536,6 +527,26 @@ static struct clksrc_clk clksrcs[] = {
},
};
+static struct clksrc_clk clk_sclk_uclk = {
+ .clk = {
+ .name = "uclk1",
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uclk,
+};
+
+static struct clk_lookup s5p6450_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
+};
+
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -634,9 +645,12 @@ void __init s5p6450_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 8d47709..9d644ec 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -962,16 +962,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
}, {
.clk = {
- .name = "uclk1",
- .ctrlbit = (1 << 3),
- .enable = s5pc100_sclk0_ctrl,
-
- },
- .sources = &clk_src_group2,
- .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
- .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
- }, {
- .clk = {
.name = "sclk_mixer",
.ctrlbit = (1 << 6),
.enable = s5pc100_sclk0_ctrl,
@@ -1098,6 +1088,17 @@ static struct clksrc_clk clksrcs[] = {
},
};
+static struct clksrc_clk clk_sclk_uart = {
+ .clk = {
+ .name = "uclk1",
+ .ctrlbit = (1 << 3),
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clk_src_group2,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+};
+
/* Clock initialisation code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -1127,6 +1128,10 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_spdif,
};
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uart,
+};
+
void __init_or_cpufreq s5pc100_setup_clocks(void)
{
unsigned long xtal;
@@ -1266,6 +1271,11 @@ static struct clk *clks[] __initdata = {
&clk_pcmcdclk1,
};
+static struct clk_lookup s5pc100_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk),
+};
+
void __init s5pc100_register_clocks(void)
{
int ptr;
@@ -1277,9 +1287,12 @@ void __init s5pc100_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 4c5ac7a..43a045d 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -809,46 +809,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
}, {
.clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.0",
- .enable = s5pv210_clk_mask0_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.1",
- .enable = s5pv210_clk_mask0_ctrl,
- .ctrlbit = (1 << 13),
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.2",
- .enable = s5pv210_clk_mask0_ctrl,
- .ctrlbit = (1 << 14),
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .devname = "s5pv210-uart.3",
- .enable = s5pv210_clk_mask0_ctrl,
- .ctrlbit = (1 << 15),
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
- }, {
- .clk = {
.name = "sclk_fimc",
.devname = "s5pv210-fimc.0",
.enable = s5pv210_clk_mask1_ctrl,
@@ -1022,6 +982,61 @@ static struct clksrc_clk clksrcs[] = {
},
};
+static struct clksrc_clk clk_sclk_uart0 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.0",
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uart1 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.1",
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 13),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uart2 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.2",
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 14),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uart3 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.3",
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 15),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
+};
+
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uart0,
+ &clk_sclk_uart1,
+ &clk_sclk_uart2,
+ &clk_sclk_uart3,
+};
+
/* Clock initialisation code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -1261,6 +1276,14 @@ static struct clk *clks[] __initdata = {
&clk_pcmcdclk2,
};
+static struct clk_lookup s5pv210_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
+ CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
+ CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
+ CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
+ CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
+};
+
void __init s5pv210_register_clocks(void)
{
int ptr;
@@ -1273,11 +1296,15 @@ void __init s5pv210_register_clocks(void)
for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
s3c_register_clksrc(sclk_tv[ptr], 1);
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
+
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk);
s3c_pwmclk_init();
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 07a4c81..4a24e15 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -179,13 +179,6 @@ static struct clksrc_clk clk_usb_bus_host = {
static struct clksrc_clk clksrc_clks[] = {
{
- /* ART baud-rate clock sourced from esysclk via a divisor */
- .clk = {
- .name = "uartclk",
- .parent = &clk_esysclk.clk,
- },
- .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
- }, {
/* camera interface bus-clock, divided down from esysclk */
.clk = {
.name = "camif-upll", /* same as 2440 name */
@@ -205,6 +198,15 @@ static struct clksrc_clk clksrc_clks[] = {
},
};
+static struct clksrc_clk clk_esys_uart = {
+ /* ART baud-rate clock sourced from esysclk via a divisor */
+ .clk = {
+ .name = "uartclk",
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+};
+
static struct clk clk_i2s_ext = {
.name = "i2s-ext",
};
@@ -469,6 +471,12 @@ static struct clksrc_clk *clksrcs[] __initdata = {
&clk_msysclk,
};
+static struct clk_lookup s3c2443_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
+};
+
void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
fdiv_fn get_fdiv)
{
@@ -493,6 +501,7 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
/* See s3c2443/etc notes on disabling clocks@init time */
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
s3c2443_common_setup_clocks(get_mpll, get_fdiv);
}
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 7/9] serial: samsung: merge all SoC specific port reset functions
From: Thomas Abraham @ 2011-10-10 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
The port reset function in each of the platform specific extension performs
the same operations and hence all the reset port functions can be merged into
one and moved into the common samsung uart driver. The SoC specific port reset
functions are removed from SoC extensions.
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/tty/serial/s3c2410.c | 18 ------------------
drivers/tty/serial/s3c2412.c | 24 ------------------------
drivers/tty/serial/s3c2440.c | 24 ------------------------
drivers/tty/serial/s3c6400.c | 24 ------------------------
drivers/tty/serial/s5pv210.c | 22 +---------------------
drivers/tty/serial/samsung.c | 23 ++++++++++++++++++-----
6 files changed, 19 insertions(+), 116 deletions(-)
diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c
index e668a9d..1491c32 100644
--- a/drivers/tty/serial/s3c2410.c
+++ b/drivers/tty/serial/s3c2410.c
@@ -25,23 +25,6 @@
#include "samsung.h"
-static int s3c2410_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- dbg("s3c2410_serial_resetport: port=%p (%08lx), cfg=%p\n",
- port, port->mapbase, cfg);
-
- wr_regl(port, S3C2410_UCON, cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
static struct s3c24xx_uart_info s3c2410_uart_inf = {
.name = "Samsung S3C2410 UART",
.type = PORT_S3C2410,
@@ -56,7 +39,6 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = {
.num_clks = 2,
.clksel_mask = S3C2410_UCON_CLKMASK,
.clksel_shift = S3C2410_UCON_CLKSHIFT,
- .reset_port = s3c2410_serial_resetport,
};
static int s3c2410_serial_probe(struct platform_device *dev)
diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c
index 5b85c19..38ae730 100644
--- a/drivers/tty/serial/s3c2412.c
+++ b/drivers/tty/serial/s3c2412.c
@@ -25,29 +25,6 @@
#include "samsung.h"
-static int s3c2412_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- dbg("%s: port=%p (%08lx), cfg=%p\n",
- __func__, port, port->mapbase, cfg);
-
- /* ensure we don't change the clock settings... */
-
- ucon &= S3C2412_UCON_CLKMASK;
-
- wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
static struct s3c24xx_uart_info s3c2412_uart_inf = {
.name = "Samsung S3C2412 UART",
.type = PORT_S3C2412,
@@ -63,7 +40,6 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = {
.num_clks = 4,
.clksel_mask = S3C2412_UCON_CLKMASK,
.clksel_shift = S3C2412_UCON_CLKSHIFT,
- .reset_port = s3c2412_serial_resetport,
};
/* device management */
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c
index 39930f8..70652f5 100644
--- a/drivers/tty/serial/s3c2440.c
+++ b/drivers/tty/serial/s3c2440.c
@@ -25,29 +25,6 @@
#include "samsung.h"
-static int s3c2440_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
- port, port->mapbase, cfg);
-
- /* ensure we don't change the clock settings... */
-
- ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
-
- wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
static struct s3c24xx_uart_info s3c2440_uart_inf = {
.name = "Samsung S3C2440 UART",
.type = PORT_S3C2440,
@@ -62,7 +39,6 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = {
.num_clks = 4,
.clksel_mask = S3C2440_UCON_CLKMASK,
.clksel_shift = S3C2440_UCON_CLKSHIFT,
- .reset_port = s3c2440_serial_resetport,
};
/* device management */
diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c
index c5a6d46..30a69f1 100644
--- a/drivers/tty/serial/s3c6400.c
+++ b/drivers/tty/serial/s3c6400.c
@@ -26,29 +26,6 @@
#include "samsung.h"
-static int s3c6400_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- dbg("s3c6400_serial_resetport: port=%p (%08lx), cfg=%p\n",
- port, port->mapbase, cfg);
-
- /* ensure we don't change the clock settings... */
-
- ucon &= S3C6400_UCON_CLKMASK;
-
- wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
static struct s3c24xx_uart_info s3c6400_uart_inf = {
.name = "Samsung S3C6400 UART",
.type = PORT_S3C6400,
@@ -64,7 +41,6 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = {
.num_clks = 4,
.clksel_mask = S3C6400_UCON_CLKMASK,
.clksel_shift = S3C6400_UCON_CLKSHIFT,
- .reset_port = s3c6400_serial_resetport,
};
/* device management */
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
index 173df5a..d232094 100644
--- a/drivers/tty/serial/s5pv210.c
+++ b/drivers/tty/serial/s5pv210.c
@@ -25,25 +25,6 @@
#include <plat/regs-serial.h>
#include "samsung.h"
-static int s5pv210_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- ucon &= S5PV210_UCON_CLKMASK;
- wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- /* It is need to delay When reset FIFO register */
- udelay(1);
-
- return 0;
-}
-
#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
.name = "Samsung S5PV210 UART0", \
.type = PORT_S3C6400, \
@@ -58,8 +39,7 @@ static int s5pv210_serial_resetport(struct uart_port *port,
.def_clk_sel = S3C2410_UCON_CLKSEL0, \
.num_clks = 2, \
.clksel_mask = S5PV210_UCON_CLKMASK, \
- .clksel_shift = S5PV210_UCON_CLKSHIFT, \
- .reset_port = s5pv210_serial_resetport
+ .clksel_shift = S5PV210_UCON_CLKSHIFT
static struct s3c24xx_uart_info s5p_port_fifo256 = {
S5PV210_UART_DEFAULT_INFO(256),
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index dc5a4ed..78aea1a 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -965,16 +965,29 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
/* s3c24xx_serial_resetport
*
- * wrapper to call the specific reset for this port (reset the fifos
- * and the settings)
+ * reset the fifos and other the settings.
*/
-static inline int s3c24xx_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
+static void s3c24xx_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
{
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+ unsigned int ucon_mask;
- return (info->reset_port)(port, cfg);
+ ucon_mask = info->clksel_mask;
+ if (info->type == PORT_S3C2440)
+ ucon_mask |= S3C2440_UCON0_DIVMASK;
+
+ ucon &= ucon_mask;
+ wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+
+ /* reset both fifos */
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ /* some delay is required after fifo reset */
+ udelay(1);
}
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 8/9] serial: samsung: merge probe() function from all SoC specific extensions
From: Thomas Abraham @ 2011-10-10 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
With reset port, set clock and get clock functions in SoC specific extentions
being removed, only the driver probe is left over in these extensions. The
probe function itself can be merged into one and moved into the samsung common
serial driver. With driver probe also moved, all the SoC specific extentions
are no longer required and they are deleted.
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/plat-samsung/include/plat/regs-serial.h | 12 +
drivers/tty/serial/Kconfig | 45 +---
drivers/tty/serial/Makefile | 5 -
drivers/tty/serial/s3c2410.c | 74 -----
drivers/tty/serial/s3c2412.c | 78 -----
drivers/tty/serial/s3c2440.c | 77 -----
drivers/tty/serial/s3c6400.c | 79 -----
drivers/tty/serial/s5pv210.c | 94 ------
drivers/tty/serial/samsung.c | 360 +++++++++++++++-------
drivers/tty/serial/samsung.h | 18 +-
10 files changed, 265 insertions(+), 577 deletions(-)
delete mode 100644 drivers/tty/serial/s3c2410.c
delete mode 100644 drivers/tty/serial/s3c2412.c
delete mode 100644 drivers/tty/serial/s3c2440.c
delete mode 100644 drivers/tty/serial/s3c6400.c
delete mode 100644 drivers/tty/serial/s5pv210.c
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 133fa97..29c26a8 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -232,6 +232,18 @@
#define S3C2410_UCON_CLKSEL2 (1 << 2)
#define S3C2410_UCON_CLKSEL3 (1 << 3)
+/* Default values for s5pv210 UCON and UFCON uart registers */
+#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
#ifndef __ASSEMBLY__
/* configuration structure for per-machine configurations for the
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 4dcb37b..6c6c90d 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -450,7 +450,7 @@ config SERIAL_SAMSUNG
config SERIAL_SAMSUNG_UARTS_4
bool
depends on ARM && PLAT_SAMSUNG
- default y if CPU_S3C2443
+ default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
help
Internal node for the common case of 4 Samsung compatible UARTs
@@ -458,7 +458,7 @@ config SERIAL_SAMSUNG_UARTS
int
depends on ARM && PLAT_SAMSUNG
default 6 if ARCH_S5P6450
- default 4 if SERIAL_SAMSUNG_UARTS_4
+ default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
default 3
help
Select the number of available UART ports for the Samsung S3C
@@ -488,47 +488,6 @@ config SERIAL_SAMSUNG_CONSOLE
your boot loader about how to pass options to the kernel at
boot time.)
-config SERIAL_S3C2410
- tristate "Samsung S3C2410 Serial port support"
- depends on SERIAL_SAMSUNG && CPU_S3C2410
- default y if CPU_S3C2410
- help
- Serial port support for the Samsung S3C2410 SoC
-
-config SERIAL_S3C2412
- tristate "Samsung S3C2412/S3C2413 Serial port support"
- depends on SERIAL_SAMSUNG && CPU_S3C2412
- default y if CPU_S3C2412
- help
- Serial port support for the Samsung S3C2412 and S3C2413 SoC
-
-config SERIAL_S3C2440
- tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
- default y if CPU_S3C2440
- default y if CPU_S3C2442
- select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
- help
- Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
-
-config SERIAL_S3C6400
- tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
- select SERIAL_SAMSUNG_UARTS_4
- default y
- help
- Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
- and S5PC100 SoCs
-
-config SERIAL_S5PV210
- tristate "Samsung S5PV210 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210)
- select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210)
- default y
- help
- Serial port support for Samsung's S5P Family of SoC's
-
-
config SERIAL_MAX3100
tristate "MAX3100 support"
depends on SPI
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 83b4da6..afa6f7b 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -38,11 +38,6 @@ obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
-obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
-obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
-obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
-obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
-obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_MAX3107) += max3107.o
obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c
deleted file mode 100644
index 1491c32..0000000
--- a/drivers/tty/serial/s3c2410.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Driver for Samsung S3C2410 SoC onboard UARTs.
- *
- * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
- * 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 <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-
-#include "samsung.h"
-
-static struct s3c24xx_uart_info s3c2410_uart_inf = {
- .name = "Samsung S3C2410 UART",
- .type = PORT_S3C2410,
- .fifosize = 16,
- .rx_fifomask = S3C2410_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2410_UFSTAT_RXFULL,
- .tx_fifofull = S3C2410_UFSTAT_TXFULL,
- .tx_fifomask = S3C2410_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
- .def_clk_sel = S3C2410_UCON_CLKSEL0,
- .num_clks = 2,
- .clksel_mask = S3C2410_UCON_CLKMASK,
- .clksel_shift = S3C2410_UCON_CLKSHIFT,
-};
-
-static int s3c2410_serial_probe(struct platform_device *dev)
-{
- return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
-}
-
-static struct platform_driver s3c2410_serial_driver = {
- .probe = s3c2410_serial_probe,
- .remove = __devexit_p(s3c24xx_serial_remove),
- .driver = {
- .name = "s3c2410-uart",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c2410_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c2410_serial_driver, &s3c2410_uart_inf);
-}
-
-static void __exit s3c2410_serial_exit(void)
-{
- platform_driver_unregister(&s3c2410_serial_driver);
-}
-
-module_init(s3c2410_serial_init);
-module_exit(s3c2410_serial_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("Samsung S3C2410 SoC Serial port driver");
-MODULE_ALIAS("platform:s3c2410-uart");
diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c
deleted file mode 100644
index 38ae730..0000000
--- a/drivers/tty/serial/s3c2412.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
- *
- * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
- * 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 <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-
-#include "samsung.h"
-
-static struct s3c24xx_uart_info s3c2412_uart_inf = {
- .name = "Samsung S3C2412 UART",
- .type = PORT_S3C2412,
- .fifosize = 64,
- .has_divslot = 1,
- .rx_fifomask = S3C2440_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2440_UFSTAT_RXFULL,
- .tx_fifofull = S3C2440_UFSTAT_TXFULL,
- .tx_fifomask = S3C2440_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .def_clk_sel = S3C2410_UCON_CLKSEL2,
- .num_clks = 4,
- .clksel_mask = S3C2412_UCON_CLKMASK,
- .clksel_shift = S3C2412_UCON_CLKSHIFT,
-};
-
-/* device management */
-
-static int s3c2412_serial_probe(struct platform_device *dev)
-{
- dbg("s3c2440_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
-}
-
-static struct platform_driver s3c2412_serial_driver = {
- .probe = s3c2412_serial_probe,
- .remove = __devexit_p(s3c24xx_serial_remove),
- .driver = {
- .name = "s3c2412-uart",
- .owner = THIS_MODULE,
- },
-};
-
-static inline int s3c2412_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c2412_serial_driver, &s3c2412_uart_inf);
-}
-
-static inline void s3c2412_serial_exit(void)
-{
- platform_driver_unregister(&s3c2412_serial_driver);
-}
-
-module_init(s3c2412_serial_init);
-module_exit(s3c2412_serial_exit);
-
-MODULE_DESCRIPTION("Samsung S3C2412,S3C2413 SoC Serial port driver");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:s3c2412-uart");
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c
deleted file mode 100644
index 70652f5..0000000
--- a/drivers/tty/serial/s3c2440.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
- *
- * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
- * 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 <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-
-#include "samsung.h"
-
-static struct s3c24xx_uart_info s3c2440_uart_inf = {
- .name = "Samsung S3C2440 UART",
- .type = PORT_S3C2440,
- .fifosize = 64,
- .rx_fifomask = S3C2440_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2440_UFSTAT_RXFULL,
- .tx_fifofull = S3C2440_UFSTAT_TXFULL,
- .tx_fifomask = S3C2440_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .def_clk_sel = S3C2410_UCON_CLKSEL2,
- .num_clks = 4,
- .clksel_mask = S3C2440_UCON_CLKMASK,
- .clksel_shift = S3C2440_UCON_CLKSHIFT,
-};
-
-/* device management */
-
-static int s3c2440_serial_probe(struct platform_device *dev)
-{
- dbg("s3c2440_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
-}
-
-static struct platform_driver s3c2440_serial_driver = {
- .probe = s3c2440_serial_probe,
- .remove = __devexit_p(s3c24xx_serial_remove),
- .driver = {
- .name = "s3c2440-uart",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c2440_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);
-}
-
-static void __exit s3c2440_serial_exit(void)
-{
- platform_driver_unregister(&s3c2440_serial_driver);
-}
-
-module_init(s3c2440_serial_init);
-module_exit(s3c2440_serial_exit);
-
-MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:s3c2440-uart");
diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c
deleted file mode 100644
index 30a69f1..0000000
--- a/drivers/tty/serial/s3c6400.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * 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 <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-
-#include "samsung.h"
-
-static struct s3c24xx_uart_info s3c6400_uart_inf = {
- .name = "Samsung S3C6400 UART",
- .type = PORT_S3C6400,
- .fifosize = 64,
- .has_divslot = 1,
- .rx_fifomask = S3C2440_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2440_UFSTAT_RXFULL,
- .tx_fifofull = S3C2440_UFSTAT_TXFULL,
- .tx_fifomask = S3C2440_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .def_clk_sel = S3C2410_UCON_CLKSEL2,
- .num_clks = 4,
- .clksel_mask = S3C6400_UCON_CLKMASK,
- .clksel_shift = S3C6400_UCON_CLKSHIFT,
-};
-
-/* device management */
-
-static int s3c6400_serial_probe(struct platform_device *dev)
-{
- dbg("s3c6400_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c6400_uart_inf);
-}
-
-static struct platform_driver s3c6400_serial_driver = {
- .probe = s3c6400_serial_probe,
- .remove = __devexit_p(s3c24xx_serial_remove),
- .driver = {
- .name = "s3c6400-uart",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c6400_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c6400_serial_driver, &s3c6400_uart_inf);
-}
-
-static void __exit s3c6400_serial_exit(void)
-{
- platform_driver_unregister(&s3c6400_serial_driver);
-}
-
-module_init(s3c6400_serial_init);
-module_exit(s3c6400_serial_exit);
-
-MODULE_DESCRIPTION("Samsung S3C6400,S3C6410 SoC Serial port driver");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:s3c6400-uart");
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
deleted file mode 100644
index d232094..0000000
--- a/drivers/tty/serial/s5pv210.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * Based on drivers/serial/s3c6400.c
- *
- * Driver for Samsung S5PV210 SoC UARTs.
- *
- * 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 <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/delay.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <plat/regs-serial.h>
-#include "samsung.h"
-
-#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
- .name = "Samsung S5PV210 UART0", \
- .type = PORT_S3C6400, \
- .fifosize = fifo_size, \
- .has_divslot = 1, \
- .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
- .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
- .rx_fifofull = S5PV210_UFSTAT_RXFULL, \
- .tx_fifofull = S5PV210_UFSTAT_TXFULL, \
- .tx_fifomask = S5PV210_UFSTAT_TXMASK, \
- .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
- .def_clk_sel = S3C2410_UCON_CLKSEL0, \
- .num_clks = 2, \
- .clksel_mask = S5PV210_UCON_CLKMASK, \
- .clksel_shift = S5PV210_UCON_CLKSHIFT
-
-static struct s3c24xx_uart_info s5p_port_fifo256 = {
- S5PV210_UART_DEFAULT_INFO(256),
-};
-
-static struct s3c24xx_uart_info s5p_port_fifo64 = {
- S5PV210_UART_DEFAULT_INFO(64),
-};
-
-static struct s3c24xx_uart_info s5p_port_fifo16 = {
- S5PV210_UART_DEFAULT_INFO(16),
-};
-
-static struct s3c24xx_uart_info *s5p_uart_inf[] = {
- [0] = &s5p_port_fifo256,
- [1] = &s5p_port_fifo64,
- [2] = &s5p_port_fifo16,
- [3] = &s5p_port_fifo16,
-};
-
-/* device management */
-static int s5p_serial_probe(struct platform_device *pdev)
-{
- return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
-}
-
-static struct platform_driver s5p_serial_driver = {
- .probe = s5p_serial_probe,
- .remove = __devexit_p(s3c24xx_serial_remove),
- .driver = {
- .name = "s5pv210-uart",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s5p_serial_init(void)
-{
- return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf);
-}
-
-static void __exit s5p_serial_exit(void)
-{
- platform_driver_unregister(&s5p_serial_driver);
-}
-
-module_init(s5p_serial_init);
-module_exit(s5p_serial_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s5pv210-uart");
-MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support");
-MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 78aea1a..c89987b 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -206,7 +206,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
struct s3c24xx_uart_info *info = ourport->info;
if (ufstat & info->rx_fifofull)
- return info->fifosize;
+ return ourport->port.fifosize;
return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
}
@@ -1079,11 +1079,10 @@ static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *p
*/
static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
- struct s3c24xx_uart_info *info,
struct platform_device *platdev)
{
struct uart_port *port = &ourport->port;
- struct s3c2410_uartcfg *cfg = platdev->dev.platform_data;
+ struct s3c2410_uartcfg *cfg = ourport->cfg;
struct resource *res;
int ret;
@@ -1095,32 +1094,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
if (port->mapbase != 0)
return 0;
- /*
- * If platform data is supplied, keep a copy of the location of
- * platform data in the driver's private data.
- */
- if (cfg)
- ourport->cfg = cfg;
-
- if (cfg->hwport > CONFIG_SERIAL_SAMSUNG_UARTS) {
- printk(KERN_ERR "%s: port %d bigger than %d\n", __func__,
- cfg->hwport, CONFIG_SERIAL_SAMSUNG_UARTS);
- return -ERANGE;
- }
-
/* setup info for port */
port->dev = &platdev->dev;
- ourport->info = info;
/* Startup sequence is different for s3c64xx and higher SoC's */
if (s3c24xx_serial_has_interrupt_mask(port))
s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
- /* copy the info in from provided structure */
- ourport->port.fifosize = info->fifosize;
-
- dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport);
-
port->uartclk = 1;
if (cfg->uart_flags & UPF_CONS_FLOW) {
@@ -1187,34 +1167,46 @@ static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
static int probe_index;
-int s3c24xx_serial_probe(struct platform_device *dev,
- struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_probe(struct platform_device *pdev)
{
struct s3c24xx_uart_port *ourport;
int ret;
- dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
+ dbg("s3c24xx_serial_probe(%p) %d\n", pdev, probe_index);
ourport = &s3c24xx_serial_ports[probe_index];
+
+ ourport->drv_data = (struct s3c24xx_serial_drv_data *)
+ platform_get_device_id(pdev)->driver_data;
+
+ ourport->info = ourport->drv_data->info;
+ ourport->cfg = (pdev->dev.platform_data) ?
+ (struct s3c2410_uartcfg *)pdev->dev.platform_data :
+ ourport->drv_data->def_cfg;
+
+ ourport->port.fifosize = (ourport->info->fifosize) ?
+ ourport->info->fifosize :
+ ourport->drv_data->fifosize[probe_index];
+
probe_index++;
dbg("%s: initialising port %p...\n", __func__, ourport);
- ret = s3c24xx_serial_init_port(ourport, info, dev);
+ ret = s3c24xx_serial_init_port(ourport, pdev);
if (ret < 0)
goto probe_err;
dbg("%s: adding port\n", __func__);
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
- platform_set_drvdata(dev, &ourport->port);
+ platform_set_drvdata(pdev, &ourport->port);
- ret = device_create_file(&dev->dev, &dev_attr_clock_source);
+ ret = device_create_file(&pdev->dev, &dev_attr_clock_source);
if (ret < 0)
- printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__);
+ dev_err(&pdev->dev, "failed to add clock source attr.\n");
ret = s3c24xx_serial_cpufreq_register(ourport);
if (ret < 0)
- dev_err(&dev->dev, "failed to add cpufreq notifier\n");
+ dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
return 0;
@@ -1222,9 +1214,7 @@ int s3c24xx_serial_probe(struct platform_device *dev,
return ret;
}
-EXPORT_SYMBOL_GPL(s3c24xx_serial_probe);
-
-int __devexit s3c24xx_serial_remove(struct platform_device *dev)
+static int __devexit s3c24xx_serial_remove(struct platform_device *dev)
{
struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
@@ -1237,8 +1227,6 @@ int __devexit s3c24xx_serial_remove(struct platform_device *dev)
return 0;
}
-EXPORT_SYMBOL_GPL(s3c24xx_serial_remove);
-
/* UART power management code */
#ifdef CONFIG_PM_SLEEP
static int s3c24xx_serial_suspend(struct device *dev)
@@ -1278,41 +1266,6 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
#define SERIAL_SAMSUNG_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */
-int s3c24xx_serial_init(struct platform_driver *drv,
- struct s3c24xx_uart_info *info)
-{
- dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
-
- drv->driver.pm = SERIAL_SAMSUNG_PM_OPS;
-
- return platform_driver_register(drv);
-}
-
-EXPORT_SYMBOL_GPL(s3c24xx_serial_init);
-
-/* module initialisation code */
-
-static int __init s3c24xx_serial_modinit(void)
-{
- int ret;
-
- ret = uart_register_driver(&s3c24xx_uart_drv);
- if (ret < 0) {
- printk(KERN_ERR "failed to register UART driver\n");
- return -1;
- }
-
- return 0;
-}
-
-static void __exit s3c24xx_serial_modexit(void)
-{
- uart_unregister_driver(&s3c24xx_uart_drv);
-}
-
-module_init(s3c24xx_serial_modinit);
-module_exit(s3c24xx_serial_modexit);
-
/* Console code */
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
@@ -1418,36 +1371,12 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
else
rate = 1;
-
*baud = rate / (16 * (ubrdiv + 1));
dbg("calculated baud %d\n", *baud);
}
}
-/* s3c24xx_serial_init_ports
- *
- * initialise the serial ports from the machine provided initialisation
- * data.
-*/
-
-static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
-{
- struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
- struct platform_device **platdev_ptr;
- int i;
-
- dbg("s3c24xx_serial_init_ports: initialising ports...\n");
-
- platdev_ptr = s3c24xx_uart_devs;
-
- for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
- s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
- }
-
- return 0;
-}
-
static int __init
s3c24xx_serial_console_setup(struct console *co, char *options)
{
@@ -1491,11 +1420,6 @@ s3c24xx_serial_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-/* s3c24xx_serial_initconsole
- *
- * initialise the console from one of the uart drivers
-*/
-
static struct console s3c24xx_serial_console = {
.name = S3C24XX_SERIAL_NAME,
.device = uart_console_device,
@@ -1505,34 +1429,238 @@ static struct console s3c24xx_serial_console = {
.setup = s3c24xx_serial_console_setup,
.data = &s3c24xx_uart_drv,
};
+#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
+
+#ifdef CONFIG_CPU_S3C2410
+static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
+ .info = &(struct s3c24xx_uart_info) {
+ .name = "Samsung S3C2410 UART",
+ .type = PORT_S3C2410,
+ .fifosize = 16,
+ .rx_fifomask = S3C2410_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2410_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2410_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2410_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL0,
+ .num_clks = 2,
+ .clksel_mask = S3C2410_UCON_CLKMASK,
+ .clksel_shift = S3C2410_UCON_CLKSHIFT,
+ },
+ .def_cfg = &(struct s3c2410_uartcfg) {
+ .ucon = S3C2410_UCON_DEFAULT,
+ .ufcon = S3C2410_UFCON_DEFAULT,
+ },
+};
+#define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data)
+#else
+#define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#endif
-int s3c24xx_serial_initconsole(struct platform_driver *drv,
- struct s3c24xx_uart_info **info)
+#ifdef CONFIG_CPU_S3C2412
+static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
+ .info = &(struct s3c24xx_uart_info) {
+ .name = "Samsung S3C2412 UART",
+ .type = PORT_S3C2412,
+ .fifosize = 64,
+ .has_divslot = 1,
+ .rx_fifomask = S3C2440_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2440_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2440_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2440_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL2,
+ .num_clks = 4,
+ .clksel_mask = S3C2412_UCON_CLKMASK,
+ .clksel_shift = S3C2412_UCON_CLKSHIFT,
+ },
+ .def_cfg = &(struct s3c2410_uartcfg) {
+ .ucon = S3C2410_UCON_DEFAULT,
+ .ufcon = S3C2410_UFCON_DEFAULT,
+ },
+};
+#define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data)
+#else
+#define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#endif
-{
- struct platform_device *dev = s3c24xx_uart_devs[0];
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \
+ defined(CONFIG_CPU_S3C2443)
+static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
+ .info = &(struct s3c24xx_uart_info) {
+ .name = "Samsung S3C2440 UART",
+ .type = PORT_S3C2440,
+ .fifosize = 64,
+ .has_divslot = 1,
+ .rx_fifomask = S3C2440_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2440_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2440_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2440_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL2,
+ .num_clks = 4,
+ .clksel_mask = S3C2412_UCON_CLKMASK,
+ .clksel_shift = S3C2412_UCON_CLKSHIFT,
+ },
+ .def_cfg = &(struct s3c2410_uartcfg) {
+ .ucon = S3C2410_UCON_DEFAULT,
+ .ufcon = S3C2410_UFCON_DEFAULT,
+ },
+};
+#define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data)
+#else
+#define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#endif
- dbg("s3c24xx_serial_initconsole\n");
+#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) || \
+ defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) || \
+ defined(CONFIG_CPU_S5PC100)
+static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
+ .info = &(struct s3c24xx_uart_info) {
+ .name = "Samsung S3C6400 UART",
+ .type = PORT_S3C6400,
+ .fifosize = 64,
+ .has_divslot = 1,
+ .rx_fifomask = S3C2440_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2440_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2440_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2440_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL2,
+ .num_clks = 4,
+ .clksel_mask = S3C6400_UCON_CLKMASK,
+ .clksel_shift = S3C6400_UCON_CLKSHIFT,
+ },
+ .def_cfg = &(struct s3c2410_uartcfg) {
+ .ucon = S3C2410_UCON_DEFAULT,
+ .ufcon = S3C2410_UFCON_DEFAULT,
+ },
+};
+#define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data)
+#else
+#define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#endif
- /* select driver based on the cpu */
+#ifdef CONFIG_CPU_S5PV210
+static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
+ .info = &(struct s3c24xx_uart_info) {
+ .name = "Samsung S5PV210 UART",
+ .type = PORT_S3C6400,
+ .has_divslot = 1,
+ .rx_fifomask = S5PV210_UFSTAT_RXMASK,
+ .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
+ .rx_fifofull = S5PV210_UFSTAT_RXFULL,
+ .tx_fifofull = S5PV210_UFSTAT_TXFULL,
+ .tx_fifomask = S5PV210_UFSTAT_TXMASK,
+ .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL0,
+ .num_clks = 2,
+ .clksel_mask = S5PV210_UCON_CLKMASK,
+ .clksel_shift = S5PV210_UCON_CLKSHIFT,
+ },
+ .def_cfg = &(struct s3c2410_uartcfg) {
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ .fifosize = { 256, 64, 16, 16 },
+};
+#define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data)
+#else
+#define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#endif
- if (dev == NULL) {
- printk(KERN_ERR "s3c24xx: no devices for console init\n");
- return 0;
- }
+#ifdef CONFIG_CPU_EXYNOS4210
+static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
+ .info = &(struct s3c24xx_uart_info) {
+ .name = "Samsung Exynos4 UART",
+ .type = PORT_S3C6400,
+ .has_divslot = 1,
+ .rx_fifomask = S5PV210_UFSTAT_RXMASK,
+ .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
+ .rx_fifofull = S5PV210_UFSTAT_RXFULL,
+ .tx_fifofull = S5PV210_UFSTAT_TXFULL,
+ .tx_fifomask = S5PV210_UFSTAT_TXMASK,
+ .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL0,
+ .num_clks = 1,
+ .clksel_mask = 0,
+ .clksel_shift = 0,
+ },
+ .def_cfg = &(struct s3c2410_uartcfg) {
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ .has_fracval = 1,
+ },
+ .fifosize = { 256, 64, 16, 16 },
+};
+#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
+#else
+#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#endif
- if (strcmp(dev->name, drv->driver.name) != 0)
- return 0;
+static struct platform_device_id s3c24xx_serial_driver_ids[] = {
+ {
+ .name = "s3c2410-uart",
+ .driver_data = S3C2410_SERIAL_DRV_DATA,
+ }, {
+ .name = "s3c2412-uart",
+ .driver_data = S3C2412_SERIAL_DRV_DATA,
+ }, {
+ .name = "s3c2440-uart",
+ .driver_data = S3C2440_SERIAL_DRV_DATA,
+ }, {
+ .name = "s3c6400-uart",
+ .driver_data = S3C6400_SERIAL_DRV_DATA,
+ }, {
+ .name = "s5pv210-uart",
+ .driver_data = S5PV210_SERIAL_DRV_DATA,
+ }, {
+ .name = "exynos4210-uart",
+ .driver_data = EXYNOS4210_SERIAL_DRV_DATA,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
+
+static struct platform_driver samsung_serial_driver = {
+ .probe = s3c24xx_serial_probe,
+ .remove = __devexit_p(s3c24xx_serial_remove),
+ .id_table = s3c24xx_serial_driver_ids,
+ .driver = {
+ .name = "samsung-uart",
+ .owner = THIS_MODULE,
+ .pm = SERIAL_SAMSUNG_PM_OPS,
+ },
+};
- s3c24xx_serial_console.data = &s3c24xx_uart_drv;
- s3c24xx_serial_init_ports(info);
+/* module initialisation code */
- register_console(&s3c24xx_serial_console);
- return 0;
+static int __init s3c24xx_serial_modinit(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&s3c24xx_uart_drv);
+ if (ret < 0) {
+ printk(KERN_ERR "failed to register UART driver\n");
+ return -1;
+ }
+
+ return platform_driver_register(&samsung_serial_driver);
}
-#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
+static void __exit s3c24xx_serial_modexit(void)
+{
+ uart_unregister_driver(&s3c24xx_uart_drv);
+}
+
+module_init(s3c24xx_serial_modinit);
+module_exit(s3c24xx_serial_modexit);
+MODULE_ALIAS("platform:samsung-uart");
MODULE_DESCRIPTION("Samsung SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index c9cab2c..1a4bca3 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -32,6 +32,12 @@ struct s3c24xx_uart_info {
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
};
+struct s3c24xx_serial_drv_data {
+ struct s3c24xx_uart_info *info;
+ struct s3c2410_uartcfg *def_cfg;
+ unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS];
+};
+
struct s3c24xx_uart_port {
unsigned char rx_claimed;
unsigned char tx_claimed;
@@ -45,6 +51,7 @@ struct s3c24xx_uart_port {
struct clk *clk;
struct clk *baudclk;
struct uart_port port;
+ struct s3c24xx_serial_drv_data *drv_data;
/* reference to platform data */
struct s3c2410_uartcfg *cfg;
@@ -69,17 +76,6 @@ struct s3c24xx_uart_port {
#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
-extern int s3c24xx_serial_probe(struct platform_device *dev,
- struct s3c24xx_uart_info *uart);
-
-extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
-
-extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
- struct s3c24xx_uart_info **uart);
-
-extern int s3c24xx_serial_init(struct platform_driver *drv,
- struct s3c24xx_uart_info *info);
-
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
extern void printascii(const char *);
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 9/9] serial: samsung: add device tree support
From: Thomas Abraham @ 2011-10-10 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
Add device tree based discovery support for Samsung's uart controller.
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
.../devicetree/bindings/serial/samsung_uart.txt | 14 ++++++++
drivers/tty/serial/samsung.c | 36 ++++++++++++++++++-
2 files changed, 48 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/serial/samsung_uart.txt
diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.txt b/Documentation/devicetree/bindings/serial/samsung_uart.txt
new file mode 100644
index 0000000..2c8a17c
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.txt
@@ -0,0 +1,14 @@
+* Samsung's UART Controller
+
+The Samsung's UART controller is used for interfacing SoC with serial communicaion
+devices.
+
+Required properties:
+- compatible: should be
+ - "samsung,exynos4210-uart", for UART's compatible with Exynos4210 uart ports.
+
+- reg: base physical address of the controller and length of memory mapped
+ region.
+
+- interrupts: interrupt number to the cpu. The interrupt specifier format depends
+ on the interrupt controller parent.
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index c89987b..efe3756 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -42,6 +42,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
+#include <linux/of.h>
#include <asm/irq.h>
@@ -1163,10 +1164,26 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
+
/* Device driver serial port probe */
+static const struct of_device_id s3c24xx_uart_dt_match[];
static int probe_index;
+static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data(
+ struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node);
+ return (struct s3c24xx_serial_drv_data *)match->data;
+ }
+#endif
+ return (struct s3c24xx_serial_drv_data *)
+ platform_get_device_id(pdev)->driver_data;
+}
+
static int s3c24xx_serial_probe(struct platform_device *pdev)
{
struct s3c24xx_uart_port *ourport;
@@ -1176,8 +1193,11 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
ourport = &s3c24xx_serial_ports[probe_index];
- ourport->drv_data = (struct s3c24xx_serial_drv_data *)
- platform_get_device_id(pdev)->driver_data;
+ ourport->drv_data = s3c24xx_get_driver_data(pdev);
+ if (!ourport->drv_data) {
+ dev_err(&pdev->dev, "could not find driver data\n");
+ return -ENODEV;
+ }
ourport->info = ourport->drv_data->info;
ourport->cfg = (pdev->dev.platform_data) ?
@@ -1626,6 +1646,17 @@ static struct platform_device_id s3c24xx_serial_driver_ids[] = {
};
MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
+#ifdef CONFIG_OF
+static const struct of_device_id s3c24xx_uart_dt_match[] = {
+ { .compatible = "samsung,exynos4210-uart",
+ .data = &exynos4210_serial_drv_data },
+ {},
+};
+MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
+#else
+#define s3c24xx_uart_dt_match NULL
+#endif
+
static struct platform_driver samsung_serial_driver = {
.probe = s3c24xx_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
@@ -1634,6 +1665,7 @@ static struct platform_driver samsung_serial_driver = {
.name = "samsung-uart",
.owner = THIS_MODULE,
.pm = SERIAL_SAMSUNG_PM_OPS,
+ .of_match_table = s3c24xx_uart_dt_match,
},
};
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH] ARM: S3C64XX: Enable TCM support
From: Mark Brown @ 2011-10-10 10:27 UTC (permalink / raw)
To: linux-arm-kernel
The S3C64xx CPUs have TCMs so enable the kernel support for it on these
systems.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8e8f239..3de4cc1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -708,6 +708,7 @@ config ARCH_S3C64XX
select CPU_V6
select ARM_VIC
select HAVE_CLK
+ select HAVE_TCM
select CLKDEV_LOOKUP
select NO_IOPORT
select ARCH_USES_GETTIMEOFFSET
--
1.7.6.3
^ permalink raw reply related
* [GIT PULL] DEBUG_LL platform updates for 3.2
From: Will Deacon @ 2011-10-10 10:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201110072251.40028.arnd@arndb.de>
Hi Arnd,
On Fri, Oct 07, 2011 at 09:51:39PM +0100, Arnd Bergmann wrote:
> On Wednesday 28 September 2011, Will Deacon wrote:
> > Please pull these DEBUG_LL platform updates for 3.2. You can find the core
> > updates (actually all resident in arch/arm/Kconfig.debug) in Russell's
> > for-next branch.
> >
> > I think Stephen Boyd was planning to move MSM to the new code as well, but
> > I've not seen any code yet so I guess that can go in later.
>
> Hi Will,
>
> I've tried to pull this branch, but I'm getting conflicts with patches
> from the 'CPU mapping platform updates' series you sent me earlier.
> Any idea what's going on there?
Hmm, I expect that I've inadvertently ended up basing my patches on a branch
that Russell has rebased. I mentioned this on the list at the time:
http://lists.infradead.org/pipermail/linux-arm-kernel/2011-September/063729.html
> I can certainly fix up the conflicts, but my feeling is that there is
> something wrong on your side and one of the two branches contains
> stuff from a stale version of Russell's tree.
It looks like both of the branches [cpu-mapping and debug-ll] may be out of
date now. I agree that fixing up the conflicts isn't the way to go here, but
I'm unsure what to use as my base. I depend on patches that aren't in
Russell's devel-stable branch but are in his for-next branch.
The only things I can think of are either:
- Wait until everything has settled down, then rebase onto Russell's
for-linus branch. This has the disadvantage that conflicts and build
breakages won't be detected until very late.
- Wait until the dependencies are in mainline, then rebase against that.
Disadvantage is that it then takes twice as long to get code upstream.
- Send another pull request against an unstable branch and hope it doesn't
change. Disadvantage being that we have to keep repeating pull requests
against a moving target.
I'm not especially fond of any of those though...
Do you have any other ideas?
Cheers,
Will
^ permalink raw reply
* [PATCH v2 10/14] ARM: tegra: tegra_powergate_is_powered should be static
From: Sergei Shtylyov @ 2011-10-10 10:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318224484-2090-11-git-send-email-olof@lixom.net>
Hello.
On 10-10-2011 9:28, Olof Johansson wrote:
> Not exported and not used externally.
> Also, fix return type and change to instead WARN_ON on bad parameters.
Change to what? You're changing _to_ WARN_ON() as we can see, not from it...
> Signed-off-by: Olof Johansson<olof@lixom.net>
> ---
> arch/arm/mach-tegra/include/mach/powergate.h | 1 -
> arch/arm/mach-tegra/powergate.c | 5 ++---
> 2 files changed, 2 insertions(+), 4 deletions(-)
[...]
> diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
> index 3cee9aa..9483064 100644
> --- a/arch/arm/mach-tegra/powergate.c
> +++ b/arch/arm/mach-tegra/powergate.c
> @@ -89,12 +89,11 @@ int tegra_powergate_power_off(int id)
> return tegra_powergate_set(id, false);
> }
>
> -bool tegra_powergate_is_powered(int id)
> +static bool tegra_powergate_is_powered(int id)
> {
> u32 status;
>
> - if (id < 0 || id >= TEGRA_NUM_POWERGATE)
> - return -EINVAL;
> + WARN_ON(id< 0 || id>= TEGRA_NUM_POWERGATE);
>
> status = pmc_read(PWRGATE_STATUS)& (1<< id);
> return !!status;
WBR, Sergei
^ permalink raw reply
* [GIT PULL] DEBUG_LL platform updates for 3.2
From: Arnd Bergmann @ 2011-10-10 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010103635.GA2451@mudshark.cambridge.arm.com>
On Monday 10 October 2011, Will Deacon wrote:
> > I can certainly fix up the conflicts, but my feeling is that there is
> > something wrong on your side and one of the two branches contains
> > stuff from a stale version of Russell's tree.
>
> It looks like both of the branches [cpu-mapping and debug-ll] may be out of
> date now. I agree that fixing up the conflicts isn't the way to go here, but
> I'm unsure what to use as my base. I depend on patches that aren't in
> Russell's devel-stable branch but are in his for-next branch.
>
> The only things I can think of are either:
>
> - Wait until everything has settled down, then rebase onto Russell's
> for-linus branch. This has the disadvantage that conflicts and build
> breakages won't be detected until very late.
>
> - Wait until the dependencies are in mainline, then rebase against that.
> Disadvantage is that it then takes twice as long to get code upstream.
>
> - Send another pull request against an unstable branch and hope it doesn't
> change. Disadvantage being that we have to keep repeating pull requests
> against a moving target.
>
> I'm not especially fond of any of those though...
>
> Do you have any other ideas?
I think the best solution would be to ask Russell to put all the dependencies
into a non-rebasing branch and publish that, or to alternatively merge your
patches through his tree instead, with my Ack.
Both of these will also have to wait for a few more days until Russell
is back online.
Can you check if the devel-stable branch in his tree already contains the
dependencies?
Arnd
^ permalink raw reply
* orion/kirkwood and device tree support
From: Jason @ 2011-10-10 11:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201110091545.55645.michael@walle.cc>
Resend, messed up my email alias. I'm a dork. :-( Apologies.
Michael,
On Sun, Oct 09, 2011 at 03:45:55PM +0200, Michael Walle wrote:
> I submitted a patch to support the Buffalo LS-XHL three months ago, which was
> rejected because no more old fashioned board setup patches will be merged.
We have the same situation with the dreamplug (kirkwood based).
> Are there any plans or even ongoing developments to convert these platforms to
> support device trees?
I'm attempting to, but that requires my learning devicetree. Which is
fine in and of itself, but it also means I'm learning how Linux supports
arm SoCs. Which is taking some time. My current thought process is this:
1.) add arch/arm/mach-kirkwood/board-dt.c, arch/arm/boot/dts/kirkwood.dtsi,
and arch/arm/boot/dts/kirkwood-dreamplug.dts
2.) fill it in with replacements of calls in common.c and irq.c
3.) get it working cleanly.
4.) add in calls from mpp.c, pcie.c, and cpuidle.c
5.) build arch/arm/boot/dts/kirkwood-*.dts for other boards.
I'd be happy to coordinate and test, although I have no buffalo gear.
And I sure would appreciate some help. ;-)
thx,
Jason.
^ permalink raw reply
* [PATCH 2/2] pinmux: add a driver for the U300 pinmux
From: Barry Song @ 2011-10-10 11:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdZ-WTecB-SPXjs531heu4M5Jc-9YvjEV2fPfaHSxiYG2A@mail.gmail.com>
2011/10/10 Linus Walleij <linus.walleij@linaro.org>:
> On Sat, Oct 8, 2011 at 11:09 AM, Barry Song <21cnbao@gmail.com> wrote:
>>> +static void __init u300_pmx_dumpregs(struct u300_pmx *upmx)
>>> +{
>>> + ? ? ? u16 regval;
>>> + ? ? ? int i;
>>> +
>>> + ? ? ? for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) {
>>> + ? ? ? ? ? ? ? regval = readw(upmx->virtbase + u300_pmx_registers[i]);
>>> + ? ? ? ? ? ? ? dev_info(upmx->dev, "PMX%u: 0x%04x\n", i, regval);
>>> + ? ? ? }
>>> +}
>>
>> is this a debug information or do you want it to be in mainline?
>
> Debug info, I'll delete it. Not that it hurt, but I'll kill it.
>
>>> + ? ? ? /* Create state holders etc for this driver */
>>> + ? ? ? upmx = devm_kzalloc(&pdev->dev, sizeof(struct u300_pmx), GFP_KERNEL);
>>
>> and this would be "devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); " ?
>
> Same semantic effect, but if you prefer it that way, sure :-)
>
> I've seen both used in the kernel before...
coding style document says :
"
Chapter 14: Allocating memory
The kernel provides the following general purpose memory allocators:
kmalloc(), kzalloc(), kcalloc(), vmalloc(), and vzalloc(). Please refer to
the API documentation for further information about them.
The preferred form for passing a size of a struct is the following:
p = kmalloc(sizeof(*p), ...);
The alternative form where struct name is spelled out hurts readability and
introduces an opportunity for a bug when the pointer variable type is changed
but the corresponding sizeof that is passed to a memory allocator is not.
"
>
> Can I have your Reviewed-by: tag after this?
yes. of course.
>
> Linus Walleij
>
Thanks
barry
^ permalink raw reply
* [PATCH 2/9] ARM: SPMP8000: Add machine base files
From: Zoltan Devai @ 2011-10-10 11:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111009172232.GB18424@gallagher>
2011/10/9 Jamie Iles <jamie@jamieiles.com>:
> A couple of minor comments inline but this looks really good!
Thanks for reviewing! Comments inline.
> On Sun, Oct 09, 2011 at 06:36:05PM +0200, Zoltan Devai wrote:
> [...]
>> diff --git a/arch/arm/mach-spmp8000/Makefile b/arch/arm/mach-spmp8000/Makefile
>> new file mode 100644
>> index 0000000..9d35cca
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/Makefile
>> @@ -0,0 +1,11 @@
>> +#
>> +# Makefile for the linux kernel.
>> +#
>
> Nit: I don't think this comment adds a great deal of value.
Yep, but this seemed like a common pattern :)
I can't imagine anything that would add value, so will just
skip the header.
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?:= core.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= timer.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= pinmux.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= clock.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= clkdev.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= board_letcool.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= adc.o
>> +obj-y ? ? ? ? ? ? ? ? ? ? ? ?+= pwm.o
>> diff --git a/arch/arm/mach-spmp8000/core.c
>> b/arch/arm/mach-spmp8000/core.c
>> new file mode 100644
>> index 0000000..ba05614
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/core.c
>> @@ -0,0 +1,103 @@
>> +/*
>> + * SPMP8000 machines core functions
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/init.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <asm/mach/map.h>
>> +#include <asm/hardware/vic.h>
>> +#include <mach/hardware.h>
>> +#include <mach/scu.h>
>> +
>> +/* Static mappings:
>> + * SCU: timer needs clk support which is inited in init_early
>> + * UART: needed for earlyprintk
>> + */
>> +static struct map_desc io_desc[] __initdata = {
>> + ? ? {
>> + ? ? ? ? ? ? .virtual ? ? ? ?= IO_ADDRESS(SPMP8000_SCU_A_BASE),
>> + ? ? ? ? ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SPMP8000_SCU_A_BASE),
>> + ? ? ? ? ? ? .length ? ? ? ? = SPMP8000_SCU_A_SIZE,
>> + ? ? ? ? ? ? .type ? ? ? ? ? = MT_DEVICE,
>> + ? ? }, {
>> + ? ? ? ? ? ? .virtual ? ? ? ?= IO_ADDRESS(SPMP8000_SCU_B_BASE),
>> + ? ? ? ? ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SPMP8000_SCU_B_BASE),
>> + ? ? ? ? ? ? .length ? ? ? ? = SPMP8000_SCU_B_SIZE,
>> + ? ? ? ? ? ? .type ? ? ? ? ? = MT_DEVICE,
>> + ? ? }, {
>> + ? ? ? ? ? ? .virtual ? ? ? ?= IO_ADDRESS(SPMP8000_SCU_C_BASE),
>> + ? ? ? ? ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SPMP8000_SCU_C_BASE),
>> + ? ? ? ? ? ? .length ? ? ? ? = SPMP8000_SCU_C_SIZE,
>> + ? ? ? ? ? ? .type ? ? ? ? ? = MT_DEVICE,
>> + ? ? },
>> +#ifdef CONFIG_DEBUG_LL
>> + ? ? {
>> + ? ? ? ? ? ? .virtual ? ? ? ?= IO_ADDRESS(SPMP8000_UARTC0_BASE),
>> + ? ? ? ? ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SPMP8000_UARTC0_BASE),
>> + ? ? ? ? ? ? .length ? ? ? ? = SPMP8000_UARTC0_SIZE,
>> + ? ? ? ? ? ? .type ? ? ? ? ? = MT_DEVICE,
>> + ? ? },
>> +#endif
>> +};
>> +
>> +#define IO_PTR(x) ? ?((void __iomem *)IO_ADDRESS(x))
>
> Generally IO_ADDRESS returns a void __iomem pointer so it would be
> easier if you could have the cast in there (though it may need to be
> enclosed in #ifndef __ASSEMBLY__ conditionals).
Every instance I've seen returns an int, mainly because it's used for
the static mappings above.
So, if I make IO_ADDRESS return void __iomem, I'd have to make
a macro for casting it back to int, and we'd be where we started.
>> +/* Make the lookup of SCU base and clk enable registers easy for the clk
>> + * code, as they are not at the same offset in each controller */
>> +struct scu_reg_t scu_regs[3] = {
>> + ? ? { ? ? ? /* SCU_A */
>> + ? ? ? ? ? ? .base = IO_PTR(SPMP8000_SCU_A_BASE),
>> + ? ? ? ? ? ? .clken = IO_PTR(SPMP8000_SCU_A_BASE) + SCU_A_PERI_CLKEN,
>> + ? ? },
>> + ? ? { ? ? ? /* SCU_B */
>> + ? ? ? ? ? ? .base = IO_PTR(SPMP8000_SCU_B_BASE),
>> + ? ? ? ? ? ? .clken = IO_PTR(SPMP8000_SCU_B_BASE) + SCU_B_PERI_CLKEN,
>> + ? ? },
>> + ? ? { ? ? ? /* SCU_C */
>> + ? ? ? ? ? ? .base = IO_PTR(SPMP8000_SCU_C_BASE),
>> + ? ? ? ? ? ? .clken = IO_PTR(SPMP8000_SCU_C_BASE) + SCU_C_PERI_CLKEN,
>> + ? ? },
>> +};
>> +
>> +/* DMA controller names to be used for the filter
>> + * function of the DMA-Engine API. */
>> +char *spmp8000_dma_controller_names[] = {
>
> const char * const?
Sure.
>> + ? ? "93010000.dma", ? ? ? ? /* APBDMA_A */
>> + ? ? "92b00000.dma", ? ? ? ? /* APBDMA_C */
>> +};
>> +
>> +void __init spmp8000_map_io(void)
>> +{
>> + ? ? iotable_init(io_desc, ARRAY_SIZE(io_desc));
>> +}
>> +
>> +void __init spmp8000_init_irq(void)
>> +{
>> + ? ? struct device_node *np;
>> + ? ? int ret;
>> +
>> + ? ? np = of_find_compatible_node(NULL, NULL, "arm,pl192");
>> + ? ? if (!np)
>> + ? ? ? ? ? ? panic("Can't find VIC0 interrupt controller\n");
>> +
>> + ? ? ret = vic_of_init(np, NULL);
>> + ? ? if (ret)
>> + ? ? ? ? ? ? panic("Can't init VIC0 interrupt controller\n");
>> +
>> + ? ? np = of_find_compatible_node(np, NULL, "arm,pl192");
>> + ? ? if (!np)
>> + ? ? ? ? ? ? panic("Can't find VIC1 interrupt controller\n");
>> +
>> + ? ? ret = vic_of_init(np, NULL);
>> + ? ? if (ret)
>> + ? ? ? ? ? ? panic("Can't init VIC1 interrupt controller\n");
>> +
>> + ? ? of_node_put(np);
>
> So with Rob Herring's of_irq_init patches you should be able to reduce
> this to:
>
> ? ? ? ?static const struct of_device_id spmp8000_vic_matches[] = {
> ? ? ? ? ? ? ? ?{ .compatible = "arm,pl192", .data = vic_of_init },
> ? ? ? ?};
>
> ? ? ? ?of_irq_init(spmp8000_vic_matches);
>
> and that will handle both VIC's and ordering.
Works like a charm, thanks for the hint.
>> +}
>> diff --git a/arch/arm/mach-spmp8000/include/mach/core.h b/arch/arm/mach-spmp8000/include/mach/core.h
>> new file mode 100644
>> index 0000000..fa1d522
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/core.h
>> @@ -0,0 +1,29 @@
>> +/*
>> + * SPMP8000 generic includes
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#ifndef __MACH_SPMP8000_GENERIC_H__
>> +#define __MACH_SPMP8000_GENERIC_H__
>> +
>> +/* core.c */
>> +extern void __init spmp8000_map_io(void);
>> +extern void __init spmp8000_init_irq(void);
>
> Nit: you don't need the __init attributes in the header files.
Copy-paste it is. Removed.
>> +extern struct sys_timer spmp8000_sys_timer;
>> +
>> +/* clkdev.c */
>> +extern void __init spmp8000_init_clkdev(void);
>> +extern void spmp8000_update_arm_freqs(void); /* For cpufreq driver */
>> +
>> +/* pinmux.c */
>> +extern void spmp8000_pinmux_pgc_set(int pc, unsigned int conf);
>> +extern unsigned int spmp8000_pinmux_pgc_get(int pc);
>> +extern void spmp8000_pinmux_pgs_set(unsigned int pg, unsigned int func);
>> +extern int spmp8000_pinmux_pgs_get(int pg);
>> +
>> +#endif /* __MACH_SPMP8000_GENERIC_H__ */
> [...]
>> diff --git a/arch/arm/mach-spmp8000/include/mach/dma.h b/arch/arm/mach-spmp8000/include/mach/dma.h
>> new file mode 100644
>> index 0000000..44bc9f2
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/dma.h
>> @@ -0,0 +1,45 @@
>> +/*
>> + * SPMP8000 dma.h
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +#include <linux/module.h>
>> +#include <linux/dmaengine.h>
>
> It may be worth splitting the DMA part out into a separate patch unless
> this really is required for basic functionality.
I'll split these out for v2.
>> +
>> +#ifndef __MACH_SPMP8000_DMA_H__
>> +#define __MACH_SPMP8000_DMA_H__
>> +
>> +enum spmp8000_dma_controller {
>> + ? ? SPMP8000_APBDMA_A ? ? ? = 0,
>> + ? ? SPMP8000_APBDMA_C,
>> +};
>> +
>> +extern char *spmp8000_dma_controller_names[];
>> +
>> +struct spmp8000_dma_params {
>> + ? ? char ? ? ? ? ? ? ? ? ? ? ? ? ? ?*dma_controller;
>> + ? ? dma_addr_t ? ? ? ? ? ? ? ? ? ? ?dma_address;
>> + ? ? enum dma_slave_buswidth ? ? ? ? dma_width;
>> + ? ? int ? ? ? ? ? ? ? ? ? ? ? ? ? ? maxburst;
>> +};
>
> dmaengine has dma_slave_config that could be used for this, but I don't
> see any of this file being used in this series so perhaps it's worth
> adding in after the core stuff has been merged?
Will split.
This struct is used by the i2s driver to pass info to the pcm driver on how
to set up the dma controller. Seems to be the way to do.
>> +
>> +/* Driver parameters */
>> +#define SPMP8000_APBDMA_MAX_PERIODS ?64
>> +
>> +static bool spmp8000_dma_filter(struct dma_chan *chan, const char *name)
>> +{
>> + ? ? int ret;
>> +
>> + ? ? ret = strcmp(dev_name(chan->device->dev), name);
>> +
>> + ? ? if (ret)
>> + ? ? ? ? ? ? return false;
>> +
>> + ? ? return true;
>
> I think you can reduce this function to just
>
> ? ? ? ?return !strcmp(dev_name(chan->device->dev), name);
>
> and the compiler will do the right thing with int->bool conversion.
Yeah, just debugging leftover.
>> diff --git a/arch/arm/mach-spmp8000/include/mach/gpio.h
>> b/arch/arm/mach-spmp8000/include/mach/gpio.h
>> new file mode 100644
>> index 0000000..3eafac2
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/gpio.h
>> @@ -0,0 +1,21 @@
>> +/*
>> + * SPMP8000 machines gpio support
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#ifndef __MACH_SPMP8000_GPIO_H__
>> +#define __MACH_SPMP8000_GPIO_H__
>> +
>> +#include <asm-generic/gpio.h>
>> +
>> +#define gpio_get_value ? ? ? ? ? ? ? __gpio_get_value
>> +#define gpio_set_value ? ? ? ? ? ? ? __gpio_set_value
>> +#define gpio_cansleep ? ? ? ? ? ? ? ?__gpio_cansleep
>> +#define gpio_to_irq ? ? ? ? ?__gpio_to_irq
>
> Russell has a patch (ARM: gpio: make trivial GPIOLIB implementation the
> default) in for-next that means you shouldn't need these definitions
> anymore.
Which tree and branch should I base my work on ?
I'm quite confused by the all the options, and it seems like
if I choose some devel-stable tree, then I don't get the new
features and my work is outdated from the beginning,
but for-next branches are quite diverged.
Is there a good strategy ?
>> diff --git a/arch/arm/mach-spmp8000/include/mach/irqs.h
>> b/arch/arm/mach-spmp8000/include/mach/irqs.h
>> new file mode 100644
>> index 0000000..7f305d3
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/irqs.h
>> @@ -0,0 +1,21 @@
>> +/*
>> + * SPMP8000 irqs.h
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#ifndef __MACH_SPMP8000_IRQS_H__
>> +#define __MACH_SPMP8000_IRQS_H__
>> +
>> +#define SPMP8000_HW_IRQS ? ? ? ? ? ? 64
>> +#define SPMP8000_GPIO_IRQS_START ? ? SPMP8000_HW_IRQS
>> +#define SPMP8000_GPIO_IRQS ? ? ? ? ? (16 + 32)
>> +#define SPMP8000_TOTAL_IRQS ? ? ? ? ?(SPMP8000_HW_IRQS + SPMP8000_GPIO_IRQS)
>> +
>> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SPMP8000_TOTAL_IRQS
>
> I think that if you use my VIC patches then you can actually define
> NR_IRQS to 0 as all IRQ descs are dynamically allocated (otherwise
> you'll be reserving a bunch of irq_descs that never get used).
OK. Tried with 0, works.
>> diff --git a/arch/arm/mach-spmp8000/include/mach/regs-timer.h
>> b/arch/arm/mach-spmp8000/include/mach/regs-timer.h
>> new file mode 100644
>> index 0000000..90735df
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/regs-timer.h
>> @@ -0,0 +1,32 @@
>> +/*
>> + * SPMP8000 timer support
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + *
>> + * These timer reg definitions are used by the timer and pwm drivers
>> + */
>
> If these definitions are only being used inside arch/arm/mach-spmp8000
> then I'd put the headers in there rather than the
> arch/arm/mach-spmp8000/include/mach subdir so that the visibility is
> restricted to the mach code.
OK.
Depends on the final place of the PWM driver.
>> +#ifndef __MACH_SPMP8000_REGS_TIMER_H__
>> +#define __MACH_SPMP8000_REGS_TIMER_H__
>> +
>> +#define SPMP8000_TMRB(tnum) ?(tnum * 0x20)
>> +#define SPMP8000_TMRB_CTR ? ?0x00
>> +#define SPMP8000_TMRB_CTR_TE BIT(0)
>> +#define SPMP8000_TMRB_CTR_IE BIT(1)
>> +#define SPMP8000_TMRB_CTR_OE BIT(2)
>> +#define SPMP8000_TMRB_CTR_PWMON ? ? ?BIT(3)
>> +#define SPMP8000_TMRB_CTR_UD BIT(4)
>> +#define SPMP8000_TMRB_CTR_UDS ? ? ? ?BIT(5)
>> +#define SPMP8000_TMRB_CTR_OM BIT(6)
>> +#define SPMP8000_TMRB_CTR_ES_SH ? ? ?8
>> +#define SPMP8000_TMRB_CTR_M_SH ? ? ? 10
>> +#define SPMP8000_TMRB_PSR ? ?0x04
>> +#define SPMP8000_TMRB_LDR ? ?0x08
>> +#define SPMP8000_TMRB_VLR ? ?0x08
>> +#define SPMP8000_TMRB_ISR ? ?0x0C
>> +#define SPMP8000_TMRB_CMP ? ?0x10
>> +
>> +#endif /* __MACH_SPMP8000_REGS_TIMER_H__ */
>> diff --git a/arch/arm/mach-spmp8000/include/mach/scu.h b/arch/arm/mach-spmp8000/include/mach/scu.h
>> new file mode 100644
>> index 0000000..e3a98d4
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/scu.h
>
> Same here as the timer regs stuff.
OK, this can definitely move.
>> @@ -0,0 +1,146 @@
>> +/*
>> + * SPMP8000 System Control Unit register definitions
>> + * SCUs are a random collection of reset, clock, gpio, pinmux, etc. controllers
>> + * so that these definitions are needed at several places.
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#include <linux/bitops.h>
>> +#include <mach/hardware.h>
>> +
>> +#ifndef __MACH_SPMP8000_SCU_H__
>> +#define __MACH_SPMP8000_SCU_H__
>> +
>> +/* Used by to the clock code to directly access the SCU base and clock
>> + * enabling registers, without looking up the according registers first.
>> + */
>> +struct scu_reg_t {
>
> Generally speaking _t isn't used for structs.
OK.
>> + ? ? void *base;
>> + ? ? void *clken;
>
> Shouldn't these be void __iomem *?
Yes.
>> +};
>> +
>> +extern struct scu_reg_t scu_regs[];
>> +
>> +#define REG_SCU_BASE(x) ? ? ? ? ? ? ?scu_regs[x].base
>> +#define REG_SCU_CLKEN(x) ? ? scu_regs[x].clken
>> +#define REG_SCU_A_ID ? ? ? ? 0
>> +#define REG_SCU_B_ID ? ? ? ? 1
>> +#define REG_SCU_C_ID ? ? ? ? 2
>> +#define REG_SCU_A(x) ? ? ? ? (scu_regs[REG_SCU_A_ID].base + x)
>> +#define REG_SCU_B(x) ? ? ? ? (scu_regs[REG_SCU_B_ID].base + x)
>> +#define REG_SCU_C(x) ? ? ? ? (scu_regs[REG_SCU_C_ID].base + x)
>
> macros that assume there is a variable in scope with a given name
> (scu_regs) are generally frowned upon as it's difficult to see what's
> going on and can be a little error prone.
Yes, this isn't really nice. Will work out another way.
>> diff --git a/arch/arm/mach-spmp8000/include/mach/system.h
>> b/arch/arm/mach-spmp8000/include/mach/system.h
>> new file mode 100644
>> index 0000000..be53ff3
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/include/mach/system.h
>> @@ -0,0 +1,45 @@
>> +/*
>> + * SPMP8000 system.h
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#ifndef __MACH_SPMP8000_SYSTEM_H__
>> +#define __MACH_SPMP8000_SYSTEM_H__
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/io.h>
>> +
>> +#define SPMP8000_WDT_BASE ? ?0x90001000
>> +#define SPMP8000_WDT_SIZE ? ?0x1000
>> +
>> +#define SPMP8000_WDT_CTR ? ? 0x00
>> +#define SPMP8000_WDT_CTR_TE ?BIT(0)
>> +#define SPMP8000_WDT_CTR_RE ?BIT(3)
>> +
>> +static inline void arch_idle(void)
>> +{
>> + ? ? cpu_do_idle();
>> +}
>> +
>> +static inline void arch_reset(char mode, const char *cmd)
>> +{
>> + ? ? void *base;
>> +
>> + ? ? base = ioremap(SPMP8000_WDT_BASE, SPMP8000_WDT_SIZE);
>> + ? ? if (!base) {
>> + ? ? ? ? ? ? pr_err("spmp8000: Can't ioremap watchdog regs for reset. "
>> + ? ? ? ? ? ? ? ? ? ? "Halt.");
>> + ? ? ? ? ? ? while (1);
>> + ? ? }
>
> It may be worth doing the ioremap earlier when the system is in a known
> good state with all functions available rather than at reset time.
Any suggestion where the best place would be ?
I can only think of either the timer init or the board init, but neither seemed
to be appropriate.
>> +
>> + ? ? /* Trigger a watchdog reset */
>> + ? ? writel(SPMP8000_WDT_CTR_RE | SPMP8000_WDT_CTR_TE,
>> + ? ? ? ? ? ? ? ? ? ? base + SPMP8000_WDT_CTR);
>> +}
> [...]
>> diff --git a/arch/arm/mach-spmp8000/timer.c
>> b/arch/arm/mach-spmp8000/timer.c
>> new file mode 100644
>> index 0000000..7d5d0eb
>> --- /dev/null
>> +++ b/arch/arm/mach-spmp8000/timer.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + * SPMP8000 machines timer functions
>> + *
>> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/irq.h>
>> +#include <linux/io.h>
>> +#include <linux/err.h>
>> +#include <linux/bitops.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/clockchips.h>
>> +#include <linux/clk.h>
>> +#include <asm/mach/time.h>
>> +
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
>> +
>> +#include <mach/hardware.h>
>> +#include <mach/regs-timer.h>
>> +#include <mach/irqs.h>
>> +
>> +static unsigned long clkrate;
>> +static const unsigned int tickrate = 1012500;
>> +
>> +/* The TIMER_B block is used as system timer
>> + * T2: Clocksource
>> + * T1: Clockevent
>> + * T0: PWM for LCD backlight
>> + * T3,4: Could be used as additional clockevent devices
>> + * Timer constraints:
>> + * - WDT: Can't clear the irq directly, only by resetting the whole counter
>> + * ? in the ISR, which means that IRQs will jitter
>> + * - Timer_B: Can't reset the timer value, so at start, the first IRQ
>> + * ? will happen at some random time.
>> + */
>> +#define ? ? ? ? ? ? ?CS_TIMER ? ? ? ?2
>> +#define ? ? ? ? ? ? ?CE_TIMER ? ? ? ?1
>
> Nit: removing the extra spaces between the define and the CS_TIMER...
> might make it easier to grep for.
OK.
>> +static void __iomem *cs_base;
>> +static void __iomem *ce_base;
>> +
>> +static void tmrb_set_mode(enum clock_event_mode mode,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *dev)
>> +{
>> + ? ? switch (mode) {
>> + ? ? case CLOCK_EVT_MODE_PERIODIC:
>> + ? ? ? ? ? ? writel((tickrate / HZ), ce_base + SPMP8000_TMRB_LDR);
>> + ? ? ? ? ? ? /* Configure as periodic, down counter, IEN, enable timer */
>> + ? ? ? ? ? ? writel(SPMP8000_TMRB_CTR_TE | SPMP8000_TMRB_CTR_IE |
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1 << SPMP8000_TMRB_CTR_M_SH),
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ce_base + SPMP8000_TMRB_CTR);
>> + ? ? ? ? ? ? break;
>> + ? ? case CLOCK_EVT_MODE_ONESHOT:
>> + ? ? ? ? ? ? BUG();
>> + ? ? ? ? ? ? break;
>
> This case can be folded into the CLOCK_EVT_MODE_RESUME case (and changed
> to be a default case).
OK.
>> + ? ? case CLOCK_EVT_MODE_SHUTDOWN:
>> + ? ? case CLOCK_EVT_MODE_UNUSED:
>> + ? ? ? ? ? ? /* Disable timer */
>> + ? ? ? ? ? ? writel(0, ce_base + SPMP8000_TMRB_CTR);
>> + ? ? ? ? ? ? break;
>> + ? ? case CLOCK_EVT_MODE_RESUME:
>> + ? ? ? ? ? ? BUG();
>> + ? ? ? ? ? ? break;
>> + ? ? }
>> +}
>> +
>> +static struct clock_event_device tmrb1_clkevt = {
>> + ? ? .name ? ? ? ? ? = "tmrb1",
>> + ? ? .features ? ? ? = CLOCK_EVT_FEAT_PERIODIC,
>> + ? ? .rating ? ? ? ? = 200,
>> + ? ? .set_mode ? ? ? = tmrb_set_mode,
>> +};
>> +
>> +static irqreturn_t tmrb1_isr(int irq, void *dev_id)
>> +{
>> + ? ? tmrb1_clkevt.event_handler(&tmrb1_clkevt);
>> +
>> + ? ? /* Clear IRQ */
>> + ? ? writel(0, ce_base + SPMP8000_TMRB_ISR);
>> +
>> + ? ? return IRQ_HANDLED;
>> +};
>> +
>> +static struct irqaction tmrb1_irq = {
>> + ? ? .name ? ? ? ? ? = "tmrb1_irq",
>> + ? ? .flags ? ? ? ? ?= IRQF_TIMER | IRQF_IRQPOLL,
>> + ? ? .handler ? ? ? ?= tmrb1_isr,
>> +};
>> +
>> +static void __init spmp8000_sys_timer_init(void)
>> +{
>> + ? ? struct device_node *np;
>> + ? ? unsigned int irq;
>> + ? ? struct clk *clk;
>> + ? ? void *tmrb_base;
>> +
>> + ? ? np = of_find_compatible_node(NULL, NULL, "sunplus,spmp8000-timer");
>> + ? ? if (!np)
>> + ? ? ? ? ? ? panic("spmp8000: unable to find timer node in dtb\n");
>> +
>> + ? ? tmrb_base = of_iomap(np, 0);
>> + ? ? if (!tmrb_base)
>> + ? ? ? ? ? ? panic("spmp8000: unable to map timer cpu registers\n");
>> +
>> + ? ? irq = of_irq_to_resource(np, CE_TIMER, NULL);
>> + ? ? if (irq == NO_IRQ)
>> + ? ? ? ? ? ? panic("spmp8000: unable to get interrupts of timer\n");
>> +
>> + ? ? of_node_put(np);
>> +
>> + ? ? cs_base = tmrb_base + SPMP8000_TMRB(CS_TIMER);
>> + ? ? ce_base = tmrb_base + SPMP8000_TMRB(CE_TIMER);
>> +
>> + ? ? clk = clk_get(NULL, "arm_apb");
>> + ? ? if (IS_ERR_OR_NULL(clk))
>
> NULL can actually be a valid clk cookie so this should just be
> IS_ERR(clk).
OK.
>> + ? ? ? ? ? ? panic("spmp8000: Can't get clock for timer device");
>> +
>> + ? ? clk_enable(clk);
>
> Should probably check for success/failure here.
OK.
>> + ? ? clkrate = clk_get_rate(clk);
>> +
>> + ? ? /* Clocksource */
>> + ? ? /* Disable timer */
>> + ? ? writel(0, cs_base + SPMP8000_TMRB_CTR);
>> +
>> + ? ? /* Reset counter value
>> + ? ? ?* Not really possible unless setting end-1 LDR value and waiting
>> + ? ? ?* until the counter reaches that */
>> +
>> + ? ? /* Prescale timer */
>> + ? ? writel((clkrate / tickrate) - 1, cs_base + SPMP8000_TMRB_PSR);
>> +
>> + ? ? /* Register the clocksource */
>> + ? ? clocksource_mmio_init(cs_base + SPMP8000_TMRB_VLR, "tmrb2",
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? tickrate, 200, 16, clocksource_mmio_readl_up);
>> +
>> + ? ? /* Configure as free running (0 - 0xFFFF), up counter, enable timer */
>> + ? ? writel(SPMP8000_TMRB_CTR_TE | SPMP8000_TMRB_CTR_UD,
>> + ? ? ? ? ? ? cs_base + SPMP8000_TMRB_CTR);
>> +
>> + ? ? /* Clockevent */
>> + ? ? setup_irq(irq, &tmrb1_irq);
>> +
>> + ? ? /* Disable timer */
>> + ? ? writel(0, ce_base + SPMP8000_TMRB_CTR);
>> +
>> + ? ? /* Prescale timer */
>> + ? ? writel((clkrate / tickrate) - 1, ce_base + SPMP8000_TMRB_PSR);
>> +
>> + ? ? clockevents_register_device(&tmrb1_clkevt);
>> +}
>> +
>> +struct sys_timer spmp8000_sys_timer = {
>> + ? ? .init ? ? ? ? ? = spmp8000_sys_timer_init,
>> +};
>
^ permalink raw reply
* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Zoltan Devai @ 2011-10-10 11:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010100020.GA3607@opensource.wolfsonmicro.com>
2011/10/10 Mark Brown <broonie@opensource.wolfsonmicro.com>:
> On Mon, Oct 10, 2011 at 10:42:49AM +0100, Jonathan Cameron wrote:
>
>> It really depends on what those general adc callbacks get used for.
>
> If it's a general purpose ADC it's up to the board designer - you
> sometimes see things like battery or supply monitoring but really it
> could be any low volume analogue input.
It's really up to the board designer. In this case, all real-world
scenarios use the adc for analog-keys AND battery monitoring.
Jonathan, your analysis of the driver is completely correct:
Currently, only the not-yet-submitted analog-keys input driver uses
this, but I'd like to add battery monitoring shortly, so this has at
least two users.
Where should the adc driver go in this case ?
Zoltan
^ permalink raw reply
* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Mark Brown @ 2011-10-10 11:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGVye5Nc9vhaF=7Y+hvGo4g-GOFb9fHeni+g=+hTj-8WCSqY+Q@mail.gmail.com>
On Mon, Oct 10, 2011 at 01:42:30PM +0200, Zoltan Devai wrote:
> Where should the adc driver go in this case ?
At the minute it seems to me that arch/arm is as good a place as any
really - currently this code is getting dumped wherever the main device
is.
^ permalink raw reply
* [PATCH 2/9] ARM: SPMP8000: Add machine base files
From: Jamie Iles @ 2011-10-10 11:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGVye5NYE+CUbAAtwuP6JWG3HDP-bYs2dVqkuX_iYVGmKq6aWA@mail.gmail.com>
On Mon, Oct 10, 2011 at 01:36:09PM +0200, Zoltan Devai wrote:
> 2011/10/9 Jamie Iles <jamie@jamieiles.com>:
> > A couple of minor comments inline but this looks really good!
> Thanks for reviewing! Comments inline.
>
> > On Sun, Oct 09, 2011 at 06:36:05PM +0200, Zoltan Devai wrote:
[...]
> >> +#ifdef CONFIG_DEBUG_LL
> >> + ? ? {
> >> + ? ? ? ? ? ? .virtual ? ? ? ?= IO_ADDRESS(SPMP8000_UARTC0_BASE),
> >> + ? ? ? ? ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SPMP8000_UARTC0_BASE),
> >> + ? ? ? ? ? ? .length ? ? ? ? = SPMP8000_UARTC0_SIZE,
> >> + ? ? ? ? ? ? .type ? ? ? ? ? = MT_DEVICE,
> >> + ? ? },
> >> +#endif
> >> +};
> >> +
> >> +#define IO_PTR(x) ? ?((void __iomem *)IO_ADDRESS(x))
> >
> > Generally IO_ADDRESS returns a void __iomem pointer so it would be
> > easier if you could have the cast in there (though it may need to be
> > enclosed in #ifndef __ASSEMBLY__ conditionals).
> Every instance I've seen returns an int, mainly because it's used for
> the static mappings above.
> So, if I make IO_ADDRESS return void __iomem, I'd have to make
> a macro for casting it back to int, and we'd be where we started.
Yes, you're quite right!
[...]
> >> +
> >> +#ifndef __MACH_SPMP8000_DMA_H__
> >> +#define __MACH_SPMP8000_DMA_H__
> >> +
> >> +enum spmp8000_dma_controller {
> >> + ? ? SPMP8000_APBDMA_A ? ? ? = 0,
> >> + ? ? SPMP8000_APBDMA_C,
> >> +};
> >> +
> >> +extern char *spmp8000_dma_controller_names[];
> >> +
> >> +struct spmp8000_dma_params {
> >> + ? ? char ? ? ? ? ? ? ? ? ? ? ? ? ? ?*dma_controller;
> >> + ? ? dma_addr_t ? ? ? ? ? ? ? ? ? ? ?dma_address;
> >> + ? ? enum dma_slave_buswidth ? ? ? ? dma_width;
> >> + ? ? int ? ? ? ? ? ? ? ? ? ? ? ? ? ? maxburst;
> >> +};
> >
> > dmaengine has dma_slave_config that could be used for this, but I don't
> > see any of this file being used in this series so perhaps it's worth
> > adding in after the core stuff has been merged?
> Will split.
> This struct is used by the i2s driver to pass info to the pcm driver on how
> to set up the dma controller. Seems to be the way to do.
OK, so this is platform data for the i2s driver?
> Which tree and branch should I base my work on ?
> I'm quite confused by the all the options, and it seems like
> if I choose some devel-stable tree, then I don't get the new
> features and my work is outdated from the beginning,
> but for-next branches are quite diverged.
> Is there a good strategy ?
That's a tricky one. I have a similar problem, and rightly or wrongly I
generally put most of the stuff I can based of off an -rc tag from
Linus' tree then merge in the others during testing. As long as those
get merged first you don't need to do anything else, but it does get a
bit fiddly.
> >> diff --git a/arch/arm/mach-spmp8000/include/mach/system.h
> >> b/arch/arm/mach-spmp8000/include/mach/system.h
> >> new file mode 100644
> >> index 0000000..be53ff3
> >> --- /dev/null
> >> +++ b/arch/arm/mach-spmp8000/include/mach/system.h
> >> @@ -0,0 +1,45 @@
> >> +/*
> >> + * SPMP8000 system.h
> >> + *
> >> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
> >> + *
> >> + * This file is licensed under the terms of the GNU General Public
> >> + * License version 2. This program is licensed "as is" without any
> >> + * warranty of any kind, whether express or implied.
> >> + */
> >> +
> >> +#ifndef __MACH_SPMP8000_SYSTEM_H__
> >> +#define __MACH_SPMP8000_SYSTEM_H__
> >> +
> >> +#include <linux/kernel.h>
> >> +#include <linux/io.h>
> >> +
> >> +#define SPMP8000_WDT_BASE ? ?0x90001000
> >> +#define SPMP8000_WDT_SIZE ? ?0x1000
> >> +
> >> +#define SPMP8000_WDT_CTR ? ? 0x00
> >> +#define SPMP8000_WDT_CTR_TE ?BIT(0)
> >> +#define SPMP8000_WDT_CTR_RE ?BIT(3)
> >> +
> >> +static inline void arch_idle(void)
> >> +{
> >> + ? ? cpu_do_idle();
> >> +}
> >> +
> >> +static inline void arch_reset(char mode, const char *cmd)
> >> +{
> >> + ? ? void *base;
> >> +
> >> + ? ? base = ioremap(SPMP8000_WDT_BASE, SPMP8000_WDT_SIZE);
> >> + ? ? if (!base) {
> >> + ? ? ? ? ? ? pr_err("spmp8000: Can't ioremap watchdog regs for reset. "
> >> + ? ? ? ? ? ? ? ? ? ? "Halt.");
> >> + ? ? ? ? ? ? while (1);
> >> + ? ? }
> >
> > It may be worth doing the ioremap earlier when the system is in a known
> > good state with all functions available rather than at reset time.
> Any suggestion where the best place would be ?
> I can only think of either the timer init or the board init, but neither seemed
> to be appropriate.
Personally I think having a soc init function that does this sort of
stuff and gets called from the board init would be suitable for this
sort of thing. If the ioremap() fails you could always fall back to a
soft reset.
Jamie
^ permalink raw reply
* [PATCH 0/2] ARM: OMAP2+: timer fixes / cleanup
From: Cousson, Benoit @ 2011-10-10 11:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAC83ZvLd27nER5z1R1L27KFR4CQ1mwhmQ18BR7OCBZEDtNFWYg@mail.gmail.com>
On 10/10/2011 12:05 PM, DebBarma, Tarun Kanti wrote:
> On Mon, Oct 10, 2011 at 11:10 AM, DebBarma, Tarun Kanti
> <tarun.kanti@ti.com> wrote:
>> On Wed, Oct 5, 2011 at 3:06 AM, Cousson, Benoit<b-cousson@ti.com> wrote:
>>> Hi Tarun,
>>>
>>> On 10/4/2011 11:20 PM, Cousson, Benoit wrote:
>>>>
>>>> Hi Tony,
>>>>
>>>> Here is the series to fix the warning and remove the redundant
>>>> latency structure that be removed since the timer runtime PM
>>>> adaptation was just pulled.
>>>>
>>>> I was just able to test that on OMAP4.
>>>
>>> It will be nice if you can test that on the other platforms.
>>> In theory, if they are properly using hwmod that should work fine.
>> Yes, I will test in other platforms.
> I have tested on OMAP2420, OMAP2430 and OMAP3430.
Thanks Tarun,
Regards,
Benoit
^ permalink raw reply
* [PATCH 2/3] ARM: plat-samsung: use Kconfig choice for debug UART selection
From: Thomas Abraham @ 2011-10-10 11:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1313530873-24961-2-git-send-email-will.deacon@arm.com>
Hi Will,
On 17 August 2011 03:11, Will Deacon <will.deacon@arm.com> wrote:
> Now that the DEBUG_LL UART can be selected by a Kconfig choice, convert
> the Samsung UART selection to use a set of bools rather than an int.
>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
> ?arch/arm/Kconfig.debug ? ? ? ?| ? 45 ++++++++++++++++++++++++++++++-----------
> ?arch/arm/plat-samsung/Kconfig | ? ?7 ++++++
> ?2 files changed, 40 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index 11604c9..2f80564 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -94,6 +94,39 @@ choice
> ? ? ? ? ? ? ? ? ?Saying N will cause the debug messages to appear on the first
> ? ? ? ? ? ? ? ? ?serial port.
>
> + ? ? ? config DEBUG_S3C_UART0
> + ? ? ? ? ? ? ? depends on PLAT_SAMSUNG
> + ? ? ? ? ? ? ? bool "Use S3C UART 0 for low-level debug"
> + ? ? ? ? ? ? ? help
> + ? ? ? ? ? ? ? ? Say Y here if you want the debug print routines to direct
> + ? ? ? ? ? ? ? ? their output to UART 0. The port must have been initialised
> + ? ? ? ? ? ? ? ? by the boot-loader before use.
> +
> + ? ? ? ? ? ? ? ? The uncompressor code port configuration is now handled
> + ? ? ? ? ? ? ? ? by CONFIG_S3C_LOWLEVEL_UART_PORT.
> +
> + ? ? ? config DEBUG_S3C_UART1
> + ? ? ? ? ? ? ? depends on PLAT_SAMSUNG
> + ? ? ? ? ? ? ? bool "Use S3C UART 1 for low-level debug"
> + ? ? ? ? ? ? ? help
> + ? ? ? ? ? ? ? ? Say Y here if you want the debug print routines to direct
> + ? ? ? ? ? ? ? ? their output to UART 1. The port must have been initialised
> + ? ? ? ? ? ? ? ? by the boot-loader before use.
> +
> + ? ? ? ? ? ? ? ? The uncompressor code port configuration is now handled
> + ? ? ? ? ? ? ? ? by CONFIG_S3C_LOWLEVEL_UART_PORT.
> +
> + ? ? ? config DEBUG_S3C_UART2
> + ? ? ? ? ? ? ? depends on PLAT_SAMSUNG
> + ? ? ? ? ? ? ? bool "Use S3C UART 2 for low-level debug"
> + ? ? ? ? ? ? ? help
> + ? ? ? ? ? ? ? ? Say Y here if you want the debug print routines to direct
> + ? ? ? ? ? ? ? ? their output to UART 2. The port must have been initialised
> + ? ? ? ? ? ? ? ? by the boot-loader before use.
> +
> + ? ? ? ? ? ? ? ? The uncompressor code port configuration is now handled
> + ? ? ? ? ? ? ? ? by CONFIG_S3C_LOWLEVEL_UART_PORT.
> +
> ?endchoice
>
> ?config EARLY_PRINTK
> @@ -124,16 +157,4 @@ config OC_ETM
> ? ? ? ? ?buffer driver that will allow you to collect traces of the
> ? ? ? ? ?kernel code.
>
> -config DEBUG_S3C_UART
> - ? ? ? depends on PLAT_SAMSUNG
> - ? ? ? int "S3C UART to use for low-level debug"
> - ? ? ? default "0"
> - ? ? ? help
> - ? ? ? ? Choice for UART for kernel low-level using S3C UARTS,
> - ? ? ? ? should be between zero and two. The port must have been
> - ? ? ? ? initialised by the boot-loader before use.
> -
> - ? ? ? ? The uncompressor code port configuration is now handled
> - ? ? ? ? by CONFIG_S3C_LOWLEVEL_UART_PORT.
> -
> ?endmenu
> diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
> index b3e1065..49b14b1 100644
> --- a/arch/arm/plat-samsung/Kconfig
> +++ b/arch/arm/plat-samsung/Kconfig
> @@ -367,4 +367,11 @@ config SAMSUNG_PD
> ? ? ? ?help
> ? ? ? ? ?Say Y here if you want to control Power Domain by Runtime PM.
>
> +config DEBUG_S3C_UART
> + ? ? ? depends on PLAT_SAMSUNG
> + ? ? ? int
> + ? ? ? default "0" if DEBUG_S3C_UART0
> + ? ? ? default "1" if DEBUG_S3C_UART1
> + ? ? ? default "2" if DEBUG_S3C_UART2
> +
> ?endif
> --
> 1.7.0.4
What is your opinion about the following diff instead of the above one?
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 65cf8c6..035f5cd 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -120,6 +120,15 @@ choice
Say Y here if you want the debug print routines to direct
their output to the second serial port on these devices.
+ config DEBUG_SAMSUNG_UART
+ bool "Kernel low-level debugging messages via samsung serial port"
+ depends on PLAT_SAMSUNG
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port for Samsung platforms. Choose
+ the uart port with the "S3C UART to use for low-level debug"
+ config option.
+
endchoice
config EARLY_PRINTK
@@ -139,7 +148,7 @@ config OC_ETM
kernel code.
config DEBUG_S3C_UART
- depends on PLAT_SAMSUNG
+ depends on DEBUG_SAMSUNG_UART
int "S3C UART to use for low-level debug"
default "0"
help
Thanks,
Thomas.
^ permalink raw reply related
* [PATCH v10] pinctrl: add a driver for the U300 pinmux
From: Barry Song @ 2011-10-10 11:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318235485-2112-1-git-send-email-linus.walleij@stericsson.com>
2011/10/10 Linus Walleij <linus.walleij@stericsson.com>:
> From: Linus Walleij <linus.walleij@linaro.org>
>
> This adds a driver for the U300 pinmux portions of the system
> controller "SYSCON". It also serves as an example of how to use
> the pinmux subsystem. This driver also houses the platform data
> for the only supported platform.
>
> This deletes the old U300 driver in arch/arm/mach-u300 and
> replace it with a driver using the new subsystem.
>
> The new driver is considerably fatter than the old one, but it
> also registers all 467 pins of the system and adds the power
> and EMIF pin groups and corresponding functions. The idea
> is to use this driver as a a reference for other
> implementation so it needs to be as complete and verbose
> as possible.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Barry Song <21cnbao@gmail.com>
> ---
> ChangeLog v9 -> v10
> - Removed debug register dump (review from Barry Song)
> - Allocate sizeof(*ptr) instead of sizeof(struct foo)
-barry
^ permalink raw reply
* Add support for the SPMP8000 SoC and Letcool board
From: Zoltan Devai @ 2011-10-10 12:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010085509.GB2561@totoro>
2011/10/10 Jamie Iles <jamie@jamieiles.com>:
> On Sun, Oct 09, 2011 at 06:36:03PM +0200, Zoltan Devai wrote:
>> Hi,
>>
>> This series adds support for the Sunplus SPMP8000 SoC, an ARM926EJ-S based
>> MCU, which is most commonly found in handheld game consoles and digital cams.
>> Most of the work was done during GSoC 2011, with Greg KH as my mentor.
>>
>> The board I'm using for development is the Letcool N350JP handheld.
>>
>> The patches are based on Arnds for-next branch with Jamie Iles' vic-dt patches
>> on top.
>
> Excellent! ?Can I take that as a Tested-by from you for that series?
Yes, I've been using it without problems.
Do you need an explicit reply to that thread with the Tested-by ?
Z
^ permalink raw reply
* [Linaro-mm-sig] [PATCHv16 0/9] Contiguous Memory Allocator
From: Clark, Rob @ 2011-10-10 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CADMYwHzZWTgSEwr9gMJrK2mZgC2WiiGC9Pp6saZGx=PY-N=ueg@mail.gmail.com>
On Mon, Oct 10, 2011 at 1:58 AM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> On Fri, Oct 7, 2011 at 6:27 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> IMHO it would be good to merge the entire series into 3.2, since
>> the ARM portion fixes an important bug (double mapping of memory
>> ranges with conflicting attributes) that we've lived with for far
>> too long, but it really depends on how everyone sees the risk
>> for regressions here. If something breaks in unfixable ways before
>> the 3.2 release, we can always revert the patches and have another
>> try later.
>
> I didn't thoroughly review the patches, but I did try them out (to be
> precise, I tried v15) on an OMAP4 PandaBoard, and really liked the
> result.
>
> The interfaces seem clean and convenient and things seem to work (I
> used a private CMA pool with rpmsg and remoteproc, but also noticed
> that several other drivers were utilizing the global pool). And with
> this in hand we can finally ditch the old reserve+ioremap approach.
>
> So from a user perspective, I sure do hope this patch set gets into
> 3.2; hopefully we can just fix anything that would show up during the
> 3.2 cycle.
>
> Marek, Michal (and everyone involved!), thanks so much for pushing
> this! Judging from the history of this patch set and the areas that it
> touches (and from the number of LWN articles ;) it looks like a
> considerable feat.
>
> FWIW, feel free to add my
>
> Tested-by: Ohad Ben-Cohen <ohad@wizery.com>
Marek, I guess I forgot to mention earlier, but I've been using CMA
for a couple of weeks now with omapdrm driver, so you can also add my:
Tested-by: Rob Clark <rob@ti.com>
BR,
-R
> (small and optional comment: I think it'd be nice if
> dma_declare_contiguous would fail if called too late, otherwise users
> of that misconfigured device will end up using the global pool without
> easily knowing that something went wrong)
>
> Thanks,
> Ohad.
>
> _______________________________________________
> Linaro-mm-sig mailing list
> Linaro-mm-sig at lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-mm-sig
>
^ permalink raw reply
* Add support for the SPMP8000 SoC and Letcool board
From: Jamie Iles @ 2011-10-10 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGVye5NAkX_OTAz2AJR_Y3T-egOiW2ZojR9qivS53M0Z_qW7Xg@mail.gmail.com>
On Mon, Oct 10, 2011 at 02:00:40PM +0200, Zoltan Devai wrote:
> 2011/10/10 Jamie Iles <jamie@jamieiles.com>:
> > On Sun, Oct 09, 2011 at 06:36:03PM +0200, Zoltan Devai wrote:
> >> Hi,
> >>
> >> This series adds support for the Sunplus SPMP8000 SoC, an ARM926EJ-S based
> >> MCU, which is most commonly found in handheld game consoles and digital cams.
> >> Most of the work was done during GSoC 2011, with Greg KH as my mentor.
> >>
> >> The board I'm using for development is the Letcool N350JP handheld.
> >>
> >> The patches are based on Arnds for-next branch with Jamie Iles' vic-dt patches
> >> on top.
> >
> > Excellent! ?Can I take that as a Tested-by from you for that series?
> Yes, I've been using it without problems.
> Do you need an explicit reply to that thread with the Tested-by ?
No that's fine, I'll add it for the next posting/pull request.
Thanks,
Jamie
^ permalink raw reply
* [Linaro-mm-sig] [PATCHv16 0/9] Contiguous Memory Allocator
From: Maxime Coquelin @ 2011-10-10 12:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317909290-29832-1-git-send-email-m.szyprowski@samsung.com>
On 10/06/2011 03:54 PM, Marek Szyprowski wrote:
> Welcome everyone again,
>
> Once again I decided to post an updated version of the Contiguous Memory
> Allocator patches.
>
> This version provides mainly a bugfix for a very rare issue that might
> have changed migration type of the CMA page blocks resulting in dropping
> CMA features from the affected page block and causing memory allocation
> to fail. Also the issue reported by Dave Hansen has been fixed.
>
> This version also introduces basic support for x86 architecture, what
> allows wide testing on KVM/QEMU emulators and all common x86 boxes. I
> hope this will result in wider testing, comments and easier merging to
> mainline.
>
> I've also dropped an examplary patch for s5p-fimc platform device
> private memory declaration and added the one from real life. CMA device
> private memory regions are defined for s5p-mfc device to let it allocate
> buffers from two memory banks.
>
> ARM integration code has not been changed since last version, it
> provides implementation of all the ideas that has been discussed during
Hello Marek,
We are currently testing CMA (v16) on Snowball platform.
This feature is very promising, thanks for pushing it!
During our stress tests, we encountered some problems :
1) Contiguous allocation lockup:
When system RAM is full of Anon pages, if we try to allocate a
contiguous buffer greater than the min_free value, we face a
dma_alloc_from_contiguous lockup.
The expected result would be dma_alloc_from_contiguous() to fail.
The problem is reproduced systematically on our side.
2) Contiguous allocation fail:
We have developed a small driver and a shell script to
allocate/release contiguous buffers.
Sometimes, dma_alloc_from_contiguous() fails to allocate the
contiguous buffer (about once every 30 runs).
We have 270MB Memory passed to the kernel in our configuration,
and the CMA pool is 90MB large.
In this setup, the overall memory is either free or full of
reclaimable pages.
For now, we didn't had time to investigate further theses problems.
Have you already faced this kind of issues?
Could someone testing CMA on other boards confirm/infirm theses
problems?
Best regards,
Maxime
> Patches in this patchset:
>
> mm: move some functions from memory_hotplug.c to page_isolation.c
> mm: alloc_contig_freed_pages() added
>
> Code "stolen" from Kamezawa. The first patch just moves code
> around and the second provide function for "allocates" already
> freed memory.
>
> mm: alloc_contig_range() added
>
> This is what Kamezawa asked: a function that tries to migrate all
> pages from given range and then use alloc_contig_freed_pages()
> (defined by the previous commit) to allocate those pages.
>
> mm: MIGRATE_CMA migration type added
> mm: MIGRATE_CMA isolation functions added
>
> Introduction of the new migratetype and support for it in CMA.
> MIGRATE_CMA works similar to ZONE_MOVABLE expect almost any
> memory range can be marked as one.
>
> mm: cma: Contiguous Memory Allocator added
>
> The code CMA code. Manages CMA contexts and performs memory
> allocations.
>
> X86: integrate CMA with DMA-mapping subsystem
> ARM: integrate CMA with dma-mapping subsystem
>
> Main clients of CMA framework. CMA serves as a alloc_pages()
> replacement.
>
> ARM: Samsung: use CMA for 2 memory banks for s5p-mfc device
>
> Use CMA device private memory regions instead of custom solution
> based on memblock_reserve() + dma_declare_coherent().
>
>
> Patch summary:
>
> KAMEZAWA Hiroyuki (2):
> mm: move some functions from memory_hotplug.c to page_isolation.c
> mm: alloc_contig_freed_pages() added
>
> Marek Szyprowski (4):
> drivers: add Contiguous Memory Allocator
> ARM: integrate CMA with DMA-mapping subsystem
> ARM: Samsung: use CMA for 2 memory banks for s5p-mfc device
> X86: integrate CMA with DMA-mapping subsystem
>
> Michal Nazarewicz (3):
> mm: alloc_contig_range() added
> mm: MIGRATE_CMA migration type added
> mm: MIGRATE_CMA isolation functions added
>
> arch/Kconfig | 3 +
> arch/arm/Kconfig | 2 +
> arch/arm/include/asm/dma-contiguous.h | 16 ++
> arch/arm/include/asm/mach/map.h | 1 +
> arch/arm/mm/dma-mapping.c | 362 +++++++++++++++++++++++++------
> arch/arm/mm/init.c | 8 +
> arch/arm/mm/mm.h | 3 +
> arch/arm/mm/mmu.c | 29 ++-
> arch/arm/plat-s5p/dev-mfc.c | 51 +----
> arch/x86/Kconfig | 1 +
> arch/x86/include/asm/dma-contiguous.h | 13 +
> arch/x86/include/asm/dma-mapping.h | 4 +
> arch/x86/kernel/pci-dma.c | 18 ++-
> arch/x86/kernel/pci-nommu.c | 8 +-
> arch/x86/kernel/setup.c | 2 +
> drivers/base/Kconfig | 79 +++++++
> drivers/base/Makefile | 1 +
> drivers/base/dma-contiguous.c | 386 +++++++++++++++++++++++++++++++++
> include/asm-generic/dma-contiguous.h | 27 +++
> include/linux/device.h | 4 +
> include/linux/dma-contiguous.h | 106 +++++++++
> include/linux/mmzone.h | 57 +++++-
> include/linux/page-isolation.h | 53 ++++-
> mm/Kconfig | 8 +-
> mm/compaction.c | 10 +
> mm/memory_hotplug.c | 111 ----------
> mm/page_alloc.c | 317 +++++++++++++++++++++++++--
> mm/page_isolation.c | 131 +++++++++++-
> 28 files changed, 1522 insertions(+), 289 deletions(-)
> create mode 100644 arch/arm/include/asm/dma-contiguous.h
> create mode 100644 arch/x86/include/asm/dma-contiguous.h
> create mode 100644 drivers/base/dma-contiguous.c
> create mode 100644 include/asm-generic/dma-contiguous.h
> create mode 100644 include/linux/dma-contiguous.h
>
> --
> 1.7.1.569.g6f426
>
>
> _______________________________________________
> Linaro-mm-sig mailing list
> Linaro-mm-sig at lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-mm-sig
^ permalink raw reply
* [PATCH 2/3] ARM: plat-samsung: use Kconfig choice for debug UART selection
From: Will Deacon @ 2011-10-10 12:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJuYYwRPwALAQcvsMPuz8XYsDicCmB52HzZehppUnKqv5itPEQ@mail.gmail.com>
On Mon, Oct 10, 2011 at 12:56:24PM +0100, Thomas Abraham wrote:
> Hi Will,
Hi Thomas,
>
> What is your opinion about the following diff instead of the above one?
>
>
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index 65cf8c6..035f5cd 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -120,6 +120,15 @@ choice
> Say Y here if you want the debug print routines to direct
> their output to the second serial port on these devices.
>
> + config DEBUG_SAMSUNG_UART
> + bool "Kernel low-level debugging messages via samsung serial port"
> + depends on PLAT_SAMSUNG
> + help
> + Say Y here if you want the debug print routines to direct
> + their output to the serial port for Samsung platforms. Choose
> + the uart port with the "S3C UART to use for low-level debug"
> + config option.
> +
> endchoice
>
> config EARLY_PRINTK
> @@ -139,7 +148,7 @@ config OC_ETM
> kernel code.
>
> config DEBUG_S3C_UART
> - depends on PLAT_SAMSUNG
> + depends on DEBUG_SAMSUNG_UART
> int "S3C UART to use for low-level debug"
> default "0"
> help
Well, it's smaller so that's always a plus. However, I don't think the extra
level of indirection helps (that is, the "Kernel low-level debugging UART")
choice should be where the UART is specified, rather than pointing you at
another (platform-specific) option).
Did your suggestion come purely out of aesthetics or are you running into
difficulties with the original patch?
Will
^ permalink raw reply
* [RFT/PATCH 1/7] OMAP3+: PM: SR: add suspend/resume handlers
From: Felipe Balbi @ 2011-10-10 12:26 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
SmartReflex should be disabled while entering low power mode due to
the following reasons:
a) SmartReflex values are not defined for retention voltage.
b) With SmartReflex enabled, if the CPU enters low power state, FSM
will try to bump the voltage to current OPP's voltage for which
it has entered low power state, causing power loss and potential
unknown states for the SoC.
Since we are sure to attempt entering the lowest possible power state
during suspend operation, SmartReflex needs to be disabled for the
voltage domains in suspend path before achieving auto retention voltage
on the device.
Traditionally, this has been done with interrupts disabled as part of
the common code which handles the idle sequence. Instead, by using the
fact that we have to disable SmartReflex for sure during suspend
operations, we can opportunistically disable SmartReflex in device
standard pm ops, instead of disabling it as part of the code which
executes with interrupts disabled and slave CPU{s} shutdown. This
allows the system to do other parallel activities(such as suspending
other devices in the system using slave CPU{s}) and save the time
required to achieve suspend and resume from suspended state as a
sequential activity.
However, by being opportunistic as described above, we also increase
the likelihood of SmartReflex library access functions being invoked in
parallel contexts *after* SmartReflex driver's suspend handler (during
suspend operation) or *before* resume handler (during resume operation)
have been invoked (Example: DVFS for dependent devices, cpufreq for
MPU etc.). We prevent this by using a flag to reject the callers in
the duration where SmartReflex has been disabled.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
arch/arm/mach-omap2/smartreflex.c | 96 ++++++++++++++++++++++++++++++++++--
1 files changed, 90 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 34c01a7..af158c0 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -23,6 +23,7 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <plat/common.h>
@@ -39,6 +40,7 @@ struct omap_sr {
int ip_type;
int nvalue_count;
bool autocomp_active;
+ bool is_suspended;
u32 clk_length;
u32 err_weight;
u32 err_minlimit;
@@ -683,6 +685,11 @@ void omap_sr_enable(struct voltagedomain *voltdm)
if (!sr->autocomp_active)
return;
+ if (sr->is_suspended) {
+ dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__);
+ return;
+ }
+
if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
"registered\n", __func__);
@@ -716,6 +723,11 @@ void omap_sr_disable(struct voltagedomain *voltdm)
if (!sr->autocomp_active)
return;
+ if (sr->is_suspended) {
+ dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__);
+ return;
+ }
+
if (!sr_class || !(sr_class->disable)) {
dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
"registered\n", __func__);
@@ -749,6 +761,11 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
if (!sr->autocomp_active)
return;
+ if (sr->is_suspended) {
+ dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__);
+ return;
+ }
+
if (!sr_class || !(sr_class->disable)) {
dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
"registered\n", __func__);
@@ -807,14 +824,16 @@ static int omap_sr_autocomp_store(void *data, u64 val)
return -EINVAL;
}
- /* control enable/disable only if there is a delta in value */
- if (sr_info->autocomp_active != val) {
- if (!val)
- sr_stop_vddautocomp(sr_info);
- else
- sr_start_vddautocomp(sr_info);
+ if (sr_info->is_suspended) {
+ pr_warning("%s: in suspended state\n", __func__);
+ return -EBUSY;
}
+ if (!val)
+ sr_stop_vddautocomp(sr_info);
+ else
+ sr_start_vddautocomp(sr_info);
+
return 0;
}
@@ -1001,10 +1020,75 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
return 0;
}
+static int omap_sr_suspend(struct device *dev)
+{
+ struct omap_sr_data *pdata;
+ struct omap_sr *sr_info;
+
+ pdata = dev_get_platdata(dev);
+ if (!pdata) {
+ dev_err(dev, "%s: platform data missing\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_info = _sr_lookup(pdata->voltdm);
+ if (IS_ERR(sr_info)) {
+ dev_warn(dev, "%s: omap_sr struct not found\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!sr_info->autocomp_active)
+ return 0;
+
+ if (sr_info->is_suspended)
+ return 0;
+
+ omap_sr_disable_reset_volt(pdata->voltdm);
+ sr_info->is_suspended = true;
+ /* Flag the same info to the other CPUs */
+ smp_wmb();
+
+ return 0;
+}
+
+static int omap_sr_resume(struct device *dev)
+{
+ struct omap_sr_data *pdata;
+ struct omap_sr *sr_info;
+
+ pdata = dev_get_platdata(dev);
+ if (!pdata) {
+ dev_err(dev, "%s: platform data missing\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_info = _sr_lookup(pdata->voltdm);
+ if (IS_ERR(sr_info)) {
+ dev_warn(dev, "%s: omap_sr struct not found\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!sr_info->autocomp_active)
+ return 0;
+
+ if (!sr_info->is_suspended)
+ return 0;
+
+ sr_info->is_suspended = false;
+ /* Flag the same info to the other CPUs */
+ smp_wmb();
+ omap_sr_enable(pdata->voltdm);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(omap_sr_dev_pm_ops, omap_sr_suspend, omap_sr_resume);
+
static struct platform_driver smartreflex_driver = {
.remove = omap_sr_remove,
.driver = {
.name = "smartreflex",
+ .pm = &omap_sr_dev_pm_ops,
},
};
--
1.7.6.396.ge0613
^ permalink raw reply related
* [RFT/PATCH 2/7] arm: omap: smartreflex: add missing platform_set_drvdata()
From: Felipe Balbi @ 2011-10-10 12:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318249579-4089-1-git-send-email-balbi@ti.com>
that's very useful to fetch the correct struct sr_info
from PM handlers.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
arch/arm/mach-omap2/smartreflex.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index af158c0..55e297e 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -855,6 +855,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ platform_set_drvdata(pdev, sr_info);
+
if (!pdata) {
dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
ret = -EINVAL;
--
1.7.6.396.ge0613
^ permalink raw reply related
* [RFT/PATCH 3/7] arm: omap: smartreflex: use dev_get_drvdata()
From: Felipe Balbi @ 2011-10-10 12:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318249579-4089-1-git-send-email-balbi@ti.com>
When we need to fetch struct omap_sr on PM
handlers, there's no need to access platform_data.
Instead, we can use dev_get_drvdata(dev) like
other drivers do.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
arch/arm/mach-omap2/smartreflex.c | 51 ++++++------------------------------
1 files changed, 9 insertions(+), 42 deletions(-)
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 55e297e..357363b 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -992,22 +992,9 @@ err_free_devinfo:
static int __devexit omap_sr_remove(struct platform_device *pdev)
{
- struct omap_sr_data *pdata = pdev->dev.platform_data;
- struct omap_sr *sr_info;
+ struct omap_sr *sr_info = platform_get_drvdata(pdev);
struct resource *mem;
- if (!pdata) {
- dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
- return -EINVAL;
- }
-
- sr_info = _sr_lookup(pdata->voltdm);
- if (IS_ERR(sr_info)) {
- dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
- __func__);
- return -EINVAL;
- }
-
if (sr_info->autocomp_active)
sr_stop_vddautocomp(sr_info);
if (sr_info->dbg_dir)
@@ -1024,20 +1011,10 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
static int omap_sr_suspend(struct device *dev)
{
- struct omap_sr_data *pdata;
- struct omap_sr *sr_info;
+ struct omap_sr *sr_info = dev_get_drvdata(dev);
- pdata = dev_get_platdata(dev);
- if (!pdata) {
- dev_err(dev, "%s: platform data missing\n", __func__);
- return -EINVAL;
- }
-
- sr_info = _sr_lookup(pdata->voltdm);
- if (IS_ERR(sr_info)) {
- dev_warn(dev, "%s: omap_sr struct not found\n", __func__);
- return -EINVAL;
- }
+ if (!sr_info)
+ return 0;
if (!sr_info->autocomp_active)
return 0;
@@ -1045,7 +1022,7 @@ static int omap_sr_suspend(struct device *dev)
if (sr_info->is_suspended)
return 0;
- omap_sr_disable_reset_volt(pdata->voltdm);
+ omap_sr_disable_reset_volt(sr_info->voltdm);
sr_info->is_suspended = true;
/* Flag the same info to the other CPUs */
smp_wmb();
@@ -1055,20 +1032,10 @@ static int omap_sr_suspend(struct device *dev)
static int omap_sr_resume(struct device *dev)
{
- struct omap_sr_data *pdata;
- struct omap_sr *sr_info;
+ struct omap_sr *sr_info = dev_get_drvdata(dev);
- pdata = dev_get_platdata(dev);
- if (!pdata) {
- dev_err(dev, "%s: platform data missing\n", __func__);
- return -EINVAL;
- }
-
- sr_info = _sr_lookup(pdata->voltdm);
- if (IS_ERR(sr_info)) {
- dev_warn(dev, "%s: omap_sr struct not found\n", __func__);
- return -EINVAL;
- }
+ if (!sr_info)
+ return 0;
if (!sr_info->autocomp_active)
return 0;
@@ -1079,7 +1046,7 @@ static int omap_sr_resume(struct device *dev)
sr_info->is_suspended = false;
/* Flag the same info to the other CPUs */
smp_wmb();
- omap_sr_enable(pdata->voltdm);
+ omap_sr_enable(sr_info->voltdm);
return 0;
}
--
1.7.6.396.ge0613
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox