[PATCH 2/3] ARM: OMAP3+: PM: introduce a central pmic control
Vishwanath Sripathy
vishwanath.bs at ti.com
Mon May 7 08:00:45 EDT 2012
Hi Tero,
> -----Original Message-----
> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-
> owner at vger.kernel.org] On Behalf Of Tero Kristo
> Sent: Friday, May 04, 2012 7:27 PM
> To: linux-omap at vger.kernel.org; khilman at ti.com
> Cc: linux-arm-kernel at lists.infradead.org; Nishanth Menon
> Subject: [PATCH 2/3] ARM: OMAP3+: PM: introduce a central pmic
> control
>
> From: Nishanth Menon <nm at ti.com>
>
> Since we are starting to use multiple PMICs in various combinations,
> use the existing .omap_chip = OMAP_CHIP_INIT() to mark the
> structures we are interested in using per OMAP device we
> are currently running on. This mapping is based on the default
> device recommendations from TI. Boards using custom PMICs now
> have an opportunity to register their own custom mapping.
>
> With this we no longer need omap4_twl_init and omap3_twl_int
> instead we introduce a registration mechanism which is PMIC
> generic and move twl implementation to use the same. This allows
> for future OMAP4460 support where there is a mixture of
> PMIC combinations used.
In this patch, you seem to be tying PMIC configuration with a OMAP version
which I think is not quite appropriate. Rather it should be a board
dependent parameter. We have many boards based on 4460 chip with different
PMICs. This implementation will not be able to support all such
configurations.
Vishwa
>
> Signed-off-by: Nishanth Menon <nm at ti.com>
> [t-kristo at ti.com: moved code under twl-common, other minor cleanups]
> Signed-off-by: Tero Kristo <t-kristo at ti.com>
> ---
> arch/arm/mach-omap2/omap_twl.c | 81 ++++++++++++++++++++++-----
> -----------
> arch/arm/mach-omap2/pm.h | 9 +---
> arch/arm/mach-omap2/twl-common.c | 55 +++++++++++++++++++++++++-
> arch/arm/mach-omap2/twl-common.h | 27 +++++++++++++
> 4 files changed, 129 insertions(+), 43 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-
> omap2/omap_twl.c
> index 7830eae..c8e418e 100644
> --- a/arch/arm/mach-omap2/omap_twl.c
> +++ b/arch/arm/mach-omap2/omap_twl.c
> @@ -19,8 +19,8 @@
> #include <linux/i2c/twl.h>
>
> #include "voltage.h"
> -
> #include "pm.h"
> +#include "twl-common.h"
>
> #define OMAP3_SRI2C_SLAVE_ADDR 0x12
> #define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00
> @@ -170,7 +170,7 @@ static struct omap_voltdm_pmic omap3_core_pmic =
> {
> .uv_to_vsel = twl4030_uv_to_vsel,
> };
>
> -static struct omap_voltdm_pmic omap4_mpu_pmic = {
> +static struct omap_voltdm_pmic twl6030_vcore1_pmic = {
> .slew_rate = 4000,
> .step_size = 12660,
> .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
> @@ -187,7 +187,7 @@ static struct omap_voltdm_pmic omap4_mpu_pmic =
> {
> .uv_to_vsel = twl6030_uv_to_vsel,
> };
>
> -static struct omap_voltdm_pmic omap4_iva_pmic = {
> +static struct omap_voltdm_pmic twl6030_vcore2_pmic = {
> .slew_rate = 4000,
> .step_size = 12660,
> .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
> @@ -204,7 +204,7 @@ static struct omap_voltdm_pmic omap4_iva_pmic =
> {
> .uv_to_vsel = twl6030_uv_to_vsel,
> };
>
> -static struct omap_voltdm_pmic omap4_core_pmic = {
> +static struct omap_voltdm_pmic twl6030_vcore3_pmic = {
> .slew_rate = 4000,
> .step_size = 12660,
> .startup_time = 500,
> @@ -222,31 +222,9 @@ static struct omap_voltdm_pmic omap4_core_pmic
> = {
> .uv_to_vsel = twl6030_uv_to_vsel,
> };
>
> -int __init omap4_twl_init(void)
> +static int __init twl_set_sr(struct voltagedomain *voltdm)
> {
> - struct voltagedomain *voltdm;
> -
> - if (!cpu_is_omap44xx())
> - return -ENODEV;
> -
> - voltdm = voltdm_lookup("mpu");
> - omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
> -
> - voltdm = voltdm_lookup("iva");
> - omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
> -
> - voltdm = voltdm_lookup("core");
> - omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
> -
> - return 0;
> -}
> -
> -int __init omap3_twl_init(void)
> -{
> - struct voltagedomain *voltdm;
> -
> - if (!cpu_is_omap34xx())
> - return -ENODEV;
> + int r = 0;
>
> /*
> * The smartreflex bit on twl4030 specifies if the setting of
> voltage
> @@ -258,15 +236,50 @@ int __init omap3_twl_init(void)
> * voltage scaling will not function on TWL over I2C_SR.
> */
> if (!twl_sr_enable_autoinit)
> - omap3_twl_set_sr_bit(true);
> + r = omap3_twl_set_sr_bit(true);
>
> - voltdm = voltdm_lookup("mpu_iva");
> - omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
> + return r;
> +}
>
> - voltdm = voltdm_lookup("core");
> - omap_voltage_register_pmic(voltdm, &omap3_core_pmic);
> +static __initdata struct omap_pmic_map omap_twl_map[] = {
> + {
> + .name = "mpu_iva",
> + .cpu = PMIC_CPU_OMAP3,
> + .pmic_data = &omap3_mpu_pmic,
> + .special_action = twl_set_sr,
> + },
> + {
> + .name = "core",
> + .cpu = PMIC_CPU_OMAP3,
> + .pmic_data = &omap3_core_pmic,
> + },
> + {
> + .name = "mpu",
> + .cpu = PMIC_CPU_OMAP4430,
> + .pmic_data = &twl6030_vcore1_pmic,
> + },
> + {
> + .name = "core",
> + .cpu = PMIC_CPU_OMAP4430,
> + .pmic_data = &twl6030_vcore3_pmic,
> + },
> + {
> + .name = "core",
> + .cpu = PMIC_CPU_OMAP4460,
> + .pmic_data = &twl6030_vcore1_pmic,
> + },
> + {
> + .name = "iva",
> + .cpu = PMIC_CPU_OMAP44XX,
> + .pmic_data = &twl6030_vcore2_pmic,
> + },
> + /* Terminator */
> + { .name = NULL, .pmic_data = NULL},
> +};
>
> - return 0;
> +int __init omap_twl_init(void)
> +{
> + return omap_pmic_register_data(omap_twl_map);
> }
>
> /**
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index 3d55926..afea204 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -128,15 +128,10 @@ static inline void
> omap_enable_smartreflex_on_init(void) {}
> #endif
>
> #ifdef CONFIG_TWL4030_CORE
> -extern int omap3_twl_init(void);
> -extern int omap4_twl_init(void);
> +extern int omap_twl_init(void);
> extern int omap3_twl_set_sr_bit(bool enable);
> #else
> -static inline int omap3_twl_init(void)
> -{
> - return -EINVAL;
> -}
> -static inline int omap4_twl_init(void)
> +static inline int omap_twl_init(void)
> {
> return -EINVAL;
> }
> diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-
> omap2/twl-common.c
> index 9120a4f..2588e04 100644
> --- a/arch/arm/mach-omap2/twl-common.c
> +++ b/arch/arm/mach-omap2/twl-common.c
> @@ -77,8 +77,7 @@ void __init omap_pmic_late_init(void)
> if (!pmic_i2c_board_info.irq)
> return;
>
> - omap3_twl_init();
> - omap4_twl_init();
> + omap_twl_init();
> }
>
> #if defined(CONFIG_ARCH_OMAP3)
> @@ -481,3 +480,55 @@ void __init omap4_pmic_get_config(struct
> twl4030_platform_data *pmic_data,
> pmic_data->clk32kg = &omap4_clk32kg_idata;
> }
> #endif /* CONFIG_ARCH_OMAP4 */
> +
> +/**
> + * omap_pmic_register_data() - Register the PMIC information to
> OMAP mapping
> + * @omap_pmic_maps: array ending with a empty element
> representing the maps
> + */
> +int __init omap_pmic_register_data(struct omap_pmic_map *map)
> +{
> + struct voltagedomain *voltdm;
> + int r;
> +
> + if (!map)
> + return 0;
> +
> + while (map->name) {
> + if (cpu_is_omap34xx() && !(map->cpu & PMIC_CPU_OMAP3))
> + goto next;
> +
> + if (cpu_is_omap443x() && !(map->cpu &
> PMIC_CPU_OMAP4430))
> + goto next;
> +
> + if (cpu_is_omap446x() && !(map->cpu &
> PMIC_CPU_OMAP4460))
> + goto next;
> +
> + voltdm = voltdm_lookup(map->name);
> + if (IS_ERR_OR_NULL(voltdm)) {
> + pr_err("%s: unable to find map %s\n", __func__,
> + map->name);
> + goto next;
> + }
> + if (IS_ERR_OR_NULL(map->pmic_data)) {
> + pr_warning("%s: domain[%s] has no pmic data\n",
> + __func__, map->name);
> + goto next;
> + }
> +
> + r = omap_voltage_register_pmic(voltdm, map->pmic_data);
> + if (r) {
> + pr_warning("%s: domain[%s] register returned
> %d\n",
> + __func__, map->name, r);
> + goto next;
> + }
> + if (map->special_action) {
> + r = map->special_action(voltdm);
> + WARN(r, "%s: domain[%s] action returned %d\n",
> __func__,
> + map->name, r);
> + }
> +next:
> + map++;
> + }
> +
> + return 0;
> +}
> diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-
> omap2/twl-common.h
> index 275dde8..2f805a3 100644
> --- a/arch/arm/mach-omap2/twl-common.h
> +++ b/arch/arm/mach-omap2/twl-common.h
> @@ -2,6 +2,7 @@
> #define __OMAP_PMIC_COMMON__
>
> #include <plat/irqs.h>
> +#include "voltage.h"
>
> #define TWL_COMMON_PDATA_USB (1 << 0)
> #define TWL_COMMON_PDATA_BCI (1 << 1)
> @@ -59,4 +60,30 @@ void omap3_pmic_get_config(struct
> twl4030_platform_data *pmic_data,
> void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
> u32 pdata_flags, u32 regulators_flags);
>
> +/**
> + * struct omap_pmic_map - Describe the OMAP PMIC data for OMAP
> + * @name: name of the voltage domain
> + * @pmic_data: pmic data associated with it
> + * @cpu: CPUs this PMIC data is valid for
> + * @special_action: callback for any specific action to take for
> that map
> + *
> + * Since we support multiple PMICs each potentially functioning on
> multiple
> + * OMAP devices, we describe the parameters in a map allowing us to
> reuse the
> + * data as necessary.
> + */
> +struct omap_pmic_map {
> + char *name;
> + struct omap_voltdm_pmic *pmic_data;
> + u32 cpu;
> + int (*special_action)(struct voltagedomain *);
> +};
> +
> +#define PMIC_CPU_OMAP3 (1 << 0)
> +#define PMIC_CPU_OMAP4430 (1 << 1)
> +#define PMIC_CPU_OMAP4460 (1 << 2)
> +#define PMIC_CPU_OMAP44XX (PMIC_CPU_OMAP4430 |
> PMIC_CPU_OMAP4460)
> +
> +extern int omap_pmic_register_data(struct omap_pmic_map *map);
> +extern void omap_pmic_data_init(void);
> +
> #endif /* __OMAP_PMIC_COMMON__ */
> --
> 1.7.4.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the linux-arm-kernel
mailing list