[PATCH 2/2] ARM: Exynos4: Register clocks via common clock framework

Sylwester Nawrocki sylvester.nawrocki at gmail.com
Fri Oct 5 11:21:42 EDT 2012


Hello,

On 10/01/2012 02:09 PM, chander.kashyap at linaro.org wrote:
> From: Thomas Abraham<thomas.abraham at linaro.org>
> 
> Register clocks for Exynos4 platfotms using common clock framework.
> Also included are set of helper functions for clock registration
> that can be reused on other Samsung platforms as well.
> 
> Cc: Mike Turquette<mturquette at linaro.org>
> Cc: Kukjin Kim<kgene.kim at samsung.com>
> Signed-off-by: Thomas Abraham<thomas.abraham at linaro.org>
> ---
>   arch/arm/mach-exynos/Kconfig      |    1 +
>   arch/arm/mach-exynos/common.h     |    3 +
>   arch/arm/mach-exynos/mct.c        |   11 +-
>   arch/arm/plat-samsung/Kconfig     |    4 +-
>   drivers/clk/Makefile              |    1 +
>   drivers/clk/clk.c                 |   12 +-
>   drivers/clk/samsung/Makefile      |    6 +
>   drivers/clk/samsung/clk-exynos4.c |  585 +++++++++++++++++++++++++++++++++++++
>   drivers/clk/samsung/clk.c         |  231 +++++++++++++++
>   drivers/clk/samsung/clk.h         |  190 ++++++++++++
>   10 files changed, 1037 insertions(+), 7 deletions(-)
>   create mode 100644 drivers/clk/samsung/Makefile
>   create mode 100644 drivers/clk/samsung/clk-exynos4.c
>   create mode 100644 drivers/clk/samsung/clk.c
>   create mode 100644 drivers/clk/samsung/clk.h
...
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 56e4495..456c50b 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1196,6 +1196,7 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
>   int __clk_init(struct device *dev, struct clk *clk)
>   {
>   	int i, ret = 0;
> +	u8 index;
>   	struct clk *orphan;
>   	struct hlist_node *tmp, *tmp2;
> 
> @@ -1259,6 +1260,7 @@ int __clk_init(struct device *dev, struct clk *clk)
>   					__clk_lookup(clk->parent_names[i]);
>   	}
> 
> +
>   	clk->parent = __clk_init_parent(clk);
> 
>   	/*
> @@ -1298,11 +1300,13 @@ int __clk_init(struct device *dev, struct clk *clk)
>   	 * this clock
>   	 */
>   	hlist_for_each_entry_safe(orphan, tmp, tmp2,&clk_orphan_list, child_node)
> -		for (i = 0; i<  orphan->num_parents; i++)
> -			if (!strcmp(clk->name, orphan->parent_names[i])) {
> +		if (orphan->num_parents>  1) {
> +			index = orphan->ops->get_parent(orphan->hw);
> +			if (!strcmp(clk->name, orphan->parent_names[index]))
>   				__clk_reparent(orphan, clk);
> -				break;
> -			}
> +		} else if (!strcmp(clk->name, orphan->parent_names[0])) {
> +			__clk_reparent(orphan, clk);
> +		}

As this touches generic code it should rather be put into a separate patch,
along with an explanation why such a change is needed.

