drivers: video: rockchip: vcodec_dma_map_sg maybe fail
[firefly-linux-kernel-4.4.55.git] / drivers / reset / reset-lpc18xx.c
1 /*
2  * Reset driver for NXP LPC18xx/43xx Reset Generation Unit (RGU).
3  *
4  * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  */
11
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/io.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/reboot.h>
20 #include <linux/reset-controller.h>
21 #include <linux/spinlock.h>
22
23 /* LPC18xx RGU registers */
24 #define LPC18XX_RGU_CTRL0               0x100
25 #define LPC18XX_RGU_CTRL1               0x104
26 #define LPC18XX_RGU_ACTIVE_STATUS0      0x150
27 #define LPC18XX_RGU_ACTIVE_STATUS1      0x154
28
29 #define LPC18XX_RGU_RESETS_PER_REG      32
30
31 /* Internal reset outputs */
32 #define LPC18XX_RGU_CORE_RST    0
33 #define LPC43XX_RGU_M0SUB_RST   12
34 #define LPC43XX_RGU_M0APP_RST   56
35
36 struct lpc18xx_rgu_data {
37         struct reset_controller_dev rcdev;
38         struct clk *clk_delay;
39         struct clk *clk_reg;
40         void __iomem *base;
41         spinlock_t lock;
42         u32 delay_us;
43 };
44
45 #define to_rgu_data(p) container_of(p, struct lpc18xx_rgu_data, rcdev)
46
47 static void __iomem *rgu_base;
48
49 static int lpc18xx_rgu_restart(struct notifier_block *this, unsigned long mode,
50                                void *cmd)
51 {
52         writel(BIT(LPC18XX_RGU_CORE_RST), rgu_base + LPC18XX_RGU_CTRL0);
53         mdelay(2000);
54
55         pr_emerg("%s: unable to restart system\n", __func__);
56
57         return NOTIFY_DONE;
58 }
59
60 static struct notifier_block lpc18xx_rgu_restart_nb = {
61         .notifier_call = lpc18xx_rgu_restart,
62         .priority = 192,
63 };
64
65 /*
66  * The LPC18xx RGU has mostly self-deasserting resets except for the
67  * two reset lines going to the internal Cortex-M0 cores.
68  *
69  * To prevent the M0 core resets from accidentally getting deasserted
70  * status register must be check and bits in control register set to
71  * preserve the state.
72  */
73 static int lpc18xx_rgu_setclear_reset(struct reset_controller_dev *rcdev,
74                                       unsigned long id, bool set)
75 {
76         struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev);
77         u32 stat_offset = LPC18XX_RGU_ACTIVE_STATUS0;
78         u32 ctrl_offset = LPC18XX_RGU_CTRL0;
79         unsigned long flags;
80         u32 stat, rst_bit;
81
82         stat_offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32);
83         ctrl_offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32);
84         rst_bit = 1 << (id % LPC18XX_RGU_RESETS_PER_REG);
85
86         spin_lock_irqsave(&rc->lock, flags);
87         stat = ~readl(rc->base + stat_offset);
88         if (set)
89                 writel(stat | rst_bit, rc->base + ctrl_offset);
90         else
91                 writel(stat & ~rst_bit, rc->base + ctrl_offset);
92         spin_unlock_irqrestore(&rc->lock, flags);
93
94         return 0;
95 }
96
97 static int lpc18xx_rgu_assert(struct reset_controller_dev *rcdev,
98                               unsigned long id)
99 {
100         return lpc18xx_rgu_setclear_reset(rcdev, id, true);
101 }
102
103 static int lpc18xx_rgu_deassert(struct reset_controller_dev *rcdev,
104                                 unsigned long id)
105 {
106         return lpc18xx_rgu_setclear_reset(rcdev, id, false);
107 }
108
109 /* Only M0 cores require explicit reset deassert */
110 static int lpc18xx_rgu_reset(struct reset_controller_dev *rcdev,
111                              unsigned long id)
112 {
113         struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev);
114
115         lpc18xx_rgu_assert(rcdev, id);
116         udelay(rc->delay_us);
117
118         switch (id) {
119         case LPC43XX_RGU_M0SUB_RST:
120         case LPC43XX_RGU_M0APP_RST:
121                 lpc18xx_rgu_setclear_reset(rcdev, id, false);
122         }
123
124         return 0;
125 }
126
127 static int lpc18xx_rgu_status(struct reset_controller_dev *rcdev,
128                               unsigned long id)
129 {
130         struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev);
131         u32 bit, offset = LPC18XX_RGU_ACTIVE_STATUS0;
132
133         offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32);
134         bit = 1 << (id % LPC18XX_RGU_RESETS_PER_REG);
135
136         return !(readl(rc->base + offset) & bit);
137 }
138
139 static struct reset_control_ops lpc18xx_rgu_ops = {
140         .reset          = lpc18xx_rgu_reset,
141         .assert         = lpc18xx_rgu_assert,
142         .deassert       = lpc18xx_rgu_deassert,
143         .status         = lpc18xx_rgu_status,
144 };
145
146 static int lpc18xx_rgu_probe(struct platform_device *pdev)
147 {
148         struct lpc18xx_rgu_data *rc;
149         struct resource *res;
150         u32 fcclk, firc;
151         int ret;
152
153         rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL);
154         if (!rc)
155                 return -ENOMEM;
156
157         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
158         rc->base = devm_ioremap_resource(&pdev->dev, res);
159         if (IS_ERR(rc->base))
160                 return PTR_ERR(rc->base);
161
162         rc->clk_reg = devm_clk_get(&pdev->dev, "reg");
163         if (IS_ERR(rc->clk_reg)) {
164                 dev_err(&pdev->dev, "reg clock not found\n");
165                 return PTR_ERR(rc->clk_reg);
166         }
167
168         rc->clk_delay = devm_clk_get(&pdev->dev, "delay");
169         if (IS_ERR(rc->clk_delay)) {
170                 dev_err(&pdev->dev, "delay clock not found\n");
171                 return PTR_ERR(rc->clk_delay);
172         }
173
174         ret = clk_prepare_enable(rc->clk_reg);
175         if (ret) {
176                 dev_err(&pdev->dev, "unable to enable reg clock\n");
177                 return ret;
178         }
179
180         ret = clk_prepare_enable(rc->clk_delay);
181         if (ret) {
182                 dev_err(&pdev->dev, "unable to enable delay clock\n");
183                 goto dis_clk_reg;
184         }
185
186         fcclk = clk_get_rate(rc->clk_reg) / USEC_PER_SEC;
187         firc = clk_get_rate(rc->clk_delay) / USEC_PER_SEC;
188         if (fcclk == 0 || firc == 0)
189                 rc->delay_us = 2;
190         else
191                 rc->delay_us = DIV_ROUND_UP(fcclk, firc * firc);
192
193         spin_lock_init(&rc->lock);
194
195         rc->rcdev.owner = THIS_MODULE;
196         rc->rcdev.nr_resets = 64;
197         rc->rcdev.ops = &lpc18xx_rgu_ops;
198         rc->rcdev.of_node = pdev->dev.of_node;
199
200         platform_set_drvdata(pdev, rc);
201
202         ret = reset_controller_register(&rc->rcdev);
203         if (ret) {
204                 dev_err(&pdev->dev, "unable to register device\n");
205                 goto dis_clks;
206         }
207
208         rgu_base = rc->base;
209         ret = register_restart_handler(&lpc18xx_rgu_restart_nb);
210         if (ret)
211                 dev_warn(&pdev->dev, "failed to register restart handler\n");
212
213         return 0;
214
215 dis_clks:
216         clk_disable_unprepare(rc->clk_delay);
217 dis_clk_reg:
218         clk_disable_unprepare(rc->clk_reg);
219
220         return ret;
221 }
222
223 static int lpc18xx_rgu_remove(struct platform_device *pdev)
224 {
225         struct lpc18xx_rgu_data *rc = platform_get_drvdata(pdev);
226         int ret;
227
228         ret = unregister_restart_handler(&lpc18xx_rgu_restart_nb);
229         if (ret)
230                 dev_warn(&pdev->dev, "failed to unregister restart handler\n");
231
232         reset_controller_unregister(&rc->rcdev);
233
234         clk_disable_unprepare(rc->clk_delay);
235         clk_disable_unprepare(rc->clk_reg);
236
237         return 0;
238 }
239
240 static const struct of_device_id lpc18xx_rgu_match[] = {
241         { .compatible = "nxp,lpc1850-rgu" },
242         { }
243 };
244 MODULE_DEVICE_TABLE(of, lpc18xx_rgu_match);
245
246 static struct platform_driver lpc18xx_rgu_driver = {
247         .probe  = lpc18xx_rgu_probe,
248         .remove = lpc18xx_rgu_remove,
249         .driver = {
250                 .name           = "lpc18xx-reset",
251                 .of_match_table = lpc18xx_rgu_match,
252         },
253 };
254 module_platform_driver(lpc18xx_rgu_driver);
255
256 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
257 MODULE_DESCRIPTION("Reset driver for LPC18xx/43xx RGU");
258 MODULE_LICENSE("GPL v2");