From patchwork Thu Mar 18 18:44:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nishanth Menon X-Patchwork-Id: 86794 X-Patchwork-Delegate: khilman@deeprootsystems.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2IIjLOj031828 for ; Thu, 18 Mar 2010 18:45:25 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751752Ab0CRSpY (ORCPT ); Thu, 18 Mar 2010 14:45:24 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:58488 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751595Ab0CRSpW (ORCPT ); Thu, 18 Mar 2010 14:45:22 -0400 Received: from dlep35.itg.ti.com ([157.170.170.118]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o2IIjHpb019602 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 18 Mar 2010 13:45:17 -0500 Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep35.itg.ti.com (8.13.7/8.13.7) with ESMTP id o2IIjDqO005375; Thu, 18 Mar 2010 13:45:13 -0500 (CDT) Received: from senorita (senorita.am.dhcp.ti.com [128.247.75.1]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id o2IIjDZ10091; Thu, 18 Mar 2010 13:45:13 -0500 (CDT) Received: by senorita (Postfix, from userid 1000) id 12D82C1F2; Thu, 18 Mar 2010 13:45:12 -0500 (CDT) From: Nishanth Menon To: Linux-Omap Cc: Nishanth Menon , Ambresh K , Benoit Cousson , Eduardo Valentin , Kevin Hilman , Phil Carmody , Sanjeev Premi , Tero Kristo , Thara Gopinath Subject: [PM-WIP-OPP][PATCH 3/4] omap: pm: opp: add ability to store data per opp Date: Thu, 18 Mar 2010 13:44:50 -0500 Message-Id: <1268937891-19445-4-git-send-email-nm@ti.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1268937891-19445-3-git-send-email-nm@ti.com> References: <1268937891-19445-1-git-send-email-nm@ti.com> <1268937891-19445-2-git-send-email-nm@ti.com> <1268937891-19445-3-git-send-email-nm@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 (demeter.kernel.org [140.211.167.41]); Thu, 18 Mar 2010 18:45:25 +0000 (UTC) diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h index dc9a0d9..666c514 100644 --- a/arch/arm/plat-omap/include/plat/opp.h +++ b/arch/arm/plat-omap/include/plat/opp.h @@ -231,6 +231,47 @@ struct omap_opp * __deprecated opp_find_by_opp_id(enum opp_t opp_type, u8 opp_id); u8 __deprecated opp_get_opp_id(struct omap_opp *opp); +/** + * opp_store_data() - Store a data corresponding to an opp + * @opp: opp where to store + * @name: unique string to identify the type of data stored + * @data: The pointer which is used to the actual data + * + * Many scenarios require a custom data to be stored corresponding to a + * specific OPP which may need to be retrieved for operations. The actual + * type of data might be very specific to a CPU, allowing opp layer to store + * any type or mixture of types of data to be adequately retrieved + * by corresponding modules which consume that data. + * typical examples are Smart reflex nTarget values, L3 threshold dependencies + * + * Returns 0 if successful or a corresponding error value if failed. + */ +int opp_store_data(struct omap_opp *opp, char *name, void *data); + +/** + * opp_get_data() - get a stored data corresponding to an opp + * @opp: pointer to opp + * @name: unique string to identify the type of data stored + * + * Retrieve a stored data identified by the name allowing usage + * accross modules on a need basis + * + * Returns ERR_PTRs and should be checked with IS_ERR() macros + */ +void *opp_get_data(struct omap_opp *opp, char *name); + +/** + * opp_remove_data() - remove the stored data corresponding to an opp + * @opp: pointer to opp + * @name: unique string to identify the type of data stored + * + * Remove a stored data identified by the name allowing replacing + * old values with new or removing the information altogether if needed + * + * Returns 0 if successfully removed, else returns corresponding error value + */ +int opp_remove_data(struct omap_opp *opp, char *name); + void opp_init_cpufreq_table(enum opp_t opp_type, struct cpufreq_frequency_table **table); #else @@ -300,6 +341,21 @@ static inline u8 __deprecated opp_get_opp_id(struct omap_opp *opp) return 0; } +int opp_store_data(struct omap_opp *opp, char *name, void *data) +{ + return -EINVAL; +} + +void *opp_get_data(struct omap_opp *opp, char *name) +{ + return ERR_PTR(-EINVAL); +} + +int opp_remove_data(struct omap_opp *opp, char *name) +{ + return -EINVAL; +} + static inline void opp_init_cpufreq_table(struct omap_opp *opps, struct cpufreq_frequency_table **table) { diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c index bb8120e..15f6f7c 100644 --- a/arch/arm/plat-omap/opp.c +++ b/arch/arm/plat-omap/opp.c @@ -14,12 +14,19 @@ #include #include #include +#include #include #include #include #include +struct omap_opp_data { + char *name; + void *data; + struct list_head list; +}; + /** * struct omap_opp - OMAP OPP description structure * @enabled: true/false - marking this OPP as enabled/disabled @@ -37,6 +44,7 @@ struct omap_opp { unsigned long rate; unsigned long u_volt; u8 opp_id; + struct list_head data_list; }; /* @@ -218,6 +226,7 @@ static void omap_opp_populate(struct omap_opp *opp, opp->rate = opp_def->freq; opp->enabled = opp_def->enabled; opp->u_volt = opp_def->u_volt; + INIT_LIST_HEAD(&opp->data_list); } int opp_add(enum opp_t opp_type, const struct omap_opp_def *opp_def) @@ -352,6 +361,63 @@ int opp_disable(struct omap_opp *opp) return 0; } +void *opp_get_data(struct omap_opp *opp, char *name) +{ + void *data = ERR_PTR(-EINVAL); + struct omap_opp_data *tmp; + + if (unlikely(!opp || !name)) + return ERR_PTR(-EINVAL); + + list_for_each_entry(tmp, &opp->data_list, list) + if (!strcmp(name, tmp->name)) { + data = tmp->data; + break; + } + return data; +} + +int opp_store_data(struct omap_opp *opp, char *name, void *data) +{ + struct omap_opp_data *new; + if (unlikely(!opp || !name)) + return -EINVAL; + /* NAK to double registration */ + if (unlikely(!IS_ERR(opp_get_data(opp, name)))) + return -EINVAL; + + new = kmalloc(sizeof(struct omap_opp), GFP_KERNEL); + if (!new) + return -ENOMEM; + new->name = kmalloc(strlen(name) + 1, GFP_KERNEL); + if (!new->name) { + kfree(new); + return -ENOMEM; + } + new->data = data; + strcpy(new->name, name); + INIT_LIST_HEAD(&new->list); + list_add(&new->list, &opp->data_list); + return 0; +} + +int opp_remove_data(struct omap_opp *opp, char *name) +{ + struct omap_opp_data *tmp; + + if (unlikely(!opp || !name)) + return -EINVAL; + + list_for_each_entry(tmp, &opp->data_list, list) + if (!strcmp(name, tmp->name)) { + list_del(&tmp->list); + kfree(tmp->name); + kfree(tmp); + return 0; + } + return -EINVAL; +} + /* XXX document */ void opp_init_cpufreq_table(enum opp_t opp_type, struct cpufreq_frequency_table **table)