From patchwork Fri Oct 29 15:38:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thara Gopinath X-Patchwork-Id: 290542 X-Patchwork-Delegate: khilman@deeprootsystems.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9TFcho4012993 for ; Fri, 29 Oct 2010 15:38:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932874Ab0J2Pik (ORCPT ); Fri, 29 Oct 2010 11:38:40 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:40341 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932682Ab0J2Pij (ORCPT ); Fri, 29 Oct 2010 11:38:39 -0400 Received: from dbdp31.itg.ti.com ([172.24.170.98]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id o9TFcYGe022150 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 29 Oct 2010 10:38:36 -0500 Received: from localhost.localdomain (localhost [127.0.0.1]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id o9TFcTYl012648; Fri, 29 Oct 2010 21:08:32 +0530 (IST) From: Thara Gopinath To: linux-omap@vger.kernel.org Cc: paul@pwsan.com, khilman@deeprootsystems.com, b-cousson@ti.com, vishwanath.bs@ti.com, sawant@ti.com, Thara Gopinath Subject: [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver. Date: Fri, 29 Oct 2010 21:08:15 +0530 Message-Id: <1288366708-32302-2-git-send-email-thara@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1288366708-32302-1-git-send-email-thara@ti.com> References: <1288366708-32302-1-git-send-email-thara@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Fri, 29 Oct 2010 15:38:44 +0000 (UTC) diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 45b0958..f0ecc30 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include #include @@ -85,6 +88,20 @@ struct vp_reg_val { }; /** + * 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 + */ +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 @@ -95,9 +112,13 @@ struct vp_reg_val { * vp registers * @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. * @volt_data_count : number of distinct voltages supported by this vdd. * @nominal_volt : nominal voltage for this vdd. - * @curr_volt : current voltage for this vdd; + * @curr_volt : current voltage for this vdd. * cmdval_reg : voltage controller cmdval register. * @vdd_sr_reg : the smartreflex register associated with this VDD. */ @@ -107,6 +128,9 @@ struct omap_vdd_info{ struct vp_reg_val vp_reg; struct voltagedomain voltdm; struct dentry *debug_dir; + spinlock_t user_lock; + struct plist_head user_list; + struct mutex scaling_mutex; int volt_data_count; u32 nominal_volt; u32 curr_volt; @@ -591,6 +615,12 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd) vdd->vp_reg.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT; vdd->vp_reg.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT; vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT; + + /* 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); } /* OMAP4 specific voltage init functions */ @@ -715,6 +745,12 @@ static void __init omap4_vdd_data_configure(struct omap_vdd_info *vdd) vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT; vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT; vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT; + + /* 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); } /* Generic voltage init functions */ @@ -1140,6 +1176,69 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) return volt_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 in the user list of the + * vdd with 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 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 812266e..c226b6d 100644 --- a/arch/arm/plat-omap/include/plat/voltage.h +++ b/arch/arm/plat-omap/include/plat/voltage.h @@ -150,11 +150,18 @@ bool omap_voltage_override_params(struct voltagedomain *voltdm); void omap_voltage_register_pmic(struct omap_volt_pmic_info *pmic_info); void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc); void omap_change_voltscale_method(int voltscale_method); +int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev, + unsigned long *volt); #else static inline void omap_voltage_register_pmic (struct omap_volt_pmic_info *pmic_info) {} static inline void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc) {} static inline void omap_change_voltscale_method(int voltscale_method) {} +static inline int omap_voltage_add_request(struct voltagedomain *voltdm, + struct device *dev, unsigned long *volt) +{ + return -EINVAL; +} #endif #endif