From patchwork Fri Jan 21 14:00:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sripathy, Vishwanath" X-Patchwork-Id: 495051 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 p0LDvgSU022977 for ; Fri, 21 Jan 2011 13:57:48 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752721Ab1AUN5q (ORCPT ); Fri, 21 Jan 2011 08:57:46 -0500 Received: from comal.ext.ti.com ([198.47.26.152]:33509 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752647Ab1AUN5o (ORCPT ); Fri, 21 Jan 2011 08:57:44 -0500 Received: from dbdp31.itg.ti.com ([172.24.170.98]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id p0LDvea8000503 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 21 Jan 2011 07:57:43 -0600 Received: from localhost.localdomain (localhost [127.0.0.1]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id p0LDvSPT010507; Fri, 21 Jan 2011 19:27:40 +0530 (IST) From: Vishwanath BS To: linux-omap@vger.kernel.org Cc: patches@linaro.org, Vishwanath BS , Thara Gopinath Subject: [PATCH 03/13] OMAP: Implement Basic DVFS Date: Fri, 21 Jan 2011 19:30:55 +0530 Message-Id: <1295618465-15234-4-git-send-email-vishwanath.bs@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1295618465-15234-1-git-send-email-vishwanath.bs@ti.com> References: <1295618465-15234-1-git-send-email-vishwanath.bs@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.6 (demeter1.kernel.org [140.211.167.41]); Fri, 21 Jan 2011 13:57:48 +0000 (UTC) diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c index 8832e4a..cefc2be 100755 --- a/arch/arm/mach-omap2/dvfs.c +++ b/arch/arm/mach-omap2/dvfs.c @@ -21,7 +21,7 @@ #include /** - * struct omap_dev_user_list - Structure maitain userlist per devide + * struct omap_dev_user_list - Structure maitain userlist per device * * @dev: The device requesting for a particular frequency * @node: The list head entry @@ -413,6 +413,91 @@ static int omap_dvfs_remove_freq_request(struct omap_vdd_dvfs_info *dvfs_info, } /** + * omap_dvfs_voltage_scale() : API to scale the devices associated with a + * voltage domain vdd voltage. + * + * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd + * + * This API runs through the list of devices associated with the + * voltage domain and scales the device rates to the one requested + * by the user or those corresponding to the new voltage of the + * voltage domain. Target voltage is the highest voltage in the vdd_user_list. + * + * Returns 0 on success + * else the error value. + */ +static int omap_dvfs_voltage_scale(struct omap_vdd_dvfs_info *dvfs_info) +{ + unsigned long curr_volt; + int is_volt_scaled = 0; + struct omap_vdd_dev_list *temp_dev; + struct plist_node *node; + int ret = 0; + struct voltagedomain *voltdm; + unsigned long volt; + + if (!dvfs_info || IS_ERR(dvfs_info)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + voltdm = dvfs_info->voltdm; + + mutex_lock(&dvfs_info->scaling_mutex); + + /* Find the highest voltage being requested */ + node = plist_last(&dvfs_info->user_list); + volt = node->prio; + + curr_volt = omap_voltage_get_nom_volt(voltdm); + + if (curr_volt == volt) { + is_volt_scaled = 1; + } else if (curr_volt < volt) { + ret = omap_voltage_scale_vdd(voltdm, volt); + if (ret) { + pr_warning("%s: Unable to scale the %s to %ld volt\n", + __func__, voltdm->name, volt); + mutex_unlock(&dvfs_info->scaling_mutex); + return ret; + } + is_volt_scaled = 1; + } + + list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) { + struct device *dev; + struct opp *opp; + unsigned long freq; + + dev = temp_dev->dev; + if (!plist_head_empty(&temp_dev->user_list)) { + node = plist_last(&temp_dev->user_list); + freq = node->prio; + } else { + opp = omap_dvfs_find_voltage(dev, volt); + if (IS_ERR(opp)) + continue; + freq = opp_get_freq(opp); + } + + if (freq == omap_device_get_rate(dev)) { + dev_dbg(dev, "%s: Already at the requested" + "rate %ld\n", __func__, freq); + continue; + } + + ret |= omap_device_set_rate(dev, freq); + } + + if (!is_volt_scaled && !ret) + omap_voltage_scale_vdd(voltdm, volt); + + mutex_unlock(&dvfs_info->scaling_mutex); + + return 0; +} + +/** * omap_dvfs_init() - Initialize omap dvfs layer * * Initalizes omap dvfs layer. It basically allocates memory for