linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Lechner <david@lechnology.com>
To: linux-arm-kernel@lists.infradead.org
Cc: David Lechner <david@lechnology.com>,
	Sekhar Nori <nsekhar@ti.com>, Kevin Hilman <khilman@kernel.org>,
	Lee Jones <lee.jones@linaro.org>, Arnd Bergmann <arnd@arndb.de>,
	Kishon Vijay Abraham I <kishon@ti.com>,
	Adam Ford <aford173@gmail.com>,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH 1/6] mfd: syscon: Add syscon_register() function
Date: Fri, 19 Jan 2018 21:20:19 -0600	[thread overview]
Message-ID: <1516418424-28686-2-git-send-email-david@lechnology.com> (raw)
In-Reply-To: <1516418424-28686-1-git-send-email-david@lechnology.com>

This adds a new syscon_register() function that creates a new syscon
regmap and adds it to the lookup list.

This function serves two purposes:

1. This is needed for platforms without device tree support where the
   syscon regmap is needed in early boot (e.g. clocks), because using a
   platform driver at this point in boot is not an option.

2. It allows other drivers to use syscon_regmap_lookup_by_compatible()
   for both device tree and non-DT platforms instead of having to have
   a separate case that calls syscon_regmap_lookup_by_pdevname().

Signed-off-by: David Lechner <david@lechnology.com>
---
 drivers/mfd/syscon.c       | 71 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/syscon.h |  9 ++++++
 2 files changed, 80 insertions(+)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index b93fe4c..ab086b1 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -25,6 +25,8 @@
 #include <linux/mfd/syscon.h>
 #include <linux/slab.h>
 
+#define SYSCON_COMPATIBLE_SIZE 50
+
 static struct platform_driver syscon_driver;
 
 static DEFINE_SPINLOCK(syscon_list_slock);
@@ -34,6 +36,7 @@ struct syscon {
 	struct device_node *np;
 	struct regmap *regmap;
 	struct list_head list;
+	char compatible[SYSCON_COMPATIBLE_SIZE];
 };
 
 static const struct regmap_config syscon_regmap_config = {
@@ -140,9 +143,27 @@ EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
 
 struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
 {
+	struct syscon *entry, *syscon = NULL;
 	struct device_node *syscon_np;
 	struct regmap *regmap;
 
+	spin_lock(&syscon_list_slock);
+
+	/* Check for entries registered with syscon_register() */
+	list_for_each_entry(entry, &syscon_list, list) {
+		if (!entry->compatible)
+			continue;
+		if (!strncmp(entry->compatible, s, SYSCON_COMPATIBLE_SIZE)) {
+			syscon = entry;
+			break;
+		}
+	}
+
+	spin_unlock(&syscon_list_slock);
+
+	if (syscon)
+		return syscon->regmap;
+
 	syscon_np = of_find_compatible_node(NULL, NULL, s);
 	if (!syscon_np)
 		return ERR_PTR(-ENODEV);
@@ -196,6 +217,56 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle);
 
+/**
+ * syscon_register - Register a new syscon regmap
+ * @start: The starting memory address of the regmap
+ * @size: The size of the regmap in bytes
+ * @compatible: Compatible string used for lookup
+ *
+ * Returns: Pointer to a regmap or a negative error code.
+ */
+struct regmap *syscon_register(resource_size_t start, size_t size,
+			       const char *compatible)
+{
+	struct regmap_config syscon_config = syscon_regmap_config;
+	struct syscon *syscon;
+	void __iomem *base;
+	int err;
+
+	syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
+	if (!syscon)
+		return ERR_PTR(-ENOMEM);
+
+	base = ioremap(start, size);
+	if (!base) {
+		err = -ENOMEM;
+		goto err_free_syscon;
+	}
+
+	strncpy(syscon->compatible, compatible, SYSCON_COMPATIBLE_SIZE);
+
+	syscon_config.max_register = size - 1;
+	syscon->regmap = regmap_init_mmio(NULL, base, &syscon_config);
+	if (IS_ERR(syscon->regmap)) {
+		err = PTR_ERR(syscon->regmap);
+		goto err_iounmap;
+	}
+
+	spin_lock(&syscon_list_slock);
+	list_add_tail(&syscon->list, &syscon_list);
+	spin_unlock(&syscon_list_slock);
+
+	return syscon->regmap;
+
+err_iounmap:
+	iounmap(base);
+err_free_syscon:
+	kfree(syscon);
+
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(syscon_register);
+
 static int syscon_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
index 40a76b9..ce531b4 100644
--- a/include/linux/mfd/syscon.h
+++ b/include/linux/mfd/syscon.h
@@ -27,6 +27,8 @@ extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s);
 extern struct regmap *syscon_regmap_lookup_by_phandle(
 					struct device_node *np,
 					const char *property);
+extern struct regmap *syscon_register(resource_size_t start, size_t size,
+				      const char *compatible);
 #else
 static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
 {
@@ -49,6 +51,13 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle(
 {
 	return ERR_PTR(-ENOTSUPP);
 }
+
+static inline struct regmap *syscon_register(resource_size_t start,
+					     size_t size,
+					     const char *id)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
 #endif
 
 #endif /* __LINUX_MFD_SYSCON_H__ */
-- 
2.7.4

  reply	other threads:[~2018-01-20  3:21 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-20  3:20 [PATCH 0/6] ARM: davinci: common clock prep work David Lechner
2018-01-20  3:20 ` David Lechner [this message]
2018-01-22 10:53   ` [PATCH 1/6] mfd: syscon: Add syscon_register() function Sekhar Nori
2018-01-22 11:08     ` Arnd Bergmann
2018-01-22 11:39       ` Sekhar Nori
2018-01-22 16:47         ` David Lechner
2018-01-20  3:20 ` [PATCH 2/6] phy: da8xx-usb: Always check for syscon compatible David Lechner
2018-01-20  3:20 ` [PATCH 3/6] phy: da8xx-usb: rename clock con_ids David Lechner
2018-01-20  3:20 ` [PATCH 4/6] ARM: davinci: move davinci_clk_init() to init_time David Lechner
2018-01-23 12:02   ` Sekhar Nori
2018-01-20  3:20 ` [PATCH 5/6] ARM: da8xx: Move CFGCHIP registration " David Lechner
2018-01-20  3:20 ` [PATCH 6/6] phy: da8xx-usb: drop use of syscon_regmap_lookup_by_pdevname() David Lechner
2018-01-22 11:13 ` [PATCH 0/6] ARM: davinci: common clock prep work Sekhar Nori
2018-01-23 23:40   ` David Lechner

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=1516418424-28686-2-git-send-email-david@lechnology.com \
    --to=david@lechnology.com \
    --cc=aford173@gmail.com \
    --cc=arnd@arndb.de \
    --cc=bgolaszewski@baylibre.com \
    --cc=khilman@kernel.org \
    --cc=kishon@ti.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nsekhar@ti.com \
    /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).