1// SPDX-License-Identifier: GPL-2.0
2/*
3 * OMAP2+ PRM driver
4 *
5 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6 *	Tero Kristo <t-kristo@ti.com>
7 */
8
9#include <linux/kernel.h>
10#include <linux/device.h>
11#include <linux/io.h>
12#include <linux/iopoll.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/platform_device.h>
17#include <linux/pm_domain.h>
18#include <linux/reset-controller.h>
19#include <linux/delay.h>
20
21#include <linux/platform_data/ti-prm.h>
22
23enum omap_prm_domain_mode {
24	OMAP_PRMD_OFF,
25	OMAP_PRMD_RETENTION,
26	OMAP_PRMD_ON_INACTIVE,
27	OMAP_PRMD_ON_ACTIVE,
28};
29
30struct omap_prm_domain_map {
31	unsigned int usable_modes;	/* Mask of hardware supported modes */
32	unsigned long statechange:1;	/* Optional low-power state change */
33	unsigned long logicretstate:1;	/* Optional logic off mode */
34};
35
36struct omap_prm_domain {
37	struct device *dev;
38	struct omap_prm *prm;
39	struct generic_pm_domain pd;
40	u16 pwrstctrl;
41	u16 pwrstst;
42	const struct omap_prm_domain_map *cap;
43	u32 pwrstctrl_saved;
44};
45
46struct omap_rst_map {
47	s8 rst;
48	s8 st;
49};
50
51struct omap_prm_data {
52	u32 base;
53	const char *name;
54	const char *clkdm_name;
55	u16 pwrstctrl;
56	u16 pwrstst;
57	const struct omap_prm_domain_map *dmap;
58	u16 rstctrl;
59	u16 rstst;
60	const struct omap_rst_map *rstmap;
61	u8 flags;
62};
63
64struct omap_prm {
65	const struct omap_prm_data *data;
66	void __iomem *base;
67	struct omap_prm_domain *prmd;
68};
69
70struct omap_reset_data {
71	struct reset_controller_dev rcdev;
72	struct omap_prm *prm;
73	u32 mask;
74	spinlock_t lock;
75	struct clockdomain *clkdm;
76	struct device *dev;
77};
78
79#define genpd_to_prm_domain(gpd) container_of(gpd, struct omap_prm_domain, pd)
80#define to_omap_reset_data(p) container_of((p), struct omap_reset_data, rcdev)
81
82#define OMAP_MAX_RESETS		8
83#define OMAP_RESET_MAX_WAIT	10000
84
85#define OMAP_PRM_HAS_RSTCTRL	BIT(0)
86#define OMAP_PRM_HAS_RSTST	BIT(1)
87#define OMAP_PRM_HAS_NO_CLKDM	BIT(2)
88
89#define OMAP_PRM_HAS_RESETS	(OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST)
90
91#define PRM_STATE_MAX_WAIT	10000
92#define PRM_LOGICRETSTATE	BIT(2)
93#define PRM_LOWPOWERSTATECHANGE	BIT(4)
94#define PRM_POWERSTATE_MASK	OMAP_PRMD_ON_ACTIVE
95
96#define PRM_ST_INTRANSITION	BIT(20)
97
98static const struct omap_prm_domain_map omap_prm_all = {
99	.usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) |
100			BIT(OMAP_PRMD_RETENTION) | BIT(OMAP_PRMD_OFF),
101	.statechange = 1,
102	.logicretstate = 1,
103};
104
105static const struct omap_prm_domain_map omap_prm_noinact = {
106	.usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_RETENTION) |
107			BIT(OMAP_PRMD_OFF),
108	.statechange = 1,
109	.logicretstate = 1,
110};
111
112static const struct omap_prm_domain_map omap_prm_nooff = {
113	.usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) |
114			BIT(OMAP_PRMD_RETENTION),
115	.statechange = 1,
116	.logicretstate = 1,
117};
118
119static const struct omap_prm_domain_map omap_prm_onoff_noauto = {
120	.usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_OFF),
121	.statechange = 1,
122};
123
124static const struct omap_rst_map rst_map_0[] = {
125	{ .rst = 0, .st = 0 },
126	{ .rst = -1 },
127};
128
129static const struct omap_rst_map rst_map_01[] = {
130	{ .rst = 0, .st = 0 },
131	{ .rst = 1, .st = 1 },
132	{ .rst = -1 },
133};
134
135static const struct omap_rst_map rst_map_012[] = {
136	{ .rst = 0, .st = 0 },
137	{ .rst = 1, .st = 1 },
138	{ .rst = 2, .st = 2 },
139	{ .rst = -1 },
140};
141
142static const struct omap_prm_data omap4_prm_data[] = {
143	{ .name = "tesla", .base = 0x4a306400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
144	{
145		.name = "abe", .base = 0x4a306500,
146		.pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_all,
147	},
148	{ .name = "core", .base = 0x4a306700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ducati", .rstmap = rst_map_012 },
149	{ .name = "ivahd", .base = 0x4a306f00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 },
150	{ .name = "device", .base = 0x4a307b00, .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
151	{ },
152};
153
154static const struct omap_prm_data omap5_prm_data[] = {
155	{ .name = "dsp", .base = 0x4ae06400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
156	{
157		.name = "abe", .base = 0x4ae06500,
158		.pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_nooff,
159	},
160	{ .name = "core", .base = 0x4ae06700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu", .rstmap = rst_map_012 },
161	{ .name = "iva", .base = 0x4ae07200, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 },
162	{ .name = "device", .base = 0x4ae07c00, .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
163	{ },
164};
165
166static const struct omap_prm_data dra7_prm_data[] = {
167	{ .name = "dsp1", .base = 0x4ae06400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
168	{ .name = "ipu", .base = 0x4ae06500, .rstctrl = 0x10, .rstst = 0x14, .clkdm_name = "ipu1", .rstmap = rst_map_012 },
169	{ .name = "core", .base = 0x4ae06700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu2", .rstmap = rst_map_012 },
170	{ .name = "iva", .base = 0x4ae06f00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 },
171	{ .name = "dsp2", .base = 0x4ae07b00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
172	{ .name = "eve1", .base = 0x4ae07b40, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
173	{ .name = "eve2", .base = 0x4ae07b80, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
174	{ .name = "eve3", .base = 0x4ae07bc0, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
175	{ .name = "eve4", .base = 0x4ae07c00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
176	{ },
177};
178
179static const struct omap_rst_map am3_per_rst_map[] = {
180	{ .rst = 1 },
181	{ .rst = -1 },
182};
183
184static const struct omap_rst_map am3_wkup_rst_map[] = {
185	{ .rst = 3, .st = 5 },
186	{ .rst = -1 },
187};
188
189static const struct omap_prm_data am3_prm_data[] = {
190	{ .name = "per", .base = 0x44e00c00, .rstctrl = 0x0, .rstmap = am3_per_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL, .clkdm_name = "pruss_ocp" },
191	{ .name = "wkup", .base = 0x44e00d00, .rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
192	{ .name = "device", .base = 0x44e00f00, .rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
193	{
194		.name = "gfx", .base = 0x44e01100,
195		.pwrstctrl = 0, .pwrstst = 0x10, .dmap = &omap_prm_noinact,
196		.rstctrl = 0x4, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3",
197	},
198	{ },
199};
200
201static const struct omap_rst_map am4_per_rst_map[] = {
202	{ .rst = 1, .st = 0 },
203	{ .rst = -1 },
204};
205
206static const struct omap_rst_map am4_device_rst_map[] = {
207	{ .rst = 0, .st = 1 },
208	{ .rst = 1, .st = 0 },
209	{ .rst = -1 },
210};
211
212static const struct omap_prm_data am4_prm_data[] = {
213	{
214		.name = "gfx", .base = 0x44df0400,
215		.pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
216		.rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3",
217	},
218	{ .name = "per", .base = 0x44df0800, .rstctrl = 0x10, .rstst = 0x14, .rstmap = am4_per_rst_map, .clkdm_name = "pruss_ocp" },
219	{ .name = "wkup", .base = 0x44df2000, .rstctrl = 0x10, .rstst = 0x14, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_NO_CLKDM },
220	{ .name = "device", .base = 0x44df4000, .rstctrl = 0x0, .rstst = 0x4, .rstmap = am4_device_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
221	{ },
222};
223
224static const struct of_device_id omap_prm_id_table[] = {
225	{ .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data },
226	{ .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data },
227	{ .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data },
228	{ .compatible = "ti,am3-prm-inst", .data = am3_prm_data },
229	{ .compatible = "ti,am4-prm-inst", .data = am4_prm_data },
230	{ },
231};
232
233#ifdef DEBUG
234static void omap_prm_domain_show_state(struct omap_prm_domain *prmd,
235				       const char *desc)
236{
237	dev_dbg(prmd->dev, "%s %s: %08x/%08x\n",
238		prmd->pd.name, desc,
239		readl_relaxed(prmd->prm->base + prmd->pwrstctrl),
240		readl_relaxed(prmd->prm->base + prmd->pwrstst));
241}
242#else
243static inline void omap_prm_domain_show_state(struct omap_prm_domain *prmd,
244					      const char *desc)
245{
246}
247#endif
248
249static int omap_prm_domain_power_on(struct generic_pm_domain *domain)
250{
251	struct omap_prm_domain *prmd;
252	int ret;
253	u32 v;
254
255	prmd = genpd_to_prm_domain(domain);
256	if (!prmd->cap)
257		return 0;
258
259	omap_prm_domain_show_state(prmd, "on: previous state");
260
261	if (prmd->pwrstctrl_saved)
262		v = prmd->pwrstctrl_saved;
263	else
264		v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl);
265
266	writel_relaxed(v | OMAP_PRMD_ON_ACTIVE,
267		       prmd->prm->base + prmd->pwrstctrl);
268
269	/* wait for the transition bit to get cleared */
270	ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst,
271					 v, !(v & PRM_ST_INTRANSITION), 1,
272					 PRM_STATE_MAX_WAIT);
273	if (ret)
274		dev_err(prmd->dev, "%s: %s timed out\n",
275			prmd->pd.name, __func__);
276
277	omap_prm_domain_show_state(prmd, "on: new state");
278
279	return ret;
280}
281
282/* No need to check for holes in the mask for the lowest mode */
283static int omap_prm_domain_find_lowest(struct omap_prm_domain *prmd)
284{
285	return __ffs(prmd->cap->usable_modes);
286}
287
288static int omap_prm_domain_power_off(struct generic_pm_domain *domain)
289{
290	struct omap_prm_domain *prmd;
291	int ret;
292	u32 v;
293
294	prmd = genpd_to_prm_domain(domain);
295	if (!prmd->cap)
296		return 0;
297
298	omap_prm_domain_show_state(prmd, "off: previous state");
299
300	v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl);
301	prmd->pwrstctrl_saved = v;
302
303	v &= ~PRM_POWERSTATE_MASK;
304	v |= omap_prm_domain_find_lowest(prmd);
305
306	if (prmd->cap->statechange)
307		v |= PRM_LOWPOWERSTATECHANGE;
308	if (prmd->cap->logicretstate)
309		v &= ~PRM_LOGICRETSTATE;
310	else
311		v |= PRM_LOGICRETSTATE;
312
313	writel_relaxed(v, prmd->prm->base + prmd->pwrstctrl);
314
315	/* wait for the transition bit to get cleared */
316	ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst,
317					 v, !(v & PRM_ST_INTRANSITION), 1,
318					 PRM_STATE_MAX_WAIT);
319	if (ret)
320		dev_warn(prmd->dev, "%s: %s timed out\n",
321			 __func__, prmd->pd.name);
322
323	omap_prm_domain_show_state(prmd, "off: new state");
324
325	return 0;
326}
327
328static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain,
329				      struct device *dev)
330{
331	struct generic_pm_domain_data *genpd_data;
332	struct of_phandle_args pd_args;
333	struct omap_prm_domain *prmd;
334	struct device_node *np;
335	int ret;
336
337	prmd = genpd_to_prm_domain(domain);
338	np = dev->of_node;
339
340	ret = of_parse_phandle_with_args(np, "power-domains",
341					 "#power-domain-cells", 0, &pd_args);
342	if (ret < 0)
343		return ret;
344
345	if (pd_args.args_count != 0)
346		dev_warn(dev, "%s: unusupported #power-domain-cells: %i\n",
347			 prmd->pd.name, pd_args.args_count);
348
349	genpd_data = dev_gpd_data(dev);
350	genpd_data->data = NULL;
351
352	return 0;
353}
354
355static void omap_prm_domain_detach_dev(struct generic_pm_domain *domain,
356				       struct device *dev)
357{
358	struct generic_pm_domain_data *genpd_data;
359
360	genpd_data = dev_gpd_data(dev);
361	genpd_data->data = NULL;
362}
363
364static int omap_prm_domain_init(struct device *dev, struct omap_prm *prm)
365{
366	struct omap_prm_domain *prmd;
367	struct device_node *np = dev->of_node;
368	const struct omap_prm_data *data;
369	const char *name;
370	int error;
371
372	if (!of_find_property(dev->of_node, "#power-domain-cells", NULL))
373		return 0;
374
375	of_node_put(dev->of_node);
376
377	prmd = devm_kzalloc(dev, sizeof(*prmd), GFP_KERNEL);
378	if (!prmd)
379		return -ENOMEM;
380
381	data = prm->data;
382	name = devm_kasprintf(dev, GFP_KERNEL, "prm_%s",
383			      data->name);
384
385	prmd->dev = dev;
386	prmd->prm = prm;
387	prmd->cap = prmd->prm->data->dmap;
388	prmd->pwrstctrl = prmd->prm->data->pwrstctrl;
389	prmd->pwrstst = prmd->prm->data->pwrstst;
390
391	prmd->pd.name = name;
392	prmd->pd.power_on = omap_prm_domain_power_on;
393	prmd->pd.power_off = omap_prm_domain_power_off;
394	prmd->pd.attach_dev = omap_prm_domain_attach_dev;
395	prmd->pd.detach_dev = omap_prm_domain_detach_dev;
396
397	pm_genpd_init(&prmd->pd, NULL, true);
398	error = of_genpd_add_provider_simple(np, &prmd->pd);
399	if (error)
400		pm_genpd_remove(&prmd->pd);
401	else
402		prm->prmd = prmd;
403
404	return error;
405}
406
407static bool _is_valid_reset(struct omap_reset_data *reset, unsigned long id)
408{
409	if (reset->mask & BIT(id))
410		return true;
411
412	return false;
413}
414
415static int omap_reset_get_st_bit(struct omap_reset_data *reset,
416				 unsigned long id)
417{
418	const struct omap_rst_map *map = reset->prm->data->rstmap;
419
420	while (map->rst >= 0) {
421		if (map->rst == id)
422			return map->st;
423
424		map++;
425	}
426
427	return id;
428}
429
430static int omap_reset_status(struct reset_controller_dev *rcdev,
431			     unsigned long id)
432{
433	struct omap_reset_data *reset = to_omap_reset_data(rcdev);
434	u32 v;
435	int st_bit = omap_reset_get_st_bit(reset, id);
436	bool has_rstst = reset->prm->data->rstst ||
437		(reset->prm->data->flags & OMAP_PRM_HAS_RSTST);
438
439	/* Check if we have rstst */
440	if (!has_rstst)
441		return -ENOTSUPP;
442
443	/* Check if hw reset line is asserted */
444	v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
445	if (v & BIT(id))
446		return 1;
447
448	/*
449	 * Check reset status, high value means reset sequence has been
450	 * completed successfully so we can return 0 here (reset deasserted)
451	 */
452	v = readl_relaxed(reset->prm->base + reset->prm->data->rstst);
453	v >>= st_bit;
454	v &= 1;
455
456	return !v;
457}
458
459static int omap_reset_assert(struct reset_controller_dev *rcdev,
460			     unsigned long id)
461{
462	struct omap_reset_data *reset = to_omap_reset_data(rcdev);
463	u32 v;
464	unsigned long flags;
465
466	/* assert the reset control line */
467	spin_lock_irqsave(&reset->lock, flags);
468	v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
469	v |= 1 << id;
470	writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
471	spin_unlock_irqrestore(&reset->lock, flags);
472
473	return 0;
474}
475
476static int omap_reset_deassert(struct reset_controller_dev *rcdev,
477			       unsigned long id)
478{
479	struct omap_reset_data *reset = to_omap_reset_data(rcdev);
480	u32 v;
481	int st_bit;
482	bool has_rstst;
483	unsigned long flags;
484	struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev);
485	int ret = 0;
486
487	/* Nothing to do if the reset is already deasserted */
488	if (!omap_reset_status(rcdev, id))
489		return 0;
490
491	has_rstst = reset->prm->data->rstst ||
492		(reset->prm->data->flags & OMAP_PRM_HAS_RSTST);
493
494	if (has_rstst) {
495		st_bit = omap_reset_get_st_bit(reset, id);
496
497		/* Clear the reset status by writing 1 to the status bit */
498		v = 1 << st_bit;
499		writel_relaxed(v, reset->prm->base + reset->prm->data->rstst);
500	}
501
502	if (reset->clkdm)
503		pdata->clkdm_deny_idle(reset->clkdm);
504
505	/* de-assert the reset control line */
506	spin_lock_irqsave(&reset->lock, flags);
507	v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
508	v &= ~(1 << id);
509	writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
510	spin_unlock_irqrestore(&reset->lock, flags);
511
512	/* wait for the reset bit to clear */
513	ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
514						reset->prm->data->rstctrl,
515						v, !(v & BIT(id)), 1,
516						OMAP_RESET_MAX_WAIT);
517	if (ret)
518		pr_err("%s: timedout waiting for %s:%lu\n", __func__,
519		       reset->prm->data->name, id);
520
521	/* wait for the status to be set */
522	if (has_rstst) {
523		ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
524						 reset->prm->data->rstst,
525						 v, v & BIT(st_bit), 1,
526						 OMAP_RESET_MAX_WAIT);
527		if (ret)
528			pr_err("%s: timedout waiting for %s:%lu\n", __func__,
529			       reset->prm->data->name, id);
530	}
531
532	if (reset->clkdm)
533		pdata->clkdm_allow_idle(reset->clkdm);
534
535	return ret;
536}
537
538static const struct reset_control_ops omap_reset_ops = {
539	.assert		= omap_reset_assert,
540	.deassert	= omap_reset_deassert,
541	.status		= omap_reset_status,
542};
543
544static int omap_prm_reset_xlate(struct reset_controller_dev *rcdev,
545				const struct of_phandle_args *reset_spec)
546{
547	struct omap_reset_data *reset = to_omap_reset_data(rcdev);
548
549	if (!_is_valid_reset(reset, reset_spec->args[0]))
550		return -EINVAL;
551
552	return reset_spec->args[0];
553}
554
555static int omap_prm_reset_init(struct platform_device *pdev,
556			       struct omap_prm *prm)
557{
558	struct omap_reset_data *reset;
559	const struct omap_rst_map *map;
560	struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev);
561	char buf[32];
562	u32 v;
563
564	/*
565	 * Check if we have controllable resets. If either rstctrl is non-zero
566	 * or OMAP_PRM_HAS_RSTCTRL flag is set, we have reset control register
567	 * for the domain.
568	 */
569	if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL))
570		return 0;
571
572	/* Check if we have the pdata callbacks in place */
573	if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle ||
574	    !pdata->clkdm_allow_idle)
575		return -EINVAL;
576
577	map = prm->data->rstmap;
578	if (!map)
579		return -EINVAL;
580
581	reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
582	if (!reset)
583		return -ENOMEM;
584
585	reset->rcdev.owner = THIS_MODULE;
586	reset->rcdev.ops = &omap_reset_ops;
587	reset->rcdev.of_node = pdev->dev.of_node;
588	reset->rcdev.nr_resets = OMAP_MAX_RESETS;
589	reset->rcdev.of_xlate = omap_prm_reset_xlate;
590	reset->rcdev.of_reset_n_cells = 1;
591	reset->dev = &pdev->dev;
592	spin_lock_init(&reset->lock);
593
594	reset->prm = prm;
595
596	sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name :
597		prm->data->name);
598
599	if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) {
600		reset->clkdm = pdata->clkdm_lookup(buf);
601		if (!reset->clkdm)
602			return -EINVAL;
603	}
604
605	while (map->rst >= 0) {
606		reset->mask |= BIT(map->rst);
607		map++;
608	}
609
610	/* Quirk handling to assert rst_map_012 bits on reset and avoid errors */
611	if (prm->data->rstmap == rst_map_012) {
612		v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
613		if ((v & reset->mask) != reset->mask) {
614			dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v);
615			writel_relaxed(reset->mask, reset->prm->base +
616				       reset->prm->data->rstctrl);
617		}
618	}
619
620	return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
621}
622
623static int omap_prm_probe(struct platform_device *pdev)
624{
625	struct resource *res;
626	const struct omap_prm_data *data;
627	struct omap_prm *prm;
628	const struct of_device_id *match;
629	int ret;
630
631	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
632	if (!res)
633		return -ENODEV;
634
635	match = of_match_device(omap_prm_id_table, &pdev->dev);
636	if (!match)
637		return -ENOTSUPP;
638
639	prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL);
640	if (!prm)
641		return -ENOMEM;
642
643	data = match->data;
644
645	while (data->base != res->start) {
646		if (!data->base)
647			return -EINVAL;
648		data++;
649	}
650
651	prm->data = data;
652
653	prm->base = devm_ioremap_resource(&pdev->dev, res);
654	if (IS_ERR(prm->base))
655		return PTR_ERR(prm->base);
656
657	ret = omap_prm_domain_init(&pdev->dev, prm);
658	if (ret)
659		return ret;
660
661	ret = omap_prm_reset_init(pdev, prm);
662	if (ret)
663		goto err_domain;
664
665	return 0;
666
667err_domain:
668	of_genpd_del_provider(pdev->dev.of_node);
669	pm_genpd_remove(&prm->prmd->pd);
670
671	return ret;
672}
673
674static struct platform_driver omap_prm_driver = {
675	.probe = omap_prm_probe,
676	.driver = {
677		.name		= KBUILD_MODNAME,
678		.of_match_table	= omap_prm_id_table,
679	},
680};
681builtin_platform_driver(omap_prm_driver);
682