Hi Tero, > -----Original Message----- > From: linux-omap-owner@xxxxxxxxxxxxxxx [mailto:linux-omap- > owner@xxxxxxxxxxxxxxx] On Behalf Of Tero Kristo > Sent: Friday, May 04, 2012 7:27 PM > To: linux-omap@xxxxxxxxxxxxxxx; khilman@xxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; Nishanth Menon > Subject: [PATCH 2/3] ARM: OMAP3+: PM: introduce a central pmic > control > > From: Nishanth Menon <nm@xxxxxx> > > 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@xxxxxx> > [t-kristo@xxxxxx: moved code under twl-common, other minor cleanups] > Signed-off-by: Tero Kristo <t-kristo@xxxxxx> > --- > 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@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html