reset: add driver for socfpga
Subsystems (2)
PATCH v2 1/4 reset: add driver for socfpga
Add a reset-controller driver for the socfpga platform.
The reset-controller has four banks with up to 32 entries all encapsulated in one module block.
---
Changes since v1:
- use BITS_PER_LONG everywhere instead of MAX_BANK_WIDTH
- print pdev->dev.of_node->full_name on error
- use proper IS_ERR/PTR_ERR
drivers/reset/Makefile | 1 + drivers/reset/reset-socfpga.c | 147 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 drivers/reset/reset-socfpga.c
drivers/reset/Makefile +1 -0
@@ -1,2 +1,3 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o +obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
drivers/reset/reset-socfpga.c new file +147 -0
147 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 2/4 Documentation: dt: socfpga: add reset-cells property
To be able to use the reset-controller framework, the property
#reset-cells
is mandatory.
--- Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt | 2 ++ 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt +2 -0
@@ -3,9 +3,11 @@ Altera SOCFPGA Reset Manager Required properties: - compatible : "altr,rst-mgr" - reg : Should contain 1 register ranges(address and length) +- #reset-cells: 1 Example: rstmgr at ffd05000 { + #reset-cells = <1>; compatible = "altr,rst-mgr"; reg = <0xffd05000 0x1000>; };
Signature · 1 line
1.9.1
PATCH v2 3/4 Documentation: dt: reset: move socfpga-reset
In reply to Steffen TrumtrarInstead of having the documentation for the socfpga-reset controller in a vendor specific directory, move it to the reset folder to all the other reset drivers.
---
Documentation/devicetree/bindings/{arm/altera => reset}/socfpga-reset.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename Documentation/devicetree/bindings/{arm/altera => reset}/socfpga-reset.txt (100%)Documentation/devicetree/bindings/reset/socfpga-reset.txt renamed from Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt +0 -0
Signature · 1 line
1.9.1
PATCH v2 4/4 ARM: socfpga: dts: add reset-controller
In reply to Steffen TrumtrarAdd the necessary #reset-cells property to the rst-mgr node and provide a header-file with all possible resets specified.
--- arch/arm/boot/dts/socfpga.dtsi | 8 ++- include/dt-bindings/reset/altr,rst-mgr.h | 90 ++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/reset/altr,rst-mgr.h
arch/arm/boot/dts/socfpga.dtsi +7 -1
@@ -16,6 +16,7 @@ */ #include "skeleton.dtsi" +#include <dt-bindings/reset/altr,rst-mgr.h> / { #address-cells = <1>;
@@ -456,6 +457,8 @@ mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ clocks = <&emac0_clk>; clock-names = "stmmaceth"; + resets = <&rst EMAC0_RESET>; + reset-names = "stmmaceth"; status = "disabled"; };
@@ -467,6 +470,8 @@ mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ clocks = <&emac1_clk>; clock-names = "stmmaceth"; + resets = <&rst EMAC1_RESET>; + reset-names = "stmmaceth"; status = "disabled"; };
@@ -584,7 +589,8 @@ reg-io-width = <4>; }; - rstmgr at ffd05000 { + rst: rstmgr at ffd05000 { + #reset-cells = <1>; compatible = "altr,rst-mgr"; reg = <0xffd05000 0x1000>; };
include/dt-bindings/reset/altr,rst-mgr.h new file +90 -0
90 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 1/4 reset: add driver for socfpga
In reply to Steffen TrumtrarQuoted 108 lines · Steffen Trumtrar
Add a reset-controller driver for the socfpga platform.
The reset-controller has four banks with up to 32 entries all encapsulated in one module block.Signed-off-by Steffen Trumtrar <[email protected]>---
Changes since v1:
- useBITS_PER_LONGeverywhere instead ofMAX_BANK_WIDTHpdev->dev.of_node->full_nameon error
- use proper IS_ERR/PTR_ERRdrivers/reset/Makefile | 1 + drivers/reset/reset-socfpga.c | 147 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+)create mode 100644
drivers/reset/reset-socfpga.cdrivers/reset/Makefile +1
-0@@ -1,2 +1,3 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o +obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.odrivers/reset/reset-socfpga.c new file +78
-0@@ -0,0 +1,147 @@ +/* +* Copyright 2014 Steffen Trumtrar <[email protected]> +* +* based on +* Allwinner SoCs Reset Controller driver +* +* Copyright 2013 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* 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; either version 2 of the License, or +* (at your option) any later version. +*/ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#define NR_BANKS 4 +#define OFFSET_MODRST 0x10 + +struct socfpga_reset_data { +spinlock_t lock; +void __iomem *membase; +struct reset_controller_dev rcdev; +}; + +static int socfpga_reset_assert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct socfpga_reset_data *data =container_of (rcdev, + struct socfpga_reset_data, + rcdev); +int bank = id /BITS_PER_LONG ; +int offset = id %BITS_PER_LONG ; +unsigned long flags; +u32 reg; + +spin_lock_irqsave (&data->lock, flags); + + reg =readl (data->membase +OFFSET_MODRST + (bank *NR_BANKS )); +writel (reg |BIT (offset), data->membase +OFFSET_MODRST + + (bank *NR_BANKS )); +spin_unlock_irqrestore (&data->lock, flags); + +return 0 ; +} + +static int socfpga_reset_deassert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct socfpga_reset_data *data =container_of (rcdev, + struct socfpga_reset_data, + rcdev); + +int bank = id /BITS_PER_LONG ; +int offset = id %BITS_PER_LONG ; +unsigned long flags; +u32 reg; + +spin_lock_irqsave (&data->lock, flags); + + reg =readl (data->membase +OFFSET_MODRST + (bank *NR_BANKS )); +writel (reg & ~BIT (offset), data->membase +OFFSET_MODRST + + (bank *NR_BANKS )); + +spin_unlock_irqrestore (&data->lock, flags); + +return 0 ; +} +
drivers/reset/reset-socfpga.c line 88
Quoted 10 lines
drivers/reset/reset-socfpga.c new file +10
-0+static struct reset_control_ops socfpga_reset_ops = { + .assert = socfpga_reset_assert, + .deassert = socfpga_reset_deassert, +}; + +static int socfpga_reset_probe (struct platform_device *pdev) +{ +struct socfpga_reset_data *data; +struct resource *res; +int ret;
'ret' is not used in this function.
Dinh
Quoted 60 lines
drivers/reset/reset-socfpga.c new file +59
-0+ +/* +* The binding was mainlined without the required property. +* Do not continue, when we encounter an old DT. +*/ +if (!of_find_property (pdev->dev.of_node,"#reset-cells" ,NULL )) { +dev_err (&pdev->dev,"%s missing #reset-cells property\n" , + pdev->dev.of_node->full_name); +return -EINVAL ; + } + + data =devm_kzalloc (&pdev->dev,sizeof (*data),GFP_KERNEL ); +if (!data) +return -ENOMEM ; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + data->membase =devm_ioremap_resource (&pdev->dev, res); +if (IS_ERR (data->membase)) +return PTR_ERR (data->membase); + +spin_lock_init (&data->lock); + + data->rcdev.owner =THIS_MODULE ; + data->rcdev.nr_resets =NR_BANKS *BITS_PER_LONG ; + data->rcdev.ops = &socfpga_reset_ops; + data->rcdev.of_node = pdev->dev.of_node; +reset_controller_register (&data->rcdev); + +return 0 ; +} + +static int socfpga_reset_remove (struct platform_device *pdev) +{ +struct socfpga_reset_data *data =platform_get_drvdata (pdev); + +reset_controller_unregister (&data->rcdev); + +return 0 ; +} + +static const struct of_device_id socfpga_reset_dt_ids[] = { + { .compatible ="altr,rst-mgr" , }, + {/* sentinel */ }, +}; + +static struct platform_driver socfpga_reset_driver = { + .probe = socfpga_reset_probe, + .remove = socfpga_reset_remove, + .driver = { + .name ="socfpga-reset" , + .owner =THIS_MODULE , + .of_match_table = socfpga_reset_dt_ids, + }, +}; +module_platform_driver (socfpga_reset_driver); + +MODULE_AUTHOR ("Steffen Trumtrar <[email protected]" ); +MODULE_DESCRIPTION ("Socfpga Reset Controller Driver" ); +MODULE_LICENSE ("GPL" );
Philipp Zabel
maintainerPATCH v2 1/4 reset: add driver for socfpga
In reply to Steffen TrumtrarHi Dinh,
Am Donnerstag, den 10.04.2014, 10:21 +0200 schrieb Steffen Trumtrar:
Quoted 5 lines
Add a reset-controller driver for the socfpga platform.
The reset-controller has four banks with up to 32 entries all encapsulated in one module block.Signed-off-by Steffen Trumtrar <[email protected]>
in case you want to take this through your branch,
If you want me to take the reset controller driver, please let me know.
regards
Philipp
Quoted 172 lines
---
Changes since v1:
- useBITS_PER_LONGeverywhere instead ofMAX_BANK_WIDTHpdev->dev.of_node->full_nameon error
- use proper IS_ERR/PTR_ERRdrivers/reset/Makefile | 1 + drivers/reset/reset-socfpga.c | 147 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 drivers/reset/reset-socfpga.cdrivers/reset/Makefile +1
-0@@ -1,2 +1,3 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o +obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.odrivers/reset/reset-socfpga.c new file +147
-0@@ -0,0 +1,147 @@ +/* +* Copyright 2014 Steffen Trumtrar <[email protected]> +* +* based on +* Allwinner SoCs Reset Controller driver +* +* Copyright 2013 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* 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; either version 2 of the License, or +* (at your option) any later version. +*/ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#define NR_BANKS 4 +#define OFFSET_MODRST 0x10 + +struct socfpga_reset_data { +spinlock_t lock; +void __iomem *membase; +struct reset_controller_dev rcdev; +}; + +static int socfpga_reset_assert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct socfpga_reset_data *data =container_of (rcdev, + struct socfpga_reset_data, + rcdev); +int bank = id /BITS_PER_LONG ; +int offset = id %BITS_PER_LONG ; +unsigned long flags; +u32 reg; + +spin_lock_irqsave (&data->lock, flags); + + reg =readl (data->membase +OFFSET_MODRST + (bank *NR_BANKS )); +writel (reg |BIT (offset), data->membase +OFFSET_MODRST + + (bank *NR_BANKS )); +spin_unlock_irqrestore (&data->lock, flags); + +return 0 ; +} + +static int socfpga_reset_deassert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct socfpga_reset_data *data =container_of (rcdev, + struct socfpga_reset_data, + rcdev); + +int bank = id /BITS_PER_LONG ; +int offset = id %BITS_PER_LONG ; +unsigned long flags; +u32 reg; + +spin_lock_irqsave (&data->lock, flags); + + reg =readl (data->membase +OFFSET_MODRST + (bank *NR_BANKS )); +writel (reg & ~BIT (offset), data->membase +OFFSET_MODRST + + (bank *NR_BANKS )); + +spin_unlock_irqrestore (&data->lock, flags); + +return 0 ; +} + +static struct reset_control_ops socfpga_reset_ops = { + .assert = socfpga_reset_assert, + .deassert = socfpga_reset_deassert, +}; + +static int socfpga_reset_probe (struct platform_device *pdev) +{ +struct socfpga_reset_data *data; +struct resource *res; +int ret; + +/* +* The binding was mainlined without the required property. +* Do not continue, when we encounter an old DT. +*/ +if (!of_find_property (pdev->dev.of_node,"#reset-cells" ,NULL )) { +dev_err (&pdev->dev,"%s missing #reset-cells property\n" , + pdev->dev.of_node->full_name); +return -EINVAL ; + } + + data =devm_kzalloc (&pdev->dev,sizeof (*data),GFP_KERNEL ); +if (!data) +return -ENOMEM ; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + data->membase =devm_ioremap_resource (&pdev->dev, res); +if (IS_ERR (data->membase)) +return PTR_ERR (data->membase); + +spin_lock_init (&data->lock); + + data->rcdev.owner =THIS_MODULE ; + data->rcdev.nr_resets =NR_BANKS *BITS_PER_LONG ; + data->rcdev.ops = &socfpga_reset_ops; + data->rcdev.of_node = pdev->dev.of_node; +reset_controller_register (&data->rcdev); + +return 0 ; +} + +static int socfpga_reset_remove (struct platform_device *pdev) +{ +struct socfpga_reset_data *data =platform_get_drvdata (pdev); + +reset_controller_unregister (&data->rcdev); + +return 0 ; +} + +static const struct of_device_id socfpga_reset_dt_ids[] = { + { .compatible ="altr,rst-mgr" , }, + {/* sentinel */ }, +}; + +static struct platform_driver socfpga_reset_driver = { + .probe = socfpga_reset_probe, + .remove = socfpga_reset_remove, + .driver = { + .name ="socfpga-reset" , + .owner =THIS_MODULE , + .of_match_table = socfpga_reset_dt_ids, + }, +}; +module_platform_driver (socfpga_reset_driver); + +MODULE_AUTHOR ("Steffen Trumtrar <[email protected]" ); +MODULE_DESCRIPTION ("Socfpga Reset Controller Driver" ); +MODULE_LICENSE ("GPL" );
PATCH v2 1/4 reset: add driver for socfpga
Quoted 7 lines · Philipp Zabel
Hi Dinh,
Am Donnerstag, den 10.04.2014, 10:21 +0200 schrieb Steffen Trumtrar:
Quoted 4 lines
Add a reset-controller driver for the socfpga platform.
The reset-controller has four banks with up to 32 entries all encapsulated in one module block.
Quoted 8 lines
Quoted 1 line
Signed-off-by Steffen Trumtrar <[email protected]>in case you want to take this through your branch,
Acked-by Philipp Zabel <[email protected]>If you want me to take the reset controller driver, please let me know.
Yes, I will.
Thanks,
Dinh
Quoted 177 lines
regards
PhilippQuoted 172 lines
---
Changes since v1:
- useBITS_PER_LONGeverywhere instead ofMAX_BANK_WIDTHpdev->dev.of_node->full_nameon error
- use proper IS_ERR/PTR_ERRdrivers/reset/Makefile | 1 + drivers/reset/reset-socfpga.c | 147 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 drivers/reset/reset-socfpga.cdrivers/reset/Makefile +1
-0@@ -1,2 +1,3 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o +obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.odrivers/reset/reset-socfpga.c new file +147
-0@@ -0,0 +1,147 @@ +/* +* Copyright 2014 Steffen Trumtrar <[email protected]> +* +* based on +* Allwinner SoCs Reset Controller driver +* +* Copyright 2013 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* 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; either version 2 of the License, or +* (at your option) any later version. +*/ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#define NR_BANKS 4 +#define OFFSET_MODRST 0x10 + +struct socfpga_reset_data { +spinlock_t lock; +void __iomem *membase; +struct reset_controller_dev rcdev; +}; + +static int socfpga_reset_assert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct socfpga_reset_data *data =container_of (rcdev, + struct socfpga_reset_data, + rcdev); +int bank = id /BITS_PER_LONG ; +int offset = id %BITS_PER_LONG ; +unsigned long flags; +u32 reg; + +spin_lock_irqsave (&data->lock, flags); + + reg =readl (data->membase +OFFSET_MODRST + (bank *NR_BANKS )); +writel (reg |BIT (offset), data->membase +OFFSET_MODRST + + (bank *NR_BANKS )); +spin_unlock_irqrestore (&data->lock, flags); + +return 0 ; +} + +static int socfpga_reset_deassert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct socfpga_reset_data *data =container_of (rcdev, + struct socfpga_reset_data, + rcdev); + +int bank = id /BITS_PER_LONG ; +int offset = id %BITS_PER_LONG ; +unsigned long flags; +u32 reg; + +spin_lock_irqsave (&data->lock, flags); + + reg =readl (data->membase +OFFSET_MODRST + (bank *NR_BANKS )); +writel (reg & ~BIT (offset), data->membase +OFFSET_MODRST + + (bank *NR_BANKS )); + +spin_unlock_irqrestore (&data->lock, flags); + +return 0 ; +} + +static struct reset_control_ops socfpga_reset_ops = { + .assert = socfpga_reset_assert, + .deassert = socfpga_reset_deassert, +}; + +static int socfpga_reset_probe (struct platform_device *pdev) +{ +struct socfpga_reset_data *data; +struct resource *res; +int ret; + +/* +* The binding was mainlined without the required property. +* Do not continue, when we encounter an old DT. +*/ +if (!of_find_property (pdev->dev.of_node,"#reset-cells" ,NULL )) { +dev_err (&pdev->dev,"%s missing #reset-cells property\n" , + pdev->dev.of_node->full_name); +return -EINVAL ; + } + + data =devm_kzalloc (&pdev->dev,sizeof (*data),GFP_KERNEL ); +if (!data) +return -ENOMEM ; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + data->membase =devm_ioremap_resource (&pdev->dev, res); +if (IS_ERR (data->membase)) +return PTR_ERR (data->membase); + +spin_lock_init (&data->lock); + + data->rcdev.owner =THIS_MODULE ; + data->rcdev.nr_resets =NR_BANKS *BITS_PER_LONG ; + data->rcdev.ops = &socfpga_reset_ops; + data->rcdev.of_node = pdev->dev.of_node; +reset_controller_register (&data->rcdev); + +return 0 ; +} + +static int socfpga_reset_remove (struct platform_device *pdev) +{ +struct socfpga_reset_data *data =platform_get_drvdata (pdev); + +reset_controller_unregister (&data->rcdev); + +return 0 ; +} + +static const struct of_device_id socfpga_reset_dt_ids[] = { + { .compatible ="altr,rst-mgr" , }, + {/* sentinel */ }, +}; + +static struct platform_driver socfpga_reset_driver = { + .probe = socfpga_reset_probe, + .remove = socfpga_reset_remove, + .driver = { + .name ="socfpga-reset" , + .owner =THIS_MODULE , + .of_match_table = socfpga_reset_dt_ids, + }, +}; +module_platform_driver (socfpga_reset_driver); + +MODULE_AUTHOR ("Steffen Trumtrar <[email protected]" ); +MODULE_DESCRIPTION ("Socfpga Reset Controller Driver" ); +MODULE_LICENSE ("GPL" );