From: Dave Gerlach <d-gerlach@ti.com>
To: linux-arm-kernel@lists.infradead.org, linux-omap@vger.kernel.org,
linux-pm@vger.kernel.org
Cc: cpufreq@vger.kernel.org, devicetree@vger.kernel.org,
kernel@pengutronix.de, "Rafael J. Wysocki" <rjw@rjwysocki.net>,
Jisheng Zhang <jszhang@marvell.com>,
Anson Huang <Anson.Huang@freescale.com>,
Shawn Guo <shawn.guo@linaro.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
Nishanth Menon <nm@ti.com>, Dave Gerlach <d-gerlach@ti.com>
Subject: [RFC 1/9] opp-modifier: Introduce OPP Modifier Framework
Date: Fri, 14 Mar 2014 14:25:27 -0500 [thread overview]
Message-ID: <1394825135-60110-2-git-send-email-d-gerlach@ti.com> (raw)
In-Reply-To: <1394825135-60110-1-git-send-email-d-gerlach@ti.com>
Introduce framework to allow an OPP modifier driver to selectively
determine which possible OPPs for an SoC are available based on
register values found in SoC through a common API.
Three functions are exported, a register and unregister function for
the opp modifier drivers to notify the API of their existence, and
opp_modify_dev_table which looks up the appropriate driver and
DT information to use for a device and then uses enable/disable to
change which previously loaded OPPs are available on the device.
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
drivers/power/Makefile | 2 +
drivers/power/opp/Makefile | 1 +
drivers/power/opp/core.c | 126 +++++++++++++++++++++++++++++++++++++++++++
include/linux/opp-modifier.h | 35 ++++++++++++
4 files changed, 164 insertions(+)
create mode 100644 drivers/power/opp/Makefile
create mode 100644 drivers/power/opp/core.c
create mode 100644 include/linux/opp-modifier.h
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index ee54a3e..ed379cf 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -58,3 +58,5 @@ obj-$(CONFIG_POWER_AVS) += avs/
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
obj-$(CONFIG_POWER_RESET) += reset/
+
+obj-y += opp/
diff --git a/drivers/power/opp/Makefile b/drivers/power/opp/Makefile
new file mode 100644
index 0000000..820eb10
--- /dev/null
+++ b/drivers/power/opp/Makefile
@@ -0,0 +1 @@
+obj-y += core.o
diff --git a/drivers/power/opp/core.c b/drivers/power/opp/core.c
new file mode 100644
index 0000000..403013b
--- /dev/null
+++ b/drivers/power/opp/core.c
@@ -0,0 +1,126 @@
+/*
+ * OPP Modifier framework
+ *
+ * Copyright (C) 2013 Texas Instruments Inc.
+ * Dave Gerlach <d-gerlach@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/opp-modifier.h>
+
+static DEFINE_MUTEX(opp_modifier_list_mutex);
+static LIST_HEAD(opp_modifier_list);
+
+static int opp_modify_dev_opp_table(struct opp_modifier_dev *opp_dev,
+ struct device *dev)
+{
+ if (opp_dev->ops->modify)
+ return opp_dev->ops->modify(dev);
+
+ return -EINVAL;
+}
+
+static struct opp_modifier_dev *opp_modifier_get(struct device *dev)
+{
+ struct opp_modifier_dev *o, *opp_dev;
+ struct device_node *np;
+
+ if (!dev)
+ return ERR_PTR(-EINVAL);
+
+ np = of_parse_phandle(dev->of_node, "platform-opp-modifier", 0);
+
+ if (!np)
+ return ERR_PTR(-ENOSYS);
+
+ opp_dev = NULL;
+
+ mutex_lock(&opp_modifier_list_mutex);
+
+ list_for_each_entry(o, &opp_modifier_list, list) {
+ if (of_get_parent(np) == o->of_node) {
+ opp_dev = o;
+ break;
+ }
+ }
+
+ if (!opp_dev) {
+ mutex_unlock(&opp_modifier_list_mutex);
+ return ERR_PTR(-EINVAL);
+ }
+
+ of_node_put(np);
+
+ try_module_get(opp_dev->owner);
+ mutex_unlock(&opp_modifier_list_mutex);
+
+ return opp_dev;
+}
+
+static void opp_modifier_put(struct opp_modifier_dev *opp_dev)
+{
+ if (IS_ERR(opp_dev))
+ return;
+
+ module_put(opp_dev->owner);
+}
+
+int opp_modifier_register(struct opp_modifier_dev *opp_dev)
+{
+ mutex_lock(&opp_modifier_list_mutex);
+ list_add(&opp_dev->list, &opp_modifier_list);
+ mutex_unlock(&opp_modifier_list_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(opp_modifier_register);
+
+void opp_modifier_unregister(struct opp_modifier_dev *opp_dev)
+{
+ mutex_lock(&opp_modifier_list_mutex);
+ list_del(&opp_dev->list);
+ mutex_unlock(&opp_modifier_list_mutex);
+}
+EXPORT_SYMBOL_GPL(opp_modifier_unregister);
+
+int opp_modify_dev_table(struct device *dev)
+{
+ struct opp_modifier_dev *opp_dev;
+ int ret;
+
+ opp_dev = opp_modifier_get(dev);
+
+ /*
+ * It is a valid case for a device to not implement
+ * an OPP modifier table so return 0 if not present
+ */
+
+ if (IS_ERR(opp_dev) && PTR_ERR(opp_dev) == -ENOSYS) {
+ dev_dbg(dev, "No platform-opp-modifier entry present\n");
+ return 0;
+ } else if (IS_ERR(opp_dev)) {
+ return PTR_ERR(opp_dev);
+ }
+
+ ret = opp_modify_dev_opp_table(opp_dev, dev);
+
+ opp_modifier_put(opp_dev);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(opp_modify_dev_table);
diff --git a/include/linux/opp-modifier.h b/include/linux/opp-modifier.h
new file mode 100644
index 0000000..8d50851
--- /dev/null
+++ b/include/linux/opp-modifier.h
@@ -0,0 +1,35 @@
+/*
+ * TI OPP Modifier Core API
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Dave Gerlach <d-gerlach@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_OPP_MODIFIER_H__
+#define __LINUX_OPP_MODIFIER_H__
+
+struct opp_modifier_dev {
+ struct opp_modifier_ops *ops;
+ struct module *owner;
+ struct list_head list;
+ struct device_node *of_node;
+};
+
+struct opp_modifier_ops {
+ int (*modify)(struct device *dev);
+};
+
+int opp_modifier_register(struct opp_modifier_dev *opp_dev);
+void opp_modifier_unregister(struct opp_modifier_dev *opp_dev);
+int opp_modify_dev_table(struct device *dev);
+
+#endif /* __LINUX_OPP_MODIFIER_H__ */
--
1.9.0
next prev parent reply other threads:[~2014-03-14 19:25 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-14 19:25 [RFC 0/9] Introduce OPP modifier for ARM SoCs Dave Gerlach
2014-03-14 19:25 ` Dave Gerlach [this message]
2014-03-14 19:25 ` [RFC 2/9] opp-modifier: Add opp-modifier-reg driver Dave Gerlach
2014-03-14 21:00 ` Rob Herring
2014-03-17 14:30 ` Nishanth Menon
2014-03-17 18:37 ` Rob Herring
2014-03-18 15:36 ` Nishanth Menon
2014-03-25 3:24 ` Dave Gerlach
2014-03-14 19:25 ` [RFC 3/9] PM / OPP: Add hook to modify OPPs after they are loaded Dave Gerlach
2014-03-14 19:25 ` [RFC 4/9] ARM: dts: AM33XX: Add opp-modifier device entry and add higher OPPs Dave Gerlach
2014-03-14 19:25 ` [RFC 5/9] ARM: dts: AM4372: " Dave Gerlach
2014-03-14 19:25 ` [RFC 6/9] ARM: dts: omap443x: Add opp-modifier " Dave Gerlach
2014-03-14 19:25 ` [RFC 7/9] ARM: dts: omap4460: " Dave Gerlach
2014-03-14 19:25 ` [RFC 8/9] ARM: dts: dra7: Add opp-modifier device " Dave Gerlach
2014-03-14 19:25 ` [RFC 9/9] ARM: dts: imx6q: Add opp-modifier device entry Dave Gerlach
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1394825135-60110-2-git-send-email-d-gerlach@ti.com \
--to=d-gerlach@ti.com \
--cc=Anson.Huang@freescale.com \
--cc=cpufreq@vger.kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jszhang@marvell.com \
--cc=kernel@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-omap@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=nm@ti.com \
--cc=rjw@rjwysocki.net \
--cc=shawn.guo@linaro.org \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).