All of lore.kernel.org
 help / color / mirror / Atom feed
From: monstr@monstr.eu (Michal Simek)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 2/3] mfd: syscon: Support early initialization
Date: Mon, 10 Feb 2014 16:42:06 +0100	[thread overview]
Message-ID: <52F8F34E.3030606@monstr.eu> (raw)
In-Reply-To: <1785585d090175da81b561b17eeef95d991ff0de.1392045742.git.michal.simek@xilinx.com>

On 02/10/2014 04:22 PM, Michal Simek wrote:
> Some platforms need to get system controller
> ready as soon as possible.
> The patch provides early_syscon_initialization
> which create early mapping for all syscon compatible
> devices in early_syscon_probe.
> Regmap is get via syscon_early_regmap_lookup_by_phandle()
> 
> Regular device probes attach device to regmap
> via regmap_attach_dev().
> 
> For early syscon initialization is necessary to extend
> struct syscon and provide remove function
> which unmap all early init structures.
> 
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/mfd/syscon.c       | 126 +++++++++++++++++++++++++++++++++++++++------
>  include/linux/mfd/syscon.h |  11 ++++
>  2 files changed, 120 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index 71841f9..5935f02 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -20,12 +20,15 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
> +#include <linux/slab.h>
>  #include <linux/mfd/syscon.h>
> 
>  static struct platform_driver syscon_driver;
> 
>  struct syscon {
> +	void __iomem *base;
>  	struct regmap *regmap;
> +	struct resource res;
>  };
> 
>  static int syscon_match_node(struct device *dev, void *data)
> @@ -95,6 +98,24 @@ struct regmap *syscon_regmap_lookup_by_pdevname(const char *s)
>  }
>  EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_pdevname);
> 
> +struct regmap *syscon_early_regmap_lookup_by_phandle(struct device_node *np,
> +						     const char *property)
> +{
> +	struct device_node *syscon_np;
> +	struct syscon *syscon;
> +
> +	syscon_np = of_parse_phandle(np, property, 0);
> +	if (!syscon_np)
> +		return ERR_PTR(-ENODEV);
> +
> +	syscon = syscon_np->data;
> +
> +	of_node_put(syscon_np);
> +
> +	return syscon->regmap;
> +}
> +EXPORT_SYMBOL_GPL(syscon_early_regmap_lookup_by_phandle);
> +
>  struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
>  					const char *property)
>  {
> @@ -128,40 +149,110 @@ static int syscon_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct syscon *syscon;
>  	struct resource *res;
> -	void __iomem *base;
> 
> -	syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
> +	/* Early syscon init */
> +	if (pdev->dev.of_node && pdev->dev.of_node->data) {
> +		syscon = pdev->dev.of_node->data;
> +		res = &syscon->res;
> +		regmap_attach_dev(dev, syscon->regmap, &syscon_regmap_config);
> +	} else {
> +
> +		syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
> +		if (!syscon)
> +			return -ENOMEM;
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +		if (!res)
> +			return -ENOENT;
> +
> +		syscon->base = devm_ioremap(dev, res->start,
> +					    resource_size(res));
> +		if (!syscon->base)
> +			return -ENOMEM;
> +
> +		syscon_regmap_config.max_register = res->end - res->start - 3;
> +		syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
> +						&syscon_regmap_config);
> +		if (IS_ERR(syscon->regmap)) {
> +			dev_err(dev, "regmap init failed\n");
> +			return PTR_ERR(syscon->regmap);
> +		}
> +	}
> +
> +	platform_set_drvdata(pdev, syscon);
> +
> +	dev_info(dev, "regmap %pR registered\n", res);
> +
> +	return 0;
> +}
> +
> +static const struct platform_device_id syscon_ids[] = {
> +	{ "syscon", },
> +	{ }
> +};
> +
> +static int syscon_remove(struct platform_device *pdev)
> +{
> +	struct syscon *syscon = platform_get_drvdata(pdev);
> +
> +	if (pdev->dev.of_node && pdev->dev.of_node->data) {
> +		iounmap(syscon->base);
> +		kfree(syscon);
> +	}
> +
> +	return 0;
> +}
> +
> +static int early_syscon_probe(struct device_node *np)
> +{
> +	struct syscon *syscon;
> +
> +	syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
>  	if (!syscon)
>  		return -ENOMEM;
> 
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (!res)
> -		return -ENOENT;
> +	if (of_address_to_resource(np, 0, &syscon->res))
> +		return -EINVAL;
> 
> -	base = devm_ioremap(dev, res->start, resource_size(res));
> -	if (!base)
> -		return -ENOMEM;
> +	syscon->base = ioremap(syscon->res.start, resource_size(&syscon->res));
> +	if (!syscon->base) {
> +		pr_err("%s: Unable to map I/O memory\n", __func__);
> +		return PTR_ERR(syscon->base);
> +	}
> 
> -	syscon_regmap_config.max_register = res->end - res->start - 3;
> -	syscon->regmap = devm_regmap_init_mmio(dev, base,
> -					&syscon_regmap_config);
> +	syscon_regmap_config.max_register = syscon->res.end -
> +					    syscon->res.start - 3;
> +	syscon->regmap = regmap_init_mmio(NULL, syscon->base,
> +					  &syscon_regmap_config);
>  	if (IS_ERR(syscon->regmap)) {
> -		dev_err(dev, "regmap init failed\n");
> +		pr_err("regmap init failed\n");
>  		return PTR_ERR(syscon->regmap);
>  	}
> 
> -	platform_set_drvdata(pdev, syscon);
> +	np->data = syscon;
> 
> -	dev_info(dev, "regmap %pR registered\n", res);
> +	of_node_put(np);
> +
> +	pr_info("%s: regmap %pR registered\n", np->full_name, &syscon->res);
> 
>  	return 0;
>  }
> 
> -static const struct platform_device_id syscon_ids[] = {
> -	{ "syscon", },
> -	{ }
> +static struct of_device_id of_syscon_ids[] = {
> +	{ .compatible = "syscon" },
> +	{},
>  };
> 
> +void __init early_syscon_init(void)
> +{
> +	struct device_node *np;
> +
> +	for_each_matching_node_and_match(np, of_syscon_ids, NULL) {
> +		if (!early_syscon_probe(np))

just
if (early_syscon_probe(np))
	BUG();
here.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140210/2a67d56a/attachment-0001.sig>

WARNING: multiple messages have this Message-ID (diff)
From: Michal Simek <monstr@monstr.eu>
To: Michal Simek <michal.simek@xilinx.com>
Cc: linux-arm-kernel@lists.infradead.org,
	Arnd Bergmann <arnd@arndb.de>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Lee Jones <lee.jones@linaro.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 2/3] mfd: syscon: Support early initialization
Date: Mon, 10 Feb 2014 16:42:06 +0100	[thread overview]
Message-ID: <52F8F34E.3030606@monstr.eu> (raw)
In-Reply-To: <1785585d090175da81b561b17eeef95d991ff0de.1392045742.git.michal.simek@xilinx.com>

[-- Attachment #1: Type: text/plain, Size: 5982 bytes --]

On 02/10/2014 04:22 PM, Michal Simek wrote:
> Some platforms need to get system controller
> ready as soon as possible.
> The patch provides early_syscon_initialization
> which create early mapping for all syscon compatible
> devices in early_syscon_probe.
> Regmap is get via syscon_early_regmap_lookup_by_phandle()
> 
> Regular device probes attach device to regmap
> via regmap_attach_dev().
> 
> For early syscon initialization is necessary to extend
> struct syscon and provide remove function
> which unmap all early init structures.
> 
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/mfd/syscon.c       | 126 +++++++++++++++++++++++++++++++++++++++------
>  include/linux/mfd/syscon.h |  11 ++++
>  2 files changed, 120 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index 71841f9..5935f02 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -20,12 +20,15 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
> +#include <linux/slab.h>
>  #include <linux/mfd/syscon.h>
> 
>  static struct platform_driver syscon_driver;
> 
>  struct syscon {
> +	void __iomem *base;
>  	struct regmap *regmap;
> +	struct resource res;
>  };
> 
>  static int syscon_match_node(struct device *dev, void *data)
> @@ -95,6 +98,24 @@ struct regmap *syscon_regmap_lookup_by_pdevname(const char *s)
>  }
>  EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_pdevname);
> 
> +struct regmap *syscon_early_regmap_lookup_by_phandle(struct device_node *np,
> +						     const char *property)
> +{
> +	struct device_node *syscon_np;
> +	struct syscon *syscon;
> +
> +	syscon_np = of_parse_phandle(np, property, 0);
> +	if (!syscon_np)
> +		return ERR_PTR(-ENODEV);
> +
> +	syscon = syscon_np->data;
> +
> +	of_node_put(syscon_np);
> +
> +	return syscon->regmap;
> +}
> +EXPORT_SYMBOL_GPL(syscon_early_regmap_lookup_by_phandle);
> +
>  struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
>  					const char *property)
>  {
> @@ -128,40 +149,110 @@ static int syscon_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct syscon *syscon;
>  	struct resource *res;
> -	void __iomem *base;
> 
> -	syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
> +	/* Early syscon init */
> +	if (pdev->dev.of_node && pdev->dev.of_node->data) {
> +		syscon = pdev->dev.of_node->data;
> +		res = &syscon->res;
> +		regmap_attach_dev(dev, syscon->regmap, &syscon_regmap_config);
> +	} else {
> +
> +		syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
> +		if (!syscon)
> +			return -ENOMEM;
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +		if (!res)
> +			return -ENOENT;
> +
> +		syscon->base = devm_ioremap(dev, res->start,
> +					    resource_size(res));
> +		if (!syscon->base)
> +			return -ENOMEM;
> +
> +		syscon_regmap_config.max_register = res->end - res->start - 3;
> +		syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
> +						&syscon_regmap_config);
> +		if (IS_ERR(syscon->regmap)) {
> +			dev_err(dev, "regmap init failed\n");
> +			return PTR_ERR(syscon->regmap);
> +		}
> +	}
> +
> +	platform_set_drvdata(pdev, syscon);
> +
> +	dev_info(dev, "regmap %pR registered\n", res);
> +
> +	return 0;
> +}
> +
> +static const struct platform_device_id syscon_ids[] = {
> +	{ "syscon", },
> +	{ }
> +};
> +
> +static int syscon_remove(struct platform_device *pdev)
> +{
> +	struct syscon *syscon = platform_get_drvdata(pdev);
> +
> +	if (pdev->dev.of_node && pdev->dev.of_node->data) {
> +		iounmap(syscon->base);
> +		kfree(syscon);
> +	}
> +
> +	return 0;
> +}
> +
> +static int early_syscon_probe(struct device_node *np)
> +{
> +	struct syscon *syscon;
> +
> +	syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
>  	if (!syscon)
>  		return -ENOMEM;
> 
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (!res)
> -		return -ENOENT;
> +	if (of_address_to_resource(np, 0, &syscon->res))
> +		return -EINVAL;
> 
> -	base = devm_ioremap(dev, res->start, resource_size(res));
> -	if (!base)
> -		return -ENOMEM;
> +	syscon->base = ioremap(syscon->res.start, resource_size(&syscon->res));
> +	if (!syscon->base) {
> +		pr_err("%s: Unable to map I/O memory\n", __func__);
> +		return PTR_ERR(syscon->base);
> +	}
> 
> -	syscon_regmap_config.max_register = res->end - res->start - 3;
> -	syscon->regmap = devm_regmap_init_mmio(dev, base,
> -					&syscon_regmap_config);
> +	syscon_regmap_config.max_register = syscon->res.end -
> +					    syscon->res.start - 3;
> +	syscon->regmap = regmap_init_mmio(NULL, syscon->base,
> +					  &syscon_regmap_config);
>  	if (IS_ERR(syscon->regmap)) {
> -		dev_err(dev, "regmap init failed\n");
> +		pr_err("regmap init failed\n");
>  		return PTR_ERR(syscon->regmap);
>  	}
> 
> -	platform_set_drvdata(pdev, syscon);
> +	np->data = syscon;
> 
> -	dev_info(dev, "regmap %pR registered\n", res);
> +	of_node_put(np);
> +
> +	pr_info("%s: regmap %pR registered\n", np->full_name, &syscon->res);
> 
>  	return 0;
>  }
> 
> -static const struct platform_device_id syscon_ids[] = {
> -	{ "syscon", },
> -	{ }
> +static struct of_device_id of_syscon_ids[] = {
> +	{ .compatible = "syscon" },
> +	{},
>  };
> 
> +void __init early_syscon_init(void)
> +{
> +	struct device_node *np;
> +
> +	for_each_matching_node_and_match(np, of_syscon_ids, NULL) {
> +		if (!early_syscon_probe(np))

just
if (early_syscon_probe(np))
	BUG();
here.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

  reply	other threads:[~2014-02-10 15:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-10 15:22 [RFC PATCH 0/3] Syscon early initialization Michal Simek
2014-02-10 15:22 ` Michal Simek
2014-02-10 15:22 ` Michal Simek
2014-02-10 15:22 ` [RFC PATCH 1/3] regmap: Separate regmap dev initialization Michal Simek
2014-02-10 15:22   ` Michal Simek
2014-02-16  1:58   ` Mark Brown
2014-02-16  1:58     ` Mark Brown
2014-02-10 15:22 ` [RFC PATCH 2/3] mfd: syscon: Support early initialization Michal Simek
2014-02-10 15:22   ` Michal Simek
2014-02-10 15:42   ` Michal Simek [this message]
2014-02-10 15:42     ` Michal Simek
2014-02-12  9:54   ` Lee Jones
2014-02-12  9:54     ` Lee Jones
2014-02-12 10:51     ` Michal Simek
2014-02-12 10:51       ` Michal Simek
2014-02-10 15:22 ` [RFC PATCH 3/3] ARM: zynq: Use early syscon initialization Michal Simek
2014-02-10 15:22   ` Michal Simek
2014-02-10 15:22   ` Michal Simek

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=52F8F34E.3030606@monstr.eu \
    --to=monstr@monstr.eu \
    --cc=linux-arm-kernel@lists.infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.