aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/reset
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-02 19:35:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-02 19:35:49 -0400
commita727eaf64ff084a50b983fc506810c7a576b7ce3 (patch)
treecb82642227ed590ebc43b12cfad285a2d7681d5d /drivers/reset
parent755a9ba7bf24a45b6dbf8bb15a5a56c8ed12461a (diff)
parent45e70b7d48d53d5eb193c6b3f012b31ca135fb4c (diff)
Merge tag 'drivers-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc into next
Pull ARM SoC driver changes from Olof Johansson: "SoC-near driver changes that we're merging through our tree. Mostly because they depend on other changes we have staged, but in some cases because the driver maintainers preferred that we did it this way. This contains a largeish cleanup series of the omap_l3_noc bus driver, cpuidle rework for Exynos, some reset driver conversions and a long branch of TI EDMA fixes and cleanups, with more to come next release. The TI EDMA cleanups is a shared branch with the dmaengine tree, with a handful of Davinci-specific fixes on top. After discussion at last year's KS (and some more on the mailing lists), we are here adding a drivers/soc directory. The purpose of this is to keep per-vendor shared code that's needed by different drivers but that doesn't fit into the MFD (nor drivers/platform) model. We expect to keep merging contents for this hierarchy through arm-soc so we can keep an eye on what the vendors keep adding here and not making it a free-for-all to shove in crazy stuff" * tag 'drivers-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (101 commits) cpufreq: exynos: Fix driver compilation with ARCH_MULTIPLATFORM tty: serial: msm: Remove direct access to GSBI power: reset: keystone-reset: introduce keystone reset driver Documentation: dt: add bindings for keystone pll control controller Documentation: dt: add bindings for keystone reset driver soc: qcom: fix of_device_id table ARM: EXYNOS: Fix kernel panic when unplugging CPU1 on exynos ARM: EXYNOS: Move the driver to drivers/cpuidle directory ARM: EXYNOS: Cleanup all unneeded headers from cpuidle.c ARM: EXYNOS: Pass the AFTR callback to the platform_data ARM: EXYNOS: Move S5P_CHECK_SLEEP into pm.c ARM: EXYNOS: Move the power sequence call in the cpu_pm notifier ARM: EXYNOS: Move the AFTR state function into pm.c ARM: EXYNOS: Encapsulate the AFTR code into a function ARM: EXYNOS: Disable cpuidle for exynos5440 ARM: EXYNOS: Encapsulate boot vector code into a function for cpuidle ARM: EXYNOS: Pass wakeup mask parameter to function for cpuidle ARM: EXYNOS: Remove ifdef for scu_enable in pm ARM: EXYNOS: Move scu_enable in the cpu_pm notifier ARM: EXYNOS: Use the cpu_pm notifier for pm ...
Diffstat (limited to 'drivers/reset')
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-socfpga.c146
-rw-r--r--drivers/reset/reset-sunxi.c21
3 files changed, 165 insertions, 3 deletions
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 4f60caf750ce..60fed3d7820b 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,3 +1,4 @@
1obj-$(CONFIG_RESET_CONTROLLER) += core.o 1obj-$(CONFIG_RESET_CONTROLLER) += core.o
2obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
2obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o 3obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
3obj-$(CONFIG_ARCH_STI) += sti/ 4obj-$(CONFIG_ARCH_STI) += sti/
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
new file mode 100644
index 000000000000..79c32ca84ef1
--- /dev/null
+++ b/drivers/reset/reset-socfpga.c
@@ -0,0 +1,146 @@
1/*
2 * Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
3 *
4 * based on
5 * Allwinner SoCs Reset Controller driver
6 *
7 * Copyright 2013 Maxime Ripard
8 *
9 * Maxime Ripard <maxime.ripard@free-electrons.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/platform_device.h>
22#include <linux/reset-controller.h>
23#include <linux/spinlock.h>
24#include <linux/types.h>
25
26#define NR_BANKS 4
27#define OFFSET_MODRST 0x10
28
29struct socfpga_reset_data {
30 spinlock_t lock;
31 void __iomem *membase;
32 struct reset_controller_dev rcdev;
33};
34
35static int socfpga_reset_assert(struct reset_controller_dev *rcdev,
36 unsigned long id)
37{
38 struct socfpga_reset_data *data = container_of(rcdev,
39 struct socfpga_reset_data,
40 rcdev);
41 int bank = id / BITS_PER_LONG;
42 int offset = id % BITS_PER_LONG;
43 unsigned long flags;
44 u32 reg;
45
46 spin_lock_irqsave(&data->lock, flags);
47
48 reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS));
49 writel(reg | BIT(offset), data->membase + OFFSET_MODRST +
50 (bank * NR_BANKS));
51 spin_unlock_irqrestore(&data->lock, flags);
52
53 return 0;
54}
55
56static int socfpga_reset_deassert(struct reset_controller_dev *rcdev,
57 unsigned long id)
58{
59 struct socfpga_reset_data *data = container_of(rcdev,
60 struct socfpga_reset_data,
61 rcdev);
62
63 int bank = id / BITS_PER_LONG;
64 int offset = id % BITS_PER_LONG;
65 unsigned long flags;
66 u32 reg;
67
68 spin_lock_irqsave(&data->lock, flags);
69
70 reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS));
71 writel(reg & ~BIT(offset), data->membase + OFFSET_MODRST +
72 (bank * NR_BANKS));
73
74 spin_unlock_irqrestore(&data->lock, flags);
75
76 return 0;
77}
78
79static struct reset_control_ops socfpga_reset_ops = {
80 .assert = socfpga_reset_assert,
81 .deassert = socfpga_reset_deassert,
82};
83
84static int socfpga_reset_probe(struct platform_device *pdev)
85{
86 struct socfpga_reset_data *data;
87 struct resource *res;
88
89 /*
90 * The binding was mainlined without the required property.
91 * Do not continue, when we encounter an old DT.
92 */
93 if (!of_find_property(pdev->dev.of_node, "#reset-cells", NULL)) {
94 dev_err(&pdev->dev, "%s missing #reset-cells property\n",
95 pdev->dev.of_node->full_name);
96 return -EINVAL;
97 }
98
99 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
100 if (!data)
101 return -ENOMEM;
102
103 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
104 data->membase = devm_ioremap_resource(&pdev->dev, res);
105 if (IS_ERR(data->membase))
106 return PTR_ERR(data->membase);
107
108 spin_lock_init(&data->lock);
109
110 data->rcdev.owner = THIS_MODULE;
111 data->rcdev.nr_resets = NR_BANKS * BITS_PER_LONG;
112 data->rcdev.ops = &socfpga_reset_ops;
113 data->rcdev.of_node = pdev->dev.of_node;
114 reset_controller_register(&data->rcdev);
115
116 return 0;
117}
118
119static int socfpga_reset_remove(struct platform_device *pdev)
120{
121 struct socfpga_reset_data *data = platform_get_drvdata(pdev);
122
123 reset_controller_unregister(&data->rcdev);
124
125 return 0;
126}
127
128static const struct of_device_id socfpga_reset_dt_ids[] = {
129 { .compatible = "altr,rst-mgr", },
130 { /* sentinel */ },
131};
132
133static struct platform_driver socfpga_reset_driver = {
134 .probe = socfpga_reset_probe,
135 .remove = socfpga_reset_remove,
136 .driver = {
137 .name = "socfpga-reset",
138 .owner = THIS_MODULE,
139 .of_match_table = socfpga_reset_dt_ids,
140 },
141};
142module_platform_driver(socfpga_reset_driver);
143
144MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de");
145MODULE_DESCRIPTION("Socfpga Reset Controller Driver");
146MODULE_LICENSE("GPL");
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
index 695bd3496eba..a94e7a7820b4 100644
--- a/drivers/reset/reset-sunxi.c
+++ b/drivers/reset/reset-sunxi.c
@@ -145,7 +145,24 @@ MODULE_DEVICE_TABLE(of, sunxi_reset_dt_ids);
145 145
146static int sunxi_reset_probe(struct platform_device *pdev) 146static int sunxi_reset_probe(struct platform_device *pdev)
147{ 147{
148 return sunxi_reset_init(pdev->dev.of_node); 148 struct sunxi_reset_data *data;
149 struct resource *res;
150
151 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
152 if (!data)
153 return -ENOMEM;
154
155 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
156 data->membase = devm_ioremap_resource(&pdev->dev, res);
157 if (IS_ERR(data->membase))
158 return PTR_ERR(data->membase);
159
160 data->rcdev.owner = THIS_MODULE;
161 data->rcdev.nr_resets = resource_size(res) * 32;
162 data->rcdev.ops = &sunxi_reset_ops;
163 data->rcdev.of_node = pdev->dev.of_node;
164
165 return reset_controller_register(&data->rcdev);
149} 166}
150 167
151static int sunxi_reset_remove(struct platform_device *pdev) 168static int sunxi_reset_remove(struct platform_device *pdev)
@@ -153,8 +170,6 @@ static int sunxi_reset_remove(struct platform_device *pdev)
153 struct sunxi_reset_data *data = platform_get_drvdata(pdev); 170 struct sunxi_reset_data *data = platform_get_drvdata(pdev);
154 171
155 reset_controller_unregister(&data->rcdev); 172 reset_controller_unregister(&data->rcdev);
156 iounmap(data->membase);
157 kfree(data);
158 173
159 return 0; 174 return 0;
160} 175}