From 01f48d308db1cfcfb0151d8d91153fd73e84ae40 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 21 Mar 2011 14:29:13 -0700 Subject: OMAP2+: voltage: split out voltage processor (VP) code into new layer This patch is primarily a move of VP specific code from voltage.c into its own code in vp.c and adds prototypes to vp.h No functional changes, except debugfs... VP debugfs moved to 'vp' subdir of /voltage/ and 'vp_' prefixes removed from all debugfs filenames. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 374 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 arch/arm/mach-omap2/vp.c (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c new file mode 100644 index 0000000..f3503de --- /dev/null +++ b/arch/arm/mach-omap2/vp.c @@ -0,0 +1,374 @@ +#include +#include +#include + +#include + +#include "voltage.h" +#include "vp.h" +#include "prm-regbits-34xx.h" +#include "prm-regbits-44xx.h" +#include "prm44xx.h" + +static void __init vp_debugfs_init(struct voltagedomain *voltdm); + +static void vp_latch_vsel(struct voltagedomain *voltdm) +{ + struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + u32 vpconfig; + unsigned long uvdc; + char vsel; + struct omap_vdd_info *vdd = voltdm->vdd; + + uvdc = omap_voltage_get_nom_volt(voltdm); + if (!uvdc) { + pr_warning("%s: unable to find current voltage for vdd_%s\n", + __func__, voltdm->name); + return; + } + + if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) { + pr_warning("%s: PMIC function to convert voltage in uV to" + " vsel not registered\n", __func__); + return; + } + + vsel = vdd->pmic_info->uv_to_vsel(uvdc); + + vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig &= ~(vp->vp_common->vpconfig_initvoltage_mask | + vp->vp_common->vpconfig_initvdd); + vpconfig |= vsel << vp->vp_common->vpconfig_initvoltage_shift; + + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + + /* Trigger initVDD value copy to voltage processor */ + vdd->write_reg((vpconfig | vp->vp_common->vpconfig_initvdd), + vp->vp_common->prm_mod, vp->vpconfig); + + /* Clear initVDD copy trigger bit */ + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); +} + +/* Generic voltage init functions */ +void __init omap_vp_init(struct voltagedomain *voltdm) +{ + struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vdd_info *vdd = voltdm->vdd; + u32 vp_val; + + if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + vp_val = vdd->vp_rt_data.vpconfig_erroroffset | + (vdd->vp_rt_data.vpconfig_errorgain << + vp->vp_common->vpconfig_errorgain_shift) | + vp->vp_common->vpconfig_timeouten; + vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vpconfig); + + vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin << + vp->vp_common->vstepmin_smpswaittimemin_shift) | + (vdd->vp_rt_data.vstepmin_stepmin << + vp->vp_common->vstepmin_stepmin_shift)); + vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vstepmin); + + vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax << + vp->vp_common->vstepmax_smpswaittimemax_shift) | + (vdd->vp_rt_data.vstepmax_stepmax << + vp->vp_common->vstepmax_stepmax_shift)); + vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vstepmax); + + vp_val = ((vdd->vp_rt_data.vlimitto_vddmax << + vp->vp_common->vlimitto_vddmax_shift) | + (vdd->vp_rt_data.vlimitto_vddmin << + vp->vp_common->vlimitto_vddmin_shift) | + (vdd->vp_rt_data.vlimitto_timeout << + vp->vp_common->vlimitto_timeout_shift)); + vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vlimitto); + + vp_debugfs_init(voltdm); +} + +/* VP force update method of voltage scaling */ +int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, + unsigned long target_volt) +{ + struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vdd_info *vdd = voltdm->vdd; + u32 vpconfig; + u8 target_vsel, current_vsel; + int ret, timeout = 0; + + ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, ¤t_vsel); + if (ret) + return ret; + + /* + * Clear all pending TransactionDone interrupt/status. Typical latency + * is <3us + */ + while (timeout++ < VP_TRANXDONE_TIMEOUT) { + vdd->write_reg(vp->prm_irqst_data->tranxdone_status, + vdd->prm_irqst_mod, vdd->prm_irqst_reg); + if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) & + vp->prm_irqst_data->tranxdone_status)) + break; + udelay(1); + } + if (timeout >= VP_TRANXDONE_TIMEOUT) { + pr_warning("%s: vdd_%s TRANXDONE timeout exceeded." + "Voltage change aborted", __func__, voltdm->name); + return -ETIMEDOUT; + } + + /* Configure for VP-Force Update */ + vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig &= ~(vp->vp_common->vpconfig_initvdd | + vp->vp_common->vpconfig_forceupdate | + vp->vp_common->vpconfig_initvoltage_mask); + vpconfig |= ((target_vsel << + vp->vp_common->vpconfig_initvoltage_shift)); + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + + /* Trigger initVDD value copy to voltage processor */ + vpconfig |= vp->vp_common->vpconfig_initvdd; + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + + /* Force update of voltage */ + vpconfig |= vp->vp_common->vpconfig_forceupdate; + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + + /* + * Wait for TransactionDone. Typical latency is <200us. + * Depends on SMPSWAITTIMEMIN/MAX and voltage change + */ + timeout = 0; + omap_test_timeout((vdd->read_reg(vdd->prm_irqst_mod, + vdd->prm_irqst_reg) & + vp->prm_irqst_data->tranxdone_status), + VP_TRANXDONE_TIMEOUT, timeout); + if (timeout >= VP_TRANXDONE_TIMEOUT) + pr_err("%s: vdd_%s TRANXDONE timeout exceeded." + "TRANXDONE never got set after the voltage update\n", + __func__, voltdm->name); + + omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); + + /* + * Disable TransactionDone interrupt , clear all status, clear + * control registers + */ + timeout = 0; + while (timeout++ < VP_TRANXDONE_TIMEOUT) { + vdd->write_reg(vp->prm_irqst_data->tranxdone_status, + vdd->prm_irqst_mod, vdd->prm_irqst_reg); + if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) & + vp->prm_irqst_data->tranxdone_status)) + break; + udelay(1); + } + + if (timeout >= VP_TRANXDONE_TIMEOUT) + pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying" + "to clear the TRANXDONE status\n", + __func__, voltdm->name); + + vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + /* Clear initVDD copy trigger bit */ + vpconfig &= ~vp->vp_common->vpconfig_initvdd; + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + /* Clear force bit */ + vpconfig &= ~vp->vp_common->vpconfig_forceupdate; + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + + return 0; +} + +/** + * omap_vp_get_curr_volt() - API to get the current vp voltage. + * @voltdm: pointer to the VDD. + * + * This API returns the current voltage for the specified voltage processor + */ +unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) +{ + struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vdd_info *vdd; + u8 curr_vsel; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return 0; + } + + vdd = voltdm->vdd; + if (!vdd->read_reg) { + pr_err("%s: No read API for reading vdd_%s regs\n", + __func__, voltdm->name); + return 0; + } + + curr_vsel = vdd->read_reg(vp->vp_common->prm_mod, vp->voltage); + + if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) { + pr_warning("%s: PMIC function to convert vsel to voltage" + "in uV not registerd\n", __func__); + return 0; + } + + return vdd->pmic_info->vsel_to_uv(curr_vsel); +} + +/** + * omap_vp_enable() - API to enable a particular VP + * @voltdm: pointer to the VDD whose VP is to be enabled. + * + * This API enables a particular voltage processor. Needed by the smartreflex + * class drivers. + */ +void omap_vp_enable(struct voltagedomain *voltdm) +{ + struct omap_vp_instance_data *vp; + struct omap_vdd_info *vdd; + u32 vpconfig; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return; + } + + vdd = voltdm->vdd; + vp = voltdm->vdd->vp_data; + if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + /* If VP is already enabled, do nothing. Return */ + if (vdd->vp_enabled) + return; + + vp_latch_vsel(voltdm); + + /* Enable VP */ + vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig |= vp->vp_common->vpconfig_vpenable; + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + vdd->vp_enabled = true; +} + +/** + * omap_vp_disable() - API to disable a particular VP + * @voltdm: pointer to the VDD whose VP is to be disabled. + * + * This API disables a particular voltage processor. Needed by the smartreflex + * class drivers. + */ +void omap_vp_disable(struct voltagedomain *voltdm) +{ + struct omap_vp_instance_data *vp; + struct omap_vdd_info *vdd; + u32 vpconfig; + int timeout; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return; + } + + vdd = voltdm->vdd; + vp = voltdm->vdd->vp_data; + if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + /* If VP is already disabled, do nothing. Return */ + if (!vdd->vp_enabled) { + pr_warning("%s: Trying to disable VP for vdd_%s when" + "it is already disabled\n", __func__, voltdm->name); + return; + } + + /* Disable VP */ + vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig &= ~vp->vp_common->vpconfig_vpenable; + vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + + /* + * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us + */ + omap_test_timeout((vdd->read_reg(vp->vp_common->prm_mod, vp->vstatus)), + VP_IDLE_TIMEOUT, timeout); + + if (timeout >= VP_IDLE_TIMEOUT) + pr_warning("%s: vdd_%s idle timedout\n", + __func__, voltdm->name); + + vdd->vp_enabled = false; + + return; +} + +/* Voltage debugfs support */ +static int vp_volt_debug_get(void *data, u64 *val) +{ + struct voltagedomain *voltdm = (struct voltagedomain *)data; + struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vdd_info *vdd = voltdm->vdd; + u8 vsel; + + if (!vdd) { + pr_warning("Wrong paramater passed\n"); + return -EINVAL; + } + + vsel = vdd->read_reg(vp->vp_common->prm_mod, vp->voltage); + + if (!vdd->pmic_info->vsel_to_uv) { + pr_warning("PMIC function to convert vsel to voltage" + "in uV not registerd\n"); + return -EINVAL; + } + + *val = vdd->pmic_info->vsel_to_uv(vsel); + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n"); + +static void __init vp_debugfs_init(struct voltagedomain *voltdm) +{ + struct omap_vdd_info *vdd = voltdm->vdd; + struct dentry *debug_dir; + + debug_dir = debugfs_create_dir("vp", vdd->debug_dir); + if (IS_ERR(debug_dir)) + pr_err("%s: Unable to create VP debugfs dir dir\n", __func__); + + (void) debugfs_create_x16("errorgain", S_IRUGO, debug_dir, + &(vdd->vp_rt_data.vpconfig_errorgain)); + (void) debugfs_create_x16("smpswaittimemin", S_IRUGO, + debug_dir, + &(vdd->vp_rt_data.vstepmin_smpswaittimemin)); + (void) debugfs_create_x8("stepmin", S_IRUGO, debug_dir, + &(vdd->vp_rt_data.vstepmin_stepmin)); + (void) debugfs_create_x16("smpswaittimemax", S_IRUGO, + debug_dir, + &(vdd->vp_rt_data.vstepmax_smpswaittimemax)); + (void) debugfs_create_x8("stepmax", S_IRUGO, debug_dir, + &(vdd->vp_rt_data.vstepmax_stepmax)); + (void) debugfs_create_x8("vddmax", S_IRUGO, debug_dir, + &(vdd->vp_rt_data.vlimitto_vddmax)); + (void) debugfs_create_x8("vddmin", S_IRUGO, debug_dir, + &(vdd->vp_rt_data.vlimitto_vddmin)); + (void) debugfs_create_x16("timeout", S_IRUGO, debug_dir, + &(vdd->vp_rt_data.vlimitto_timeout)); + (void) debugfs_create_file("curr_volt", S_IRUGO, debug_dir, + (void *) voltdm, &vp_volt_debug_fops); +} -- cgit v1.1 From 842ec22852cf843558828e6f7a6da2bf72f341a5 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 28 Mar 2011 11:57:18 -0700 Subject: OMAP3+ VP: replace transaction done check/clear with VP ops Replace the VP tranxdone check/clear with helper functions from the PRM layer. In the process, remove prm_irqst_* voltage structure fields for IRQ status checking which are no longer needed. Since these reads/writes of the IRQ status bits were the only PRM accesses that were not to VC/VP registers, this allows the rest of the register accesses in the VC/VP code to use VC/VP specific register access functions (done in the following patch.) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index f3503de..113c839 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -111,10 +111,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, * is <3us */ while (timeout++ < VP_TRANXDONE_TIMEOUT) { - vdd->write_reg(vp->prm_irqst_data->tranxdone_status, - vdd->prm_irqst_mod, vdd->prm_irqst_reg); - if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) & - vp->prm_irqst_data->tranxdone_status)) + vp->vp_common->ops->clear_txdone(vp->id); + if (!vp->vp_common->ops->check_txdone(vp->id)) break; udelay(1); } @@ -146,9 +144,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, * Depends on SMPSWAITTIMEMIN/MAX and voltage change */ timeout = 0; - omap_test_timeout((vdd->read_reg(vdd->prm_irqst_mod, - vdd->prm_irqst_reg) & - vp->prm_irqst_data->tranxdone_status), + omap_test_timeout(vp->vp_common->ops->check_txdone(vp->id), VP_TRANXDONE_TIMEOUT, timeout); if (timeout >= VP_TRANXDONE_TIMEOUT) pr_err("%s: vdd_%s TRANXDONE timeout exceeded." @@ -163,10 +159,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, */ timeout = 0; while (timeout++ < VP_TRANXDONE_TIMEOUT) { - vdd->write_reg(vp->prm_irqst_data->tranxdone_status, - vdd->prm_irqst_mod, vdd->prm_irqst_reg); - if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) & - vp->prm_irqst_data->tranxdone_status)) + vp->vp_common->ops->clear_txdone(vp->id); + if (!vp->vp_common->ops->check_txdone(vp->id)) break; udelay(1); } -- cgit v1.1 From 4bcc475ebd06a04e1531254c27c6cf508ef8ebf9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 28 Mar 2011 10:40:15 -0700 Subject: OMAP3+: voltage: convert to PRM register access functions Convert VC/VP register access to use PRM VC/VP accessor functions. In the process, move the read/write function pointers from vdd_info into struct voltagedomain. No functional changes. Additional cleanup: - remove prm_mod field from VC/VP data structures, the PRM register access functions know which PRM module to use. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 57 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 113c839..88ac742 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -35,19 +35,19 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) vsel = vdd->pmic_info->uv_to_vsel(uvdc); - vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~(vp->vp_common->vpconfig_initvoltage_mask | vp->vp_common->vpconfig_initvdd); vpconfig |= vsel << vp->vp_common->vpconfig_initvoltage_shift; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ - vdd->write_reg((vpconfig | vp->vp_common->vpconfig_initvdd), - vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write((vpconfig | vp->vp_common->vpconfig_initvdd), + vp->vpconfig); /* Clear initVDD copy trigger bit */ - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); } /* Generic voltage init functions */ @@ -57,7 +57,7 @@ void __init omap_vp_init(struct voltagedomain *voltdm) struct omap_vdd_info *vdd = voltdm->vdd; u32 vp_val; - if (!vdd->read_reg || !vdd->write_reg) { + if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); return; @@ -67,19 +67,19 @@ void __init omap_vp_init(struct voltagedomain *voltdm) (vdd->vp_rt_data.vpconfig_errorgain << vp->vp_common->vpconfig_errorgain_shift) | vp->vp_common->vpconfig_timeouten; - vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vp_val, vp->vpconfig); vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin << vp->vp_common->vstepmin_smpswaittimemin_shift) | (vdd->vp_rt_data.vstepmin_stepmin << vp->vp_common->vstepmin_stepmin_shift)); - vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vstepmin); + voltdm->write(vp_val, vp->vstepmin); vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax << vp->vp_common->vstepmax_smpswaittimemax_shift) | (vdd->vp_rt_data.vstepmax_stepmax << vp->vp_common->vstepmax_stepmax_shift)); - vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vstepmax); + voltdm->write(vp_val, vp->vstepmax); vp_val = ((vdd->vp_rt_data.vlimitto_vddmax << vp->vp_common->vlimitto_vddmax_shift) | @@ -87,7 +87,7 @@ void __init omap_vp_init(struct voltagedomain *voltdm) vp->vp_common->vlimitto_vddmin_shift) | (vdd->vp_rt_data.vlimitto_timeout << vp->vp_common->vlimitto_timeout_shift)); - vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vlimitto); + voltdm->write(vp_val, vp->vlimitto); vp_debugfs_init(voltdm); } @@ -97,7 +97,6 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, unsigned long target_volt) { struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; - struct omap_vdd_info *vdd = voltdm->vdd; u32 vpconfig; u8 target_vsel, current_vsel; int ret, timeout = 0; @@ -123,21 +122,21 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, } /* Configure for VP-Force Update */ - vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~(vp->vp_common->vpconfig_initvdd | vp->vp_common->vpconfig_forceupdate | vp->vp_common->vpconfig_initvoltage_mask); vpconfig |= ((target_vsel << vp->vp_common->vpconfig_initvoltage_shift)); - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ vpconfig |= vp->vp_common->vpconfig_initvdd; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); /* Force update of voltage */ vpconfig |= vp->vp_common->vpconfig_forceupdate; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); /* * Wait for TransactionDone. Typical latency is <200us. @@ -170,13 +169,13 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, "to clear the TRANXDONE status\n", __func__, voltdm->name); - vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig = voltdm->read(vp->vpconfig); /* Clear initVDD copy trigger bit */ vpconfig &= ~vp->vp_common->vpconfig_initvdd; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); /* Clear force bit */ vpconfig &= ~vp->vp_common->vpconfig_forceupdate; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); return 0; } @@ -199,13 +198,13 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) } vdd = voltdm->vdd; - if (!vdd->read_reg) { + if (!voltdm->read) { pr_err("%s: No read API for reading vdd_%s regs\n", __func__, voltdm->name); return 0; } - curr_vsel = vdd->read_reg(vp->vp_common->prm_mod, vp->voltage); + curr_vsel = voltdm->read(vp->voltage); if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) { pr_warning("%s: PMIC function to convert vsel to voltage" @@ -236,7 +235,7 @@ void omap_vp_enable(struct voltagedomain *voltdm) vdd = voltdm->vdd; vp = voltdm->vdd->vp_data; - if (!vdd->read_reg || !vdd->write_reg) { + if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); return; @@ -249,9 +248,9 @@ void omap_vp_enable(struct voltagedomain *voltdm) vp_latch_vsel(voltdm); /* Enable VP */ - vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig = voltdm->read(vp->vpconfig); vpconfig |= vp->vp_common->vpconfig_vpenable; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); vdd->vp_enabled = true; } @@ -276,7 +275,7 @@ void omap_vp_disable(struct voltagedomain *voltdm) vdd = voltdm->vdd; vp = voltdm->vdd->vp_data; - if (!vdd->read_reg || !vdd->write_reg) { + if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); return; @@ -290,15 +289,15 @@ void omap_vp_disable(struct voltagedomain *voltdm) } /* Disable VP */ - vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig); + vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~vp->vp_common->vpconfig_vpenable; - vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig); + voltdm->write(vpconfig, vp->vpconfig); /* * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us */ - omap_test_timeout((vdd->read_reg(vp->vp_common->prm_mod, vp->vstatus)), - VP_IDLE_TIMEOUT, timeout); + omap_test_timeout((voltdm->read(vp->vstatus)), + VP_IDLE_TIMEOUT, timeout); if (timeout >= VP_IDLE_TIMEOUT) pr_warning("%s: vdd_%s idle timedout\n", @@ -322,7 +321,7 @@ static int vp_volt_debug_get(void *data, u64 *val) return -EINVAL; } - vsel = vdd->read_reg(vp->vp_common->prm_mod, vp->voltage); + vsel = voltdm->read(vp->voltage); if (!vdd->pmic_info->vsel_to_uv) { pr_warning("PMIC function to convert vsel to voltage" -- cgit v1.1 From ce8ebe0dfb1f8713337cebf82499d3dced288328 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 30 Mar 2011 11:01:10 -0700 Subject: OMAP3+: voltage domain: move PMIC struct from vdd_info into struct voltagedomain Move structure containing PMIC configurable settings into struct voltagedomain. In the process, rename from omap_volt_pmic_info to omap_voltdm_pmic (_info suffix is not helpful.) No functional changes. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 88ac742..a3afcbe 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -18,7 +18,6 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) u32 vpconfig; unsigned long uvdc; char vsel; - struct omap_vdd_info *vdd = voltdm->vdd; uvdc = omap_voltage_get_nom_volt(voltdm); if (!uvdc) { @@ -27,13 +26,13 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) return; } - if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) { + if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { pr_warning("%s: PMIC function to convert voltage in uV to" " vsel not registered\n", __func__); return; } - vsel = vdd->pmic_info->uv_to_vsel(uvdc); + vsel = voltdm->pmic->uv_to_vsel(uvdc); vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~(vp->vp_common->vpconfig_initvoltage_mask | @@ -206,13 +205,13 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) curr_vsel = voltdm->read(vp->voltage); - if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) { + if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) { pr_warning("%s: PMIC function to convert vsel to voltage" "in uV not registerd\n", __func__); return 0; } - return vdd->pmic_info->vsel_to_uv(curr_vsel); + return voltdm->pmic->vsel_to_uv(curr_vsel); } /** @@ -323,13 +322,13 @@ static int vp_volt_debug_get(void *data, u64 *val) vsel = voltdm->read(vp->voltage); - if (!vdd->pmic_info->vsel_to_uv) { + if (!voltdm->pmic->vsel_to_uv) { pr_warning("PMIC function to convert vsel to voltage" "in uV not registerd\n"); return -EINVAL; } - *val = vdd->pmic_info->vsel_to_uv(vsel); + *val = voltdm->pmic->vsel_to_uv(vsel); return 0; } -- cgit v1.1 From b7ea803e55769768d1eff3b32e4f99837fa6ddb5 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 4 Apr 2011 15:25:07 -0700 Subject: OMAP3+: VP: cleanup: move VP instance into voltdm, misc. renames - move VP instance struct from vdd_info into struct voltage domain - remove _data suffix from structure name - rename vp_ prefix from vp_common field: accesses are now vp->common - move vp_enabled bool from vdd_info into VP instance - remove remaining references to omap_vdd_info No functional changes. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 88 ++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 47 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index a3afcbe..53d6018 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -14,7 +14,7 @@ static void __init vp_debugfs_init(struct voltagedomain *voltdm); static void vp_latch_vsel(struct voltagedomain *voltdm) { - struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vp_instance *vp = voltdm->vp; u32 vpconfig; unsigned long uvdc; char vsel; @@ -35,14 +35,14 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) vsel = voltdm->pmic->uv_to_vsel(uvdc); vpconfig = voltdm->read(vp->vpconfig); - vpconfig &= ~(vp->vp_common->vpconfig_initvoltage_mask | - vp->vp_common->vpconfig_initvdd); - vpconfig |= vsel << vp->vp_common->vpconfig_initvoltage_shift; + vpconfig &= ~(vp->common->vpconfig_initvoltage_mask | + vp->common->vpconfig_initvdd); + vpconfig |= vsel << vp->common->vpconfig_initvoltage_shift; voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ - voltdm->write((vpconfig | vp->vp_common->vpconfig_initvdd), + voltdm->write((vpconfig | vp->common->vpconfig_initvdd), vp->vpconfig); /* Clear initVDD copy trigger bit */ @@ -52,7 +52,7 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) /* Generic voltage init functions */ void __init omap_vp_init(struct voltagedomain *voltdm) { - struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vp_instance *vp = voltdm->vp; struct omap_vdd_info *vdd = voltdm->vdd; u32 vp_val; @@ -64,28 +64,28 @@ void __init omap_vp_init(struct voltagedomain *voltdm) vp_val = vdd->vp_rt_data.vpconfig_erroroffset | (vdd->vp_rt_data.vpconfig_errorgain << - vp->vp_common->vpconfig_errorgain_shift) | - vp->vp_common->vpconfig_timeouten; + vp->common->vpconfig_errorgain_shift) | + vp->common->vpconfig_timeouten; voltdm->write(vp_val, vp->vpconfig); vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin << - vp->vp_common->vstepmin_smpswaittimemin_shift) | + vp->common->vstepmin_smpswaittimemin_shift) | (vdd->vp_rt_data.vstepmin_stepmin << - vp->vp_common->vstepmin_stepmin_shift)); + vp->common->vstepmin_stepmin_shift)); voltdm->write(vp_val, vp->vstepmin); vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax << - vp->vp_common->vstepmax_smpswaittimemax_shift) | + vp->common->vstepmax_smpswaittimemax_shift) | (vdd->vp_rt_data.vstepmax_stepmax << - vp->vp_common->vstepmax_stepmax_shift)); + vp->common->vstepmax_stepmax_shift)); voltdm->write(vp_val, vp->vstepmax); vp_val = ((vdd->vp_rt_data.vlimitto_vddmax << - vp->vp_common->vlimitto_vddmax_shift) | + vp->common->vlimitto_vddmax_shift) | (vdd->vp_rt_data.vlimitto_vddmin << - vp->vp_common->vlimitto_vddmin_shift) | + vp->common->vlimitto_vddmin_shift) | (vdd->vp_rt_data.vlimitto_timeout << - vp->vp_common->vlimitto_timeout_shift)); + vp->common->vlimitto_timeout_shift)); voltdm->write(vp_val, vp->vlimitto); vp_debugfs_init(voltdm); @@ -95,7 +95,7 @@ void __init omap_vp_init(struct voltagedomain *voltdm) int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, unsigned long target_volt) { - struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vp_instance *vp = voltdm->vp; u32 vpconfig; u8 target_vsel, current_vsel; int ret, timeout = 0; @@ -109,8 +109,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, * is <3us */ while (timeout++ < VP_TRANXDONE_TIMEOUT) { - vp->vp_common->ops->clear_txdone(vp->id); - if (!vp->vp_common->ops->check_txdone(vp->id)) + vp->common->ops->clear_txdone(vp->id); + if (!vp->common->ops->check_txdone(vp->id)) break; udelay(1); } @@ -122,19 +122,19 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, /* Configure for VP-Force Update */ vpconfig = voltdm->read(vp->vpconfig); - vpconfig &= ~(vp->vp_common->vpconfig_initvdd | - vp->vp_common->vpconfig_forceupdate | - vp->vp_common->vpconfig_initvoltage_mask); + vpconfig &= ~(vp->common->vpconfig_initvdd | + vp->common->vpconfig_forceupdate | + vp->common->vpconfig_initvoltage_mask); vpconfig |= ((target_vsel << - vp->vp_common->vpconfig_initvoltage_shift)); + vp->common->vpconfig_initvoltage_shift)); voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ - vpconfig |= vp->vp_common->vpconfig_initvdd; + vpconfig |= vp->common->vpconfig_initvdd; voltdm->write(vpconfig, vp->vpconfig); /* Force update of voltage */ - vpconfig |= vp->vp_common->vpconfig_forceupdate; + vpconfig |= vp->common->vpconfig_forceupdate; voltdm->write(vpconfig, vp->vpconfig); /* @@ -142,7 +142,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, * Depends on SMPSWAITTIMEMIN/MAX and voltage change */ timeout = 0; - omap_test_timeout(vp->vp_common->ops->check_txdone(vp->id), + omap_test_timeout(vp->common->ops->check_txdone(vp->id), VP_TRANXDONE_TIMEOUT, timeout); if (timeout >= VP_TRANXDONE_TIMEOUT) pr_err("%s: vdd_%s TRANXDONE timeout exceeded." @@ -157,8 +157,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, */ timeout = 0; while (timeout++ < VP_TRANXDONE_TIMEOUT) { - vp->vp_common->ops->clear_txdone(vp->id); - if (!vp->vp_common->ops->check_txdone(vp->id)) + vp->common->ops->clear_txdone(vp->id); + if (!vp->common->ops->check_txdone(vp->id)) break; udelay(1); } @@ -170,10 +170,10 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, vpconfig = voltdm->read(vp->vpconfig); /* Clear initVDD copy trigger bit */ - vpconfig &= ~vp->vp_common->vpconfig_initvdd; + vpconfig &= ~vp->common->vpconfig_initvdd; voltdm->write(vpconfig, vp->vpconfig); /* Clear force bit */ - vpconfig &= ~vp->vp_common->vpconfig_forceupdate; + vpconfig &= ~vp->common->vpconfig_forceupdate; voltdm->write(vpconfig, vp->vpconfig); return 0; @@ -187,8 +187,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, */ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) { - struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; - struct omap_vdd_info *vdd; + struct omap_vp_instance *vp = voltdm->vp; u8 curr_vsel; if (!voltdm || IS_ERR(voltdm)) { @@ -196,7 +195,6 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) return 0; } - vdd = voltdm->vdd; if (!voltdm->read) { pr_err("%s: No read API for reading vdd_%s regs\n", __func__, voltdm->name); @@ -223,8 +221,7 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) */ void omap_vp_enable(struct voltagedomain *voltdm) { - struct omap_vp_instance_data *vp; - struct omap_vdd_info *vdd; + struct omap_vp_instance *vp; u32 vpconfig; if (!voltdm || IS_ERR(voltdm)) { @@ -232,8 +229,7 @@ void omap_vp_enable(struct voltagedomain *voltdm) return; } - vdd = voltdm->vdd; - vp = voltdm->vdd->vp_data; + vp = voltdm->vp; if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); @@ -241,16 +237,16 @@ void omap_vp_enable(struct voltagedomain *voltdm) } /* If VP is already enabled, do nothing. Return */ - if (vdd->vp_enabled) + if (vp->enabled) return; vp_latch_vsel(voltdm); /* Enable VP */ vpconfig = voltdm->read(vp->vpconfig); - vpconfig |= vp->vp_common->vpconfig_vpenable; + vpconfig |= vp->common->vpconfig_vpenable; voltdm->write(vpconfig, vp->vpconfig); - vdd->vp_enabled = true; + vp->enabled = true; } /** @@ -262,8 +258,7 @@ void omap_vp_enable(struct voltagedomain *voltdm) */ void omap_vp_disable(struct voltagedomain *voltdm) { - struct omap_vp_instance_data *vp; - struct omap_vdd_info *vdd; + struct omap_vp_instance *vp; u32 vpconfig; int timeout; @@ -272,8 +267,7 @@ void omap_vp_disable(struct voltagedomain *voltdm) return; } - vdd = voltdm->vdd; - vp = voltdm->vdd->vp_data; + vp = voltdm->vp; if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); @@ -281,7 +275,7 @@ void omap_vp_disable(struct voltagedomain *voltdm) } /* If VP is already disabled, do nothing. Return */ - if (!vdd->vp_enabled) { + if (!vp->enabled) { pr_warning("%s: Trying to disable VP for vdd_%s when" "it is already disabled\n", __func__, voltdm->name); return; @@ -289,7 +283,7 @@ void omap_vp_disable(struct voltagedomain *voltdm) /* Disable VP */ vpconfig = voltdm->read(vp->vpconfig); - vpconfig &= ~vp->vp_common->vpconfig_vpenable; + vpconfig &= ~vp->common->vpconfig_vpenable; voltdm->write(vpconfig, vp->vpconfig); /* @@ -302,7 +296,7 @@ void omap_vp_disable(struct voltagedomain *voltdm) pr_warning("%s: vdd_%s idle timedout\n", __func__, voltdm->name); - vdd->vp_enabled = false; + vp->enabled = false; return; } @@ -311,7 +305,7 @@ void omap_vp_disable(struct voltagedomain *voltdm) static int vp_volt_debug_get(void *data, u64 *val) { struct voltagedomain *voltdm = (struct voltagedomain *)data; - struct omap_vp_instance_data *vp = voltdm->vdd->vp_data; + struct omap_vp_instance *vp = voltdm->vp; struct omap_vdd_info *vdd = voltdm->vdd; u8 vsel; -- cgit v1.1 From 633ef8b7475a224b6be662d7c698cd705157064f Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 5 Apr 2011 14:39:11 -0700 Subject: OMAP3+: voltage: remove unneeded debugfs interface Remove read-only debugfs interface to VP values. Most of the values are init-time only and never change. Current voltage value should be retreived from the (eventual) regulator framework interface to the voltage domain. Fixes to original version provided by Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 63 ------------------------------------------------ 1 file changed, 63 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 53d6018..c9a315f 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -1,6 +1,5 @@ #include #include -#include #include @@ -10,8 +9,6 @@ #include "prm-regbits-44xx.h" #include "prm44xx.h" -static void __init vp_debugfs_init(struct voltagedomain *voltdm); - static void vp_latch_vsel(struct voltagedomain *voltdm) { struct omap_vp_instance *vp = voltdm->vp; @@ -87,8 +84,6 @@ void __init omap_vp_init(struct voltagedomain *voltdm) (vdd->vp_rt_data.vlimitto_timeout << vp->common->vlimitto_timeout_shift)); voltdm->write(vp_val, vp->vlimitto); - - vp_debugfs_init(voltdm); } /* VP force update method of voltage scaling */ @@ -300,61 +295,3 @@ void omap_vp_disable(struct voltagedomain *voltdm) return; } - -/* Voltage debugfs support */ -static int vp_volt_debug_get(void *data, u64 *val) -{ - struct voltagedomain *voltdm = (struct voltagedomain *)data; - struct omap_vp_instance *vp = voltdm->vp; - struct omap_vdd_info *vdd = voltdm->vdd; - u8 vsel; - - if (!vdd) { - pr_warning("Wrong paramater passed\n"); - return -EINVAL; - } - - vsel = voltdm->read(vp->voltage); - - if (!voltdm->pmic->vsel_to_uv) { - pr_warning("PMIC function to convert vsel to voltage" - "in uV not registerd\n"); - return -EINVAL; - } - - *val = voltdm->pmic->vsel_to_uv(vsel); - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n"); - -static void __init vp_debugfs_init(struct voltagedomain *voltdm) -{ - struct omap_vdd_info *vdd = voltdm->vdd; - struct dentry *debug_dir; - - debug_dir = debugfs_create_dir("vp", vdd->debug_dir); - if (IS_ERR(debug_dir)) - pr_err("%s: Unable to create VP debugfs dir dir\n", __func__); - - (void) debugfs_create_x16("errorgain", S_IRUGO, debug_dir, - &(vdd->vp_rt_data.vpconfig_errorgain)); - (void) debugfs_create_x16("smpswaittimemin", S_IRUGO, - debug_dir, - &(vdd->vp_rt_data.vstepmin_smpswaittimemin)); - (void) debugfs_create_x8("stepmin", S_IRUGO, debug_dir, - &(vdd->vp_rt_data.vstepmin_stepmin)); - (void) debugfs_create_x16("smpswaittimemax", S_IRUGO, - debug_dir, - &(vdd->vp_rt_data.vstepmax_smpswaittimemax)); - (void) debugfs_create_x8("stepmax", S_IRUGO, debug_dir, - &(vdd->vp_rt_data.vstepmax_stepmax)); - (void) debugfs_create_x8("vddmax", S_IRUGO, debug_dir, - &(vdd->vp_rt_data.vlimitto_vddmax)); - (void) debugfs_create_x8("vddmin", S_IRUGO, debug_dir, - &(vdd->vp_rt_data.vlimitto_vddmin)); - (void) debugfs_create_x16("timeout", S_IRUGO, debug_dir, - &(vdd->vp_rt_data.vlimitto_timeout)); - (void) debugfs_create_file("curr_volt", S_IRUGO, debug_dir, - (void *) voltdm, &vp_volt_debug_fops); -} -- cgit v1.1 From 0ec3041e91cf365a76c81b224e85d3c2574fec23 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 4 Apr 2011 16:02:28 -0700 Subject: OMAP3+: VP: struct omap_vp_common: replace shift with __ffs(mask) In struct omap_vp_common, the shift value can be derived from the mask value by using __ffs(), so remove the shift value for the various VPCONFIG bitfields, and use __ffs() in the code for the shift value. While here, rename field names in kerneldoc comment to match actual field names in structure. Also, cleanup indendentaion for other VP register accesses in omap_vp_init(). No functional changes. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index c9a315f..297d094 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -34,8 +34,7 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~(vp->common->vpconfig_initvoltage_mask | vp->common->vpconfig_initvdd); - vpconfig |= vsel << vp->common->vpconfig_initvoltage_shift; - + vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask); voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ @@ -61,28 +60,28 @@ void __init omap_vp_init(struct voltagedomain *voltdm) vp_val = vdd->vp_rt_data.vpconfig_erroroffset | (vdd->vp_rt_data.vpconfig_errorgain << - vp->common->vpconfig_errorgain_shift) | + __ffs(vp->common->vpconfig_errorgain_mask)) | vp->common->vpconfig_timeouten; voltdm->write(vp_val, vp->vpconfig); vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin << - vp->common->vstepmin_smpswaittimemin_shift) | - (vdd->vp_rt_data.vstepmin_stepmin << - vp->common->vstepmin_stepmin_shift)); + vp->common->vstepmin_smpswaittimemin_shift) | + (vdd->vp_rt_data.vstepmin_stepmin << + vp->common->vstepmin_stepmin_shift)); voltdm->write(vp_val, vp->vstepmin); vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax << - vp->common->vstepmax_smpswaittimemax_shift) | - (vdd->vp_rt_data.vstepmax_stepmax << - vp->common->vstepmax_stepmax_shift)); + vp->common->vstepmax_smpswaittimemax_shift) | + (vdd->vp_rt_data.vstepmax_stepmax << + vp->common->vstepmax_stepmax_shift)); voltdm->write(vp_val, vp->vstepmax); vp_val = ((vdd->vp_rt_data.vlimitto_vddmax << - vp->common->vlimitto_vddmax_shift) | - (vdd->vp_rt_data.vlimitto_vddmin << - vp->common->vlimitto_vddmin_shift) | - (vdd->vp_rt_data.vlimitto_timeout << - vp->common->vlimitto_timeout_shift)); + vp->common->vlimitto_vddmax_shift) | + (vdd->vp_rt_data.vlimitto_vddmin << + vp->common->vlimitto_vddmin_shift) | + (vdd->vp_rt_data.vlimitto_timeout << + vp->common->vlimitto_timeout_shift)); voltdm->write(vp_val, vp->vlimitto); } @@ -121,7 +120,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, vp->common->vpconfig_forceupdate | vp->common->vpconfig_initvoltage_mask); vpconfig |= ((target_vsel << - vp->common->vpconfig_initvoltage_shift)); + __ffs(vp->common->vpconfig_initvoltage_mask))); voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ -- cgit v1.1 From 6f56727383ca3233f40af5e792a08bf07b18f5fd Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 14 Jul 2011 11:10:27 -0700 Subject: OMAP3+: VP: move timing calculation/config into VP init Move VP timing calcluation (based on sys clock) and register programming into VP init. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 297d094..ea61a47 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -50,7 +50,7 @@ void __init omap_vp_init(struct voltagedomain *voltdm) { struct omap_vp_instance *vp = voltdm->vp; struct omap_vdd_info *vdd = voltdm->vdd; - u32 vp_val; + u32 vp_val, sys_clk_rate, timeout_val, waittime; if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", @@ -58,6 +58,27 @@ void __init omap_vp_init(struct voltagedomain *voltdm) return; } + vp->enabled = false; + + /* Divide to avoid overflow */ + sys_clk_rate = voltdm->sys_clk.rate / 1000; + + vdd->vp_rt_data.vpconfig_erroroffset = + (voltdm->pmic->vp_erroroffset << + __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)); + + timeout_val = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; + vdd->vp_rt_data.vlimitto_timeout = timeout_val; + vdd->vp_rt_data.vlimitto_vddmin = voltdm->pmic->vp_vddmin; + vdd->vp_rt_data.vlimitto_vddmax = voltdm->pmic->vp_vddmax; + + waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) * + sys_clk_rate) / 1000; + vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime; + vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime; + vdd->vp_rt_data.vstepmin_stepmin = voltdm->pmic->vp_vstepmin; + vdd->vp_rt_data.vstepmax_stepmax = voltdm->pmic->vp_vstepmax; + vp_val = vdd->vp_rt_data.vpconfig_erroroffset | (vdd->vp_rt_data.vpconfig_errorgain << __ffs(vp->common->vpconfig_errorgain_mask)) | -- cgit v1.1 From 76ea7424f80350884b4d70ae54cfa51f7f9b2a48 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 5 Apr 2011 15:15:31 -0700 Subject: OMAP3+: VP: create VP helper function for updating error gain Create new helper function in VP layer for updating VP error gain. Currently used during pre-scale for VP force update and VC bypass. TODO: determine if this can be removed from the pre-scale path and moved to VP enable path. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index ea61a47..f68a6db 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -106,6 +106,25 @@ void __init omap_vp_init(struct voltagedomain *voltdm) voltdm->write(vp_val, vp->vlimitto); } +int omap_vp_update_errorgain(struct voltagedomain *voltdm, + unsigned long target_volt) +{ + struct omap_volt_data *volt_data; + + /* Get volt_data corresponding to target_volt */ + volt_data = omap_voltage_get_voltdata(voltdm, target_volt); + if (IS_ERR(volt_data)) + return -EINVAL; + + /* Setting vp errorgain based on the voltage */ + voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask, + volt_data->vp_errgain << + __ffs(voltdm->vp->common->vpconfig_errorgain_mask), + voltdm->vp->vpconfig); + + return 0; +} + /* VP force update method of voltage scaling */ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, unsigned long target_volt) -- cgit v1.1 From 667216d6a435a27f5aed64aa30de583ddccc58c8 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 4 Apr 2011 17:58:21 -0700 Subject: OMAP3+: VP: remove omap_vp_runtime_data Remove the "runtime" VP data in favor of direct programming of VP registers. The VP is in the PRM, which is in the wakeup powerdomain, so there is no need to keep the state dynamically. Fixes to original version from Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 70 +++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 39 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index f68a6db..e7d38f6 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -49,8 +49,8 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) void __init omap_vp_init(struct voltagedomain *voltdm) { struct omap_vp_instance *vp = voltdm->vp; - struct omap_vdd_info *vdd = voltdm->vdd; - u32 vp_val, sys_clk_rate, timeout_val, waittime; + u32 val, sys_clk_rate, timeout, waittime; + u32 vddmin, vddmax, vstepmin, vstepmax; if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", @@ -63,47 +63,39 @@ void __init omap_vp_init(struct voltagedomain *voltdm) /* Divide to avoid overflow */ sys_clk_rate = voltdm->sys_clk.rate / 1000; - vdd->vp_rt_data.vpconfig_erroroffset = - (voltdm->pmic->vp_erroroffset << - __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)); - - timeout_val = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; - vdd->vp_rt_data.vlimitto_timeout = timeout_val; - vdd->vp_rt_data.vlimitto_vddmin = voltdm->pmic->vp_vddmin; - vdd->vp_rt_data.vlimitto_vddmax = voltdm->pmic->vp_vddmax; + timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; + vddmin = voltdm->pmic->vp_vddmin; + vddmax = voltdm->pmic->vp_vddmax; waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) * sys_clk_rate) / 1000; - vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime; - vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime; - vdd->vp_rt_data.vstepmin_stepmin = voltdm->pmic->vp_vstepmin; - vdd->vp_rt_data.vstepmax_stepmax = voltdm->pmic->vp_vstepmax; - - vp_val = vdd->vp_rt_data.vpconfig_erroroffset | - (vdd->vp_rt_data.vpconfig_errorgain << - __ffs(vp->common->vpconfig_errorgain_mask)) | + vstepmin = voltdm->pmic->vp_vstepmin; + vstepmax = voltdm->pmic->vp_vstepmax; + + /* + * VP_CONFIG: error gain is not set here, it will be updated + * on each scale, based on OPP. + */ + val = (voltdm->pmic->vp_erroroffset << + __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) | vp->common->vpconfig_timeouten; - voltdm->write(vp_val, vp->vpconfig); - - vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin << - vp->common->vstepmin_smpswaittimemin_shift) | - (vdd->vp_rt_data.vstepmin_stepmin << - vp->common->vstepmin_stepmin_shift)); - voltdm->write(vp_val, vp->vstepmin); - - vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax << - vp->common->vstepmax_smpswaittimemax_shift) | - (vdd->vp_rt_data.vstepmax_stepmax << - vp->common->vstepmax_stepmax_shift)); - voltdm->write(vp_val, vp->vstepmax); - - vp_val = ((vdd->vp_rt_data.vlimitto_vddmax << - vp->common->vlimitto_vddmax_shift) | - (vdd->vp_rt_data.vlimitto_vddmin << - vp->common->vlimitto_vddmin_shift) | - (vdd->vp_rt_data.vlimitto_timeout << - vp->common->vlimitto_timeout_shift)); - voltdm->write(vp_val, vp->vlimitto); + voltdm->write(val, vp->vpconfig); + + /* VSTEPMIN */ + val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) | + (vstepmin << vp->common->vstepmin_stepmin_shift); + voltdm->write(val, vp->vstepmin); + + /* VSTEPMAX */ + val = (vstepmax << vp->common->vstepmax_stepmax_shift) | + (waittime << vp->common->vstepmax_smpswaittimemax_shift); + voltdm->write(val, vp->vstepmax); + + /* VLIMITTO */ + val = (vddmax << vp->common->vlimitto_vddmax_shift) | + (vddmin << vp->common->vlimitto_vddmin_shift) | + (timeout << vp->common->vlimitto_timeout_shift); + voltdm->write(val, vp->vlimitto); } int omap_vp_update_errorgain(struct voltagedomain *voltdm, -- cgit v1.1 From bea30ed65fb2432097f362ce17042e22febcb616 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Fri, 27 May 2011 19:15:59 -0700 Subject: OMAP: VP: Explicitly mask VPVOLTAGE field Reading the VPVOLTAGE field of PRM_VP_*_VOLTAGE registers currently relies on a u32 -> u8 conversion to mask off the FORCEUPDATEWAIT field in the upper bits. Make this explicit using the mask symbol already defined, added as a new field in struct omap_vp_common. Signed-off-by: Todd Poynor Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index e7d38f6..3807620 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -227,7 +227,8 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) return 0; } - curr_vsel = voltdm->read(vp->voltage); + curr_vsel = (voltdm->read(vp->voltage) & vp->common->vpvoltage_mask) + >> __ffs(vp->common->vpvoltage_mask); if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) { pr_warning("%s: PMIC function to convert vsel to voltage" -- cgit v1.1 From 8798c4ab56d8f726092870cb2cf15c5a7a0a93bf Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jul 2011 15:31:43 -0700 Subject: OMAP3+: VP: update_errorgain(): return error if VP Add check for valid VP in omap_vp_update_errorgain() Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 3807620..29698ac 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -103,6 +103,9 @@ int omap_vp_update_errorgain(struct voltagedomain *voltdm, { struct omap_volt_data *volt_data; + if (!voltdm->vp) + return -EINVAL; + /* Get volt_data corresponding to target_volt */ volt_data = omap_voltage_get_voltdata(voltdm, target_volt); if (IS_ERR(volt_data)) -- cgit v1.1 From cc6962dbab223ae51b47c8057d39d89ac6af0d35 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 15 Jul 2011 16:38:10 -0700 Subject: OMAP3+: VP: remove unused omap_vp_get_curr_volt() Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 29698ac..24020ea 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -209,40 +209,6 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, } /** - * omap_vp_get_curr_volt() - API to get the current vp voltage. - * @voltdm: pointer to the VDD. - * - * This API returns the current voltage for the specified voltage processor - */ -unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) -{ - struct omap_vp_instance *vp = voltdm->vp; - u8 curr_vsel; - - if (!voltdm || IS_ERR(voltdm)) { - pr_warning("%s: VDD specified does not exist!\n", __func__); - return 0; - } - - if (!voltdm->read) { - pr_err("%s: No read API for reading vdd_%s regs\n", - __func__, voltdm->name); - return 0; - } - - curr_vsel = (voltdm->read(vp->voltage) & vp->common->vpvoltage_mask) - >> __ffs(vp->common->vpvoltage_mask); - - if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) { - pr_warning("%s: PMIC function to convert vsel to voltage" - "in uV not registerd\n", __func__); - return 0; - } - - return voltdm->pmic->vsel_to_uv(curr_vsel); -} - -/** * omap_vp_enable() - API to enable a particular VP * @voltdm: pointer to the VDD whose VP is to be enabled. * -- cgit v1.1 From b666b4767d3e6a23634b4d485c8511bd42d50023 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 15 Jul 2011 17:05:48 -0700 Subject: OMAP3+: VP: combine setting init voltage into common function combine VPCONFIG init voltage setup into common function and use from both vp_enable and from vp_forceupdate_scale(). NOTE: this patch changes the sequence of when the initVDD bit is cleared. The bit is now cleared immediately after it was written. Since only the rising edge of this bit has any affect according to the TRM, the exact timing of clearing of this bit should not have any effect. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vp.c | 58 ++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 24020ea..66bd700 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -9,31 +9,18 @@ #include "prm-regbits-44xx.h" #include "prm44xx.h" -static void vp_latch_vsel(struct voltagedomain *voltdm) +static u32 _vp_set_init_voltage(struct voltagedomain *voltdm, u32 volt) { struct omap_vp_instance *vp = voltdm->vp; u32 vpconfig; - unsigned long uvdc; char vsel; - uvdc = omap_voltage_get_nom_volt(voltdm); - if (!uvdc) { - pr_warning("%s: unable to find current voltage for vdd_%s\n", - __func__, voltdm->name); - return; - } - - if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { - pr_warning("%s: PMIC function to convert voltage in uV to" - " vsel not registered\n", __func__); - return; - } - - vsel = voltdm->pmic->uv_to_vsel(uvdc); + vsel = voltdm->pmic->uv_to_vsel(volt); vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~(vp->common->vpconfig_initvoltage_mask | - vp->common->vpconfig_initvdd); + vp->common->vpconfig_forceupdate | + vp->common->vpconfig_initvdd); vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask); voltdm->write(vpconfig, vp->vpconfig); @@ -43,6 +30,8 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) /* Clear initVDD copy trigger bit */ voltdm->write(vpconfig, vp->vpconfig); + + return vpconfig; } /* Generic voltage init functions */ @@ -149,22 +138,11 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, return -ETIMEDOUT; } - /* Configure for VP-Force Update */ - vpconfig = voltdm->read(vp->vpconfig); - vpconfig &= ~(vp->common->vpconfig_initvdd | - vp->common->vpconfig_forceupdate | - vp->common->vpconfig_initvoltage_mask); - vpconfig |= ((target_vsel << - __ffs(vp->common->vpconfig_initvoltage_mask))); - voltdm->write(vpconfig, vp->vpconfig); - - /* Trigger initVDD value copy to voltage processor */ - vpconfig |= vp->common->vpconfig_initvdd; - voltdm->write(vpconfig, vp->vpconfig); + vpconfig = _vp_set_init_voltage(voltdm, target_volt); /* Force update of voltage */ - vpconfig |= vp->common->vpconfig_forceupdate; - voltdm->write(vpconfig, vp->vpconfig); + voltdm->write(vpconfig | vp->common->vpconfig_forceupdate, + voltdm->vp->vpconfig); /* * Wait for TransactionDone. Typical latency is <200us. @@ -197,12 +175,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, "to clear the TRANXDONE status\n", __func__, voltdm->name); - vpconfig = voltdm->read(vp->vpconfig); - /* Clear initVDD copy trigger bit */ - vpconfig &= ~vp->common->vpconfig_initvdd; - voltdm->write(vpconfig, vp->vpconfig); /* Clear force bit */ - vpconfig &= ~vp->common->vpconfig_forceupdate; voltdm->write(vpconfig, vp->vpconfig); return 0; @@ -218,7 +191,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, void omap_vp_enable(struct voltagedomain *voltdm) { struct omap_vp_instance *vp; - u32 vpconfig; + u32 vpconfig, volt; if (!voltdm || IS_ERR(voltdm)) { pr_warning("%s: VDD specified does not exist!\n", __func__); @@ -236,12 +209,19 @@ void omap_vp_enable(struct voltagedomain *voltdm) if (vp->enabled) return; - vp_latch_vsel(voltdm); + volt = voltdm_get_voltage(voltdm); + if (!volt) { + pr_warning("%s: unable to find current voltage for %s\n", + __func__, voltdm->name); + return; + } + + vpconfig = _vp_set_init_voltage(voltdm, volt); /* Enable VP */ - vpconfig = voltdm->read(vp->vpconfig); vpconfig |= vp->common->vpconfig_vpenable; voltdm->write(vpconfig, vp->vpconfig); + vp->enabled = true; } -- cgit v1.1 From 758e4d3da5bc2a30a7618cb8f1710e096dac0e53 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 09:42:11 +0000 Subject: ARM: omap: fix oops in arch/arm/mach-omap2/vp.c when pmic is not found commit d980e0f8d858c6963d676013e976ff00ab7acb2b upstream. When the PMIC is not found, voltdm->pmic will be NULL. vp.c's initialization function tries to dereferences this, which causes an oops: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT Modules linked in: CPU: 0 Not tainted (3.3.0-rc2+ #204) PC is at omap_vp_init+0x5c/0x15c LR is at omap_vp_init+0x58/0x15c pc : [] lr : [] psr: 60000013 sp : c181ff30 ip : c181ff68 fp : c181ff64 r10: c0407808 r9 : c040786c r8 : c0407814 r7 : c0026868 r6 : c00264fc r5 : c040ad6c r4 : 00000000 r3 : 00000040 r2 : 000032c8 r1 : 0000fa00 r0 : 000032c8 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 80004019 DAC: 00000015 Process swapper (pid: 1, stack limit = 0xc181e2e8) Stack: (0xc181ff30 to 0xc1820000) ff20: c0381d00 c02e9c6d c0383582 c040786c ff40: c040ad6c c00264fc c0026868 c0407814 00000000 c03d9de4 c181ff8c c181ff68 ff60: c03db448 c03db830 c02e982c c03fdfb8 c03fe004 c0039988 00000013 00000000 ff80: c181ff9c c181ff90 c03d9df8 c03db390 c181ffdc c181ffa0 c0008798 c03d9df0 ffa0: c181ffc4 c181ffb0 c0055a44 c0187050 c0039988 c03fdfb8 c03fe004 c0039988 ffc0: 00000013 00000000 00000000 00000000 c181fff4 c181ffe0 c03d1284 c0008708 ffe0: 00000000 c03d1208 00000000 c181fff8 c0039988 c03d1214 1077ce40 01f7ee08 Backtrace: [] (omap_vp_init+0x0/0x15c) from [] (omap_voltage_late_init+0xc4/0xfc) [] (omap_voltage_late_init+0x0/0xfc) from [] (omap2_common_pm_late_init+0x14/0x54) r8:00000000 r7:00000013 r6:c0039988 r5:c03fe004 r4:c03fdfb8 [] (omap2_common_pm_late_init+0x0/0x54) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x7c/0x120) [] (kernel_init+0x0/0x120) from [] (do_exit+0x0/0x2cc) r5:c03d1208 r4:00000000 Code: e5ca300b e5900034 ebf69027 e5994024 (e5941000) ---[ end trace aed617dddaf32c3d ]--- Kernel panic - not syncing: Attempted to kill init! Signed-off-by: Russell King Cc: Igor Grinberg Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/vp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm/mach-omap2/vp.c') diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 66bd700..3b52027 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -41,6 +41,11 @@ void __init omap_vp_init(struct voltagedomain *voltdm) u32 val, sys_clk_rate, timeout, waittime; u32 vddmin, vddmax, vstepmin, vstepmax; + if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { + pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name); + return; + } + if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); -- cgit v1.1