Re: [PATCH v3 11/12] ARM: EXYNOS: Add platform driver support for Exynos PMU.
On 04/30/2014 03:05 PM, Vikas Sajjan wrote: Hi Pankaj, On Wed, Apr 30, 2014 at 10:47 AM, Pankaj Dubey wrote: This patch modifies Exynos Power Management Unit (PMU) initialization implementation in following way: - Added platform_device support by registering static platform device. - Added platform struct exynos_pmu_data to hold platform specific data. - For each SoC's PMU support now we can add platform data and statically bind PMU configuration and SoC specific initialization function. - Probe function will scan DT and based on matching PMU compatibility string initialize pmu_context which will be platform_data for driver. - Obtain PMU regmap handle using "syscon_regmap_lookup_by_phandle" so that we can reduce dependency over machine header files. - Separate each SoC's PMU initialization function and make it as part of platform data. - It also removes uses of soc_is_exynos() thus making PMU implementation independent of "plat/cpu.h". Signed-off-by: Pankaj Dubey Signed-off-by: Young-Gun Jang --- arch/arm/mach-exynos/pmu.c | 280 +++- 1 file changed, 224 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 67116a5..030df96 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * EXYNOS - CPU PMU(Power Management Unit) support @@ -9,20 +9,33 @@ * published by the Free Software Foundation. */ -#include -#include +#include #include - -#include +#include +#include +#include +#include #include "common.h" #include "regs-pmu.h" -static const struct exynos_pmu_conf *exynos_pmu_config; -static struct regmap *pmu_regmap; +struct exynos_pmu_data { + const struct exynos_pmu_conf *pmu_config; + const struct exynos_pmu_conf *pmu_config_extra; + void (*pmu_init)(void); + void (*powerdown_conf)(enum sys_powerdown); +}; + +struct exynos_pmu_context { + struct device *dev; + struct exynos_pmu_data *pmu_data; + struct regmap *pmu_regmap; +}; + +static struct exynos_pmu_context *pmu_context; static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0,{ 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -216,7 +229,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = { }; static const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { EXYNOS5_ARM_CORE0_SYS_PWR_REG,{ 0x0, 0x0, 0x2} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG,{ 0x0, 0x0, 0x0} }, @@ -339,7 +352,7 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; -static void exynos5_init_pmu(void) +void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; unsigned int tmp; @@ -348,81 +361,236 @@ static void exynos5_init_pmu(void) * Enable both SC_FEEDBACK and SC_COUNTER */ for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { - regmap_read(pmu_regmap, exynos5_list_both_cnt_feed[i], ); + regmap_read(pmu_context->pmu_regmap, + exynos5_list_both_cnt_feed[i], ); tmp |= (EXYNOS5_USE_SC_FEEDBACK | EXYNOS5_USE_SC_COUNTER); - regmap_write(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_write(pmu_context->pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); } /* * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable */ - regmap_read(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, ); + regmap_read(pmu_context->pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, ); tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - regmap_write(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_write(pmu_context->pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); /* * Disable WFI/WFE on XXX_OPTION */ for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { - tmp = regmap_read(pmu_regmap, exynos5_list_diable_wfi_wfe[i], - ); + tmp = regmap_read(pmu_context->pmu_regmap, + exynos5_list_diable_wfi_wfe[i],
Re: [PATCH v3 11/12] ARM: EXYNOS: Add platform driver support for Exynos PMU.
Hi Pankaj, On Wed, Apr 30, 2014 at 10:47 AM, Pankaj Dubey wrote: > This patch modifies Exynos Power Management Unit (PMU) initialization > implementation in following way: > > - Added platform_device support by registering static platform device. > - Added platform struct exynos_pmu_data to hold platform specific data. > - For each SoC's PMU support now we can add platform data and statically > bind PMU configuration and SoC specific initialization function. > - Probe function will scan DT and based on matching PMU compatibility > string initialize pmu_context which will be platform_data for driver. > - Obtain PMU regmap handle using "syscon_regmap_lookup_by_phandle" so > that we can reduce dependency over machine header files. > - Separate each SoC's PMU initialization function and make it as part of > platform data. > - It also removes uses of soc_is_exynos() thus making PMU implementation > independent of "plat/cpu.h". > > Signed-off-by: Pankaj Dubey > Signed-off-by: Young-Gun Jang > --- > arch/arm/mach-exynos/pmu.c | 280 > +++- > 1 file changed, 224 insertions(+), 56 deletions(-) > > diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c > index 67116a5..030df96 100644 > --- a/arch/arm/mach-exynos/pmu.c > +++ b/arch/arm/mach-exynos/pmu.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. > + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. > * http://www.samsung.com/ > * > * EXYNOS - CPU PMU(Power Management Unit) support > @@ -9,20 +9,33 @@ > * published by the Free Software Foundation. > */ > > -#include > -#include > +#include > #include > - > -#include > +#include > +#include > +#include > +#include > > #include "common.h" > #include "regs-pmu.h" > > -static const struct exynos_pmu_conf *exynos_pmu_config; > -static struct regmap *pmu_regmap; > +struct exynos_pmu_data { > + const struct exynos_pmu_conf *pmu_config; > + const struct exynos_pmu_conf *pmu_config_extra; > + void (*pmu_init)(void); > + void (*powerdown_conf)(enum sys_powerdown); > +}; > + > +struct exynos_pmu_context { > + struct device *dev; > + struct exynos_pmu_data *pmu_data; > + struct regmap *pmu_regmap; > +}; > + > +static struct exynos_pmu_context *pmu_context; > > static const struct exynos_pmu_conf exynos4210_pmu_config[] = { > - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ > + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ > { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, > { S5P_DIS_IRQ_CORE0,{ 0x0, 0x0, 0x0 } }, > { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, > @@ -216,7 +229,7 @@ static const struct exynos_pmu_conf > exynos4412_pmu_config[] = { > }; > > static const struct exynos_pmu_conf exynos5250_pmu_config[] = { > - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ > + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ > { EXYNOS5_ARM_CORE0_SYS_PWR_REG,{ 0x0, 0x0, 0x2} }, > { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG,{ 0x0, 0x0, > 0x0} }, > @@ -339,7 +352,7 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = > { > EXYNOS5_ISP_ARM_OPTION, > }; > > -static void exynos5_init_pmu(void) > +void exynos5_powerdown_conf(enum sys_powerdown mode) > { > unsigned int i; > unsigned int tmp; > @@ -348,81 +361,236 @@ static void exynos5_init_pmu(void) > * Enable both SC_FEEDBACK and SC_COUNTER > */ > for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { > - regmap_read(pmu_regmap, exynos5_list_both_cnt_feed[i], ); > + regmap_read(pmu_context->pmu_regmap, > + exynos5_list_both_cnt_feed[i], ); > tmp |= (EXYNOS5_USE_SC_FEEDBACK | > EXYNOS5_USE_SC_COUNTER); > - regmap_write(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); > + regmap_write(pmu_context->pmu_regmap, > + exynos5_list_both_cnt_feed[i], tmp); > } > > /* > * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable > */ > - regmap_read(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, ); > + regmap_read(pmu_context->pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, ); > tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; > - regmap_write(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); > + regmap_write(pmu_context->pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); > > /* > * Disable WFI/WFE on XXX_OPTION > */ > for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { > - tmp = regmap_read(pmu_regmap, exynos5_list_diable_wfi_wfe[i], > -
Re: [PATCH v3 11/12] ARM: EXYNOS: Add platform driver support for Exynos PMU.
Hi Pankaj, On Wed, Apr 30, 2014 at 10:47 AM, Pankaj Dubey pankaj.du...@samsung.com wrote: This patch modifies Exynos Power Management Unit (PMU) initialization implementation in following way: - Added platform_device support by registering static platform device. - Added platform struct exynos_pmu_data to hold platform specific data. - For each SoC's PMU support now we can add platform data and statically bind PMU configuration and SoC specific initialization function. - Probe function will scan DT and based on matching PMU compatibility string initialize pmu_context which will be platform_data for driver. - Obtain PMU regmap handle using syscon_regmap_lookup_by_phandle so that we can reduce dependency over machine header files. - Separate each SoC's PMU initialization function and make it as part of platform data. - It also removes uses of soc_is_exynos() thus making PMU implementation independent of plat/cpu.h. Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com Signed-off-by: Young-Gun Jang yg1004.j...@samsung.com --- arch/arm/mach-exynos/pmu.c | 280 +++- 1 file changed, 224 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 67116a5..030df96 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * EXYNOS - CPU PMU(Power Management Unit) support @@ -9,20 +9,33 @@ * published by the Free Software Foundation. */ -#include linux/io.h -#include linux/kernel.h +#include linux/module.h #include linux/regmap.h - -#include plat/cpu.h +#include linux/of.h +#include linux/platform_device.h +#include linux/slab.h +#include linux/mfd/syscon.h #include common.h #include regs-pmu.h -static const struct exynos_pmu_conf *exynos_pmu_config; -static struct regmap *pmu_regmap; +struct exynos_pmu_data { + const struct exynos_pmu_conf *pmu_config; + const struct exynos_pmu_conf *pmu_config_extra; + void (*pmu_init)(void); + void (*powerdown_conf)(enum sys_powerdown); +}; + +struct exynos_pmu_context { + struct device *dev; + struct exynos_pmu_data *pmu_data; + struct regmap *pmu_regmap; +}; + +static struct exynos_pmu_context *pmu_context; static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0,{ 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -216,7 +229,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = { }; static const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { EXYNOS5_ARM_CORE0_SYS_PWR_REG,{ 0x0, 0x0, 0x2} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG,{ 0x0, 0x0, 0x0} }, @@ -339,7 +352,7 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; -static void exynos5_init_pmu(void) +void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; unsigned int tmp; @@ -348,81 +361,236 @@ static void exynos5_init_pmu(void) * Enable both SC_FEEDBACK and SC_COUNTER */ for (i = 0 ; i ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { - regmap_read(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_read(pmu_context-pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); tmp |= (EXYNOS5_USE_SC_FEEDBACK | EXYNOS5_USE_SC_COUNTER); - regmap_write(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_write(pmu_context-pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); } /* * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable */ - regmap_read(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_read(pmu_context-pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - regmap_write(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_write(pmu_context-pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); /* * Disable WFI/WFE on XXX_OPTION */ for (i = 0 ; i ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { -
Re: [PATCH v3 11/12] ARM: EXYNOS: Add platform driver support for Exynos PMU.
On 04/30/2014 03:05 PM, Vikas Sajjan wrote: Hi Pankaj, On Wed, Apr 30, 2014 at 10:47 AM, Pankaj Dubey pankaj.du...@samsung.com wrote: This patch modifies Exynos Power Management Unit (PMU) initialization implementation in following way: - Added platform_device support by registering static platform device. - Added platform struct exynos_pmu_data to hold platform specific data. - For each SoC's PMU support now we can add platform data and statically bind PMU configuration and SoC specific initialization function. - Probe function will scan DT and based on matching PMU compatibility string initialize pmu_context which will be platform_data for driver. - Obtain PMU regmap handle using syscon_regmap_lookup_by_phandle so that we can reduce dependency over machine header files. - Separate each SoC's PMU initialization function and make it as part of platform data. - It also removes uses of soc_is_exynos() thus making PMU implementation independent of plat/cpu.h. Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com Signed-off-by: Young-Gun Jang yg1004.j...@samsung.com --- arch/arm/mach-exynos/pmu.c | 280 +++- 1 file changed, 224 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 67116a5..030df96 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * EXYNOS - CPU PMU(Power Management Unit) support @@ -9,20 +9,33 @@ * published by the Free Software Foundation. */ -#include linux/io.h -#include linux/kernel.h +#include linux/module.h #include linux/regmap.h - -#include plat/cpu.h +#include linux/of.h +#include linux/platform_device.h +#include linux/slab.h +#include linux/mfd/syscon.h #include common.h #include regs-pmu.h -static const struct exynos_pmu_conf *exynos_pmu_config; -static struct regmap *pmu_regmap; +struct exynos_pmu_data { + const struct exynos_pmu_conf *pmu_config; + const struct exynos_pmu_conf *pmu_config_extra; + void (*pmu_init)(void); + void (*powerdown_conf)(enum sys_powerdown); +}; + +struct exynos_pmu_context { + struct device *dev; + struct exynos_pmu_data *pmu_data; + struct regmap *pmu_regmap; +}; + +static struct exynos_pmu_context *pmu_context; static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0,{ 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -216,7 +229,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = { }; static const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { EXYNOS5_ARM_CORE0_SYS_PWR_REG,{ 0x0, 0x0, 0x2} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG,{ 0x0, 0x0, 0x0} }, @@ -339,7 +352,7 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; -static void exynos5_init_pmu(void) +void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; unsigned int tmp; @@ -348,81 +361,236 @@ static void exynos5_init_pmu(void) * Enable both SC_FEEDBACK and SC_COUNTER */ for (i = 0 ; i ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { - regmap_read(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_read(pmu_context-pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); tmp |= (EXYNOS5_USE_SC_FEEDBACK | EXYNOS5_USE_SC_COUNTER); - regmap_write(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_write(pmu_context-pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); } /* * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable */ - regmap_read(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_read(pmu_context-pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - regmap_write(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_write(pmu_context-pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); /* * Disable WFI/WFE on XXX_OPTION */ for (i = 0 ; i ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { - tmp =
[PATCH v3 11/12] ARM: EXYNOS: Add platform driver support for Exynos PMU.
This patch modifies Exynos Power Management Unit (PMU) initialization implementation in following way: - Added platform_device support by registering static platform device. - Added platform struct exynos_pmu_data to hold platform specific data. - For each SoC's PMU support now we can add platform data and statically bind PMU configuration and SoC specific initialization function. - Probe function will scan DT and based on matching PMU compatibility string initialize pmu_context which will be platform_data for driver. - Obtain PMU regmap handle using "syscon_regmap_lookup_by_phandle" so that we can reduce dependency over machine header files. - Separate each SoC's PMU initialization function and make it as part of platform data. - It also removes uses of soc_is_exynos() thus making PMU implementation independent of "plat/cpu.h". Signed-off-by: Pankaj Dubey Signed-off-by: Young-Gun Jang --- arch/arm/mach-exynos/pmu.c | 280 +++- 1 file changed, 224 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 67116a5..030df96 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * EXYNOS - CPU PMU(Power Management Unit) support @@ -9,20 +9,33 @@ * published by the Free Software Foundation. */ -#include -#include +#include #include - -#include +#include +#include +#include +#include #include "common.h" #include "regs-pmu.h" -static const struct exynos_pmu_conf *exynos_pmu_config; -static struct regmap *pmu_regmap; +struct exynos_pmu_data { + const struct exynos_pmu_conf *pmu_config; + const struct exynos_pmu_conf *pmu_config_extra; + void (*pmu_init)(void); + void (*powerdown_conf)(enum sys_powerdown); +}; + +struct exynos_pmu_context { + struct device *dev; + struct exynos_pmu_data *pmu_data; + struct regmap *pmu_regmap; +}; + +static struct exynos_pmu_context *pmu_context; static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0,{ 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -216,7 +229,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = { }; static const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { EXYNOS5_ARM_CORE0_SYS_PWR_REG,{ 0x0, 0x0, 0x2} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG,{ 0x0, 0x0, 0x0} }, @@ -339,7 +352,7 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; -static void exynos5_init_pmu(void) +void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; unsigned int tmp; @@ -348,81 +361,236 @@ static void exynos5_init_pmu(void) * Enable both SC_FEEDBACK and SC_COUNTER */ for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { - regmap_read(pmu_regmap, exynos5_list_both_cnt_feed[i], ); + regmap_read(pmu_context->pmu_regmap, + exynos5_list_both_cnt_feed[i], ); tmp |= (EXYNOS5_USE_SC_FEEDBACK | EXYNOS5_USE_SC_COUNTER); - regmap_write(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_write(pmu_context->pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); } /* * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable */ - regmap_read(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, ); + regmap_read(pmu_context->pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, ); tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - regmap_write(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_write(pmu_context->pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); /* * Disable WFI/WFE on XXX_OPTION */ for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { - tmp = regmap_read(pmu_regmap, exynos5_list_diable_wfi_wfe[i], - ); + tmp = regmap_read(pmu_context->pmu_regmap, + exynos5_list_diable_wfi_wfe[i], ); tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | EXYNOS5_OPTION_USE_STANDBYWFI); -
[PATCH v3 11/12] ARM: EXYNOS: Add platform driver support for Exynos PMU.
This patch modifies Exynos Power Management Unit (PMU) initialization implementation in following way: - Added platform_device support by registering static platform device. - Added platform struct exynos_pmu_data to hold platform specific data. - For each SoC's PMU support now we can add platform data and statically bind PMU configuration and SoC specific initialization function. - Probe function will scan DT and based on matching PMU compatibility string initialize pmu_context which will be platform_data for driver. - Obtain PMU regmap handle using syscon_regmap_lookup_by_phandle so that we can reduce dependency over machine header files. - Separate each SoC's PMU initialization function and make it as part of platform data. - It also removes uses of soc_is_exynos() thus making PMU implementation independent of plat/cpu.h. Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com Signed-off-by: Young-Gun Jang yg1004.j...@samsung.com --- arch/arm/mach-exynos/pmu.c | 280 +++- 1 file changed, 224 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 67116a5..030df96 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * EXYNOS - CPU PMU(Power Management Unit) support @@ -9,20 +9,33 @@ * published by the Free Software Foundation. */ -#include linux/io.h -#include linux/kernel.h +#include linux/module.h #include linux/regmap.h - -#include plat/cpu.h +#include linux/of.h +#include linux/platform_device.h +#include linux/slab.h +#include linux/mfd/syscon.h #include common.h #include regs-pmu.h -static const struct exynos_pmu_conf *exynos_pmu_config; -static struct regmap *pmu_regmap; +struct exynos_pmu_data { + const struct exynos_pmu_conf *pmu_config; + const struct exynos_pmu_conf *pmu_config_extra; + void (*pmu_init)(void); + void (*powerdown_conf)(enum sys_powerdown); +}; + +struct exynos_pmu_context { + struct device *dev; + struct exynos_pmu_data *pmu_data; + struct regmap *pmu_regmap; +}; + +static struct exynos_pmu_context *pmu_context; static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0,{ 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -216,7 +229,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = { }; static const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + /* { .offset = address, .val = { AFTR, LPA, SLEEP } */ { EXYNOS5_ARM_CORE0_SYS_PWR_REG,{ 0x0, 0x0, 0x2} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG,{ 0x0, 0x0, 0x0} }, @@ -339,7 +352,7 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; -static void exynos5_init_pmu(void) +void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; unsigned int tmp; @@ -348,81 +361,236 @@ static void exynos5_init_pmu(void) * Enable both SC_FEEDBACK and SC_COUNTER */ for (i = 0 ; i ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { - regmap_read(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_read(pmu_context-pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); tmp |= (EXYNOS5_USE_SC_FEEDBACK | EXYNOS5_USE_SC_COUNTER); - regmap_write(pmu_regmap, exynos5_list_both_cnt_feed[i], tmp); + regmap_write(pmu_context-pmu_regmap, + exynos5_list_both_cnt_feed[i], tmp); } /* * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable */ - regmap_read(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_read(pmu_context-pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - regmap_write(pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); + regmap_write(pmu_context-pmu_regmap, EXYNOS5_ARM_COMMON_OPTION, tmp); /* * Disable WFI/WFE on XXX_OPTION */ for (i = 0 ; i ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { - tmp = regmap_read(pmu_regmap, exynos5_list_diable_wfi_wfe[i], - tmp); + tmp = regmap_read(pmu_context-pmu_regmap, +