From: Pankaj Dubey <pankaj.dubey@samsung.com>
To: linux-arm-kernel@lists.infradead.org,
linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: kgene.kim@samsung.com, linux@arm.linux.org.uk, arnd@arndb.de,
vikas.sajjan@samsung.com, joshi@samsung.com, naushad@samsung.com,
thomas.ab@samsung.com, chow.kim@samsung.com,
"'Tomasz Figa'" <t.figa@samsung.com>,
Lee Jones <lee.jones@linaro.org>,
Tomasz Figa <tomasz.figa@gmail.com>
Subject: RE: [PATCH] mfd: syscon: Decouple syscon interface from syscon devices
Date: Mon, 01 Sep 2014 09:58:55 +0530 [thread overview]
Message-ID: <000501cfc59d$5c717330$15545990$@samsung.com> (raw)
In-Reply-To: <1408694991-21615-1-git-send-email-pankaj.dubey@samsung.com>
Sorry I forgot to add maintainer into CC.
+Lee Jones
Any comments on this patch.
As a lot of Exynos PMU patch sets are dependent on this patch.
Thanks,
Pankaj Dubey
> -----Original Message-----
> From: Pankaj Dubey [mailto:pankaj.dubey@samsung.com]
> Sent: Friday, August 22, 2014 1:40 PM
> To: linux-arm-kernel@lists.infradead.org;
linux-samsung-soc@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Cc: kgene.kim@samsung.com; linux@arm.linux.org.uk; arnd@arndb.de;
> vikas.sajjan@samsung.com; joshi@samsung.com; naushad@samsung.com;
> thomas.ab@samsung.com; chow.kim@samsung.com; Tomasz Figa; Pankaj Dubey
> Subject: [PATCH] mfd: syscon: Decouple syscon interface from syscon
devices
>
> From: Tomasz Figa <t.figa@samsung.com>
>
> Currently a syscon entity can be only registered directly through a
platform device
> that binds to a dedicated driver. However in certain use cases it is
desirable to make a
> device used with another driver a syscon interface provider. For example,
certain
> SoCs (e.g. Exynos) contain system controller blocks which perform various
functions
> such as power domain control, CPU power management, low power mode
control,
> but in addition contain certain IP integration glue, such as various
signal masks,
> coprocessor power control, etc. In such case, there is a need to have a
dedicated
> driver for such system controller but also share registers with other
drivers. The latter
> is where the syscon interface is helpful.
>
> This patch decouples syscon object from syscon driver, so that it can be
registered
> from any driver in addition to the original "syscon" platform driver.
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>
> RFC patch [1] was posted by Tomasz Figa. This patch addresses some of
comments
> given by Arnd to RFC patch, and further decouples syscon from device
model. It also
> gives flexibility of registering with syscon at early stage using
device_node object.
>
> [1]: https://lkml.org/lkml/2014/6/17/331
>
> drivers/mfd/syscon.c | 112 ++++++++++++++++++++++++++++----
> ------------
> include/linux/mfd/syscon.h | 14 ++++++
> 2 files changed, 86 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index
ca15878..a91db30
> 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -14,6 +14,7 @@
>
> #include <linux/err.h>
> #include <linux/io.h>
> +#include <linux/list.h>
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_address.h>
> @@ -22,33 +23,32 @@
> #include <linux/platform_device.h>
> #include <linux/regmap.h>
> #include <linux/mfd/syscon.h>
> +#include <linux/slab.h>
>
> -static struct platform_driver syscon_driver;
> +static DEFINE_SPINLOCK(syscon_list_slock);
> +static LIST_HEAD(syscon_list);
>
> struct syscon {
> + struct device_node *np;
> struct regmap *regmap;
> + struct list_head list;
> };
>
> -static int syscon_match_node(struct device *dev, void *data) -{
> - struct device_node *dn = data;
> -
> - return (dev->of_node == dn) ? 1 : 0;
> -}
> -
> struct regmap *syscon_node_to_regmap(struct device_node *np) {
> - struct syscon *syscon;
> - struct device *dev;
> + struct syscon *entry, *syscon = NULL;
>
> - dev = driver_find_device(&syscon_driver.driver, NULL, np,
> - syscon_match_node);
> - if (!dev)
> - return ERR_PTR(-EPROBE_DEFER);
> + spin_lock(&syscon_list_slock);
>
> - syscon = dev_get_drvdata(dev);
> + list_for_each_entry(entry, &syscon_list, list)
> + if (entry->np == np) {
> + syscon = entry;
> + break;
> + }
>
> - return syscon->regmap;
> + spin_unlock(&syscon_list_slock);
> +
> + return syscon ? syscon->regmap : ERR_PTR(-EPROBE_DEFER);
> }
> EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
>
> @@ -68,24 +68,22 @@ struct regmap
> *syscon_regmap_lookup_by_compatible(const char *s) }
> EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
>
> -static int syscon_match_pdevname(struct device *dev, void *data) -{
> - return !strcmp(dev_name(dev), (const char *)data);
> -}
> -
> struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) {
> - struct device *dev;
> - struct syscon *syscon;
> -
> - dev = driver_find_device(&syscon_driver.driver, NULL, (void *)s,
> - syscon_match_pdevname);
> - if (!dev)
> - return ERR_PTR(-EPROBE_DEFER);
> -
> - syscon = dev_get_drvdata(dev);
> + struct syscon *entry, *syscon = NULL;
> + struct platform_device *pdev = NULL;
> +
> + spin_lock(&syscon_list_slock);
> + list_for_each_entry(entry, &syscon_list, list) {
> + pdev = of_find_device_by_node(entry->np);
> + if (pdev && !strcmp(dev_name(&pdev->dev), s)) {
> + syscon = entry;
> + break;
> + }
> + }
> + spin_unlock(&syscon_list_slock);
>
> - return syscon->regmap;
> + return syscon ? syscon->regmap : ERR_PTR(-EPROBE_DEFER);
> }
> EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_pdevname);
>
> @@ -121,17 +119,49 @@ static struct regmap_config syscon_regmap_config = {
> .reg_stride = 4,
> };
>
> +void of_syscon_unregister(struct device_node *np) {
> + struct syscon *entry;
> +
> + spin_lock(&syscon_list_slock);
> +
> + list_for_each_entry(entry, &syscon_list, list)
> + if (entry->np == np) {
> + list_del(&entry->list);
> + break;
> + }
> +
> + spin_unlock(&syscon_list_slock);
> +}
> +EXPORT_SYMBOL_GPL(of_syscon_unregister);
> +
> +int of_syscon_register(struct device_node *np, struct regmap *regmap) {
> + struct syscon *syscon;
> +
> + syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
> + if (!syscon)
> + return -ENOMEM;
> +
> + syscon->regmap = regmap;
> + syscon->np = np;
> +
> + spin_lock(&syscon_list_slock);
> + list_add_tail(&syscon->list, &syscon_list);
> + spin_unlock(&syscon_list_slock);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_syscon_register);
> +
> static int syscon_probe(struct platform_device *pdev) {
> struct device *dev = &pdev->dev;
> struct syscon_platform_data *pdata = dev_get_platdata(dev);
> - struct syscon *syscon;
> + struct regmap *regmap;
> struct resource *res;
> void __iomem *base;
> -
> - syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
> - if (!syscon)
> - return -ENOMEM;
> + int ret;
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!res)
> @@ -144,14 +174,16 @@ static int syscon_probe(struct platform_device
*pdev)
> syscon_regmap_config.max_register = res->end - res->start - 3;
> if (pdata)
> syscon_regmap_config.name = pdata->label;
> - syscon->regmap = devm_regmap_init_mmio(dev, base,
> + regmap = devm_regmap_init_mmio(dev, base,
> &syscon_regmap_config);
> - if (IS_ERR(syscon->regmap)) {
> + if (IS_ERR(regmap)) {
> dev_err(dev, "regmap init failed\n");
> - return PTR_ERR(syscon->regmap);
> + return PTR_ERR(regmap);
> }
>
> - platform_set_drvdata(pdev, syscon);
> + ret = of_syscon_register(dev->of_node, regmap);
> + if (ret)
> + return ret;
>
> dev_dbg(dev, "regmap %pR registered\n", res);
>
> diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h index
> 75e543b..dc2807b 100644
> --- a/include/linux/mfd/syscon.h
> +++ b/include/linux/mfd/syscon.h
> @@ -18,8 +18,12 @@
> #include <linux/err.h>
>
> struct device_node;
> +struct regmap;
>
> #ifdef CONFIG_MFD_SYSCON
> +extern int of_syscon_register(struct device_node *np, struct regmap
> +*regmap); extern void of_syscon_unregister(struct device_node *np);
> +
> extern struct regmap *syscon_node_to_regmap(struct device_node *np);
extern
> struct regmap *syscon_regmap_lookup_by_compatible(const char *s); extern
struct
> regmap *syscon_regmap_lookup_by_pdevname(const char *s); @@ -27,6 +31,16
> @@ extern struct regmap *syscon_regmap_lookup_by_phandle(
> struct device_node *np,
> const char *property);
> #else
> +static inline int of_syscon_register(struct device_node *np,
> + struct regmap *regmap)
> +{
> + return -ENOSYS;
> +}
> +
> +static inline void of_syscon_unregister(struct device_node *np) { }
> +
> static inline struct regmap *syscon_node_to_regmap(struct device_node
*np) {
> return ERR_PTR(-ENOSYS);
> --
> 1.7.9.5
next prev parent reply other threads:[~2014-09-01 4:27 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-22 8:09 Pankaj Dubey
2014-09-01 4:28 ` Pankaj Dubey [this message]
2014-09-01 7:49 ` Lee Jones
2014-09-01 10:37 ` Arnd Bergmann
2014-09-01 11:25 ` Lee Jones
2014-09-01 14:24 ` Arnd Bergmann
2014-09-01 16:04 ` Lee Jones
2014-09-01 17:05 ` Arnd Bergmann
2014-09-02 8:05 ` Lee Jones
2014-09-02 8:14 ` Arnd Bergmann
2014-09-02 8:32 ` Pankaj Dubey
2014-09-02 8:34 ` Lee Jones
2014-09-01 11:35 ` Pankaj Dubey
2014-09-01 14:18 ` Arnd Bergmann
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='000501cfc59d$5c717330$15545990$@samsung.com' \
--to=pankaj.dubey@samsung.com \
--cc=arnd@arndb.de \
--cc=chow.kim@samsung.com \
--cc=joshi@samsung.com \
--cc=kgene.kim@samsung.com \
--cc=lee.jones@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=naushad@samsung.com \
--cc=t.figa@samsung.com \
--cc=thomas.ab@samsung.com \
--cc=tomasz.figa@gmail.com \
--cc=vikas.sajjan@samsung.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
Powered by JetHome