Syscon early initialization
Subsystems (9)
cover Syscon early initialization
Hi,
this series come from my discussion with Arnd at KS and then on some other threads/IRCs(Arnd and Mark) that SoC vendors are more and more try to add misc functionality to
one memory region. For this purpose syscon driver is in the kernel. But regular syscon driver is initialized too late
and platforms are trying to create specific code to handle it.
For this purpose the series have been created to provide early syscon initialization and regmap creation first and then attaching device.
The last patch is zynq specific patch to clear slcr driver and clock driver can profit from it too when clk regmap is ready.
Also moving syscon driver from mfs should be consider.
Thanks for your comments,
Michal
Michal Simek (3):
regmap: Separate regmap dev initialization
mfd: syscon: Support early initialization
ARM: zynq: Use early syscon initialization
arch/arm/boot/dts/zynq-7000.dtsi | 1 + arch/arm/mach-zynq/common.c | 6 +- arch/arm/mach-zynq/slcr.c | 42 +------------ drivers/base/regmap/regmap.c | 41 +++++++++---- drivers/clk/zynq/clkc.c | 57 ++++++------------ drivers/mfd/syscon.c | 126 +++++++++++++++++++++++++++++++++------ include/linux/mfd/syscon.h | 11 ++++ include/linux/regmap.h | 2 + 8 files changed, 173 insertions(+), 113 deletions(-)
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140210/69ed2e02/attachment.sig>
RFC PATCH 1/3 regmap: Separate regmap dev initialization
Create special function regmap_attach_dev which can be called separately out of regmap_init.
---
drivers/base/regmap/regmap.c | 41 ++++++++++++++++++++++++++++------------- include/linux/regmap.h | 2 ++ 2 files changed, 30 insertions(+), 13 deletions(-)
drivers/base/regmap/regmap.c +28 -13
@@ -380,6 +380,28 @@ static void regmap_range_exit(struct regmap *map)kfree (map->selector_work_buf); } +int regmap_attach_dev (struct device *dev,struct regmap *map, +const struct regmap_config *config) +{ +struct regmap **m; + + map->dev = dev; + +regmap_debugfs_init (map, config->name); + +/* Add a devres resource for dev_get_regmap() */ + m =devres_alloc (dev_get_regmap_release,sizeof (*m),GFP_KERNEL ); +if (!m) { +regmap_debugfs_exit (map); +return -ENOMEM ; + } + *m = map; +devres_add (dev, m); + +return 0 ; +} +EXPORT_SYMBOL_GPL (regmap_attach_dev); +/** * regmap_init(): Initialise register map *
@@ -397,7 +419,7 @@ struct regmap *regmap_init(struct device *dev,void *bus_context, const struct regmap_config *config) { - struct regmap *map, **m; + struct regmap *map;int ret = -EINVAL ;enum regmap_endian reg_endian, val_endian;int i, j;
@@ -734,25 +756,18 @@ skip_format_initialization: } } -regmap_debugfs_init (map, config->name); - ret =regcache_init (map, config);if (ret !=0 ) goto err_range; -/* Add a devres resource for dev_get_regmap() */ - m =devres_alloc (dev_get_regmap_release,sizeof (*m),GFP_KERNEL ); -if (!m) { - ret = -ENOMEM ; - goto err_debugfs; - } - *m = map; -devres_add (dev, m); +if (dev) + ret =regmap_attach_dev (dev, map, config); +if (ret !=0 ) + goto err_regcache;return map; -err_debugfs: -regmap_debugfs_exit (map); +err_regcache:regcache_exit (map); err_range:regmap_range_exit (map);
include/linux/regmap.h +2 -0
@@ -317,6 +317,8 @@ struct regmap *regmap_init(struct device *dev,const struct regmap_bus *bus, void *bus_context, const struct regmap_config *config); +int regmap_attach_dev (struct device *dev,struct regmap *map, +const struct regmap_config *config);struct regmap *regmap_init_i2c (struct i2c_client *i2c,const struct regmap_config *config); struct regmap *regmap_init_spi(struct spi_device *dev,
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140210/2f6b4e20/attachment.sig>
Re: [RFC PATCH 1/3] regmap: Separate regmap dev initialization
Quoted 2 lines · Michal Simek
Create special function
regmap_attach_devwhich can be called separately out ofregmap_init.
Applied, thanks. I've pushed a signed tag too so dependencies can pull this in:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git tags/nodev
When sending things like this that add new functionality it's often
helpful to send the patches adding users to review along with the core
patch since this helps to review if the usage is actually sane and
sensible. From a purely regmap point of view this seems OK but...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140216/0d9e2231/attachment.sig>
RFC PATCH 2/3 mfd: syscon: Support early initialization
In reply to Michal SimekSome 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.
---
drivers/mfd/syscon.c | 126 +++++++++++++++++++++++++++++++++++++++------ include/linux/mfd/syscon.h | 11 ++++ 2 files changed, 120 insertions(+), 17 deletions(-)
drivers/mfd/syscon.c +109 -17
@@ -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)) +BUG (); + } +} +static struct platform_driver syscon_driver = { .driver = { .name ="syscon" ,
@@ -169,6 +260,7 @@ static struct platform_driver syscon_driver = { .of_match_table = of_syscon_match, }, .probe = syscon_probe, + .remove = syscon_remove, .id_table = syscon_ids, };
include/linux/mfd/syscon.h +11 -0
@@ -24,6 +24,10 @@ 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_early_regmap_lookup_by_phandle ( +struct device_node *np, +const char *property); +extern void early_syscon_init (void );#else static inline struct regmap *syscon_node_to_regmap (struct device_node *np) {
@@ -46,6 +50,13 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle( {return ERR_PTR (-ENOSYS ); } + +static struct regmap *syscon_early_regmap_lookup_by_phandle ( +struct device_node *np, +const char *property) +{ +return ERR_PTR (-ENOSYS ); +}#endif #endif /* __LINUX_MFD_SYSCON_H__ */
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140210/b29e2420/attachment-0001.sig>
Re: [RFC PATCH 2/3] mfd: syscon: Support early initialization
Quoted 177 lines · Michal Simek
Some platforms need to get system controller ready as soon as possible.
The patch providesearly_syscon_initializationwhich create early mapping for all syscon compatible devices inearly_syscon_probe.
Regmap is get viasyscon_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 <[email protected]>---
drivers/mfd/syscon.c | 126 +++++++++++++++++++++++++++++++++++++++------ include/linux/mfd/syscon.h | 11 ++++ 2 files changed, 120 insertions(+), 17 deletions(-)drivers/mfd/syscon.c +96
-17@@ -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[] = {
drivers/mfd/syscon.c static int syscon_probe(struct platform_device *pdev) · line 251
Quoted 10 lines
drivers/mfd/syscon.c +8
-0+ { .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
Signature · 14 lines
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>
Re: [RFC PATCH 2/3] mfd: syscon: Support early initialization
In reply to Michal SimekQuoted 22 lines · Michal Simek
Some platforms need to get system controller ready as soon as possible.
The patch providesearly_syscon_initializationwhich create early mapping for all syscon compatible devices inearly_syscon_probe.
Regmap is get viasyscon_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 <[email protected]>---
drivers/mfd/syscon.c | 126 +++++++++++++++++++++++++++++++++++++++------ include/linux/mfd/syscon.h | 11 ++++ 2 files changed, 120 insertions(+), 17 deletions(-)drivers/mfd/syscon.c +0
-0
<snip>
Quoted 5 lines
struct regmap *syscon_regmap_lookup_by_phandle(struct
device_node*np,drivers/mfd/syscon.c +0
-0const char *property) {@@ -128,40 +149,110 @@ static int syscon_probe(struct platform_device *pdev)struct device *dev = &pdev->dev;
drivers/mfd/syscon.c static int syscon_probe(struct platform_device *pdev) · line 157
Quoted 10 lines
drivers/mfd/syscon.c +5
-2struct 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);
Instead of duplicating all of the init code with early and late versions of each, is there any reason why we can't always do the early stuff early and then connect it to the dev infrastructure when it becomes available?
Quoted 152 lines
drivers/mfd/syscon.c +82
-15+ }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)) +BUG (); + } +} +static struct platform_driver syscon_driver = { .driver = { .name ="syscon" ,@@ -169,6 +260,7 @@ static struct platform_driver syscon_driver = { .of_match_table = of_syscon_match, }, .probe = syscon_probe, + .remove = syscon_remove, .id_table = syscon_ids, };include/linux/mfd/syscon.h +11
-0@@ -24,6 +24,10 @@ 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_early_regmap_lookup_by_phandle ( +struct device_node *np, +const char *property); +extern void early_syscon_init (void );#else static inline struct regmap *syscon_node_to_regmap (struct device_node *np) {@@ -46,6 +50,13 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle( {return ERR_PTR (-ENOSYS ); } + +static struct regmap *syscon_early_regmap_lookup_by_phandle ( +struct device_node *np, +const char *property) +{ +return ERR_PTR (-ENOSYS ); +}#endif #endif /* __LINUX_MFD_SYSCON_H__ */
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [RFC PATCH 2/3] mfd: syscon: Support early initialization
Quoted 36 lines · Lee Jones
Quoted 22 lines · Michal Simek
Some platforms need to get system controller ready as soon as possible.
The patch providesearly_syscon_initializationwhich create early mapping for all syscon compatible devices inearly_syscon_probe.
Regmap is get viasyscon_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 <[email protected]>---
drivers/mfd/syscon.c | 126 +++++++++++++++++++++++++++++++++++++++------ include/linux/mfd/syscon.h | 11 ++++ 2 files changed, 120 insertions(+), 17 deletions(-)drivers/mfd/syscon.c +0
-0<snip>
Quoted 9 lines
struct regmap *syscon_regmap_lookup_by_phandle(struct
device_node*np,drivers/mfd/syscon.c +0
-1const 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;
Quoted 11 lines
drivers/mfd/syscon.c static int syscon_probe(struct platform_device *pdev) · line 157
Quoted 6 lines
drivers/mfd/syscon.c +5
-1- 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);Instead of duplicating all of the init code with early and late versions of each, is there any reason why we can't always do the early stuff early and then connect it to the dev infrastructure when it becomes available?
I am waiting for Arnd and Mark opinions regarding this. That's why it was just RFC.
There the next question is if this should still stay in mfd or moved to base.
I wanted to keep this to be driver compatible
that's why I have done it in this way.
We will see.
Thanks,
Michal
Signature · 14 lines
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/20140212/3f71a6b5/attachment.sig>
RFC PATCH 3/3 ARM: zynq: Use early syscon initialization
In reply to Michal SimekUse early syscon initialization to simplify slcr code.
- Remove two slcr inits (zynq_slcr_init, zynq_early_slcr_init)
- Directly use regmap accesses in zynq_slcr_read/write
- Remove zynq_clock_init() and use addresses from syscon (This is the most problematic part now because clock doesn't support regmap accesses that's why reading slcr base is ugly. There are some attempts to get clk regmap to work - for example:
https://lkml.org/lkml/2013/10/16/112)
---
Especially look at slcr.c which is much simpler than was before. clkc.c will be simpler when regmap support is added because then syscon_early_regmap_lookup_by_phandle() will be called without zynq_slcr_base search.
--- arch/arm/boot/dts/zynq-7000.dtsi | 1 + arch/arm/mach-zynq/common.c | 6 ++--- arch/arm/mach-zynq/slcr.c | 42 ++--------------------------- drivers/clk/zynq/clkc.c | 57 ++++++++++++---------------------------- 4 files changed, 23 insertions(+), 83 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +1 -0
@@ -135,6 +135,7 @@ compatible = "xlnx,zynq-slcr", "syscon"; reg = <0xF8000000 0x1000>; ranges; + syscon = <&slcr>; clkc: clkc at 100 { #clock-cells = <1>; compatible = "xlnx,ps7-clkc";
arch/arm/mach-zynq/common.c +3 -3
@@ -28,6 +28,7 @@#include <linux/of.h> #include <linux/irqchip.h> #include <linux/irqchip/arm-gic.h> +#include <linux/mfd/syscon.h> #include <linux/slab.h> #include <linux/sys_soc.h>
@@ -130,15 +131,14 @@ out:of_platform_populate (NULL , of_default_bus_match_table,NULL , parent);platform_device_register (&zynq_cpuidle_device); - -zynq_slcr_init (); }static void __init zynq_timer_init (void ) { +early_syscon_init (); +zynq_early_slcr_init (); -zynq_clock_init ();of_clk_init (NULL );clocksource_of_init (); }
arch/arm/mach-zynq/slcr.c +2 -40
76 lines not on this page · raw message
drivers/clk/zynq/clkc.c +17 -40
72 lines not on this page · raw message
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140210/2103137c/attachment.sig>