From patchwork Tue Sep 25 16:33:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 1505991 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id BF4FA40079 for ; Tue, 25 Sep 2012 16:34:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758163Ab2IYQek (ORCPT ); Tue, 25 Sep 2012 12:34:40 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:44064 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758052Ab2IYQej (ORCPT ); Tue, 25 Sep 2012 12:34:39 -0400 Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id q8PGYWjZ023957; Tue, 25 Sep 2012 11:34:32 -0500 Received: from DLEE74.ent.ti.com (dlee74.ent.ti.com [157.170.170.8]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id q8PGYWK6001300; Tue, 25 Sep 2012 11:34:32 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Tue, 25 Sep 2012 11:34:32 -0500 Received: from localhost.localdomain (h64-6.vpn.ti.com [172.24.64.6]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id q8PGY1Bv005410; Tue, 25 Sep 2012 11:34:31 -0500 From: Tero Kristo To: , , CC: , Nishanth Menon Subject: [PATCHv7 19/21] ARM: OMAP3+: PM: introduce a central pmic control Date: Tue, 25 Sep 2012 19:33:51 +0300 Message-ID: <1348590833-12335-20-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1348590833-12335-1-git-send-email-t-kristo@ti.com> References: <1348590833-12335-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Nishanth Menon 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. Signed-off-by: Nishanth Menon [t-kristo@ti.com: moved code under twl-common, other minor cleanups] Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/omap_twl.c | 81 ++++++++++++++++++++++---------------- arch/arm/mach-omap2/pm.h | 9 +--- arch/arm/mach-omap2/twl-common.c | 58 +++++++++++++++++++++++++-- arch/arm/mach-omap2/twl-common.h | 27 +++++++++++++ 4 files changed, 129 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 7ff9667..f6ee038 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -19,8 +19,8 @@ #include #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, @@ -188,7 +188,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, @@ -206,7 +206,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, .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, @@ -224,31 +224,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 @@ -260,15 +238,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 d070ac6..26ac43c 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -122,15 +122,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 db5ff66..4a9ca89 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -97,11 +97,7 @@ void __init omap4_pmic_init(const char *pmic_type, void __init omap_pmic_late_init(void) { - /* Init the OMAP TWL parameters (if PMIC has been registered) */ - if (pmic_i2c_board_info.irq) - omap3_twl_init(); - if (omap4_i2c1_board_info[0].irq) - omap4_twl_init(); + omap_twl_init(); } #if defined(CONFIG_ARCH_OMAP3) @@ -538,3 +534,55 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, pmic_data->v2v1 = &omap4_v2v1_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_warn("%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_warn("%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 8fe71cf..c501b55 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 +#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__ */