> 
>   	/*
>   	 * optional platform-specific magic
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> new file mode 100644
> index 0000000..69487f7
> --- /dev/null
> +++ b/drivers/clk/samsung/Makefile
> @@ -0,0 +1,6 @@
> +#
> +# Samsung Clock specific Makefile
> +#
> +
> +obj-$(CONFIG_PLAT_SAMSUNG)	+= clk.o
> +obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
> diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
> new file mode 100644
> index 0000000..74a6f03
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -0,0 +1,585 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro 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.
> + *
> + * Common Clock Framework support for all Exynos4 platforms
> +*/
> +
> +#include<linux/clk.h>
> +#include<linux/clkdev.h>
> +#include<linux/io.h>
> +#include<linux/clk-provider.h>
> +
> +#include<plat/pll.h>
> +#include<plat/cpu.h>
> +#include<mach/regs-clock.h>
> +#include<mach/sysmmu.h>
> +#include<plat/map-s5p.h>
> +
> +#include "clk.h"
> +
> +#define EXYNOS4_OP_MODE		(S5P_VA_CHIPID + 8)
> +
> +static const char *pll_parent_names[] __initdata = { "fin_pll" };
> +static const char *fin_pll_parents[] __initdata = { "xxti", "xusbxti" };
> +static const char *mout_apll_parents[] __initdata = { "fin_pll", "fout_apll", };
> +static const char *mout_mpll_parents[] __initdata = { "fin_pll", "fout_mpll", };
> +static const char *mout_epll_parents[] __initdata = { "fin_pll", "fout_epll", };
> +
> +static const char *sclk_ampll_parents[] __initdata = {
> +		"mout_mpll", "sclk_apll", };
> +
> +static const char *sclk_evpll_parents[] __initdata = {
> +		"mout_epll", "mout_vpll", };
> +
> +static const char *mout_core_parents[] __initdata = {
> +		"mout_apll", "mout_mpll", };
> +
> +static const char *mout_mfc_parents[] __initdata = {
> +		"mout_mfc0", "mout_mfc1", };
> +
> +static const char *mout_dac_parents[] __initdata = {
> +		"mout_vpll", "sclk_hdmiphy", };
> +
> +static const char *mout_hdmi_parents[] __initdata = {
> +		"sclk_pixel", "sclk_hdmiphy", };
> +
> +static const char *mout_mixer_parents[] __initdata = {
> +		"sclk_dac", "sclk_hdmi", };
> +
> +static const char *group1_parents[] __initdata = {
> +		"xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
> +		"none", "sclk_hdmiphy", "mout_mpll", "mout_epll",
> +		"mout_vpll" };
> +
> +static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
> +	FRATE_CLK(NULL, "xxti", NULL, CLK_IS_ROOT, 24000000),
> +	FRATE_CLK(NULL, "xusbxti", NULL, CLK_IS_ROOT, 24000000),
> +	FRATE_CLK(NULL, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
> +	FRATE_CLK(NULL, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
> +	FRATE_CLK(NULL, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +static struct samsung_mux_clock exynos4_mux_clks[] = {
> +	MUXCLK(NULL, "fin_pll", fin_pll_parents, 0,
> +			EXYNOS4_OP_MODE, 0, 1, 0),
> +	MUXCLK(NULL, "mout_apll", mout_apll_parents, 0,
> +			EXYNOS4_CLKSRC_CPU, 0, 1, 0),
> +	MUXCLK(NULL, "mout_epll", mout_epll_parents, 0,
> +			EXYNOS4_CLKSRC_TOP0, 4, 1, 0),
> +	MUXCLK(NULL, "mout_core", mout_core_parents, 0,
> +			EXYNOS4_CLKSRC_CPU, 16, 1, 0),
> +	MUXCLK(NULL, "mout_aclk_200", sclk_ampll_parents, 0,
> +			EXYNOS4_CLKSRC_TOP0, 12, 1, 0),
> +	MUXCLK(NULL, "mout_aclk_100", sclk_ampll_parents, 0,
> +			EXYNOS4_CLKSRC_TOP0, 16, 1, 0),
> +	MUXCLK(NULL, "mout_aclk_160", sclk_ampll_parents, 0,
> +			EXYNOS4_CLKSRC_TOP0, 20, 1, 0),
> +	MUXCLK(NULL, "mout_aclk_133", sclk_ampll_parents, 0,
> +			EXYNOS4_CLKSRC_TOP0, 24, 1, 0),
> +	MUXCLK("exynos4210-uart.0", "mout_uart0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL0, 0, 4, 0),
> +	MUXCLK("exynos4210-uart.1", "mout_uart1", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL0, 4, 4, 0),
> +	MUXCLK("exynos4210-uart.2", "mout_uart2", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL0, 8, 4, 0),
> +	MUXCLK("exynos4210-uart.3", "mout_uart3", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL0, 12, 4, 0),
> +	MUXCLK("exynos4-sdhci.0", "mout_mmc0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_FSYS, 0, 4, 0),
> +	MUXCLK("exynos4-sdhci.1", "mout_mmc1", group1_parents, 0,
> +			EXYNOS4_CLKSRC_FSYS, 4, 4, 0),
> +	MUXCLK("exynos4-sdhci.1", "mout_mmc2", group1_parents, 0,
> +			EXYNOS4_CLKSRC_FSYS, 8, 4, 0),
> +	MUXCLK("exynos4-sdhci.1", "mout_mmc3", group1_parents, 0,
> +			EXYNOS4_CLKSRC_FSYS, 12, 4, 0),
> +	MUXCLK("exynos4210-spi.0", "mout_spi0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL1, 16, 4, 0),
> +	MUXCLK("exynos4210-spi.1", "mout_spi1", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL1, 20, 4, 0),
> +	MUXCLK("exynos4210-spi.2", "mout_spi2", group1_parents, 0,
> +			EXYNOS4_CLKSRC_PERIL1, 24, 4, 0),
> +	MUXCLK(NULL, "mout_sata", sclk_ampll_parents, 0,
> +			EXYNOS4_CLKSRC_FSYS, 24, 1, 0),
> +	MUXCLK(NULL, "mout_mfc0", sclk_ampll_parents, 0,
> +			EXYNOS4_CLKSRC_MFC, 0, 1, 0),
> +	MUXCLK(NULL, "mout_mfc1", sclk_evpll_parents, 0,
> +			EXYNOS4_CLKSRC_MFC, 4, 1, 0),
> +	MUXCLK("s5p-mfc", "mout_mfc", mout_mfc_parents, 0,
> +			EXYNOS4_CLKSRC_MFC, 8, 1, 0),
> +	MUXCLK("s5p-mipi-csis.0", "mout_csis0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 24, 4, 0),
> +	MUXCLK("s5p-mipi-csis.1", "mout_csis1", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 28, 4, 0),
> +	MUXCLK(NULL, "mout_cam0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 16, 4, 0),
> +	MUXCLK(NULL, "mout_cam1", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 20, 4, 0),
> +	MUXCLK("exynos4-fimc.0", "mout_fimc0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 0, 4, 0),
> +	MUXCLK("exynos4-fimc.1", "mout_fimc1", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 4, 4, 0),
> +	MUXCLK("exynos4-fimc.2", "mout_fimc2", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 8, 4, 0),
> +	MUXCLK("exynos4-fimc.3", "mout_fimc3", group1_parents, 0,
> +			EXYNOS4_CLKSRC_CAM, 12, 4, 0),
> +	MUXCLK("exynos4-fb.0", "mout_fimd0", group1_parents, 0,
> +			EXYNOS4_CLKSRC_LCD0, 0, 4, 0),
> +	MUXCLK(NULL, "sclk_dac", mout_dac_parents, 0,
> +			EXYNOS4_CLKSRC_TV, 8, 1, 0),
> +	MUXCLK(NULL, "sclk_hdmi", mout_hdmi_parents, 0,
> +			EXYNOS4_CLKSRC_TV, 0, 1, 0),
> +	MUXCLK(NULL, "sclk_mixer", mout_mixer_parents, 0,
> +			EXYNOS4_CLKSRC_TV, 4, 1, 0),
> +};
> +
> +static struct samsung_div_clock exynos4_div_clks[] = {
> +	DIVCLK(NULL, "sclk_apll", "mout_apll", 0,
> +			EXYNOS4_CLKDIV_CPU, 24, 3, 0),
> +	DIVCLK(NULL, "div_core", "mout_core", 0,
> +			EXYNOS4_CLKDIV_CPU, 0, 3, 0),
> +	DIVCLK(NULL, "armclk", "div_core", 0,
> +			EXYNOS4_CLKDIV_CPU, 28, 3, 0),
> +	DIVCLK(NULL, "aclk_200", "mout_aclk_200", 0,
> +			EXYNOS4_CLKDIV_TOP, 0, 3, 0),
> +	DIVCLK(NULL, "aclk_100", "mout_aclk_100", 0,
> +			EXYNOS4_CLKDIV_TOP, 4, 4, 0),
> +	DIVCLK(NULL, "aclk_160", "mout_aclk_160", 0,
> +			EXYNOS4_CLKDIV_TOP, 8, 3, 0),
> +	DIVCLK(NULL, "aclk_133", "mout_aclk_133", 0,
> +			EXYNOS4_CLKDIV_TOP, 12, 3, 0),
> +	DIVCLK("exynos4210-uart.0", "div_uart0", "mout_uart0", 0,
> +			EXYNOS4_CLKDIV_PERIL0, 0, 4, 0),
> +	DIVCLK("exynos4210-uart.1", "div_uart1", "mout_uart1", 0,
> +			EXYNOS4_CLKDIV_PERIL0, 4, 4, 0),
> +	DIVCLK("exynos4210-uart.2", "div_uart2", "mout_uart2", 0,
> +			EXYNOS4_CLKDIV_PERIL0, 8, 4, 0),
> +	DIVCLK("exynos4210-uart.3", "div_uart3", "mout_uart3", 0,
> +			EXYNOS4_CLKDIV_PERIL0, 12, 4, 0),
> +	DIVCLK("exynos4-sdhci.0", "div_mmc0", "mout_mmc0", 0,
> +			EXYNOS4_CLKDIV_FSYS1, 0, 4, 0),
> +	DIVCLK("exynos4-sdhci.0", "div_mmc0_pre", "div_mmc0", 0,
> +			EXYNOS4_CLKDIV_FSYS1, 8, 8, 0),
> +	DIVCLK("exynos4-sdhci.1", "div_mmc1", "mout_mmc1", 0,
> +			EXYNOS4_CLKDIV_FSYS1, 16, 4, 0),
> +	DIVCLK("exynos4-sdhci.1", "div_mmc1_pre", "div_mmc1", 0,
> +			EXYNOS4_CLKDIV_FSYS1, 24, 8, 0),
> +	DIVCLK("exynos4-sdhci.2", "div_mmc2", "mout_mmc2", 0,
> +			EXYNOS4_CLKDIV_FSYS2, 0, 4, 0),
> +	DIVCLK("exynos4-sdhci.2", "div_mmc2_pre", "div_mmc2", 0,
> +			EXYNOS4_CLKDIV_FSYS2, 8, 8, 0),
> +	DIVCLK("exynos4-sdhci.3", "div_mmc3", "mout_mmc3", 0,
> +			EXYNOS4_CLKDIV_FSYS2, 16, 4, 0),
> +	DIVCLK("exynos4-sdhci.3", "div_mmc3_pre", "div_mmc3", 0,
> +			EXYNOS4_CLKDIV_FSYS2, 24, 8, 0),
> +	DIVCLK("exynos4210-spi.0", "div_spi0", "mout_spi0", 0,
> +			EXYNOS4_CLKDIV_PERIL1, 0, 4, 0),
> +	DIVCLK("exynos4210-spi.1", "div_spi1", "mout_spi1", 0,
> +			EXYNOS4_CLKDIV_PERIL1, 16, 4, 0),
> +	DIVCLK("exynos4210-spi.2", "div_spi2", "mout_spi2", 0,
> +			EXYNOS4_CLKDIV_PERIL2, 0, 4, 0),
> +	DIVCLK("exynos4210-spi.0", "div_spi0_pre", "div_spi0", 0,
> +			EXYNOS4_CLKDIV_PERIL1, 8, 8, 0),
> +	DIVCLK("exynos4210-spi.1", "div_spi1_pre", "div_spi1", 0,
> +			EXYNOS4_CLKDIV_PERIL1, 24, 8, 0),
> +	DIVCLK("exynos4210-spi.2", "div_spi2_pre", "div_spi2", 0,
> +			EXYNOS4_CLKDIV_PERIL2, 8, 8, 0),
> +	DIVCLK(NULL, "div_sata", "mout_sata", 0,
> +			EXYNOS4_CLKDIV_FSYS0, 20, 4, 0),
> +	DIVCLK("s5p-mfc", "div_mfc", "mout_mfc", 0,
> +			EXYNOS4_CLKDIV_MFC, 0, 4, 0),
> +	DIVCLK("s5p-mipi-csis.0", "div_csis0", "mout_csis0", 0,
> +			EXYNOS4_CLKDIV_CAM, 24, 4, 0),
> +	DIVCLK("s5p-mipi-csis.1", "div_csis1", "mout_csis1", 0,
> +			EXYNOS4_CLKDIV_CAM, 28, 4, 0),
> +	DIVCLK(NULL, "div_cam0", "mout_cam0", 0,
> +			EXYNOS4_CLKDIV_CAM, 16, 4, 0),
> +	DIVCLK(NULL, "div_cam1", "mout_cam1", 0,
> +			EXYNOS4_CLKDIV_CAM, 20, 4, 0),
> +	DIVCLK("exynos4-fimc.0", "div_fimc0", "mout_fimc0", 0,
> +			EXYNOS4_CLKDIV_CAM, 0, 4, 0),
> +	DIVCLK("exynos4-fimc.1", "div_fimc1", "mout_fimc1", 0,
> +			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
> +	DIVCLK("exynos4-fimc.2", "div_fimc2", "mout_fimc2", 0,
> +			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
> +	DIVCLK("exynos4-fimc.3", "div_fimc3", "mout_fimc3", 0,
> +			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
> +	DIVCLK("exynos4-fb.0", "div_fimd0", "mout_fimd0", 0,
> +			EXYNOS4_CLKDIV_LCD0, 0, 4, 0),
> +	DIVCLK(NULL, "sclk_pixel", "mout_vpll", 0,
> +			EXYNOS4_CLKDIV_TV, 0, 4, 0),
> +};
> +
> +struct samsung_gate_clock exynos4_gate_clks[] = {
> +	GATECLK("exynos4210-uart.0", "uart0", "aclk_100", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKGATE_IP_PERIL, 0, "uart"),
> +	GATECLK("exynos4210-uart.1", "uart1", "aclk_100", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKGATE_IP_PERIL, 1, "uart"),
> +	GATECLK("exynos4210-uart.2", "uart2", "aclk_100", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKGATE_IP_PERIL, 2, "uart"),
> +	GATECLK("exynos4210-uart.3", "uart3", "aclk_100", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKGATE_IP_PERIL, 3, "uart"),
> +	GATECLK("exynos4210-uart.4", "uart4", "aclk_100", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKGATE_IP_PERIL, 4, "uart"),
> +	GATECLK("exynos4210-uart.5", "uart5", "aclk_100", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKGATE_IP_PERIL, 5, "uart"),
> +	GATECLK("exynos4210-uart.0", "uclk0", "div_uart0", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKSRC_MASK_PERIL0, 0, "clk_uart_baud0"),
> +	GATECLK("exynos4210-uart.1", "uclk1", "div_uart1", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKSRC_MASK_PERIL0, 4, "clk_uart_baud0"),
> +	GATECLK("exynos4210-uart.2", "uclk2", "div_uart2", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKSRC_MASK_PERIL0, 8, "clk_uart_baud0"),
> +	GATECLK("exynos4210-uart.3", "uclk3", "div_uart3", CLK_SET_RATE_PARENT,
> +			EXYNOS4_CLKSRC_MASK_PERIL0, 12, "clk_uart_baud0"),
> +	GATECLK(NULL, "timers", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 24, NULL),
> +	GATECLK("s5p-mipi-csis.0", "csis", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 5, NULL),
> +	GATECLK(NULL, "jpeg", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 6, NULL),
> +	GATECLK("exynos4-fimc.0", "fimc0", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 0, "fimc"),
> +	GATECLK("exynos4-fimc.1", "fimc1", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 1, "fimc"),
> +	GATECLK("exynos4-fimc.2", "fimc2", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 2, "fimc"),
> +	GATECLK("exynos4-fimc.3", "fimc3", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 3, "fimc"),
> +	GATECLK("exynos4-sdhci.0", "hsmmc0", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 5, "hsmmc"),
> +	GATECLK("exynos4-sdhci.1", "hsmmc1", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 6, "hsmmc"),
> +	GATECLK("exynos4-sdhci.2", "hsmmc2", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 7, "hsmmc"),
> +	GATECLK("exynos4-sdhci.3", "hsmmc3", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 8, "hsmmc"),
> +	GATECLK(NULL, "dwmmc", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 9, NULL),
> +	GATECLK("s5p-sdo", "dac", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_TV, 2, NULL),
> +	GATECLK("s5p-mixer", "mixer", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_TV, 1, NULL),
> +	GATECLK("s5p-mixer", "vp", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_TV, 0, NULL),
> +	GATECLK("exynos4-hdmi", "hdmi", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_TV, 3, NULL),
> +	GATECLK("exynos4-hdmi", "hdmiphy", "aclk_160", 0,
> +			S5P_HDMI_PHY_CONTROL, 0, NULL),
> +	GATECLK("s5p-sdo", "dacphy", "aclk_160", 0,
> +			S5P_DAC_PHY_CONTROL, 0, NULL),
> +	GATECLK(NULL, "adc", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 15, NULL),
> +	GATECLK(NULL, "keypad", "aclk_100", 0,
> +			EXYNOS4210_CLKGATE_IP_PERIR, 16, NULL),
> +	GATECLK(NULL, "rtc", "aclk_100", 0,
> +			EXYNOS4210_CLKGATE_IP_PERIR, 15, NULL),
> +	GATECLK(NULL, "watchdog", "aclk_100", 0,
> +			EXYNOS4210_CLKGATE_IP_PERIR, 14, NULL),
> +	GATECLK(NULL, "usbhost", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 12, NULL),
> +	GATECLK(NULL, "otg", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 13, NULL),
> +	GATECLK("exynos4210-spi.0", "spi0", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 16, "spi"),
> +	GATECLK("exynos4210-spi.1", "spi1", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 17, "spi"),
> +	GATECLK("exynos4210-spi.2", "spi2", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 18, "spi"),
> +	GATECLK("samsung-i2s.0", "iis0", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 19, "iis"),
> +	GATECLK("samsung-i2s.1", "iis1", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 20, "iis"),
> +	GATECLK("samsung-i2s.2", "iis2", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 21, "iis"),
> +	GATECLK("samsung-ac97", "ac97", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 27, NULL),
> +	GATECLK("s5p-mfc", "mfc", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_MFC, 0, NULL),
> +	GATECLK("s3c2440-i2c.0", "i2c0", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 6, "i2c"),
> +	GATECLK("s3c2440-i2c.1", "i2c1", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 7, "i2c"),
> +	GATECLK("s3c2440-i2c.2", "i2c2", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 8, "i2c"),
> +	GATECLK("s3c2440-i2c.3", "i2c3", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 9, "i2c"),
> +	GATECLK("s3c2440-i2c.4", "i2c4", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 10, "i2c"),
> +	GATECLK("s3c2440-i2c.5", "i2c5", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 11, "i2c"),
> +	GATECLK("s3c2440-i2c.6", "i2c6", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 12, "i2c"),
> +	GATECLK("s3c2440-i2c.7", "i2c7", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 13, "i2c"),
> +	GATECLK("s3c2440-hdmiphy-i2c", "i2c", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_PERIL, 14, NULL),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_l, 0), "sysmmu0", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_MFC, 1, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_r, 1), "sysmmu1", "aclk_100", 0,
> +			EXYNOS4_CLKGATE_IP_MFC, 2, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(tv, 2), "sysmmu2", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_TV, 4, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(jpeg, 3), "sysmmu3", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 11, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(rot, 4), "sysmmu4", "aclk_200", 0,
> +			EXYNOS4210_CLKGATE_IP_IMAGE, 4, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc0, 5), "sysmmu5", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 7, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc1, 6), "sysmmu6", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 8, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc2, 7), "sysmmu7", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 9, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc3, 8), "sysmmu8", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_CAM, 10, "sysmmu"),
> +	GATECLK(SYSMMU_CLOCK_DEVNAME(fimd, 10), "sysmmu10", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_LCD0, 4, "sysmmu"),
> +	GATECLK("dma-pl330.0", "dma0", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 0, "dma"),
> +	GATECLK("dma-pl330.1", "dma1", "aclk_133", 0,
> +			EXYNOS4_CLKGATE_IP_FSYS, 1, "dma"),
> +	GATECLK("exynos4-fb.0", "fimd", "aclk_160", 0,
> +			EXYNOS4_CLKGATE_IP_LCD0, 0, "lcd"),
> +	GATECLK("exynos4210-spi.0", "sclk_spi0", "div_spi0_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_PERIL1, 16, "spi_busclk0"),
> +	GATECLK("exynos4210-spi.1", "sclk_spi1", "div_spi1_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_PERIL1, 20, "spi_busclk0"),
> +	GATECLK("exynos4210-spi.2", "sclk_spi2", "div_spi2_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_PERIL1, 24, "spi_busclk0"),
> +	GATECLK("exynos4-sdhci.0", "sclk_mmc0", "div_mmc0_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_FSYS, 0, "mmc_busclk.2"),
> +	GATECLK("exynos4-sdhci.1", "sclk_mmc1", "div_mmc1_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_FSYS, 4, "mmc_busclk.2"),
> +	GATECLK("exynos4-sdhci.2", "sclk_mmc2", "div_mmc2_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_FSYS, 8, "mmc_busclk.2"),
> +	GATECLK("exynos4-sdhci.3", "sclk_mmc3", "div_mmc3_pre", 0,
> +			EXYNOS4_CLKSRC_MASK_FSYS, 12, "mmc_busclk.2"),
> +	GATECLK("s5p-mipi-csis.0", "sclk_csis0", "div_csis0", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 24, "sclk_csis"),
> +	GATECLK("s5p-mipi-csis.1", "sclk_csis1", "div_csis1", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 28, "sclk_csis"),
> +	GATECLK(NULL, "sclk_cam0", "div_cam0", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 16, NULL),
> +	GATECLK(NULL, "sclk_cam1", "div_cam1", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 20, NULL),
> +	GATECLK("exynos4-fimc.0", "sclk_fimc", "div_fimc0", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 0, "sclk_fimc"),
> +	GATECLK("exynos4-fimc.1", "sclk_fimc", "div_fimc1", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 4, "sclk_fimc"),
> +	GATECLK("exynos4-fimc.2", "sclk_fimc", "div_fimc2", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 8, "sclk_fimc"),
> +	GATECLK("exynos4-fimc.3", "sclk_fimc", "div_fimc3", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 12, "sclk_fimc"),
> +	GATECLK("exynos4-fb.0", "sclk_fimd", "div_fimd0", 0,
> +			EXYNOS4_CLKSRC_MASK_LCD0, 0, "sclk_fimd"),
> +};
> +
> +/* register clock common to all Exynos4 platforms */
> +void __init exynos4_clk_init(void)
> +{
> +	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
> +			ARRAY_SIZE(exynos4_fixed_rate_clks));
> +	samsung_clk_register_mux(exynos4_mux_clks,
> +			ARRAY_SIZE(exynos4_mux_clks));
> +	samsung_clk_register_div(exynos4_div_clks,
> +			ARRAY_SIZE(exynos4_div_clks));
> +	samsung_clk_register_gate(exynos4_gate_clks,
> +			ARRAY_SIZE(exynos4_gate_clks));
> +}
...
> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
> new file mode 100644
> index 0000000..65156b9
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.c
> @@ -0,0 +1,231 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro 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.
> + *
> + * This file includes utility functions to register clocks to common
> + * clock framework for Samsung platforms. This includes an implementation
> + * of Samsung 'pll type' clock to represent the implementation of the
> + * pll found on Samsung platforms. In addition to that, utility functions
> + * to register mux, div, gate and fixed rate types of clocks are included.
> +*/
> +
> +#include "clk.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +
> +#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> +
> +/* determine the output clock speed of the pll */
> +static unsigned long samsung_clk_pll_recalc_rate(struct clk_hw *hw,
> +				unsigned long parent_rate)
> +{
> +	struct samsung_clk_pll *clk_pll = to_clk_pll(hw);
> +
> +	if (clk_pll->get_rate)
> +		return to_clk_pll(hw)->get_rate(parent_rate);
> +
> +	return 0;
> +}
> +
> +/* round operation not supported */
> +static long samsung_clk_pll_round_rate(struct clk_hw *hw, unsigned long drate,
> +				unsigned long *prate)
> +{
> +	return samsung_clk_pll_recalc_rate(hw, *prate);
> +}
> +
> +/* set the clock output rate of the pll */
> +static int samsung_clk_pll_set_rate(struct clk_hw *hw, unsigned long drate,
> +				unsigned long prate)
> +{
> +	struct samsung_clk_pll *clk_pll = to_clk_pll(hw);
> +
> +	if (clk_pll->set_rate)
> +		return to_clk_pll(hw)->set_rate(drate);
> +
> +	return 0;
> +}
> +
> +/* clock operations for samsung pll clock type */
> +static const struct clk_ops samsung_clk_pll_ops = {
> +	.recalc_rate = samsung_clk_pll_recalc_rate,
> +	.round_rate = samsung_clk_pll_round_rate,
> +	.set_rate = samsung_clk_pll_set_rate,
> +};
> +
> +/* register a samsung pll type clock */
> +void __init samsung_clk_register_pll(const char *name, const char **pnames,
> +				int (*set_rate)(unsigned long rate),
> +				unsigned long (*get_rate)(unsigned long rate))
> +{
> +	struct samsung_clk_pll *clk_pll;
> +	struct clk *clk;
> +	struct clk_init_data init;
> +	int ret;
> +
> +	clk_pll = kzalloc(sizeof(*clk_pll), GFP_KERNEL);
> +	if (!clk_pll) {
> +		pr_err("%s: could not allocate pll clk %s\n", __func__, name);
> +		return;
> +	}
> +
> +	init.name = name;
> +	init.ops =&samsung_clk_pll_ops;
> +	init.flags = CLK_GET_RATE_NOCACHE;
> +	init.parent_names = pnames;
> +	init.num_parents = 1;
> +
> +	clk_pll->set_rate = set_rate;
> +	clk_pll->get_rate = get_rate;
> +	clk_pll->hw.init =&init;
> +
> +	/* register the clock */
> +	clk = clk_register(NULL,&clk_pll->hw);
> +	if (IS_ERR(clk)) {
> +		pr_err("%s: failed to register pll clock %s\n", __func__,
> +				name);
> +		kfree(clk_pll);
> +		return;
> +	}
> +
> +	ret = clk_register_clkdev(clk, name, NULL);
> +	if (ret)
> +		pr_err("%s: failed to register clock lookup for %s", __func__,
> +				name);
> +}
> +
> +/* register a list of fixed clocks */
> +void __init samsung_clk_register_fixed_rate(
> +		struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk)
> +{
> +	struct clk *clk;
> +	unsigned int idx, ret;
> +
> +	for (idx = 0; idx<  nr_clk; idx++, clk_list++) {
> +		clk = clk_register_fixed_rate(NULL, clk_list->name,
> +				clk_list->parent_name, clk_list->flags,
> +				clk_list->fixed_rate);
> +		if (IS_ERR_OR_NULL(clk)) {

clk_register_fixed_rate() always returns an error code (ERR_PTR()), i.e. never 
NULL, thus IS_ERR(clk) is more appropriate here.

> +			pr_err("clock: failed to register clock %s\n",
> +				clk_list->name);
> +			continue;
> +		}
> +
> +		ret = clk_register_clkdev(clk, clk_list->name,
> +						clk_list->dev_name);
> +		if (ret)
> +			pr_err("clock: failed to register clock lookup for %s",
> +				clk_list->name);
> +	}
> +}
> +
> +/* register a list of mux clocks */
> +void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list,
> +						unsigned int nr_clk)
> +{
> +	struct clk *clk;
> +	unsigned int idx, ret;
> +
> +	for (idx = 0; idx<  nr_clk; idx++, clk_list++) {
> +		clk = clk_register_mux(NULL, clk_list->name,
> +			clk_list->parent_names, clk_list->num_parents,
> +			clk_list->flags, clk_list->reg, clk_list->shift,
> +			clk_list->width, clk_list->mux_flags,&lock);
> +		if (IS_ERR_OR_NULL(clk)) {

Ditto.

> +			pr_err("clock: failed to register clock %s\n",
> +				clk_list->name);
> +			continue;
> +		}
> +
> +		ret = clk_register_clkdev(clk, clk_list->name,
> +						clk_list->dev_name);
> +		if (ret)
> +			pr_err("clock: failed to register clock lookup for %s",
> +				clk_list->name);
> +
> +		if (clk_list->alias)
> +			clk_register_clkdev(clk, clk_list->alias,
> +						clk_list->dev_name);
> +	}
> +}
> +
> +/* reguster a list of div clocks */
> +void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
> +						unsigned int nr_clk)
> +{
> +	struct clk *clk;
> +	unsigned int idx, ret;
> +
> +	for (idx = 0; idx<  nr_clk; idx++, clk_list++) {
> +		clk = clk_register_divider(NULL, clk_list->name,
> +			clk_list->parent_name, clk_list->flags, clk_list->reg,
> +			clk_list->shift, clk_list->width, clk_list->div_flags,
> +			&lock);
> +		if (IS_ERR_OR_NULL(clk)) {

Ditto.

> +			pr_err("clock: failed to register clock %s\n",
> +				clk_list->name);
> +			continue;
> +		}
> +
> +		ret = clk_register_clkdev(clk, clk_list->name,
> +						clk_list->dev_name);
> +		if (ret)
> +			pr_err("clock: failed to register clock lookup for %s",
> +				clk_list->name);
> +
> +		if (clk_list->alias)
> +			clk_register_clkdev(clk, clk_list->alias,
> +						clk_list->dev_name);
> +	}
> +}
> +
> +/* register a list of gate clocks */
> +void __init samsung_clk_register_gate(struct samsung_gate_clock *clk_list,
> +						unsigned int nr_clk)
> +{
> +	struct clk *clk;
> +	unsigned int idx, ret;
> +
> +	for (idx = 0; idx<  nr_clk; idx++, clk_list++) {
> +		clk = clk_register_gate(NULL, clk_list->name,
> +			clk_list->parent_name, clk_list->flags, clk_list->reg,
> +			clk_list->bit_idx, clk_list->gate_flags,&lock);
> +		if (IS_ERR_OR_NULL(clk)) {

Ditto.

> +			pr_err("clock: failed to register clock %s\n",
> +				clk_list->name);
> +			continue;
> +		}
> +
> +		ret = clk_register_clkdev(clk, clk_list->name,
> +						clk_list->dev_name);
> +		if (ret) {
> +			pr_err("clock: failed to register clock lookup for %s",
> +				clk_list->name);
> +			continue;
> +		}
> +
> +		ret = clk_register_clkdev(clk, clk_list->alias,
> +						clk_list->dev_name);
> +		if (ret)
> +			pr_err("clock: failed to register alias %s for clock "
> +					" %s", clk_list->alias, clk_list->name);
> +	}
> +}


Do we really need all these clock lookup entries registered for each clk 
primitive ? There seem to be more struck clk objects than with the original 
samsung clock code, now when each instance of struct clk_clksrc has been 
replaced with a corresponding div and mux clock object. All these are not 
needed to be referenced from drivers, so why do we see so many 
clk_register_clkdev() here ?

Couldn't this be avoided by instantiating all platform clocks first and 
then creating required clock object - device associations by adding the 
clkdev lookup entries ? Something like this is done in case of 
arch/arm/mach-imx for instance. I think this would result in less data 
and more clear implementation.


> +/* utility function to get the rate of a specified clock */
> +unsigned long _get_rate(const char *clk_name)
> +{
> +	struct clk *clk;
> +	unsigned long rate;
> +
> +	clk = clk_get(NULL, clk_name);
> +	if (IS_ERR(clk))
> +		return 0;
> +	rate = clk_get_rate(clk);
> +	clk_put(clk);
> +	return rate;
> +}
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> new file mode 100644
> index 0000000..40bdff9
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.h
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro 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.
> + *
> + * Common Clock Framework support for all Samsung platforms
> +*/
> +
> +#ifndef __SAMSUNG_CLK_H
> +#define __SAMSUNG_CLK_H
> +
> +#include<linux/clk.h>
> +#include<linux/clkdev.h>
> +#include<linux/io.h>
> +#include<linux/clk-provider.h>
> +#include<mach/regs-clock.h>
> +
> +/**
> + * struct samsung_clk_pll: represents a samsung pll type clock
> + * @hw: connection to struct clk.
> + * @set_rate: callback for setting the pll clock rate
> + * @get_rate: callback for determing the pll clock rate
> + *
> + * Internal representation of the pll type clock. Platform specific
> + * implementation can instantiate clocks of this type by calling
> + * samsung_clk_register_pll() function.
> + */
> +struct samsung_clk_pll {
> +	struct clk_hw		hw;
> +	int			(*set_rate)(unsigned long rate);
> +	unsigned long		(*get_rate)(unsigned long xtal_rate);
> +};
> +
> +/**
> + * struct samsung_fixed_rate_clock: information about fixed-rate clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this fixed-rate clock.
> + * @parent_name: optional parent clock name.
> + * @flags: optional fixed-rate clock flags.
> + * @fixed-rate: fixed clock rate of this clock.
> + */
> +struct samsung_fixed_rate_clock {
> +	const char		*dev_name;
> +	const char		*name;
> +	const char		*parent_name;
> +	unsigned long		flags;
> +	unsigned long		fixed_rate;
> +};
> +
> +#define FRATE_CLK(dname, cname, pname, f, frate)	\
> +	{						\
> +		.dev_name	= dname,		\
> +		.name		= cname,		\
> +		.parent_name	= pname,		\
> +		.flags		= f,			\
> +		.fixed_rate	= frate,		\
> +	}
> +
> +/**
> + * struct samsung_mux_clock: information about mux clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this mux clock.
> + * @parent_names: array of pointer to parent clock names.
> + * @num_parents: number of parents listed in @parent_names.
> + * @flags: optional flags for basic clock.
> + * @reg: address of register for configuring the mux.
> + * @shift: starting bit location of the mux control bit-field in @reg.
> + * @width: width of the mux control bit-field in @reg.
> + * @mux_flags: flags for mux-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_mux_clock {
> +	const char		*dev_name;
> +	const char		*name;
> +	const char		**parent_names;
> +	u8			num_parents;
> +	unsigned long		flags;
> +	void __iomem		*reg;
> +	u8			shift;
> +	u8			width;
> +	u8			mux_flags;
> +	const char		*alias;
> +};
> +
> +#define MUXCLK(dname, cname, pnames, f, r, s, w, mf)		\
> +	{							\
> +		.dev_name	= dname,			\
> +		.name		= cname,			\
> +		.parent_names	= pnames,			\
> +		.num_parents	= ARRAY_SIZE(pnames),		\
> +		.flags		= f,				\
> +		.reg		= r,				\
> +		.shift		= s,				\
> +		.width		= w,				\
> +		.mux_flags	= mf,				\
> +	}
> +
> +/**
> + * struct samsung_div_clock: information about div clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this div clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @reg: address of register for configuring the div.
> + * @shift: starting bit location of the div control bit-field in @reg.
> + * @div_flags: flags for div-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_div_clock {
> +	const char		*dev_name;
> +	const char		*name;
> +	const char		*parent_name;
> +	unsigned long		flags;
> +	void __iomem		*reg;
> +	u8			shift;
> +	u8			width;
> +	u8			div_flags;
> +	const char		*alias;
> +};
> +
> +#define DIVCLK(dname, cname, pname, f, r, s, w, df)		\
> +	{							\
> +		.dev_name	= dname,			\
> +		.name		= cname,			\
> +		.parent_name	= pname,			\
> +		.flags		= f,				\
> +		.reg		= r,				\
> +		.shift		= s,				\
> +		.width		= w,				\
> +		.div_flags	= df,				\
> +	}
> +
> +/**
> + * struct samsung_gate_clock: information about gate clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this gate clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @reg: address of register for configuring the gate.
> + * @bit_idx: bit index of the gate control bit-field in @reg.
> + * @gate_flags: flags for gate-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_gate_clock {
> +	const char		*dev_name;
> +	const char		*name;
> +	const char		*parent_name;
> +	unsigned long		flags;
> +	void __iomem		*reg;
> +	u8			bit_idx;
> +	u8			gate_flags;
> +	const char		*alias;
> +};
> +
> +#define GATECLK(dname, cname, pname, f, r, b, a)		\
> +	{							\
> +		.dev_name	= dname,			\
> +		.name		= cname,			\
> +		.parent_name	= pname,			\
> +		.flags		= f,				\
> +		.reg		= r,				\
> +		.bit_idx	= b,				\
> +		.alias		= a,				\
> +	}

--

Regards,
Sylwester



More information about the linux-arm-kernel mailing list