* [PATCH 4/5 v4] Realview PCIX support - add main support module code
From: Colin Tuckley @ 2011-10-10 9:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111007231937.GC25689@n2100.arm.linux.org.uk>
> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Subject: Re: [PATCH 4/5 v4] Realview PCIX support - add main support
> module code
Russell said:
> I thought one of my previous review points on this was that it was
> completely unsafe to match only on dev->device, rather than on both
> dev->device and dev->vendor. Device IDs are allocated by individual
> vendors and are meaningless without also checking the vendor ID.
And
> And I thought we'd got to the point where we had a swizzle here.
The patch I sent to the list was indeed an old version. However the reason
is that despite the testing we did and your suggested changes the swizzle
based code still does not fully work. So I thought it best to post working
code.
I'm still waiting for a response from you on the last round of test results
I sent.
Regards,
Colin
^ permalink raw reply
* [PATCH V2 1/2] ARM: EXYNOS4: Add SPI support
From: Kukjin Kim @ 2011-10-10 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318234084-19960-2-git-send-email-padma.v@samsung.com>
Padmavathi Venna wrote:
>
> Define SPI platform devices.
> Register SPI bus clock with clkdev using generic
> connection id.
>
I can't see your second patch 'SPI: EXYNOS4: Enable the SPI driver for
EXYNOS4'. Probably you think it should be handled by spi side, Grant. Yes
right. But when you submit patch set is related to each subsystem such as
arch/arm/ and drivers/, please adding regarding maintainers on your patch
set. So they can know whether necessity of talking to each other is required
or not if there are dependencies. In this case, I need to know the progress
of driver/spi side.
> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
> ---
> arch/arm/mach-exynos4/Kconfig | 1 +
> arch/arm/mach-exynos4/Makefile | 1 +
> arch/arm/mach-exynos4/clock.c | 82 +++++---
> arch/arm/mach-exynos4/dev-spi.c | 225
> ++++++++++++++++++++++
> arch/arm/mach-exynos4/include/mach/irqs.h | 3 +
> arch/arm/mach-exynos4/include/mach/map.h | 3 +
> arch/arm/mach-exynos4/include/mach/spi-clocks.h | 16 ++
> arch/arm/plat-samsung/include/plat/devs.h | 3 +
> arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | 1 +
> 9 files changed, 305 insertions(+), 30 deletions(-)
> create mode 100644 arch/arm/mach-exynos4/dev-spi.c
> create mode 100644 arch/arm/mach-exynos4/include/mach/spi-clocks.h
>
> diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
> index d0491c2..96b2511 100644
> --- a/arch/arm/mach-exynos4/Kconfig
> +++ b/arch/arm/mach-exynos4/Kconfig
> @@ -154,6 +154,7 @@ config MACH_SMDKV310
> select EXYNOS4_SETUP_KEYPAD
> select EXYNOS4_SETUP_SDHCI
> select EXYNOS4_SETUP_USB_PHY
> + select S3C64XX_DEV_SPI
Hmm...if possible, please keep the alphabetical ordering here and I wonder
S3C64XX_DEV_SPI is proper name......
> help
> Machine support for Samsung SMDKV310
>
> diff --git a/arch/arm/mach-exynos4/Makefile
b/arch/arm/mach-exynos4/Makefile
> index e19cd12..7376869 100644
> --- a/arch/arm/mach-exynos4/Makefile
> +++ b/arch/arm/mach-exynos4/Makefile
> @@ -43,6 +43,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-
> ahci.o
> obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
> obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
> obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
> +obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
>
> obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
> obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
> diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
> index a25c818..2497176 100644
> --- a/arch/arm/mach-exynos4/clock.c
> +++ b/arch/arm/mach-exynos4/clock.c
> @@ -1152,36 +1152,6 @@ static struct clksrc_clk clksrcs[] = {
> .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4
},
> }, {
> .clk = {
> - .name = "sclk_spi",
> - .devname = "s3c64xx-spi.0",
> - .enable = exynos4_clksrc_mask_peril1_ctrl,
> - .ctrlbit = (1 << 16),
> - },
> - .sources = &clkset_group,
> - .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size =
4 },
> - .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4
},
> - }, {
> - .clk = {
> - .name = "sclk_spi",
> - .devname = "s3c64xx-spi.1",
> - .enable = exynos4_clksrc_mask_peril1_ctrl,
> - .ctrlbit = (1 << 20),
> - },
> - .sources = &clkset_group,
> - .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size =
4 },
> - .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size =
4 },
> - }, {
> - .clk = {
> - .name = "sclk_spi",
> - .devname = "s3c64xx-spi.2",
> - .enable = exynos4_clksrc_mask_peril1_ctrl,
> - .ctrlbit = (1 << 24),
> - },
> - .sources = &clkset_group,
> - .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size =
4 },
> - .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4
},
> - }, {
> - .clk = {
> .name = "sclk_fimg2d",
> },
> .sources = &clkset_mout_g2d,
> @@ -1242,6 +1212,53 @@ static struct clksrc_clk clksrcs[] = {
> }
> };
>
> +static struct clksrc_clk sclk_spi0 = {
> + .clk = {
> + .name = "sclk_spi",
> + .devname = "s3c64xx-spi.0",
> + .enable = exynos4_clksrc_mask_peril1_ctrl,
> + .ctrlbit = (1 << 16),
> + },
> + .sources = &clkset_group,
> + .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
> + .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
> +};
> +
> +static struct clksrc_clk sclk_spi1 = {
> + .clk = {
> + .name = "sclk_spi",
> + .devname = "s3c64xx-spi.1",
> + .enable = exynos4_clksrc_mask_peril1_ctrl,
> + .ctrlbit = (1 << 20),
> + },
> + .sources = &clkset_group,
> + .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
> + .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
> +};
> +static struct clksrc_clk sclk_spi2 = {
> + .clk = {
> + .name = "sclk_spi",
> + .devname = "s3c64xx-spi.2",
> + .enable = exynos4_clksrc_mask_peril1_ctrl,
> + .ctrlbit = (1 << 24),
> + },
> + .sources = &clkset_group,
> + .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
> + .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
> +};
> +
> +static struct clk_lookup clk_lookup_table[] = {
> + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &sclk_spi0.clk),
> + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &sclk_spi1.clk),
> + CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &sclk_spi2.clk),
Yes, as you said, firstly your CLKDEV_INIT patch is needed before this. So I
need to think this can be sent to upstream in this time or next time even
though this patch is good.
> +};
> +
> +static struct clksrc_clk *clksrc_cdev[] = {
> + &sclk_spi0,
> + &sclk_spi1,
> + &sclk_spi2,
> +};
> +
> /* Clock initialization code */
> static struct clksrc_clk *sysclks[] = {
> &clk_mout_apll,
> @@ -1480,6 +1497,9 @@ void __init exynos4_register_clocks(void)
> for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
> s3c_register_clksrc(sysclks[ptr], 1);
>
> + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
> + s3c_register_clksrc(clksrc_cdev[ptr], 1);
> +
> for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
> s3c_register_clksrc(sclk_tv[ptr], 1);
>
> @@ -1493,4 +1513,6 @@ void __init exynos4_register_clocks(void)
> s3c24xx_register_clock(&dummy_apb_pclk);
>
> s3c_pwmclk_init();
> +
> + clkdev_add_table(clk_lookup_table, ARRAY_SIZE(clk_lookup_table));
> }
> diff --git a/arch/arm/mach-exynos4/dev-spi.c
b/arch/arm/mach-exynos4/dev-spi.c
> new file mode 100644
> index 0000000..0c9704d
> --- /dev/null
> +++ b/arch/arm/mach-exynos4/dev-spi.c
> @@ -0,0 +1,225 @@
> +/* linux/arch/arm/mach-exynos4/dev-spi.c
> + *
> + * Copyright (C) 2011 Samsung Electronics Co. Ltd.
> + *
> + * 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/platform_device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/gpio.h>
> +
> +#include <mach/dma.h>
> +#include <mach/map.h>
> +#include <mach/irqs.h>
> +#include <mach/spi-clocks.h>
> +
> +#include <plat/s3c64xx-spi.h>
> +#include <plat/gpio-cfg.h>
> +
> +/* SPI Controller platform_devices */
> +
> +/* Since we emulate multi-cs capability, we do not touch the CS.
According to coding style(multi-line comments) ......
/*
* foo
* foo
*/
So,
+/*
+ * Since we emulate multi-cs capability, we do not touch the CS.
> + * The emulated CS is toggled by board specific mechanism, as it can
> + * be either some immediate GPIO or some signal out of some other
> + * chip in between ... or some yet another way.
> + * We simply do not assume anything about CS.
> + */
> +static int exynos4_spi_cfg_gpio(struct platform_device *pdev)
> +{
> + switch (pdev->id) {
> + case 0:
> + s3c_gpio_cfgpin(EXYNOS4_GPB(0), S3C_GPIO_SFN(2));
> + s3c_gpio_setpull(EXYNOS4_GPB(0), S3C_GPIO_PULL_UP);
> + s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
> + S3C_GPIO_SFN(2),
> S3C_GPIO_PULL_UP);
> + break;
> +
> + case 1:
> + s3c_gpio_cfgpin(EXYNOS4_GPB(4), S3C_GPIO_SFN(2));
> + s3c_gpio_setpull(EXYNOS4_GPB(4), S3C_GPIO_PULL_UP);
> + s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
> + S3C_GPIO_SFN(2),
> S3C_GPIO_PULL_UP);
> + break;
> +
> + case 2:
> + s3c_gpio_cfgpin(EXYNOS4_GPC1(1), S3C_GPIO_SFN(5));
> + s3c_gpio_setpull(EXYNOS4_GPC1(1), S3C_GPIO_PULL_UP);
> + s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
> + S3C_GPIO_SFN(5),
> S3C_GPIO_PULL_UP);
> + break;
> +
> + default:
> + dev_err(&pdev->dev, "Invalid SPI Controller number!");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static struct resource exynos4_spi0_resource[] = {
> + [0] = {
> + .start = EXYNOS4_PA_SPI0,
> + .end = EXYNOS4_PA_SPI0 + 0x100 - 1,
Please use SZ_256 instead of 0x100.
> + .flags = IORESOURCE_MEM,
> + },
DEFINE_RES_MEM(...)
> + [1] = {
> + .start = DMACH_SPI0_TX,
> + .end = DMACH_SPI0_TX,
> + .flags = IORESOURCE_DMA,
> + },
DEFINE_RES_DMA(...)
> + [2] = {
> + .start = DMACH_SPI0_RX,
> + .end = DMACH_SPI0_RX,
> + .flags = IORESOURCE_DMA,
> + },
Same as above.
> + [3] = {
> + .start = IRQ_SPI0,
> + .end = IRQ_SPI0,
> + .flags = IORESOURCE_IRQ,
> + },
DEFINE_RES_IRQ(...)
> +};
> +
> +static struct s3c64xx_spi_info exynos4_spi0_pdata = {
> + .cfg_gpio = exynos4_spi_cfg_gpio,
> + .fifo_lvl_mask = 0x1ff,
> + .rx_lvl_offset = 15,
> + .high_speed = 1,
> + .clk_from_cmu = true,
> + .tx_st_done = 25,
I don't think we need all exynos4_spi0_pdata, exynos4_spi1_pdata and
exynos4_spi2_pdata because only its fifo_lvl_mask is different with each
other. As you know it can be added when it is initialized.
> +};
> +
> +static u64 spi_dmamask = DMA_BIT_MASK(32);
> +
> +struct platform_device exynos4_device_spi0 = {
> + .name = "s3c64xx-spi",
> + .id = 0,
> + .num_resources = ARRAY_SIZE(exynos4_spi0_resource),
> + .resource = exynos4_spi0_resource,
> + .dev = {
> + .dma_mask = &spi_dmamask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + .platform_data = &exynos4_spi0_pdata,
> + },
> +};
> +
> +static struct resource exynos4_spi1_resource[] = {
> + [0] = {
> + .start = EXYNOS4_PA_SPI1,
> + .end = EXYNOS4_PA_SPI1 + 0x100 - 1,
> + .flags = IORESOURCE_MEM,
> + },
> + [1] = {
> + .start = DMACH_SPI1_TX,
> + .end = DMACH_SPI1_TX,
> + .flags = IORESOURCE_DMA,
> + },
> + [2] = {
> + .start = DMACH_SPI1_RX,
> + .end = DMACH_SPI1_RX,
> + .flags = IORESOURCE_DMA,
> + },
> + [3] = {
> + .start = IRQ_SPI1,
> + .end = IRQ_SPI1,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct s3c64xx_spi_info exynos4_spi1_pdata = {
> + .cfg_gpio = exynos4_spi_cfg_gpio,
> + .fifo_lvl_mask = 0x7f,
> + .rx_lvl_offset = 15,
> + .high_speed = 1,
> + .clk_from_cmu = true,
> + .tx_st_done = 25,
> +};
> +
> +struct platform_device exynos4_device_spi1 = {
> + .name = "s3c64xx-spi",
> + .id = 1,
> + .num_resources = ARRAY_SIZE(exynos4_spi1_resource),
> + .resource = exynos4_spi1_resource,
> + .dev = {
> + .dma_mask = &spi_dmamask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + .platform_data = &exynos4_spi1_pdata,
> + },
> +};
> +
> +static struct resource exynos4_spi2_resource[] = {
> + [0] = {
> + .start = EXYNOS4_PA_SPI2,
> + .end = EXYNOS4_PA_SPI2 + 0x100 - 1,
> + .flags = IORESOURCE_MEM,
> + },
> + [1] = {
> + .start = DMACH_SPI2_TX,
> + .end = DMACH_SPI2_TX,
> + .flags = IORESOURCE_DMA,
> + },
> + [2] = {
> + .start = DMACH_SPI2_RX,
> + .end = DMACH_SPI2_RX,
> + .flags = IORESOURCE_DMA,
> + },
> + [3] = {
> + .start = IRQ_SPI2,
> + .end = IRQ_SPI2,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct s3c64xx_spi_info exynos4_spi2_pdata = {
> + .cfg_gpio = exynos4_spi_cfg_gpio,
> + .fifo_lvl_mask = 0x7f,
> + .rx_lvl_offset = 15,
> + .high_speed = 1,
> + .clk_from_cmu = true,
> + .tx_st_done = 25,
> +};
> +
> +struct platform_device exynos4_device_spi2 = {
> + .name = "s3c64xx-spi",
> + .id = 2,
> + .num_resources = ARRAY_SIZE(exynos4_spi2_resource),
> + .resource = exynos4_spi2_resource,
> + .dev = {
> + .dma_mask = &spi_dmamask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + .platform_data = &exynos4_spi2_pdata,
> + },
> +};
> +
> +void __init exynos4_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
> +{
> + struct s3c64xx_spi_info *pd;
> +
> + /* Reject invalid configuration */
> + if (!num_cs || src_clk_nr < 0
> + || src_clk_nr > EXYNOS4_SPI_SRCCLK_SCLK) {
> + printk(KERN_ERR "%s: Invalid SPI configuration\n",
__func__);
> + return;
> + }
> +
> + switch (cntrlr) {
> + case 0:
> + pd = &exynos4_spi0_pdata;
> + break;
> + case 1:
> + pd = &exynos4_spi1_pdata;
> + break;
> + case 2:
> + pd = &exynos4_spi2_pdata;
> + break;
> + default:
> + printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
> + __func__, cntrlr);
> + return;
> + }
> +
> + pd->num_cs = num_cs;
> + pd->src_clk_nr = src_clk_nr;
> +}
I think you can consolidate dev-spi.c in mach-s3c64xx directory. How about
to move them into plat-samsung/devs.c?
Please refer to next/topic-plat-samsung-devs branch in my tree.
> diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-
> exynos4/include/mach/irqs.h
> index 62093b9..a9f0341 100644
> --- a/arch/arm/mach-exynos4/include/mach/irqs.h
> +++ b/arch/arm/mach-exynos4/include/mach/irqs.h
> @@ -70,6 +70,9 @@
> #define IRQ_IIC5 IRQ_SPI(63)
> #define IRQ_IIC6 IRQ_SPI(64)
> #define IRQ_IIC7 IRQ_SPI(65)
> +#define IRQ_SPI0 IRQ_SPI(66)
> +#define IRQ_SPI1 IRQ_SPI(67)
> +#define IRQ_SPI2 IRQ_SPI(68)
>
> #define IRQ_USB_HOST IRQ_SPI(70)
> #define IRQ_USB_HSOTG IRQ_SPI(71)
> diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-
> exynos4/include/mach/map.h
> index 1bea7d1..8dd509e 100644
> --- a/arch/arm/mach-exynos4/include/mach/map.h
> +++ b/arch/arm/mach-exynos4/include/mach/map.h
> @@ -88,6 +88,9 @@
> #define EXYNOS4_PA_SYSMMU_TV 0x12E20000
> #define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
> #define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
> +#define EXYNOS4_PA_SPI0 0x13920000
> +#define EXYNOS4_PA_SPI1 0x13930000
> +#define EXYNOS4_PA_SPI2 0x13940000
>
> #define EXYNOS4_PA_GPIO1 0x11400000
> #define EXYNOS4_PA_GPIO2 0x11000000
> diff --git a/arch/arm/mach-exynos4/include/mach/spi-clocks.h
b/arch/arm/mach-
> exynos4/include/mach/spi-clocks.h
> new file mode 100644
> index 0000000..576efdf
> --- /dev/null
> +++ b/arch/arm/mach-exynos4/include/mach/spi-clocks.h
> @@ -0,0 +1,16 @@
> +/* linux/arch/arm/mach-exynos4/include/mach/spi-clocks.h
> + *
> + * Copyright (C) 2011 Samsung Electronics Co. Ltd.
> + *
> + * 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.
> + */
> +
> +#ifndef __ASM_ARCH_SPI_CLKS_H
> +#define __ASM_ARCH_SPI_CLKS_H __FILE__
> +
> +/* Must source from SCLK_SPI */
> +#define EXYNOS4_SPI_SRCCLK_SCLK 0
> +
> +#endif /* __ASM_ARCH_SPI_CLKS_H */
> diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-
> samsung/include/plat/devs.h
> index ee5014a..7949131 100644
> --- a/arch/arm/plat-samsung/include/plat/devs.h
> +++ b/arch/arm/plat-samsung/include/plat/devs.h
> @@ -84,6 +84,9 @@ extern struct platform_device s5pv210_device_spi0;
> extern struct platform_device s5pv210_device_spi1;
> extern struct platform_device s5p64x0_device_spi0;
> extern struct platform_device s5p64x0_device_spi1;
> +extern struct platform_device exynos4_device_spi0;
> +extern struct platform_device exynos4_device_spi1;
> +extern struct platform_device exynos4_device_spi2;
>
> extern struct platform_device s3c_device_hwmon;
>
> diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
b/arch/arm/plat-
> samsung/include/plat/s3c64xx-spi.h
> index c3d82a5..1ec1ea3 100644
> --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
> +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
> @@ -69,5 +69,6 @@ extern void s3c64xx_spi_set_info(int cntrlr, int
src_clk_nr, int
> num_cs);
> extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
> extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
> extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
> +extern void exynos4_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
>
> #endif /* __S3C64XX_PLAT_SPI_H */
> --
> 1.7.4.4
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH v2] ARM: EXYNOS4: Add support for M-5MOLS camera on Nuri board
From: Kukjin Kim @ 2011-10-10 9:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318238959-28012-1-git-send-email-s.nawrocki@samsung.com>
Sylwester Nawrocki wrote:
>
> Add voltage regulator and platform data definition for M-5MOLS sensor
> and MIPI-CSI receiver drivers. Add CAM power domain dependencies for
> FIMC device and set up camera port A GPIO. Configure I2C0 bus timings.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> Signed-off-by: HeungJun Kim <riverful.kim@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
> Hi Kgene,
>
> I have corrected the white space issues as you pointed out and removed
> unnecessary gpio_free() in this patch.
>
> Thanks,
> Sylwester
> ---
> arch/arm/mach-exynos4/Kconfig | 8 ++
> arch/arm/mach-exynos4/mach-nuri.c | 156
> +++++++++++++++++++++++++++++++++++++
> 2 files changed, 164 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
> index dd660eb..4bc4b1f 100644
> --- a/arch/arm/mach-exynos4/Kconfig
> +++ b/arch/arm/mach-exynos4/Kconfig
> @@ -215,6 +215,7 @@ config MACH_UNIVERSAL_C210
> config MACH_NURI
> bool "Mobile NURI Board"
> select CPU_EXYNOS4210
> + select S5P_GPIO_INT
> select S3C_DEV_WDT
> select S3C_DEV_RTC
> select S5P_DEV_FIMD0
> @@ -224,9 +225,16 @@ config MACH_NURI
> select S3C_DEV_I2C1
> select S3C_DEV_I2C3
> select S3C_DEV_I2C5
> + select S5P_DEV_CSIS0
> + select S5P_DEV_FIMC0
> + select S5P_DEV_FIMC1
> + select S5P_DEV_FIMC2
> + select S5P_DEV_FIMC3
> select S5P_DEV_MFC
> select S5P_DEV_USB_EHCI
> + select S5P_SETUP_MIPIPHY
> select EXYNOS4_DEV_PD
> + select EXYNOS4_SETUP_FIMC
> select EXYNOS4_SETUP_FIMD0
> select EXYNOS4_SETUP_I2C1
> select EXYNOS4_SETUP_I2C3
> diff --git a/arch/arm/mach-exynos4/mach-nuri.c
b/arch/arm/mach-exynos4/mach-
> nuri.c
> index bbd13f4..f5cecd8 100644
> --- a/arch/arm/mach-exynos4/mach-nuri.c
> +++ b/arch/arm/mach-exynos4/mach-nuri.c
> @@ -27,6 +27,9 @@
> #include <linux/pwm_backlight.h>
>
> #include <video/platform_lcd.h>
> +#include <media/m5mols.h>
> +#include <media/s5p_fimc.h>
> +#include <media/v4l2-mediabus.h>
>
> #include <asm/mach/arch.h>
> #include <asm/mach-types.h>
> @@ -45,6 +48,9 @@
> #include <plat/iic.h>
> #include <plat/mfc.h>
> #include <plat/pd.h>
> +#include <plat/fimc-core.h>
> +#include <plat/camport.h>
> +#include <plat/mipi_csis.h>
>
> #include <mach/map.h>
>
> @@ -65,6 +71,8 @@
> enum fixed_regulator_id {
> FIXED_REG_ID_MMC = 0,
> FIXED_REG_ID_MAX8903,
> + FIXED_REG_ID_CAM_A28V,
> + FIXED_REG_ID_CAM_12V,
> };
>
> static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
> @@ -1117,10 +1125,145 @@ static void __init nuri_ehci_init(void)
> s5p_ehci_set_platdata(pdata);
> }
>
> +/* CAMERA */
> +static struct regulator_consumer_supply cam_vdda_supply[] = {
> + REGULATOR_SUPPLY("a_sensor", "0-001f"),
> +};
> +
> +static struct regulator_init_data cam_vdda_reg_init_data = {
> + .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
> + .num_consumer_supplies = ARRAY_SIZE(cam_vdda_supply),
> + .consumer_supplies = cam_vdda_supply,
> +};
> +
> +static struct fixed_voltage_config cam_vdda_fixed_voltage_cfg = {
> + .supply_name = "CAM_IO_EN",
> + .microvolts = 2800000,
> + .gpio = EXYNOS4_GPE2(1), /* CAM_IO_EN */
> + .enable_high = 1,
> + .init_data = &cam_vdda_reg_init_data,
> +};
> +
> +static struct platform_device cam_vdda_fixed_rdev = {
> + .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_A28V,
> + .dev = { .platform_data = &cam_vdda_fixed_voltage_cfg },
> +};
> +
> +static struct regulator_consumer_supply camera_8m_12v_supply =
> + REGULATOR_SUPPLY("dig_12", "0-001f");
> +
> +static struct regulator_init_data cam_8m_12v_reg_init_data = {
> + .num_consumer_supplies = 1,
> + .consumer_supplies = &camera_8m_12v_supply,
> + .constraints = {
> + .valid_ops_mask = REGULATOR_CHANGE_STATUS
> + },
> +};
> +
> +static struct fixed_voltage_config cam_8m_12v_fixed_voltage_cfg = {
> + .supply_name = "8M_1.2V",
> + .microvolts = 1200000,
> + .gpio = EXYNOS4_GPE2(5), /* 8M_1.2V_EN */
> + .enable_high = 1,
> + .init_data = &cam_8m_12v_reg_init_data,
> +};
> +
> +static struct platform_device cam_8m_12v_fixed_rdev = {
> + .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_12V,
> + .dev = { .platform_data = &cam_8m_12v_fixed_voltage_cfg },
> +};
> +
> +static struct s5p_platform_mipi_csis mipi_csis_platdata = {
> + .clk_rate = 166000000UL,
> + .lanes = 2,
> + .alignment = 32,
> + .hs_settle = 12,
> + .phy_enable = s5p_csis_phy_enable,
> +};
> +
> +#define GPIO_CAM_MEGA_RST EXYNOS4_GPY3(7) /* ISP_RESET */
> +#define GPIO_CAM_8M_ISP_INT EXYNOS4_GPL2(5)
> +
> +static struct m5mols_platform_data m5mols_platdata = {
> + .gpio_reset = GPIO_CAM_MEGA_RST,
> +};
> +
> +static struct i2c_board_info m5mols_board_info = {
> + I2C_BOARD_INFO("M5MOLS", 0x1F),
> + .platform_data = &m5mols_platdata,
> +};
> +
> +static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
> + {
> + .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
> + V4L2_MBUS_VSYNC_ACTIVE_LOW,
> + .bus_type = FIMC_MIPI_CSI2,
> + .board_info = &m5mols_board_info,
> + .clk_frequency = 24000000UL,
> + .csi_data_align = 32,
> + },
> +};
> +
> +static struct s5p_platform_fimc fimc_md_platdata = {
> + .isp_info = nuri_camera_sensors,
> + .num_clients = ARRAY_SIZE(nuri_camera_sensors),
> +};
> +
> +struct platform_device s5p_device_fimc_md = {
> + .name = "s5p-fimc-md",
> + .id = -1,
> +};
> +
> +static struct gpio nuri_camera_gpios[] = {
> + { GPIO_CAM_8M_ISP_INT, GPIOF_IN,
> "8M_ISP_INT" },
> + { GPIO_CAM_MEGA_RST, GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
> +};
> +
> +static void nuri_camera_init(void)
> +{
> + s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
> + &s5p_device_mipi_csis0);
> + s3c_set_platdata(&fimc_md_platdata, sizeof(fimc_md_platdata),
> + &s5p_device_fimc_md);
> +
> + if (gpio_request_array(nuri_camera_gpios,
> + ARRAY_SIZE(nuri_camera_gpios))) {
> + pr_err("%s: GPIO request failed\n", __func__);
> + return;
> + }
> +
> + m5mols_board_info.irq =
> s5p_register_gpio_interrupt(GPIO_CAM_8M_ISP_INT);
> + if (!IS_ERR_VALUE(m5mols_board_info.irq))
> + s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT,
> S3C_GPIO_SFN(0xF));
> + else
> + pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n",
__func__);
> +
> + /* Free GPIOs controlled directly by the sensor drivers. */
> + gpio_free(GPIO_CAM_MEGA_RST);
> +
> + if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
> + pr_err("%s: Camera port A setup failed\n", __func__);
> + return;
> + }
> + /* Increase drive strength of the sensor clock output */
> + s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
> +}
> +
> +static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
> + .frequency = 400000U,
> + .sda_delay = 200,
> +};
> +
> static struct platform_device *nuri_devices[] __initdata = {
> /* Samsung Platform Devices */
> &s3c_device_i2c5, /* PMIC should initialize first */
> + &s3c_device_i2c0,
> &emmc_fixed_voltage,
> + &s5p_device_mipi_csis0,
> + &s5p_device_fimc0,
> + &s5p_device_fimc1,
> + &s5p_device_fimc2,
> + &s5p_device_fimc3,
> &s5p_device_fimd0,
> &s3c_device_hsmmc0,
> &s3c_device_hsmmc2,
> @@ -1137,6 +1280,8 @@ static struct platform_device *nuri_devices[]
__initdata =
> {
> &s5p_device_mfc_r,
> &exynos4_device_pd[PD_MFC],
> &exynos4_device_pd[PD_LCD0],
> + &exynos4_device_pd[PD_CAM],
> + &s5p_device_fimc_md,
>
> /* NURI Devices */
> &nuri_gpio_keys,
> @@ -1144,6 +1289,8 @@ static struct platform_device *nuri_devices[]
__initdata =
> {
> &nuri_backlight_device,
> &max8903_fixed_reg_dev,
> &nuri_max8903_device,
> + &cam_vdda_fixed_rdev,
> + &cam_8m_12v_fixed_rdev,
> };
>
> static void __init nuri_map_io(void)
> @@ -1164,6 +1311,7 @@ static void __init nuri_machine_init(void)
> nuri_tsp_init();
> nuri_power_init();
>
> + s3c_i2c0_set_platdata(&nuri_i2c0_platdata);
> i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
> s3c_i2c3_set_platdata(&i2c3_data);
> i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
> @@ -1175,6 +1323,8 @@ static void __init nuri_machine_init(void)
>
> s5p_fimd0_set_platdata(&nuri_fb_pdata);
>
> + nuri_camera_init();
> +
> nuri_ehci_init();
> clk_xusbxti.rate = 24000000;
>
> @@ -1182,6 +1332,12 @@ static void __init nuri_machine_init(void)
> platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
> s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
> s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
> +
> + s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
> + s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
> + s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
> + s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
> + s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
> }
>
> MACHINE_START(NURI, "NURI")
> --
> 1.7.7
Looks better, will apply this.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH 2/7] s3c-adc: describe features via quirk constants
From: Heiko Stübner @ 2011-10-10 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <034d01cc8705$09ddd160$1d997420$%kim@samsung.com>
Hi Kgene,
Am Montag, 10. Oktober 2011, 06:28:19 schrieb Kukjin Kim:
> Kukjin Kim wrote:
> > Heiko St?bner wrote:
> > > Hi Kgene,
> > >
> > > Am Sonntag 02 Oktober 2011, 09:38:18 schrieb Kukjin Kim:
> > > > How about following? I think following is also not bad...
> > >
> > > ok, I don't claim to have the right solution, so if keeping the
> > > TYPE_xxx
>
> enum
>
> > > is better, I will do a rework of the series according to your solution
>
> and
>
> > > resend it.
> >
> > Thanks for your understanding and please re-send it :)
>
> Any re-sending?
as I'm this in my spare time I'm not sure I will make your "deadline" for the
merge-window, but will try to get it sorted today or tomorrow.
Meanwhile please take a look at the armclk series and the hsmmc devname patch.
Heiko
^ permalink raw reply
* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Jonathan Cameron @ 2011-10-10 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKnu2MrAEbS-36YaU+i6+zhwH4KW7ST7-mkKT49tv7jhhSo2UQ@mail.gmail.com>
On 10/10/11 02:29, Linus Walleij wrote:
> 2011/10/9 Zoltan Devai <zoss@devai.org>:
>
>> Signed-off-by: Zoltan Devai <zoss@devai.org>
>> ---
>> arch/arm/mach-spmp8000/adc.c | 465 +++++++++++++++++++++
>> arch/arm/mach-spmp8000/include/mach/spmp8000adc.h | 29 ++
>
> I think we stopped stuffing misc drivers under arch/arm/*
>
> And stuffing them under drivers/misc/* won't be popular either.
>
> IIO has some ADCs in drivers/staging/iio/adc
> these seem all to be intended to be used from userspace.
Yeah, we've had various discussions about adding support for
in kernel users. Its always fallen on the fact that no one
has had the time to write the code to allow it all to be
linked up. Right now it's a case of drivers providing their
own interfaces if they want to allow this.
Mark Brown has raised this issue before so I've cc'd him.
For reference of those not following the original thread (based
on a quick scan of the driver code in question).
Driver has two callback sets:
1) Touch panel reads (I guess going straight to an input driver)
(1 of these only). This is annoyingly tied up with the more general
adc registers.
2) General purpose adc callbacks.
Both are driven off an interrupt, but data ready
appears to manually driven (so software triggered sampling then data
ready signal when sampling is done for a single channel).
So what are these callbacks used for? Note they all run as
interrupt top halves...
Options at current time are:
mfd supporting input device and either hwmon or iio device.
A driver that hosts both a hwmon / iio and an input device.
Be brave (+ have a lot of time) and propose patches adding the relevant
tying together code to allow iio drivers to be queried in kernel.
It shouldn't be that bad actually if you solve the how to work
out which device / channel you want in a consistent way.
It really depends on what those general adc callbacks get used for.
>
> There are a few in-kernel ADCs all over the kernel tree
> for various specific purposes.
>
> I don't know where we should go with this kind of stuff,
> really :-/
>
> Yours,
> Linus Walleij
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH V3 0/4]: ARM: SAMSUNG: Add SPI clkdev support
From: Kukjin Kim @ 2011-10-10 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318233789-19882-1-git-send-email-padma.v@samsung.com>
Padmavathi Venna wrote:
>
> This patchset modifies the existing clkdev to make SPI driver
> independent of the clock names send from platform data. This
> patches enables the SPI driver to request SPI bus clocks
> using generic connection ID.
>
> V1 patch series are:
> http://www.spinics.net/lists/arm-kernel/msg141671.html
>
> Changes since V1:
> -Add newly introduced CLKDEV_INIT macro for creating clk_lookup
> structure as suggested by Russell King
> V2 patches series are:
> http://www.spinics.net/lists/arm-kernel/msg142733.html
>
> Changes since V2:
> -Reworked the patches as per the following link. Patch series in
> the following link removed & and , from the macro declaration and
added
> in the macro defination.
> http://www.spinics.net/lists/arm-kernel/msg143663.html
>
> Padmavathi Venna (4):
> ARM: S3C64XX: Add SPI clkdev support
> ARM: S5PC100: Add SPI clkdev support
> ARM: S5P64X0: Add SPI clkdev support
> ARM: S5PV210: Add SPI clkdev support
>
> arch/arm/mach-s3c64xx/clock.c | 98 ++++++++++++++++--------
> arch/arm/mach-s5p64x0/clock-s5p6440.c | 57 +++++++++-----
> arch/arm/mach-s5p64x0/clock-s5p6450.c | 57 +++++++++-----
> arch/arm/mach-s5pc100/clock.c | 132 ++++++++++++++++++++--------
> -----
> arch/arm/mach-s5pv210/clock.c | 58 ++++++++++-----
> 5 files changed, 259 insertions(+), 143 deletions(-)
>
> --
> 1.7.4.4
Looks ok but this needs 'CLKDEV_INIT' patch. Please wait until it can be
sent to upstream for this patch.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [GIT PULL] at91: driver for Atmel true hardware random number generator
From: Nicolas Ferre @ 2011-10-10 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd,
Here is a couple of patches for adding the True Random Number Generator
that can be find on some AT91SAM SoCs.
Herbert Xu told me that this material can go through the ARM SoC tree.
They may conflict with future work on at91 gpio that can be found on at91-next
branch. We will recall you this during the "pull request" that we will send you
for those bits...
The following changes since commit 976d167615b64e14bc1491ca51d424e2ba9a5e84:
Linux 3.1-rc9 (2011-10-04 18:11:50 -0700)
are available in the git repository at:
git://github.com/at91linux/linux-at91.git for-arnd/at91-trng
Peter Korsgaard (2):
ARM: at91: at91sam9g45: add trng clock and platform device
hw_random: add driver for atmel true hardware random number generator
arch/arm/mach-at91/at91sam9g45.c | 7 ++
arch/arm/mach-at91/at91sam9g45_devices.c | 29 ++++++
drivers/char/hw_random/Kconfig | 13 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/atmel-rng.c | 158 ++++++++++++++++++++++++++++++
5 files changed, 208 insertions(+), 0 deletions(-)
create mode 100644 drivers/char/hw_random/atmel-rng.c
Thanks, cheers,
--
Nicolas Ferre
^ permalink raw reply
* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Jonathan Cameron @ 2011-10-10 9:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E92BE19.4060907@cam.ac.uk>
On 10/10/11 10:42, Jonathan Cameron wrote:
> On 10/10/11 02:29, Linus Walleij wrote:
>> 2011/10/9 Zoltan Devai <zoss@devai.org>:
>>
>>> Signed-off-by: Zoltan Devai <zoss@devai.org>
>>> ---
>>> arch/arm/mach-spmp8000/adc.c | 465 +++++++++++++++++++++
>>> arch/arm/mach-spmp8000/include/mach/spmp8000adc.h | 29 ++
>>
>> I think we stopped stuffing misc drivers under arch/arm/*
>>
>> And stuffing them under drivers/misc/* won't be popular either.
>>
>> IIO has some ADCs in drivers/staging/iio/adc
>> these seem all to be intended to be used from userspace.
> Yeah, we've had various discussions about adding support for
> in kernel users. Its always fallen on the fact that no one
> has had the time to write the code to allow it all to be
> linked up. Right now it's a case of drivers providing their
> own interfaces if they want to allow this.
> Mark Brown has raised this issue before so I've cc'd him.
>
> For reference of those not following the original thread (based
> on a quick scan of the driver code in question).
>
> Driver has two callback sets:
>
> 1) Touch panel reads (I guess going straight to an input driver)
> (1 of these only). This is annoyingly tied up with the more general
> adc registers.
> 2) General purpose adc callbacks.
>
> Both are driven off an interrupt, but data ready
> appears to manually driven (so software triggered sampling then data
> ready signal when sampling is done for a single channel).
>
> So what are these callbacks used for? Note they all run as
> interrupt top halves...
>
> Options at current time are:
>
> mfd supporting input device and either hwmon or iio device.
>
> A driver that hosts both a hwmon / iio and an input device.
>
> Be brave (+ have a lot of time) and propose patches adding the relevant
> tying together code to allow iio drivers to be queried in kernel.
> It shouldn't be that bad actually if you solve the how to work
> out which device / channel you want in a consistent way.
>
> It really depends on what those general adc callbacks get used for.
Ah, just taken a look at your dts file.
Looks like some are used for 'analog-keys'. So input? If so this
should probably be an entirely input driver for now.
>
>>
>> There are a few in-kernel ADCs all over the kernel tree
>> for various specific purposes.
>>
>> I don't know where we should go with this kind of stuff,
>> really :-/
>>
>> Yours,
>> Linus Walleij
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH v3 1/6] iommu/core: split mapping to page sizes as supported by the hardware
From: Roedel, Joerg @ 2011-10-10 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAK=WgbbNs5fWHDEputZ=jzU5YN0sn0tf6AETkcsoq_Jbvc2XgQ@mail.gmail.com>
Hi Ohad,
sorry, I was on vacation last week and had no time to look into this.
On Sun, Oct 02, 2011 at 11:58:12AM -0400, Ohad Ben-Cohen wrote:
> drivers/iommu/iommu.c | 138 ++++++++++++++++++++++++++++++++++++++++---
> drivers/iommu/omap-iovmm.c | 12 +---
> include/linux/iommu.h | 6 +-
> virt/kvm/iommu.c | 4 +-
> 4 files changed, 137 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index a7b0862..f23563f 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -16,6 +16,8 @@
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> */
>
> +#define pr_fmt(fmt) "%s: " fmt, __func__
> +
> #include <linux/kernel.h>
> #include <linux/bug.h>
> #include <linux/types.h>
> @@ -23,15 +25,54 @@
> #include <linux/slab.h>
> #include <linux/errno.h>
> #include <linux/iommu.h>
> +#include <linux/bitmap.h>
Is this still required?
>
> static struct iommu_ops *iommu_ops;
>
> +/* bitmap of supported page sizes */
> +static unsigned long iommu_pgsize_bitmap;
> +
> +/* size of the smallest supported page (in bytes) */
> +static unsigned int iommu_min_pagesz;
> +
> +/**
> + * register_iommu() - register an IOMMU hardware
> + * @ops: iommu handlers
> + * @pgsize_bitmap: bitmap of page sizes supported by the hardware
> + *
> + * Note: this is a temporary function, which will be removed once
> + * all IOMMU drivers are converted. The only reason it exists is to
> + * allow splitting the pgsizes changes to several patches in order to ease
> + * the review.
> + */
> +void register_iommu_pgsize(struct iommu_ops *ops, unsigned long pgsize_bitmap)
> +{
> + if (iommu_ops || iommu_pgsize_bitmap || !pgsize_bitmap)
> + BUG();
> +
> + iommu_ops = ops;
> + iommu_pgsize_bitmap = pgsize_bitmap;
> +
> + /* find out the minimum page size only once */
> + iommu_min_pagesz = 1 << __ffs(pgsize_bitmap);
> +}
Hmm, I thought a little bit about that and came to the conculusion it
might be best to just keep the page-sizes as a part of the iommu_ops
structure. So there is no need to extend the register_iommu interface.
Also, the bus_set_iommu interface is now in the -next branch. Would be
good if you rebase the patches to that interface.
You can find the current iommu tree with these changes at
git://git.8bytes.org/scm/iommu.git
> @@ -115,26 +156,103 @@ int iommu_domain_has_cap(struct iommu_domain *domain,
> EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
>
> int iommu_map(struct iommu_domain *domain, unsigned long iova,
> - phys_addr_t paddr, int gfp_order, int prot)
> + phys_addr_t paddr, size_t size, int prot)
> {
> - size_t size;
> + int ret = 0;
> +
> + /*
> + * both the virtual address and the physical one, as well as
> + * the size of the mapping, must be aligned (at least) to the
> + * size of the smallest page supported by the hardware
> + */
> + if (!IS_ALIGNED(iova | paddr | size, iommu_min_pagesz)) {
> + pr_err("unaligned: iova 0x%lx pa 0x%lx size 0x%lx min_pagesz "
> + "0x%x\n", iova, (unsigned long)paddr,
> + (unsigned long)size, iommu_min_pagesz);
> + return -EINVAL;
> + }
>
> - size = 0x1000UL << gfp_order;
> + pr_debug("map: iova 0x%lx pa 0x%lx size 0x%lx\n", iova,
> + (unsigned long)paddr, (unsigned long)size);
>
> - BUG_ON(!IS_ALIGNED(iova | paddr, size));
> + while (size) {
> + unsigned long pgsize, addr_merge = iova | paddr;
> + unsigned int pgsize_idx;
>
> - return iommu_ops->map(domain, iova, paddr, gfp_order, prot);
> + /* Max page size that still fits into 'size' */
> + pgsize_idx = __fls(size);
> +
> + /* need to consider alignment requirements ? */
> + if (likely(addr_merge)) {
> + /* Max page size allowed by both iova and paddr */
> + unsigned int align_pgsize_idx = __ffs(addr_merge);
> +
> + pgsize_idx = min(pgsize_idx, align_pgsize_idx);
> + }
> +
> + /* build a mask of acceptable page sizes */
> + pgsize = (1UL << (pgsize_idx + 1)) - 1;
> +
> + /* throw away page sizes not supported by the hardware */
> + pgsize &= iommu_pgsize_bitmap;
I think we need some care here and check pgsize for 0. A BUG_ON should
do.
> +
> + /* pick the biggest page */
> + pgsize_idx = __fls(pgsize);
> + pgsize = 1UL << pgsize_idx;
> +
> + /* convert index to page order */
> + pgsize_idx -= PAGE_SHIFT;
> +
> + pr_debug("mapping: iova 0x%lx pa 0x%lx order %u\n", iova,
> + (unsigned long)paddr, pgsize_idx);
> +
> + ret = iommu_ops->map(domain, iova, paddr, pgsize_idx, prot);
> + if (ret)
> + break;
> +
> + iova += pgsize;
> + paddr += pgsize;
> + size -= pgsize;
> + }
> +
> + return ret;
> }
> EXPORT_SYMBOL_GPL(iommu_map);
Otherwise this looks much better, thanks.
>
> -int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)
> +int iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
> {
> - size_t size;
> + int order, unmapped_size, unmapped_order, total_unmapped = 0;
> +
> + /*
> + * The virtual address, as well as the size of the mapping, must be
> + * aligned (at least) to the size of the smallest page supported
> + * by the hardware
> + */
> + if (!IS_ALIGNED(iova | size, iommu_min_pagesz)) {
> + pr_err("unaligned: iova 0x%lx size 0x%lx min_pagesz 0x%x\n",
> + iova, (unsigned long)size, iommu_min_pagesz);
> + return -EINVAL;
> + }
> +
> + pr_debug("unmap this: iova 0x%lx size 0x%lx\n", iova,
> + (unsigned long)size);
> +
> + while (size > total_unmapped) {
> + order = get_order(size - total_unmapped);
> +
> + unmapped_order = iommu_ops->unmap(domain, iova, order);
I think we should make sure that we call iommu_ops->unmap with the same
parameters as iommu_ops->map. Otherwise we still need some page-size
complexity in the iommu-drivers.
> + if (unmapped_order < 0)
> + return unmapped_order;
> +
> + pr_debug("unmapped: iova 0x%lx order %d\n", iova,
> + unmapped_order);
>
> - size = 0x1000UL << gfp_order;
> + unmapped_size = 0x1000UL << unmapped_order;
>
> - BUG_ON(!IS_ALIGNED(iova, size));
> + iova += unmapped_size;
> + total_unmapped += unmapped_size;
> + }
>
> - return iommu_ops->unmap(domain, iova, gfp_order);
> + return get_order(total_unmapped);
> }
When we pass the size now it makes sense to also return the
unmapped-size instead of the order.
Also the semantics of iommu_unmap need some more discussion I think. We
should require that iommu_map/iommu_unmap are called with the same
parameters for the same range. Otherwise we can give no guarantees what
a unmap-call will unmap.
Joerg
--
AMD Operating System Research Center
Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632
^ permalink raw reply
* [PATCH] ARM: CSR: PM: use outer_resume to resume L2 cache
From: Barry Song @ 2011-10-10 9:50 UTC (permalink / raw)
To: linux-arm-kernel
From: Barry Song <Baohua.Song@csr.com>
now we move l2x0 resume to Linux from bootloader since l2x0 already has
resume support in core.
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
This patch depends on Barry Song's
ARM: cache-l2x0: add resume entry for l2 in secure mode
http://www.spinics.net/lists/arm-kernel/msg142696.html
which has been in rmk's tree
arch/arm/mach-prima2/pm.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c
index 0ba39f3..cb53160 100644
--- a/arch/arm/mach-prima2/pm.c
+++ b/arch/arm/mach-prima2/pm.c
@@ -71,6 +71,7 @@ static int sirfsoc_pm_enter(suspend_state_t state)
outer_disable();
/* go zzz */
cpu_suspend(0, sirfsoc_finish_suspend);
+ outer_resume();
break;
default:
return -EINVAL;
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related
* [RFC][PATCH] plat-mxc: iomux-v3.h: implicitly enable pull-up/down when that's desired
From: Lothar Waßmann @ 2011-10-10 9:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010081407.GA32718@sapphire.tkos.co.il>
Hi,
Baruch Siach writes:
> Hi Paul,
>
> On Mon, Oct 10, 2011 at 11:19:23AM +0400, Paul Fertser wrote:
> > To configure pads during the initialisation a set of special constants
> > is used, e.g.
> > #define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP)
> >
> > The problem is that no pull-up/down is getting activated unless both
> > PAD_CTL_PUE (pull-up enable) and PAD_CTL_PKE (pull/keeper module
> > enable) set. This is clearly stated in the i.MX25 datasheet and is
> > confirmed by the measurements on hardware. This leads to some rather
> > hard to understand bugs such as misdetecting an absent ethernet PHY (a
> > real bug i had), unstable data transfer etc. This might affect mx25,
> > mx35, mx50, mx51 and mx53 SoCs.
> >
> > It's reasonable to expect that if the pullup value is specified, the
> > intention was to have it actually active, so we implicitly add the
> > needed bits.
>
> IMO, this patch should include the removal of the now redundant PAD_CTL_PKE
> from arch/arm/plat-mxc/include/mach/iomux-mx25.h, and other v3 iomux headers.
>
Why should PAD_CTL_PKE be redundant? You still need it to configure a
pin for the 'Keeper' functionality.
Even if there is no default pin configuration that uses this, it
should be possible to enable it when desired.
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply
* [PATCH v2 6/6] OMAP4: Clock: Correct the name of SLIMBUS interface clocks
From: Cousson, Benoit @ 2011-10-10 9:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E8F8149.6090100@ti.com>
Hi Jon,
On 10/8/2011 12:46 AM, Hunter, Jon wrote:
> Hi Benoit,
>
> On 10/7/2011 3:23, Cousson, Benoit wrote:
>> Hi Paul& Jon,
>>
>> On 10/7/2011 3:42 AM, Paul Walmsley wrote:
>>> + Beno?t
>>>
>>> On Fri, 16 Sep 2011, Jon Hunter wrote:
>>>
>>>> From: Jon Hunter<jon-hunter@ti.com>
>>>>
>>>> Currently the interface clocks for the two SLIMBUS peripherals are
>>>> named slimbus1_fck and slimbus2_fck. Rename these clocks to be
>>>> slimbus1_ick and slimbus2_ick so it is clear that these are
>>>> interface clocks and not functional clocks.
>>>>
>>>> Signed-off-by: Jon Hunter<jon-hunter@ti.com>
>>>
>>> This one, I don't quite understand. We should probably be removing these
>>> MODULEMODE-only clocks from the OMAP4 tree, and using their parent clock
>>> as the main_clk. That would be a good cleanup for 3.3...
>>
>> Yes, but in order to remove that from the clock data we must ensure that
>> the hwmod entry is there.
>> I kept a lot of legacy MODULEMODE clocks just because of missing hwmod /
>> runtime_pm adaptation on some drivers.
>>
>> In the case of slimbus, there is no main_clk but a bunch of optional
>> clocks. It looks similar to the DSS case. So we should not use the
>> parent clock as a main_clk.
>>
>> We should probably promote one of the opt_clk as the main_clk. The
>> slimbus_clk seems to be the good candidate for both instances.
>>
>> static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = {
>> { .role = "fclk_1", .clk = "slimbus1_fclk_1" },
>> { .role = "fclk_0", .clk = "slimbus1_fclk_0" },
>> { .role = "fclk_2", .clk = "slimbus1_fclk_2" },
>> { .role = "slimbus_clk", .clk = "slimbus1_slimbus_clk" },
>> };
>>
>> static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = {
>> { .role = "fclk_1", .clk = "slimbus2_fclk_1" },
>> { .role = "fclk_0", .clk = "slimbus2_fclk_0" },
>> { .role = "slimbus_clk", .clk = "slimbus2_slimbus_clk" },
>> };
>>
>> Jon,
>> Do you know if that one is indeed mandatory to use the slimbus IP?
>
> Sorry, are you asking about the clocks I was re-naming or the
> slimbus_clk you are referring to above?
The clocks you are renaming should not exist at all, so I was referring
to the real clocks that are all listed as optional clocks.
Usually we do need to have a main_clk in order to access the IP
registers (at least the sysconfig). But for some IPs, the iclk can be
enough.
If the interface clock is enough, then potentially that main clock is
not mandatory. But if one functional clock is mandatory, then we have to
figured out which one from the various optional functional clocks can be
used as the main_clk.
> Looking at the clock tree tool, the slimbus_clk is the actual external
> slimbus clock that can be generated by OMAP or by an external device.
>
> The TRM states ...
>
> "Most of the SLIMbus module runs off two main clocks: the L4 interface
> clock for the data input and output registers, and the control and
> status control registers; and the SLIMbus clock, taken from the serial
> interface (CLK line) for the SLIMbus-side logic.
>
> The SLIMbus controller operates as clock source component (active
> framer), which drives the SLIMbus clock line CLK, or as clock receiver
> component, which gets its clock from the same CLK line."
>
> So, if you are operating as the clock source component on the bus then
> one of the optional clocks to drive the peripheral logic and if you are
> the clock receiver then you use slimbus_clk.
OK, so clearly, the slimbus_clk cannot be a main_clk. We have to check
if the registers can be accessed only with the iclk.
Regards,
Benoit
^ permalink raw reply
* [PATCH 2/5] ARM: s3c64xx: Add generic high resolution time support using PWM timers.
From: Kukjin Kim @ 2011-10-10 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3260808.zUY9bHslbC@flatron>
Tomasz Figa wrote:
>
> From d1fa581f09d8f8a3cc24d05420e9e65112fd8c12 Mon Sep 17 00:00:00 2001
> From: Tomasz Figa <tomasz.figa@gmail.com>
> Date: Sun, 28 Aug 2011 02:45:06 +0200
> Subject: [PATCH 2/5] ARM: s3c64xx: Add generic high resolution time
support
> using PWM timers.
>
> This patch adds a sys_timer implementing generic clock source and clock
event
> device on S3C64xx using PWM timers 3 and 4. It can be enabled by a Kconfig
> option, based on which either the new sys_timer is used as s3c64xx_timer
or
> s3c64xx_timer is defined to s3c24xx_timer which is the old tick timer.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
> arch/arm/Kconfig | 1 -
> arch/arm/mach-s3c64xx/Kconfig | 12 ++
> arch/arm/mach-s3c64xx/Makefile | 3 +
> arch/arm/mach-s3c64xx/time.c | 320
> ++++++++++++++++++++++++++++++
> arch/arm/plat-samsung/include/plat/cpu.h | 7 +
> 5 files changed, 342 insertions(+), 1 deletions(-)
> create mode 100644 arch/arm/mach-s3c64xx/time.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 9adc278..05941f6 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -700,7 +700,6 @@ config ARCH_S3C64XX
> select ARM_VIC
> select HAVE_CLK
> select NO_IOPORT
> - select ARCH_USES_GETTIMEOFFSET
> select ARCH_HAS_CPUFREQ
> select ARCH_REQUIRE_GPIOLIB
> select SAMSUNG_CLKSRC
> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
> index e4177e2..2db76fd 100644
> --- a/arch/arm/mach-s3c64xx/Kconfig
> +++ b/arch/arm/mach-s3c64xx/Kconfig
> @@ -25,6 +25,18 @@ config CPU_S3C6410
> help
> Enable S3C6410 CPU support
>
> +config S3C64XX_GENERIC_CLOCKEVENTS
> + bool "Enable high resolution generic time support using PWM timers"
> + select GENERIC_CLOCKEVENTS
> + help
> + This option enables high resolution generic time support
> + on S3C6400/S3C6410 SoCs using PWM timers 3 and 4 instead
> + of standard periodic tick using PWM timer 4.
> +
> +config S3C64XX_ARCH_USES_GETTIMEOFFSET
> + def_bool y if !S3C64XX_GENERIC_CLOCKEVENTS
> + select ARCH_USES_GETTIMEOFFSET
> +
> config S3C64XX_DMA
> bool "S3C64XX DMA"
> select S3C_DMA
> diff --git a/arch/arm/mach-s3c64xx/Makefile
b/arch/arm/mach-s3c64xx/Makefile
> index 4657363..a152002 100644
> --- a/arch/arm/mach-s3c64xx/Makefile
> +++ b/arch/arm/mach-s3c64xx/Makefile
> @@ -15,6 +15,9 @@ obj-y += cpu.o
> obj-y += clock.o
> obj-y += gpiolib.o
>
> +# Generic clockevents
> +obj-$(CONFIG_S3C64XX_GENERIC_CLOCKEVENTS) += time.o
> +
> # Core support for S3C6400 system
>
> obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
> diff --git a/arch/arm/mach-s3c64xx/time.c b/arch/arm/mach-s3c64xx/time.c
> new file mode 100644
> index 0000000..4fa57f0
> --- /dev/null
> +++ b/arch/arm/mach-s3c64xx/time.c
> @@ -0,0 +1,320 @@
> +/* linux/arch/arm/mach-s3c64xx/time.c
> + *
> + * Copyright (c) 2011 Tomasz Figa <tomasz.figa@gmail.com>
> + *
> + * based on linux/arch/arm/plat-samsung/s5p-time.c
> + *
> + * S3C64XX generic high resolution time support using PWM 3 and PWM 4
timers.
> + *
> + * 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.
> + *
> + * Notes:
> + * - Frequency divisors are currently hardcoded to make both timers
operate
> + * at 1/6 the frequency of PCLK, so with the usual PCLK frequency of 66
MHz,
> + * the timers are clocked at 11 MHz giving us the operating range from
> + * 90 nsec to 386 sec.
> + * - PWM registers, especially TCON, are shared with PWM driver, but
since
> + * all the clock event callbacks are run in atomic context
synchronization
> + * is not needed.
> + */
> +
> +#include <linux/sched.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/platform_device.h>
> +
> +#include <mach/map.h>
> +#include <plat/regs-timer.h>
> +#include <asm/mach/time.h>
> +
> +#define PWM_EVENT (3)
> +#define PWM_SOURCE (4)
> +
> +#define ONESHOT (0)
> +#define PERIODIC (1)
> +
> +#define TCNT_MAX (0xffffffff)
> +
> +static struct clk *timerclk;
> +
> +/*
> + * PWM timers setup code
> + */
> +
> +static inline void s3c64xx_pwm_stop(unsigned int pwm_id)
> +{
> + unsigned long tcon = __raw_readl(S3C2410_TCON);
> +
> + switch (pwm_id) {
> + case 3:
> + tcon &= ~S3C2410_TCON_T3START;
> + break;
> + case 4:
> + tcon &= ~S3C2410_TCON_T4START;
> + break;
> + }
> +
> + __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +static inline void s3c64xx_pwm_init(unsigned int pwm_id, unsigned long
tcnt)
> +{
> + unsigned long tcon = __raw_readl(S3C2410_TCON);
> +
> + /* timers reload after counting zero, so reduce the count by 1 */
> + --tcnt;
> +
> + /* stop the timer and ask it to load the new value */
> + switch (pwm_id) {
> + case 3:
> + tcon &= ~(0xf<<16);
> + tcon |= S3C2410_TCON_T3MANUALUPD;
> + break;
> + case 4:
> + tcon &= ~(7<<20);
> + tcon |= S3C2410_TCON_T4MANUALUPD;
> + break;
> + }
> +
> + __raw_writel(tcnt, S3C2410_TCNTB(pwm_id));
> + __raw_writel(tcnt, S3C2410_TCMPB(pwm_id));
> + __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +static inline void s3c64xx_pwm_start(unsigned int pwm_id, bool periodic)
> +{
> + unsigned long tcon = __raw_readl(S3C2410_TCON);
> +
> + switch (pwm_id) {
> + case 3:
> + tcon |= S3C2410_TCON_T3START;
> + tcon &= ~S3C2410_TCON_T3MANUALUPD;
> +
> + if (periodic)
> + tcon |= S3C2410_TCON_T3RELOAD;
> + else
> + tcon &= ~S3C2410_TCON_T3RELOAD;
> + break;
> + case 4:
> + tcon |= S3C2410_TCON_T4START;
> + tcon &= ~S3C2410_TCON_T4MANUALUPD;
> +
> + if (periodic)
> + tcon |= S3C2410_TCON_T4RELOAD;
> + else
> + tcon &= ~S3C2410_TCON_T4RELOAD;
> + break;
> + }
> +
> + __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +/*
> + * Clock event
> + */
> +
> +static struct clk *event_in;
> +static struct clk *event_div;
> +
> +static unsigned long clock_count_per_tick;
> +
> +static int s3c64xx_clock_event_set_next_event(unsigned long cycles,
> + struct clock_event_device
> *evt)
> +{
> + s3c64xx_pwm_init(PWM_EVENT, cycles);
> + s3c64xx_pwm_start(PWM_EVENT, ONESHOT);
> + return 0;
> +}
> +
> +static void s3c64xx_clock_event_resume(void)
> +{
> + unsigned long pclk;
> + struct clk *tscaler;
> +
> + pclk = clk_get_rate(timerclk);
> + tscaler = clk_get_parent(event_div);
> + clk_set_rate(tscaler, pclk / 3);
> +
> + clk_set_rate(event_div, pclk / 6);
> + clk_set_parent(event_in, event_div);
> +
> + s3c64xx_pwm_init(PWM_EVENT, clock_count_per_tick);
> + s3c64xx_pwm_start(PWM_EVENT, PERIODIC);
> +}
> +
> +static void s3c64xx_clock_event_set_mode(enum clock_event_mode mode,
> + struct clock_event_device
> *evt)
> +{
> + s3c64xx_pwm_stop(PWM_EVENT);
> +
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + s3c64xx_pwm_init(PWM_EVENT, clock_count_per_tick);
> + s3c64xx_pwm_start(PWM_EVENT, PERIODIC);
> + break;
> + case CLOCK_EVT_MODE_ONESHOT:
> + break;
> + case CLOCK_EVT_MODE_UNUSED:
> + case CLOCK_EVT_MODE_SHUTDOWN:
> + break;
> + case CLOCK_EVT_MODE_RESUME:
> + s3c64xx_clock_event_resume();
> + break;
> + }
> +}
> +
> +static struct clock_event_device s3c64xx_clock_event_device = {
> + .name = "s3c64xx_clkevt",
> + .features = CLOCK_EVT_FEAT_PERIODIC |
> CLOCK_EVT_FEAT_ONESHOT,
> + .rating = 200,
> + .shift = 32,
> + .set_next_event = s3c64xx_clock_event_set_next_event,
> + .set_mode = s3c64xx_clock_event_set_mode,
> +};
> +
> +static irqreturn_t s3c64xx_clock_event_isr(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = &s3c64xx_clock_event_device;
> +
> + evt->event_handler(evt);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct irqaction s3c64xx_clock_event_irq = {
> + .name = "s3c64xx_clkevt_irq",
> + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> + .handler = s3c64xx_clock_event_isr,
> +};
> +
> +static void __init s3c64xx_clock_event_init(void)
> +{
> + unsigned long clock_rate;
> +
> + clock_rate = clk_get_rate(event_in);
> +
> + clock_count_per_tick = clock_rate / HZ;
> +
> + s3c64xx_clock_event_device.mult = div_sc(clock_rate,
> + NSEC_PER_SEC, s3c64xx_clock_event_device.shift);
> + s3c64xx_clock_event_device.max_delta_ns =
> + clockevent_delta2ns(-1,
&s3c64xx_clock_event_device);
> + s3c64xx_clock_event_device.min_delta_ns =
> + clockevent_delta2ns(1, &s3c64xx_clock_event_device);
> +
> + s3c64xx_clock_event_device.cpumask = cpumask_of(0);
> + clockevents_register_device(&s3c64xx_clock_event_device);
> +
> + setup_irq(IRQ_TIMER3, &s3c64xx_clock_event_irq);
> +}
> +
> +/*
> + * Clock source
> + */
> +
> +static struct clk *source_in;
> +static struct clk *source_div;
> +
> +static cycle_t s3c64xx_clocksource_read(struct clocksource *cs)
> +{
> + return (cycle_t) ~__raw_readl(S3C2410_TCNTO(PWM_SOURCE));
> +}
> +
> +static void s3c64xx_clocksource_resume(struct clocksource *cs)
> +{
> + unsigned long pclk;
> + struct clk *tscaler;
> +
> + pclk = clk_get_rate(timerclk);
> + tscaler = clk_get_parent(source_div);
> + clk_set_rate(tscaler, pclk / 3);
> +
> + clk_set_rate(source_div, pclk / 6);
> + clk_set_parent(source_in, source_div);
> +
> + s3c64xx_pwm_init(PWM_SOURCE, TCNT_MAX);
> + s3c64xx_pwm_start(PWM_SOURCE, PERIODIC);
> +}
> +
> +static struct clocksource pwm_clocksource = {
> + .name = "s3c64xx_clksrc",
> + .rating = 250,
> + .read = s3c64xx_clocksource_read,
> + .mask = CLOCKSOURCE_MASK(32),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> + .resume = s3c64xx_clocksource_resume,
> +};
> +
> +static void __init s3c64xx_clocksource_init(void)
> +{
> + unsigned long clock_rate;
> +
> + clock_rate = clk_get_rate(source_in);
> +
> + s3c64xx_pwm_init(PWM_SOURCE, TCNT_MAX);
> + s3c64xx_pwm_start(PWM_SOURCE, PERIODIC);
> +
> + if (clocksource_register_hz(&pwm_clocksource, clock_rate))
> + panic("%s: can't register clocksource\n",
> pwm_clocksource.name);
> +}
> +
> +static void __init s3c64xx_timer_init_common(void)
> +{
> + struct platform_device tmpdev;
> + unsigned long pclk;
> + struct clk *tscaler;
> +
> + tmpdev.dev.bus = &platform_bus_type;
> +
> + timerclk = clk_get(NULL, "timers");
> + if (IS_ERR(timerclk))
> + panic("failed to get timers clock for system timer");
> +
> + tmpdev.id = PWM_EVENT;
> + event_in = clk_get(&tmpdev.dev, "pwm-tin");
> + if (IS_ERR(event_in))
> + panic("failed to get pwm-event_in clock for system timer");
> +
> + event_div = clk_get(&tmpdev.dev, "pwm-tdiv");
> + if (IS_ERR(event_div))
> + panic("failed to get pwm-event_div clock for system timer");
> +
> + tmpdev.id = PWM_SOURCE;
> + source_in = clk_get(&tmpdev.dev, "pwm-tin");
> + if (IS_ERR(source_in))
> + panic("failed to get pwm-source_in clock for system timer");
> +
> + source_div = clk_get(&tmpdev.dev, "pwm-tdiv");
> + if (IS_ERR(source_div))
> + panic("failed to get pwm-source_div clock for system
timer");
> +
> + pclk = clk_get_rate(timerclk);
> + tscaler = clk_get_parent(event_div);
> + clk_set_rate(tscaler, pclk / 3);
> +
> + clk_set_rate(event_div, pclk / 6);
> + clk_set_parent(event_in, event_div);
> +
> + clk_set_rate(source_div, pclk / 6);
> + clk_set_parent(source_in, source_div);
> +
> + clk_enable(timerclk);
> + clk_enable(event_in);
> + clk_enable(source_in);
> +}
> +
> +static void __init s3c64xx_timer_init(void)
> +{
> + s3c64xx_timer_init_common();
> + s3c64xx_clock_event_init();
> + s3c64xx_clocksource_init();
> +}
> +
> +struct sys_timer s3c64xx_timer = {
> + .init = s3c64xx_timer_init,
> +};
> diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-
> samsung/include/plat/cpu.h
> index c0a5741..e1fcad0 100644
> --- a/arch/arm/plat-samsung/include/plat/cpu.h
> +++ b/arch/arm/plat-samsung/include/plat/cpu.h
> @@ -74,6 +74,13 @@ extern struct syscore_ops s3c2416_pm_syscore_ops;
> extern struct syscore_ops s3c244x_pm_syscore_ops;
> extern struct syscore_ops s3c64xx_irq_syscore_ops;
>
> +/* timer for 64xx */
> +#ifdef CONFIG_S3C64XX_GENERIC_CLOCKEVENTS
> +extern struct sys_timer s3c64xx_timer;
> +#else
> +#define s3c64xx_timer s3c24xx_timer
> +#endif
> +
> /* system device classes */
>
> extern struct sysdev_class s3c2410_sysclass;
> --
> 1.7.6.1
Hi Tomasz Figa,
Sorry for late response, probably I'm missing this......and I couldn't
review this in detail :(
But as you know above mach-s3c64xx/time.c is similar with
plat-s5p/s5p-time.c so I'd prefer that you could consolidate them,
samsung_timer into plat-samsung directory. In addition, if you need to
implement SoC specific feature, you can use soc_is_xxxx() like
soc_is_s3c64xx() there.
If any problems, please let me know.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH 1/5] ARM: Samsung: PWM: Allow to differentiate SoCs based on platform device name.
From: Kukjin Kim @ 2011-10-10 9:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110907190120.GA24703@sirena.org.uk>
Mark Brown wrote:
>
> On Tue, Sep 06, 2011 at 01:04:30PM +0100, Russell King - ARM Linux wrote:
>
> > Pros to platform driver name:
> > 1. Can re-use existing names if feature compatible without driver mods.
> > 2. Scales well with an increasing number of SoCs.
>
> > Cons:
> > 1. People will hate having SoC names which don't refer to their exact
SoC.
> > 2. Probably requires storage of a set of flags in driver private data
> > to identify SoC specific features.
> > 3. Requires additional string space to identify each driver name.
>
> There's also an issue with actually getting the devices together to
> register which causes fragility here.
>
> > However, thinking about this more wrt DT, there's another aspect to
this.
> > Rather than encoding into the driver "this SoC has features and quirks
> > X,Y,Z" maybe that information should be in the device tree itself. For
> > example, SoC 1 has X and Z, SoC 2 has Y. Then a new SoC 3 comes along
> > with X and Y but not Z. If X, Y, Z are encoded into DT then there's no
> > need to touch the kernel to support SoC 3, not even to change driver
> > names or soc_is_xxx macros etc.
>
> This does depend pretty strongly on making sure that the SoC DT is
> distributed separately to the board DT - that should be solved now.
Yes, I agree. So we can keep the current way to support each SoCs' device
with one driver until DT world.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Mark Brown @ 2011-10-10 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E92BE19.4060907@cam.ac.uk>
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.
^ permalink raw reply
* [RFC][PATCH] plat-mxc: iomux-v3.h: implicitly enable pull-up/down when that's desired
From: Paul Fertser @ 2011-10-10 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20114.49362.842057.846334@ipc1.ka-ro>
On Mon, Oct 10, 2011 at 11:54:26AM +0200, Lothar Wa?mann wrote:
> Baruch Siach writes:
> > IMO, this patch should include the removal of the now redundant PAD_CTL_PKE
> > from arch/arm/plat-mxc/include/mach/iomux-mx25.h, and other v3 iomux headers.
> >
> Why should PAD_CTL_PKE be redundant? You still need it to configure a
> pin for the 'Keeper' functionality.
> Even if there is no default pin configuration that uses this, it
> should be possible to enable it when desired.
He meant not removing the definition itself but removing its usage
whereever it becomes redudant if my patch is accepted. I can do that
with a follow-up patch if desired.
--
Be free, use free (http://www.gnu.org/philosophy/free-sw.html) software!
mailto:fercerpav at gmail.com
^ permalink raw reply
* [PATCH 2/7] s3c-adc: describe features via quirk constants
From: Kukjin Kim @ 2011-10-10 10:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201110101142.20028.heiko@sntech.de>
Heiko St?bner wrote:
>
> Hi Kgene,
>
Hi,
(snip)
> > > Thanks for your understanding and please re-send it :)
> >
> > Any re-sending?
> as I'm this in my spare time I'm not sure I will make your "deadline" for
the
> merge-window, but will try to get it sorted today or tomorrow.
>
OK. I cannot promise now but I think you can do it for upcoming merge window
:)
> Meanwhile please take a look at the armclk series and the hsmmc devname
patch.
>
OK, sorry still missing.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH 0/2] ARM: OMAP2+: timer fixes / cleanup
From: DebBarma, Tarun Kanti @ 2011-10-10 10:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAC83Zv+r0emW7rREkPhjPyn_jBCbNLXKCNTY0=vMNxCTzzp=Xg@mail.gmail.com>
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.
--
Tarun
>> Thanks,
>> Benoit
>>
>>>
>>> Patches are based on Kevin's for_3.2/omap_device-2 branch
>>> and are available here:
>>> git://gitorious.org/omap-pm/linux.git for_3.2/timer_fixes
>>>
>>> Regards,
>>> Benoit
>>>
>>>
>>> Benoit Cousson (2):
>>> ? ARM: OMAP2+: clock data: Remove redundant timer clkdev
>>> ? ARM: OMAP2+: timer: Remove omap_device_pm_latency
>>>
>>> ?arch/arm/mach-omap2/clock2420_data.c | ? 12 ------------
>>> ?arch/arm/mach-omap2/clock2430_data.c | ? 12 ------------
>>> ?arch/arm/mach-omap2/clock3xxx_data.c | ? 12 ------------
>>> ?arch/arm/mach-omap2/clock44xx_data.c | ? 11 -----------
>>> ?arch/arm/mach-omap2/timer.c ? ? ? ? ?| ? 12 +-----------
>>> ?5 files changed, 1 insertions(+), 58 deletions(-)
>>>
>>
>>
>
^ permalink raw reply
* [PATCH v2 0/9] serial: samsung: rework clock lookup and add device tree support
From: Thomas Abraham @ 2011-10-10 10:07 UTC (permalink / raw)
To: linux-arm-kernel
Changes since v1:
- Included the missing dt bindings documentation in the last patch.
- Rebased and tested with linux 3.1-rc9 on linux-samsung-soc tree.
- Commit messages are modified to be elaborate.
- No changes in code.
This patchset reworks the lookup of parent clocks for baud rate generator in
the uart controller and adds support for device tree based discovery for the
uart controller.
The Samsung uart driver was dependent on the clock names supplied in the
platform data. This dependency had to be first removed to add device tree based
discovery support for Samsung uart driver. In the process of reworking the clock
lookup logic, several changes had to be made which in turn made parts of the
driver redundant and such portions of the driver have been removed in this
patchset. As a result, all the SoC specific extensions have been deleted.
Patch 1 modifies the driver to keep a copy of the location of the platform data
in the driver's private data. This makes device tree support addition
non-intrusive.
Patch 2 moves the complicated clock divider handling for fclk source clock for
s3c2440 SoC into platform code. The fclk clock can be easily managed by
representing it as a clock in the platform code. fclk clock handling was
specific to s3c2440 and moving this out of the driver makes the rest of the
clock handling in the driver almost identical for all SoC's supported by the
driver.
Patch 3 modifies the driver to lookup source clocks for baud rate generator
by using generic clock names. The generic clock name used by the driver is
'clk_uart_baud' appended with the parent number of the clock. For instance,
the second parent clock source option for baud rate generator is named as
'clk_uart_baud2'.
The driver stops depending on the set_clock and get_clock callbacks in the
SoC specific extensions. Instead, the driver is modified to lookup parent
clock rates and decide/calculate the best parent clock source for the baud
rate generator (best clock would have the least delta when compared to buad
rate requested).
In this process, four new members are added in the driver's private data
structure. The 'def_clk_sel' member is a platform set bit-value that specifies
the possible parents that the driver is allowed to use for baud rate clock.
A bit set at a particular bit position selects that parent clock source.
Example: If bit number 2 is set in 'def_clk_sel', then parent clock source '2'
can be a possible parent clock for baud rate generator. The 'num_clks'
is the number of possible parent clocks that the SoC supports. The
'clksel_mask' and 'clksel_shift' members are used to operate on the parent clock
selection bit field int the uart controller's contol register.
Patch 4 removes all uses and instances of 'struct s3c24xx_uart_clksrc'. This
structure was used to pass source clock 'names' between platform code, driver
and SoC specific extensions. By moving away from using platform specified clock
names in the driver, all uses and instances of 'struct s3c24xx_uart_clksrc'
is removed.
Patch 5 removes all the SoC specific get_clksrc and set_clksrc callbacks. These
callbacks were using SoC specific clock names to communicate the clock to be
set or retrieved. These callbacks are removed as they are no longer required.
Patch 6 reworks the uart clocks in platform code of all Samsung SoC's. The
driver would use generic clock names and this patch creates aliases to uart
clocks with generic clock names as the alias name.
Patch 7 merges all the SoC specific port reset functions into one common port
reset function and moves the common function into the common Samsung uart
driver. All the SoC specific port reset functions perform the same operation
allowing all of them to be converged.
Patch 8 collapses all the SoC specific probe functions and associated driver
private data into the Samsung common uart driver. With get_clksrc, set_clksrc
and reset_port functions removed from SoC specific extensions, all the remains
in those extensions is the probe function along with SoC specific driver data.
These are merged into the common Samsung uart driver and all the SoC specific
extensions are deleted.
Patch 9 adds device tree based discovery support for the uart driver.
This patchset is based on the following tree
https://github.com/kgene/linux-samsung.git branch: for-next
with the following two patches applied
[PATCH] serial: samsung: Add unified interrupt handler for s3c64xx and later SoC's
[PATCH] ARM: SAMSUNG: Remove uart irq handling from plaform code
and tested on the following boards.
SMDK2440, SMDK2416, SMDK6410, SMDK6440, SMDK6450, SMDKC100, SMDKV210, SMDKV310.
This patchset has dependency on the following patchset:
[PATCH V2 0/2] Add a common macro for creating struct clk_lookup entries
Thomas Abraham (9):
serial: samsung: Keep a copy of the location of platform data in driver's private data
serial: samsung: move handling of fclk/n clock to platform code
serial: samsung: switch to clkdev based clock lookup
serial: samsung: remove struct 's3c24xx_uart_clksrc' and all uses of it
serial: samsung: remove all uses of get_clksrc and set_clksrc
arm: samsung: register uart clocks to clock lookup list
serial: samsung: merge all SoC specific port reset functions
serial: samsung: merge probe() function from all SoC specific extensions
serial: samsung: add device tree support
.../devicetree/bindings/serial/samsung_uart.txt | 14 +
arch/arm/mach-exynos4/clock.c | 106 ++--
arch/arm/mach-exynos4/init.c | 21 +-
arch/arm/mach-s3c2410/mach-bast.c | 22 -
arch/arm/mach-s3c2410/mach-vr1000.c | 24 -
arch/arm/mach-s3c2410/s3c2410.c | 6 +
arch/arm/mach-s3c2412/clock.c | 7 +
arch/arm/mach-s3c2440/clock.c | 44 ++
arch/arm/mach-s3c2440/mach-anubis.c | 22 +-
arch/arm/mach-s3c2440/mach-at2440evb.c | 22 +-
arch/arm/mach-s3c2440/mach-osiris.c | 24 +-
arch/arm/mach-s3c2440/mach-rx1950.c | 18 +-
arch/arm/mach-s3c2440/mach-rx3715.c | 19 +-
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-s5p64x0/init.c | 31 -
arch/arm/mach-s5pc100/clock.c | 33 +-
arch/arm/mach-s5pv210/clock.c | 107 ++--
arch/arm/mach-s5pv210/init.c | 19 -
arch/arm/plat-s3c24xx/s3c2443-clock.c | 23 +-
arch/arm/plat-samsung/include/plat/regs-serial.h | 45 +-
drivers/tty/serial/Kconfig | 45 +--
drivers/tty/serial/Makefile | 5 -
drivers/tty/serial/s3c2410.c | 115 ----
drivers/tty/serial/s3c2412.c | 149 -----
drivers/tty/serial/s3c2440.c | 178 ------
drivers/tty/serial/s3c6400.c | 149 -----
drivers/tty/serial/s5pv210.c | 158 -----
drivers/tty/serial/samsung.c | 639 ++++++++++++--------
drivers/tty/serial/samsung.h | 32 +-
31 files changed, 752 insertions(+), 1426 deletions(-)
create mode 100644 Documentation/devicetree/bindings/serial/samsung_uart.txt
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
^ permalink raw reply
* [PATCH v2 1/9] serial: samsung: Keep a copy of the location of platform data in driver's private data
From: Thomas Abraham @ 2011-10-10 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
Add a pointer to the location of the platform data in the driver's private
data. When instantiated using device tree, pdev->dev->platform_data does not
necessarily point to a valid instance of platform data. The platform data
pointer in the driver's private data could be set to pdev->dev->platform_data
or platform data instance created from device tree.
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/tty/serial/s5pv210.c | 12 ++++++++++--
drivers/tty/serial/samsung.c | 16 ++++++++++++----
drivers/tty/serial/samsung.h | 4 +++-
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
index 8b0b888..03b249e 100644
--- a/drivers/tty/serial/s5pv210.c
+++ b/drivers/tty/serial/s5pv210.c
@@ -28,9 +28,13 @@
static int s5pv210_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
- struct s3c2410_uartcfg *cfg = port->dev->platform_data;
+ struct s3c24xx_uart_port *ourport;
+ struct s3c2410_uartcfg *cfg;
unsigned long ucon = rd_regl(port, S3C2410_UCON);
+ ourport = container_of(port, struct s3c24xx_uart_port, port);
+ cfg = ourport->cfg;
+
if (cfg->flags & NO_NEED_CHECK_CLKSRC)
return 0;
@@ -51,9 +55,13 @@ static int s5pv210_serial_setsource(struct uart_port *port,
static int s5pv210_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
- struct s3c2410_uartcfg *cfg = port->dev->platform_data;
+ struct s3c24xx_uart_port *ourport;
+ struct s3c2410_uartcfg *cfg;
u32 ucon = rd_regl(port, S3C2410_UCON);
+ ourport = container_of(port, struct s3c24xx_uart_port, port);
+ cfg = ourport->cfg;
+
clk->divisor = 1;
if (cfg->flags & NO_NEED_CHECK_CLKSRC)
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index b31f1c3..51cfb9f 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -190,10 +190,13 @@ static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *p
static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
{
+ struct s3c24xx_uart_port *ourport;
+
if (port->dev == NULL)
return NULL;
- return (struct s3c2410_uartcfg *)port->dev->platform_data;
+ ourport = container_of(port, struct s3c24xx_uart_port, port);
+ return ourport->cfg;
}
static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
@@ -1125,7 +1128,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
struct platform_device *platdev)
{
struct uart_port *port = &ourport->port;
- struct s3c2410_uartcfg *cfg;
+ struct s3c2410_uartcfg *cfg = platdev->dev.platform_data;
struct resource *res;
int ret;
@@ -1134,11 +1137,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
if (platdev == NULL)
return -ENODEV;
- cfg = s3c24xx_dev_to_cfg(&platdev->dev);
-
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);
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 8e87b78..6c9cb9d 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -48,6 +48,9 @@ struct s3c24xx_uart_port {
struct clk *baudclk;
struct uart_port port;
+ /* reference to platform data */
+ struct s3c2410_uartcfg *cfg;
+
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
#endif
@@ -56,7 +59,6 @@ struct s3c24xx_uart_port {
/* conversion functions */
#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
-#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
/* register access controls */
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 2/9] serial: samsung: move handling of fclk/n clock to platform code
From: Thomas Abraham @ 2011-10-10 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
s3c2440 uses fclk/n (fclk divided by n) clock as one of the possible clocks used
to generate the baud rate clock. The divider 'n' in this case can be logically
represented outside of the uart controller.
This patch creates a new clock by name "fclk_n" for s3c2440 based platforms to
represent the fclk/n clock in the platform code. This clock provides a get_rate
callback that checks the UCON0/1/2 registers to determine the clock rate. The
samsung uart driver would receive the "fclk_n" clock name as one of the possible
baud rate clock options and the driver need not determine clock rate of fclk/n.
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-s3c2440/clock.c | 37 +++++++++++++++++++++++++++++++++++
arch/arm/mach-s3c2440/mach-rx1950.c | 4 +-
arch/arm/mach-s3c2440/mach-rx3715.c | 4 +-
drivers/tty/serial/s3c2440.c | 33 ++----------------------------
drivers/tty/serial/samsung.c | 21 -------------------
5 files changed, 44 insertions(+), 55 deletions(-)
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index f9e6bda..f85853c 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/serial_core.h>
#include <mach/hardware.h>
#include <linux/atomic.h>
@@ -43,6 +44,7 @@
#include <plat/clock.h>
#include <plat/cpu.h>
+#include <plat/regs-serial.h>
/* S3C2440 extended clock support */
@@ -108,6 +110,40 @@ static struct clk s3c2440_clk_ac97 = {
.ctrlbit = S3C2440_CLKCON_CAMERA,
};
+static unsigned long s3c2440_fclk_n_getrate(struct clk *clk)
+{
+ unsigned long ucon0, ucon1, ucon2, divisor;
+
+ /* the fun of calculating the uart divisors on the s3c2440 */
+ ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
+ ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
+ ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
+
+ ucon0 &= S3C2440_UCON0_DIVMASK;
+ ucon1 &= S3C2440_UCON1_DIVMASK;
+ ucon2 &= S3C2440_UCON2_DIVMASK;
+
+ if (ucon0 != 0)
+ divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
+ else if (ucon1 != 0)
+ divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
+ else if (ucon2 != 0)
+ divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
+ else
+ /* manual calims 44, seems to be 9 */
+ divisor = 9;
+
+ return clk_get_rate(clk->parent) / divisor;
+}
+
+static struct clk s3c2440_clk_fclk_n = {
+ .name = "fclk_n",
+ .parent = &clk_f,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2440_fclk_n_getrate,
+ },
+};
+
static int s3c2440_clk_add(struct sys_device *sysdev)
{
struct clk *clock_upll;
@@ -126,6 +162,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
s3c2440_clk_cam.parent = clock_h;
s3c2440_clk_ac97.parent = clock_p;
s3c2440_clk_cam_upll.parent = clock_upll;
+ s3c24xx_register_clock(&s3c2440_clk_fclk_n);
s3c24xx_register_clock(&s3c2440_clk_ac97);
s3c24xx_register_clock(&s3c2440_clk_cam);
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 27ea950..9528b37 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -69,8 +69,8 @@ static struct map_desc rx1950_iodesc[] __initdata = {
static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
[0] = {
- .name = "fclk",
- .divisor = 0x0a,
+ .name = "fclk_n",
+ .divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 1472b1a..a88247e 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -70,8 +70,8 @@ static struct map_desc rx3715_iodesc[] __initdata = {
static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
[0] = {
- .name = "fclk",
- .divisor = 0,
+ .name = "fclk_n",
+ .divisor = 1,
.min_baud = 0,
.max_baud = 0,
}
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c
index 1d0c324..4498828 100644
--- a/drivers/tty/serial/s3c2440.c
+++ b/drivers/tty/serial/s3c2440.c
@@ -39,7 +39,7 @@ static int s3c2440_serial_setsource(struct uart_port *port,
ucon |= S3C2440_UCON_UCLK;
else if (strcmp(clk->name, "pclk") == 0)
ucon |= S3C2440_UCON_PCLK;
- else if (strcmp(clk->name, "fclk") == 0)
+ else if (strcmp(clk->name, "fclk_n") == 0)
ucon |= S3C2440_UCON_FCLK;
else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
@@ -55,7 +55,6 @@ static int s3c2440_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
- unsigned long ucon0, ucon1, ucon2;
switch (ucon & S3C2440_UCON_CLKMASK) {
case S3C2440_UCON_UCLK:
@@ -70,34 +69,8 @@ static int s3c2440_serial_getsource(struct uart_port *port,
break;
case S3C2440_UCON_FCLK:
- /* the fun of calculating the uart divisors on
- * the s3c2440 */
-
- ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
- ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
- ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
-
- printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
-
- ucon0 &= S3C2440_UCON0_DIVMASK;
- ucon1 &= S3C2440_UCON1_DIVMASK;
- ucon2 &= S3C2440_UCON2_DIVMASK;
-
- if (ucon0 != 0) {
- clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
- clk->divisor += 6;
- } else if (ucon1 != 0) {
- clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
- clk->divisor += 21;
- } else if (ucon2 != 0) {
- clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
- clk->divisor += 36;
- } else {
- /* manual calims 44, seems to be 9 */
- clk->divisor = 9;
- }
-
- clk->name = "fclk";
+ clk->divisor = 1;
+ clk->name = "fclk_n";
break;
}
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 51cfb9f..fc242b2 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -649,27 +649,6 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
if (cfg->clocks_size == 0)
clkp = &tmp_clksrc;
- /* check to see if we're sourcing fclk, and if so we're
- * going to have to update the clock source
- */
-
- if (strcmp(clkp->name, "fclk") == 0) {
- struct s3c24xx_uart_clksrc src;
-
- s3c24xx_serial_getsource(port, &src);
-
- /* check that the port already using fclk, and if
- * not, then re-select fclk
- */
-
- if (strcmp(src.name, clkp->name) == 0) {
- s3c24xx_serial_setsource(port, clkp);
- s3c24xx_serial_getsource(port, &src);
- }
-
- clkp->divisor = src.divisor;
- }
-
s3c24xx_serial_calcbaud(res, port, clkp, baud);
best = res;
resptr = best + 1;
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 3/9] serial: samsung: switch to clkdev based clock lookup
From: Thomas Abraham @ 2011-10-10 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318241285-23568-1-git-send-email-thomas.abraham@linaro.org>
Instead of using clock names supplied in platform data, use a generic
clock name 'clk_uart_baud' to look up clocks. The platform code should
register clocks with the name 'clk_uart_baud' which can be used by the
baud rate generator. The clock lookup and selection of the best clock
as baud rate clock is reworked.
Platform code can specify the clocks that can be used as source for the
baud clock (as supported previously by passing names of clocks). A new
member is added to the platform data 'clk_sel' which holds a bit-field
value with each bit representing a baud source clock. If a bit at any
bit position is set, that clock is looked up to participate in the
selection of the baud clock source.
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 | 5 +
drivers/tty/serial/samsung.c | 207 +++++++++-------------
drivers/tty/serial/samsung.h | 4 +
3 files changed, 95 insertions(+), 121 deletions(-)
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 7207348..b493d8d 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -222,6 +222,10 @@
#define S5PV210_UFSTAT_RXSHIFT (0)
#define NO_NEED_CHECK_CLKSRC 1
+#define S3C2410_UCON_CLKSEL0 (1 << 0)
+#define S3C2410_UCON_CLKSEL1 (1 << 1)
+#define S3C2410_UCON_CLKSEL2 (1 << 2)
+#define S3C2410_UCON_CLKSEL3 (1 << 3)
#ifndef __ASSEMBLY__
@@ -257,6 +261,7 @@ struct s3c2410_uartcfg {
unsigned char unused;
unsigned short flags;
upf_t uart_flags; /* default uart flags */
+ unsigned int clk_sel;
unsigned int has_fracval;
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index fc242b2..dc5a4ed 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -49,6 +49,7 @@
#include <mach/map.h>
#include <plat/regs-serial.h>
+#include <plat/clock.h>
#include "samsung.h"
@@ -558,133 +559,98 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
*
*/
+#define MAX_CLK_NAME_LENGTH 15
-#define MAX_CLKS (8)
-
-static struct s3c24xx_uart_clksrc tmp_clksrc = {
- .name = "pclk",
- .min_baud = 0,
- .max_baud = 0,
- .divisor = 1,
-};
-
-static inline int
-s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
+static inline int s3c24xx_serial_getsource(struct uart_port *port)
{
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+ unsigned int ucon;
- return (info->get_clksrc)(port, c);
-}
-
-static inline int
-s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+ if (info->num_clks == 1)
+ return 0;
- return (info->set_clksrc)(port, c);
+ ucon = rd_regl(port, S3C2410_UCON);
+ ucon &= info->clksel_mask;
+ return ucon >> info->clksel_shift;
}
-struct baud_calc {
- struct s3c24xx_uart_clksrc *clksrc;
- unsigned int calc;
- unsigned int divslot;
- unsigned int quot;
- struct clk *src;
-};
-
-static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
- struct uart_port *port,
- struct s3c24xx_uart_clksrc *clksrc,
- unsigned int baud)
+static void s3c24xx_serial_setsource(struct uart_port *port,
+ unsigned int clk_sel)
{
- struct s3c24xx_uart_port *ourport = to_ourport(port);
- unsigned long rate;
-
- calc->src = clk_get(port->dev, clksrc->name);
- if (calc->src == NULL || IS_ERR(calc->src))
- return 0;
-
- rate = clk_get_rate(calc->src);
- rate /= clksrc->divisor;
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+ unsigned int ucon;
- calc->clksrc = clksrc;
+ if (info->num_clks == 1)
+ return;
- if (ourport->info->has_divslot) {
- unsigned long div = rate / baud;
-
- /* The UDIVSLOT register on the newer UARTs allows us to
- * get a divisor adjustment of 1/16th on the baud clock.
- *
- * We don't keep the UDIVSLOT value (the 16ths we calculated
- * by not multiplying the baud by 16) as it is easy enough
- * to recalculate.
- */
-
- calc->quot = div / 16;
- calc->calc = rate / div;
- } else {
- calc->quot = (rate + (8 * baud)) / (16 * baud);
- calc->calc = (rate / (calc->quot * 16));
- }
+ ucon = rd_regl(port, S3C2410_UCON);
+ if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel)
+ return;
- calc->quot--;
- return 1;
+ ucon &= ~info->clksel_mask;
+ ucon |= clk_sel << info->clksel_shift;
+ wr_regl(port, S3C2410_UCON, ucon);
}
-static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
- struct s3c24xx_uart_clksrc **clksrc,
- struct clk **clk,
- unsigned int baud)
+static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
+ unsigned int req_baud, struct clk **best_clk,
+ unsigned int *clk_num)
{
- struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
- struct s3c24xx_uart_clksrc *clkp;
- struct baud_calc res[MAX_CLKS];
- struct baud_calc *resptr, *best, *sptr;
- int i;
-
- clkp = cfg->clocks;
- best = NULL;
-
- if (cfg->clocks_size < 2) {
- if (cfg->clocks_size == 0)
- clkp = &tmp_clksrc;
-
- s3c24xx_serial_calcbaud(res, port, clkp, baud);
- best = res;
- resptr = best + 1;
- } else {
- resptr = res;
-
- for (i = 0; i < cfg->clocks_size; i++, clkp++) {
- if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
- resptr++;
+ struct s3c24xx_uart_info *info = ourport->info;
+ struct clk *clk;
+ unsigned long rate;
+ unsigned int cnt, baud, quot, clk_sel, best_quot = 0;
+ char clkname[MAX_CLK_NAME_LENGTH];
+ int calc_deviation, deviation = (1 << 30) - 1;
+
+ *best_clk = NULL;
+ clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel :
+ ourport->info->def_clk_sel;
+ for (cnt = 0; cnt < info->num_clks; cnt++) {
+ if (!(clk_sel & (1 << cnt)))
+ continue;
+
+ sprintf(clkname, "clk_uart_baud%d", cnt);
+ clk = clk_get(ourport->port.dev, clkname);
+ if (IS_ERR_OR_NULL(clk))
+ continue;
+
+ rate = clk_get_rate(clk);
+ if (!rate)
+ continue;
+
+ if (ourport->info->has_divslot) {
+ unsigned long div = rate / req_baud;
+
+ /* The UDIVSLOT register on the newer UARTs allows us to
+ * get a divisor adjustment of 1/16th on the baud clock.
+ *
+ * We don't keep the UDIVSLOT value (the 16ths we
+ * calculated by not multiplying the baud by 16) as it
+ * is easy enough to recalculate.
+ */
+
+ quot = div / 16;
+ baud = rate / div;
+ } else {
+ quot = (rate + (8 * req_baud)) / (16 * req_baud);
+ baud = rate / (quot * 16);
}
- }
-
- /* ok, we now need to select the best clock we found */
-
- if (!best) {
- unsigned int deviation = (1<<30)|((1<<30)-1);
- int calc_deviation;
+ quot--;
- for (sptr = res; sptr < resptr; sptr++) {
- calc_deviation = baud - sptr->calc;
- if (calc_deviation < 0)
- calc_deviation = -calc_deviation;
+ calc_deviation = req_baud - baud;
+ if (calc_deviation < 0)
+ calc_deviation = -calc_deviation;
- if (calc_deviation < deviation) {
- best = sptr;
- deviation = calc_deviation;
- }
+ if (calc_deviation < deviation) {
+ *best_clk = clk;
+ best_quot = quot;
+ *clk_num = cnt;
+ deviation = calc_deviation;
}
}
- /* store results to pass back */
-
- *clksrc = best->clksrc;
- *clk = best->src;
-
- return best->quot;
+ return best_quot;
}
/* udivslot_table[]
@@ -717,10 +683,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
{
struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- struct s3c24xx_uart_clksrc *clksrc = NULL;
struct clk *clk = NULL;
unsigned long flags;
- unsigned int baud, quot;
+ unsigned int baud, quot, clk_sel = 0;
unsigned int ulcon;
unsigned int umcon;
unsigned int udivslot = 0;
@@ -736,17 +701,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
*/
baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
-
+ quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor;
- else
- quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);
+ if (!clk)
+ return;
/* check to see if we need to change clock source */
- if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
- dbg("selecting clock %p\n", clk);
- s3c24xx_serial_setsource(port, clksrc);
+ if (ourport->baudclk != clk) {
+ s3c24xx_serial_setsource(port, clk_sel);
if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
clk_disable(ourport->baudclk);
@@ -755,7 +719,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
clk_enable(clk);
- ourport->clksrc = clksrc;
ourport->baudclk = clk;
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
}
@@ -1202,7 +1165,7 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name);
+ return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name);
}
static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
@@ -1382,12 +1345,13 @@ static void __init
s3c24xx_serial_get_options(struct uart_port *port, int *baud,
int *parity, int *bits)
{
- struct s3c24xx_uart_clksrc clksrc;
struct clk *clk;
unsigned int ulcon;
unsigned int ucon;
unsigned int ubrdiv;
unsigned long rate;
+ unsigned int clk_sel;
+ char clk_name[MAX_CLK_NAME_LENGTH];
ulcon = rd_regl(port, S3C2410_ULCON);
ucon = rd_regl(port, S3C2410_UCON);
@@ -1432,11 +1396,12 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
/* now calculate the baud rate */
- s3c24xx_serial_getsource(port, &clksrc);
+ clk_sel = s3c24xx_serial_getsource(port);
+ sprintf(clk_name, "clk_uart_baud%d", clk_sel);
- clk = clk_get(port->dev, clksrc.name);
+ clk = clk_get(port->dev, clk_name);
if (!IS_ERR(clk) && clk != NULL)
- rate = clk_get_rate(clk) / clksrc.divisor;
+ rate = clk_get_rate(clk);
else
rate = 1;
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 6c9cb9d..11369f3 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -19,6 +19,10 @@ struct s3c24xx_uart_info {
unsigned long tx_fifomask;
unsigned long tx_fifoshift;
unsigned long tx_fifofull;
+ unsigned int def_clk_sel;
+ unsigned long num_clks;
+ unsigned long clksel_mask;
+ unsigned long clksel_shift;
/* uart port features */
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 4/9] serial: samsung: remove struct 's3c24xx_uart_clksrc' and all uses of it
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 clkdev based clock lookup added to samsung serial driver, the use
of 'struct s3c24xx_uart_clksrc' to supply clock names in platform
data is removed from all the Samsung platform code.
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Ramax Lo <ramaxlo@gmail.com>
Cc: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos4/init.c | 15 +----------
arch/arm/mach-s3c2410/mach-bast.c | 22 ---------------
arch/arm/mach-s3c2410/mach-vr1000.c | 24 -----------------
arch/arm/mach-s3c2440/mach-anubis.c | 22 +--------------
arch/arm/mach-s3c2440/mach-at2440evb.c | 22 +--------------
arch/arm/mach-s3c2440/mach-osiris.c | 24 ++---------------
arch/arm/mach-s3c2440/mach-rx1950.c | 18 ++----------
arch/arm/mach-s3c2440/mach-rx3715.c | 19 ++-----------
arch/arm/mach-s5p64x0/init.c | 31 ----------------------
arch/arm/mach-s5pv210/init.c | 19 -------------
arch/arm/plat-samsung/include/plat/regs-serial.h | 23 ----------------
drivers/tty/serial/samsung.h | 1 -
12 files changed, 14 insertions(+), 226 deletions(-)
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c
index a8a83e3..e836c9c 100644
--- a/arch/arm/mach-exynos4/init.c
+++ b/arch/arm/mach-exynos4/init.c
@@ -14,15 +14,6 @@
#include <plat/devs.h>
#include <plat/regs-serial.h>
-static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
- [0] = {
- .name = "uclk1",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
-};
-
/* uart registration process */
void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
@@ -30,11 +21,7 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
u32 ucnt;
for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
- if (!tcfg->clocks) {
- tcfg->has_fracval = 1;
- tcfg->clocks = exynos4_serial_clocks;
- tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
- }
+ tcfg->has_fracval = 1;
tcfg->flags |= NO_NEED_CHECK_CLKSRC;
}
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 1e2d536..e92e29b 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -164,22 +164,6 @@ static struct map_desc bast_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
- [0] = {
- .name = "uclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "pclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- }
-};
-
-
static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
@@ -187,8 +171,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = bast_serial_clocks,
- .clocks_size = ARRAY_SIZE(bast_serial_clocks),
},
[1] = {
.hwport = 1,
@@ -196,8 +178,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = bast_serial_clocks,
- .clocks_size = ARRAY_SIZE(bast_serial_clocks),
},
/* port 2 is not actually used */
[2] = {
@@ -206,8 +186,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = bast_serial_clocks,
- .clocks_size = ARRAY_SIZE(bast_serial_clocks),
}
};
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 6ccce5a..208d83a 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -109,23 +109,6 @@ static struct map_desc vr1000_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-/* uart clock source(s) */
-
-static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
- [0] = {
- .name = "uclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "pclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0.
- }
-};
-
static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
@@ -133,8 +116,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = vr1000_serial_clocks,
- .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
},
[1] = {
.hwport = 1,
@@ -142,8 +123,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = vr1000_serial_clocks,
- .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
},
/* port 2 is not actually used */
[2] = {
@@ -152,9 +131,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = vr1000_serial_clocks,
- .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
-
}
};
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index d708678..0097585 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -96,22 +96,6 @@ static struct map_desc anubis_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
- [0] = {
- .name = "uclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "pclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- }
-};
-
-
static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
@@ -119,8 +103,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = anubis_serial_clocks,
- .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
},
[1] = {
.hwport = 2,
@@ -128,8 +111,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = anubis_serial_clocks,
- .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
},
};
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
index 6c98b78..4cc60b1 100644
--- a/arch/arm/mach-s3c2440/mach-at2440evb.c
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -57,22 +57,6 @@ static struct map_desc at2440evb_iodesc[] __initdata = {
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = {
- [0] = {
- .name = "uclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "pclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- }
-};
-
-
static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
@@ -80,8 +64,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = at2440evb_serial_clocks,
- .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
},
[1] = {
.hwport = 1,
@@ -89,8 +72,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = at2440evb_serial_clocks,
- .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
},
};
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index d885363..b75ed46 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -100,21 +100,6 @@ static struct map_desc osiris_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
- [0] = {
- .name = "uclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "pclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- }
-};
-
static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
@@ -122,8 +107,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = osiris_serial_clocks,
- .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
},
[1] = {
.hwport = 1,
@@ -131,8 +115,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = osiris_serial_clocks,
- .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
},
[2] = {
.hwport = 2,
@@ -140,8 +123,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
- .clocks = osiris_serial_clocks,
- .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
}
};
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 9528b37..04bb392 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -67,15 +67,6 @@
static struct map_desc rx1950_iodesc[] __initdata = {
};
-static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
- [0] = {
- .name = "fclk_n",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
-};
-
static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
@@ -83,8 +74,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
- .clocks = rx1950_serial_clocks,
- .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL3,
},
[1] = {
.hwport = 1,
@@ -92,8 +82,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
- .clocks = rx1950_serial_clocks,
- .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL3,
},
/* IR port */
[2] = {
@@ -102,8 +91,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
.ucon = 0x3c5,
.ulcon = 0x43,
.ufcon = 0xf1,
- .clocks = rx1950_serial_clocks,
- .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL3,
},
};
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index a88247e..3c0d17c 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -67,16 +67,6 @@ static struct map_desc rx3715_iodesc[] __initdata = {
},
};
-
-static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
- [0] = {
- .name = "fclk_n",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- }
-};
-
static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
[0] = {
.hwport = 0,
@@ -84,8 +74,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
- .clocks = rx3715_serial_clocks,
- .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL3,
},
[1] = {
.hwport = 1,
@@ -93,8 +82,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x00,
- .clocks = rx3715_serial_clocks,
- .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL3,
},
/* IR port */
[2] = {
@@ -103,8 +91,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
.ucon = 0x3c5,
.ulcon = 0x43,
.ufcon = 0x51,
- .clocks = rx3715_serial_clocks,
- .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+ .clk_sel = S3C2410_UCON_CLKSEL3,
}
};
diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c
index 79833ca..659a66c 100644
--- a/arch/arm/mach-s5p64x0/init.c
+++ b/arch/arm/mach-s5p64x0/init.c
@@ -23,36 +23,7 @@
#include <plat/s5p6450.h>
#include <plat/regs-serial.h>
-static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
- [0] = {
- .name = "pclk_low",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "uclk1",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
-};
-
/* uart registration process */
-
-void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- struct s3c2410_uartcfg *tcfg = cfg;
- u32 ucnt;
-
- for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
- if (!tcfg->clocks) {
- tcfg->clocks = s5p64x0_serial_clocks;
- tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
- }
- }
-}
-
void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
int uart;
@@ -62,12 +33,10 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
}
- s5p64x0_common_init_uarts(cfg, no);
s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
}
void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
- s5p64x0_common_init_uarts(cfg, no);
s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
}
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
index 4865ae2..468a5f8 100644
--- a/arch/arm/mach-s5pv210/init.c
+++ b/arch/arm/mach-s5pv210/init.c
@@ -18,27 +18,8 @@
#include <plat/s5pv210.h>
#include <plat/regs-serial.h>
-static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
- [0] = {
- .name = "pclk",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
-};
-
/* uart registration process */
void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
- struct s3c2410_uartcfg *tcfg = cfg;
- u32 ucnt;
-
- for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
- if (!tcfg->clocks) {
- tcfg->clocks = s5pv210_serial_clocks;
- tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
- }
- }
-
s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
}
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index b493d8d..25f0c36 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -229,26 +229,6 @@
#ifndef __ASSEMBLY__
-/* struct s3c24xx_uart_clksrc
- *
- * this structure defines a named clock source that can be used for the
- * uart, so that the best clock can be selected for the requested baud
- * rate.
- *
- * min_baud and max_baud define the range of baud-rates this clock is
- * acceptable for, if they are both zero, it is assumed any baud rate that
- * can be generated from this clock will be used.
- *
- * divisor gives the divisor from the clock to the one seen by the uart
-*/
-
-struct s3c24xx_uart_clksrc {
- const char *name;
- unsigned int divisor;
- unsigned int min_baud;
- unsigned int max_baud;
-};
-
/* configuration structure for per-machine configurations for the
* serial port
*
@@ -268,9 +248,6 @@ struct s3c2410_uartcfg {
unsigned long ucon; /* value of ucon for port */
unsigned long ulcon; /* value of ulcon for port */
unsigned long ufcon; /* value of ufcon for port */
-
- struct s3c24xx_uart_clksrc *clocks;
- unsigned int clocks_size;
};
/* s3c24xx_uart_devs
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 11369f3..40e9ef1 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -47,7 +47,6 @@ struct s3c24xx_uart_port {
unsigned int tx_irq;
struct s3c24xx_uart_info *info;
- struct s3c24xx_uart_clksrc *clksrc;
struct clk *clk;
struct clk *baudclk;
struct uart_port port;
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 5/9] serial: samsung: remove all uses of get_clksrc and set_clksrc
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 clkdev based clock lookup support, the clock set and get operation
using clock names communicated between the samsung uart driver and the
SoC specific extension can be removed.
In addition to that, for each platform specific extension, add the
default clock selection, number of clock options for uart baud generator,
clock selection bit mask and shift values which is required by the
clkdev support in samsung uart driver.
The default clock selection value 'def_clk_sel' specifies the default clock
to be used as the source clock for baud rate generator in case the platform
code does not specify the same.
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos4/init.c | 4 +-
arch/arm/plat-samsung/include/plat/regs-serial.h | 7 ++-
drivers/tty/serial/s3c2410.c | 31 ++----------
drivers/tty/serial/s3c2412.c | 55 ++------------------
drivers/tty/serial/s3c2440.c | 58 ++-------------------
drivers/tty/serial/s3c6400.c | 54 ++------------------
drivers/tty/serial/s5pv210.c | 60 ++--------------------
drivers/tty/serial/samsung.h | 5 --
8 files changed, 27 insertions(+), 247 deletions(-)
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c
index e836c9c..3c9590b 100644
--- a/arch/arm/mach-exynos4/init.c
+++ b/arch/arm/mach-exynos4/init.c
@@ -20,10 +20,8 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
struct s3c2410_uartcfg *tcfg = cfg;
u32 ucnt;
- for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
tcfg->has_fracval = 1;
- tcfg->flags |= NO_NEED_CHECK_CLKSRC;
- }
s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
}
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 25f0c36..133fa97 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -71,6 +71,7 @@
#define S3C2410_LCON_IRM (1<<6)
#define S3C2440_UCON_CLKMASK (3<<10)
+#define S3C2440_UCON_CLKSHIFT (10)
#define S3C2440_UCON_PCLK (0<<10)
#define S3C2440_UCON_UCLK (1<<10)
#define S3C2440_UCON_PCLK2 (2<<10)
@@ -78,6 +79,7 @@
#define S3C2443_UCON_EPLL (3<<10)
#define S3C6400_UCON_CLKMASK (3<<10)
+#define S3C6400_UCON_CLKSHIFT (10)
#define S3C6400_UCON_PCLK (0<<10)
#define S3C6400_UCON_PCLK2 (2<<10)
#define S3C6400_UCON_UCLK0 (1<<10)
@@ -90,11 +92,14 @@
#define S3C2440_UCON_DIVSHIFT (12)
#define S3C2412_UCON_CLKMASK (3<<10)
+#define S3C2412_UCON_CLKSHIFT (10)
#define S3C2412_UCON_UCLK (1<<10)
#define S3C2412_UCON_USYSCLK (3<<10)
#define S3C2412_UCON_PCLK (0<<10)
#define S3C2412_UCON_PCLK2 (2<<10)
+#define S3C2410_UCON_CLKMASK (1 << 10)
+#define S3C2410_UCON_CLKSHIFT (10)
#define S3C2410_UCON_UCLK (1<<10)
#define S3C2410_UCON_SBREAK (1<<4)
@@ -193,6 +198,7 @@
/* Following are specific to S5PV210 */
#define S5PV210_UCON_CLKMASK (1<<10)
+#define S5PV210_UCON_CLKSHIFT (10)
#define S5PV210_UCON_PCLK (0<<10)
#define S5PV210_UCON_UCLK (1<<10)
@@ -221,7 +227,6 @@
#define S5PV210_UFSTAT_RXMASK (255<<0)
#define S5PV210_UFSTAT_RXSHIFT (0)
-#define NO_NEED_CHECK_CLKSRC 1
#define S3C2410_UCON_CLKSEL0 (1 << 0)
#define S3C2410_UCON_CLKSEL1 (1 << 1)
#define S3C2410_UCON_CLKSEL2 (1 << 2)
diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c
index b1d7e7c..e668a9d 100644
--- a/drivers/tty/serial/s3c2410.c
+++ b/drivers/tty/serial/s3c2410.c
@@ -25,31 +25,6 @@
#include "samsung.h"
-static int s3c2410_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- if (strcmp(clk->name, "uclk") == 0)
- ucon |= S3C2410_UCON_UCLK;
- else
- ucon &= ~S3C2410_UCON_UCLK;
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-static int s3c2410_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- clk->divisor = 1;
- clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk";
-
- return 0;
-}
-
static int s3c2410_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
@@ -77,8 +52,10 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = {
.tx_fifofull = S3C2410_UFSTAT_TXFULL,
.tx_fifomask = S3C2410_UFSTAT_TXMASK,
.tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2410_serial_getsource,
- .set_clksrc = s3c2410_serial_setsource,
+ .def_clk_sel = S3C2410_UCON_CLKSEL0,
+ .num_clks = 2,
+ .clksel_mask = S3C2410_UCON_CLKMASK,
+ .clksel_shift = S3C2410_UCON_CLKSHIFT,
.reset_port = s3c2410_serial_resetport,
};
diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c
index 2234bf9..5b85c19 100644
--- a/drivers/tty/serial/s3c2412.c
+++ b/drivers/tty/serial/s3c2412.c
@@ -25,55 +25,6 @@
#include "samsung.h"
-static int s3c2412_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- ucon &= ~S3C2412_UCON_CLKMASK;
-
- if (strcmp(clk->name, "uclk") == 0)
- ucon |= S3C2440_UCON_UCLK;
- else if (strcmp(clk->name, "pclk") == 0)
- ucon |= S3C2440_UCON_PCLK;
- else if (strcmp(clk->name, "usysclk") == 0)
- ucon |= S3C2412_UCON_USYSCLK;
- else {
- printk(KERN_ERR "unknown clock source %s\n", clk->name);
- return -EINVAL;
- }
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-
-static int s3c2412_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- switch (ucon & S3C2412_UCON_CLKMASK) {
- case S3C2412_UCON_UCLK:
- clk->divisor = 1;
- clk->name = "uclk";
- break;
-
- case S3C2412_UCON_PCLK:
- case S3C2412_UCON_PCLK2:
- clk->divisor = 1;
- clk->name = "pclk";
- break;
-
- case S3C2412_UCON_USYSCLK:
- clk->divisor = 1;
- clk->name = "usysclk";
- break;
- }
-
- return 0;
-}
-
static int s3c2412_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
@@ -108,8 +59,10 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = {
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2412_serial_getsource,
- .set_clksrc = s3c2412_serial_setsource,
+ .def_clk_sel = S3C2410_UCON_CLKSEL2,
+ .num_clks = 4,
+ .clksel_mask = S3C2412_UCON_CLKMASK,
+ .clksel_shift = S3C2412_UCON_CLKSHIFT,
.reset_port = s3c2412_serial_resetport,
};
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c
index 4498828..39930f8 100644
--- a/drivers/tty/serial/s3c2440.c
+++ b/drivers/tty/serial/s3c2440.c
@@ -25,58 +25,6 @@
#include "samsung.h"
-
-static int s3c2440_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- /* todo - proper fclk<>nonfclk switch. */
-
- ucon &= ~S3C2440_UCON_CLKMASK;
-
- if (strcmp(clk->name, "uclk") == 0)
- ucon |= S3C2440_UCON_UCLK;
- else if (strcmp(clk->name, "pclk") == 0)
- ucon |= S3C2440_UCON_PCLK;
- else if (strcmp(clk->name, "fclk_n") == 0)
- ucon |= S3C2440_UCON_FCLK;
- else {
- printk(KERN_ERR "unknown clock source %s\n", clk->name);
- return -EINVAL;
- }
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-
-static int s3c2440_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- switch (ucon & S3C2440_UCON_CLKMASK) {
- case S3C2440_UCON_UCLK:
- clk->divisor = 1;
- clk->name = "uclk";
- break;
-
- case S3C2440_UCON_PCLK:
- case S3C2440_UCON_PCLK2:
- clk->divisor = 1;
- clk->name = "pclk";
- break;
-
- case S3C2440_UCON_FCLK:
- clk->divisor = 1;
- clk->name = "fclk_n";
- break;
- }
-
- return 0;
-}
-
static int s3c2440_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
@@ -110,8 +58,10 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = {
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2440_serial_getsource,
- .set_clksrc = s3c2440_serial_setsource,
+ .def_clk_sel = S3C2410_UCON_CLKSEL2,
+ .num_clks = 4,
+ .clksel_mask = S3C2440_UCON_CLKMASK,
+ .clksel_shift = S3C2440_UCON_CLKSHIFT,
.reset_port = s3c2440_serial_resetport,
};
diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c
index e2f6913..c5a6d46 100644
--- a/drivers/tty/serial/s3c6400.c
+++ b/drivers/tty/serial/s3c6400.c
@@ -26,54 +26,6 @@
#include "samsung.h"
-static int s3c6400_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- if (strcmp(clk->name, "uclk0") == 0) {
- ucon &= ~S3C6400_UCON_CLKMASK;
- ucon |= S3C6400_UCON_UCLK0;
- } else if (strcmp(clk->name, "uclk1") == 0)
- ucon |= S3C6400_UCON_UCLK1;
- else if (strcmp(clk->name, "pclk") == 0) {
- /* See notes about transitioning from UCLK to PCLK */
- ucon &= ~S3C6400_UCON_UCLK0;
- } else {
- printk(KERN_ERR "unknown clock source %s\n", clk->name);
- return -EINVAL;
- }
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-
-static int s3c6400_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- u32 ucon = rd_regl(port, S3C2410_UCON);
-
- clk->divisor = 1;
-
- switch (ucon & S3C6400_UCON_CLKMASK) {
- case S3C6400_UCON_UCLK0:
- clk->name = "uclk0";
- break;
-
- case S3C6400_UCON_UCLK1:
- clk->name = "uclk1";
- break;
-
- case S3C6400_UCON_PCLK:
- case S3C6400_UCON_PCLK2:
- clk->name = "pclk";
- break;
- }
-
- return 0;
-}
-
static int s3c6400_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
@@ -108,8 +60,10 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = {
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .get_clksrc = s3c6400_serial_getsource,
- .set_clksrc = s3c6400_serial_setsource,
+ .def_clk_sel = S3C2410_UCON_CLKSEL2,
+ .num_clks = 4,
+ .clksel_mask = S3C6400_UCON_CLKMASK,
+ .clksel_shift = S3C6400_UCON_CLKSHIFT,
.reset_port = s3c6400_serial_resetport,
};
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
index 03b249e..173df5a 100644
--- a/drivers/tty/serial/s5pv210.c
+++ b/drivers/tty/serial/s5pv210.c
@@ -25,60 +25,6 @@
#include <plat/regs-serial.h>
#include "samsung.h"
-static int s5pv210_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- struct s3c24xx_uart_port *ourport;
- struct s3c2410_uartcfg *cfg;
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- ourport = container_of(port, struct s3c24xx_uart_port, port);
- cfg = ourport->cfg;
-
- if (cfg->flags & NO_NEED_CHECK_CLKSRC)
- return 0;
-
- if (strcmp(clk->name, "pclk") == 0)
- ucon &= ~S5PV210_UCON_CLKMASK;
- else if (strcmp(clk->name, "uclk1") == 0)
- ucon |= S5PV210_UCON_CLKMASK;
- else {
- printk(KERN_ERR "unknown clock source %s\n", clk->name);
- return -EINVAL;
- }
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-
-static int s5pv210_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- struct s3c24xx_uart_port *ourport;
- struct s3c2410_uartcfg *cfg;
- u32 ucon = rd_regl(port, S3C2410_UCON);
-
- ourport = container_of(port, struct s3c24xx_uart_port, port);
- cfg = ourport->cfg;
-
- clk->divisor = 1;
-
- if (cfg->flags & NO_NEED_CHECK_CLKSRC)
- return 0;
-
- switch (ucon & S5PV210_UCON_CLKMASK) {
- case S5PV210_UCON_PCLK:
- clk->name = "pclk";
- break;
- case S5PV210_UCON_UCLK:
- clk->name = "uclk1";
- break;
- }
-
- return 0;
-}
-
static int s5pv210_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
@@ -109,8 +55,10 @@ static int s5pv210_serial_resetport(struct uart_port *port,
.tx_fifofull = S5PV210_UFSTAT_TXFULL, \
.tx_fifomask = S5PV210_UFSTAT_TXMASK, \
.tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
- .get_clksrc = s5pv210_serial_getsource, \
- .set_clksrc = s5pv210_serial_setsource, \
+ .def_clk_sel = S3C2410_UCON_CLKSEL0, \
+ .num_clks = 2, \
+ .clksel_mask = S5PV210_UCON_CLKMASK, \
+ .clksel_shift = S5PV210_UCON_CLKSHIFT, \
.reset_port = s5pv210_serial_resetport
static struct s3c24xx_uart_info s5p_port_fifo256 = {
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 40e9ef1..c9cab2c 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -28,11 +28,6 @@ struct s3c24xx_uart_info {
unsigned int has_divslot:1;
- /* clock source control */
-
- int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
- int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
-
/* uart controls */
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
};
--
1.6.6.rc2
^ permalink raw reply related
* [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
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