devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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).