aboutsummaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch199
1 files changed, 199 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch b/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch
new file mode 100644
index 00000000..516c7cb0
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch
@@ -0,0 +1,199 @@
+From a4107498616e8dafa2a0155a6d45a990766b161b Mon Sep 17 00:00:00 2001
+From: Thara Gopinath <thara@ti.com>
+Date: Fri, 29 Oct 2010 20:43:07 +0530
+Subject: [PATCH 06/20] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
+
+This patch introduces a user list of devices associated with each
+voltage domain instance. The user list is implemented using plist
+structure with priority node populated with the voltage values.
+This patch also adds an API which will take in a device and
+requested voltage as parameters, adds the info to the user list
+and returns back the maximum voltage requested by all the user
+devices. This can be used anytime to get the voltage that the
+voltage domain instance can be transitioned into.
+
+Signed-off-by: Thara Gopinath <thara@ti.com>
+---
+ arch/arm/mach-omap2/voltage.c | 97 +++++++++++++++++++++++++++++
+ arch/arm/plat-omap/include/plat/voltage.h | 8 +++
+ 2 files changed, 105 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
+index ed6079c..76c98c6 100644
+--- a/arch/arm/mach-omap2/voltage.c
++++ b/arch/arm/mach-omap2/voltage.c
+@@ -24,6 +24,9 @@
+ #include <linux/err.h>
+ #include <linux/debugfs.h>
+ #include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/plist.h>
++#include <linux/slab.h>
+
+ #include <plat/common.h>
+ #include <plat/voltage.h>
+@@ -118,6 +121,20 @@ struct vc_reg_info {
+ };
+
+ /**
++ * struct omap_vdd_user_list - The per vdd user list
++ *
++ * @dev: The device asking for the vdd to be set at a particular
++ * voltage
++ * @node: The list head entry
++ * @volt: The voltage requested by the device <dev>
++ */
++struct omap_vdd_user_list {
++ struct device *dev;
++ struct plist_node node;
++ u32 volt;
++};
++
++/**
+ * omap_vdd_info - Per Voltage Domain info
+ *
+ * @volt_data : voltage table having the distinct voltages supported
+@@ -132,6 +149,10 @@ struct vc_reg_info {
+ * shifts, masks etc.
+ * @voltdm : pointer to the voltage domain structure
+ * @debug_dir : debug directory for this voltage domain.
++ * @user_lock : the lock to be used by the plist user_list
++ * @user_list : the list head maintaining the various users.
++ * @scaling_mutex : the dvfs muutex.
++ * of this vdd with the voltage requested by each user.
+ * @curr_volt : current voltage for this vdd.
+ * @ocp_mod : The prm module for accessing the prm irqstatus reg.
+ * @prm_irqst_reg : prm irqstatus register.
+@@ -146,6 +167,9 @@ struct omap_vdd_info {
+ struct vc_reg_info vc_reg;
+ struct voltagedomain voltdm;
+ struct dentry *debug_dir;
++ spinlock_t user_lock;
++ struct plist_head user_list;
++ struct mutex scaling_mutex;
+ u32 curr_volt;
+ u16 ocp_mod;
+ u8 prm_irqst_reg;
+@@ -869,6 +893,11 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
+ vdd->write_reg = omap3_voltage_write_reg;
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ vdd->vp_enabled = false;
++ /* Init the plist */
++ spin_lock_init(&vdd->user_lock);
++ plist_head_init(&vdd->user_list, &vdd->user_lock);
++ /* Init the DVFS mutex */
++ mutex_init(&vdd->scaling_mutex);
+
+ /* VC parameters */
+ vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
+@@ -1059,6 +1088,11 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
+ vdd->write_reg = omap4_voltage_write_reg;
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ vdd->vp_enabled = false;
++ /* Init the plist */
++ spin_lock_init(&vdd->user_lock);
++ plist_head_init(&vdd->user_list, &vdd->user_lock);
++ /* Init the DVFS mutex */
++ mutex_init(&vdd->scaling_mutex);
+
+ /* VC parameters */
+ vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
+@@ -1171,6 +1205,69 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
+
+ return vdd->pmic_info->vsel_to_uv(curr_vsel);
+ }
++/**
++ * omap_voltage_add_request() - API to keep track of various requests to
++ * scale the VDD and returns the best possible
++ * voltage the VDD can be put to.
++ * @volt_domain: pointer to the voltage domain.
++ * @dev: the device pointer.
++ * @volt: the voltage which is requested by the device.
++ *
++ * This API is to be called before the actual voltage scaling is
++ * done to determine what is the best possible voltage the VDD can
++ * be put to. This API adds the device <dev> in the user list of the
++ * vdd <volt_domain> with <volt> as the requested voltage. The user list
++ * is a plist with the priority element absolute voltage values.
++ * The API then finds the maximum of all the requested voltages for
++ * the VDD and returns it back through <volt> pointer itself.
++ * Returns error value in case of any errors.
++ */
++int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
++ unsigned long *volt)
++{
++ struct omap_vdd_info *vdd;
++ struct omap_vdd_user_list *user;
++ struct plist_node *node;
++ int found = 0;
++
++ if (!voltdm || IS_ERR(voltdm)) {
++ pr_warning("%s: VDD specified does not exist!\n", __func__);
++ return -EINVAL;
++ }
++
++ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
++
++ mutex_lock(&vdd->scaling_mutex);
++
++ plist_for_each_entry(user, &vdd->user_list, node) {
++ if (user->dev == dev) {
++ found = 1;
++ break;
++ }
++ }
++
++ if (!found) {
++ user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL);
++ if (!user) {
++ pr_err("%s: Unable to creat a new user for vdd_%s\n",
++ __func__, voltdm->name);
++ mutex_unlock(&vdd->scaling_mutex);
++ return -ENOMEM;
++ }
++ user->dev = dev;
++ } else {
++ plist_del(&user->node, &vdd->user_list);
++ }
++
++ plist_node_init(&user->node, *volt);
++ plist_add(&user->node, &vdd->user_list);
++ node = plist_last(&vdd->user_list);
++ *volt = user->volt = node->prio;
++
++ mutex_unlock(&vdd->scaling_mutex);
++
++ return 0;
++}
+
+ /**
+ * omap_vp_enable() - API to enable a particular VP
+diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
+index 0ff1233..bd07eca 100644
+--- a/arch/arm/plat-omap/include/plat/voltage.h
++++ b/arch/arm/plat-omap/include/plat/voltage.h
+@@ -132,6 +132,9 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method);
+ int omap_voltage_late_init(void);
++int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
++ unsigned long *volt);
++
+ #else
+ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info) {}
+@@ -141,6 +144,11 @@ static inline int omap_voltage_late_init(void)
+ {
+ return -EINVAL;
+ }
++static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
++ struct device *dev, unsigned long *volt)
++{
++ return -EINVAL;
++}
+ #endif
+
+ #endif
+--
+1.6.6.1
+