xref: /linux/drivers/clk/renesas/renesas-cpg-mssr.c (revision 9f32a03e3e0d372c520d829dd4da6022fe88832a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Renesas Clock Pulse Generator / Module Standby and Software Reset
4  *
5  * Copyright (C) 2015 Glider bvba
6  *
7  * Based on clk-mstp.c, clk-rcar-gen2.c, and clk-rcar-gen3.c
8  *
9  * Copyright (C) 2013 Ideas On Board SPRL
10  * Copyright (C) 2015 Renesas Electronics Corp.
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/clk-provider.h>
15 #include <linux/clk/renesas.h>
16 #include <linux/delay.h>
17 #include <linux/device.h>
18 #include <linux/init.h>
19 #include <linux/io.h>
20 #include <linux/iopoll.h>
21 #include <linux/mod_devicetable.h>
22 #include <linux/module.h>
23 #include <linux/of_address.h>
24 #include <linux/platform_device.h>
25 #include <linux/pm_clock.h>
26 #include <linux/pm_domain.h>
27 #include <linux/psci.h>
28 #include <linux/reset-controller.h>
29 #include <linux/slab.h>
30 #include <linux/string_choices.h>
31 
32 #include <dt-bindings/clock/renesas-cpg-mssr.h>
33 
34 #include "renesas-cpg-mssr.h"
35 #include "clk-div6.h"
36 
37 #ifdef DEBUG
38 #define WARN_DEBUG(x)	WARN_ON(x)
39 #else
40 #define WARN_DEBUG(x)	do { } while (0)
41 #endif
42 
43 /*
44  * Module Standby and Software Reset register offets.
45  *
46  * If the registers exist, these are valid for SH-Mobile, R-Mobile,
47  * R-Car Gen2, R-Car Gen3, and RZ/G1.
48  * These are NOT valid for R-Car Gen1 and RZ/A1!
49  */
50 
51 /*
52  * Module Stop Status Register offsets
53  */
54 
55 static const u16 mstpsr[] = {
56 	0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
57 	0x9A0, 0x9A4, 0x9A8, 0x9AC,
58 };
59 
60 static const u16 mstpsr_for_gen4[] = {
61 	0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
62 	0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38, 0x2E3C,
63 	0x2E40, 0x2E44, 0x2E48, 0x2E4C, 0x2E50, 0x2E54, 0x2E58, 0x2E5C,
64 	0x2E60, 0x2E64, 0x2E68, 0x2E6C, 0x2E70, 0x2E74,
65 };
66 
67 /*
68  * System Module Stop Control Register offsets
69  */
70 
71 static const u16 smstpcr[] = {
72 	0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
73 	0x990, 0x994, 0x998, 0x99C,
74 };
75 
76 static const u16 mstpcr_for_gen4[] = {
77 	0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
78 	0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38, 0x2D3C,
79 	0x2D40, 0x2D44, 0x2D48, 0x2D4C, 0x2D50, 0x2D54, 0x2D58, 0x2D5C,
80 	0x2D60, 0x2D64, 0x2D68, 0x2D6C, 0x2D70, 0x2D74,
81 };
82 
83 /*
84  * Standby Control Register offsets (RZ/A)
85  * Base address is FRQCR register
86  */
87 
88 static const u16 stbcr[] = {
89 	0xFFFF/*dummy*/, 0x010, 0x014, 0x410, 0x414, 0x418, 0x41C, 0x420,
90 	0x424, 0x428, 0x42C,
91 };
92 
93 /*
94  * Software Reset Register offsets
95  */
96 
97 static const u16 srcr[] = {
98 	0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC,
99 	0x920, 0x924, 0x928, 0x92C,
100 };
101 
102 static const u16 srcr_for_gen4[] = {
103 	0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
104 	0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, 0x2C3C,
105 	0x2C40, 0x2C44, 0x2C48, 0x2C4C, 0x2C50, 0x2C54, 0x2C58, 0x2C5C,
106 	0x2C60, 0x2C64, 0x2C68, 0x2C6C, 0x2C70, 0x2C74,
107 };
108 
109 /*
110  * Software Reset Clearing Register offsets
111  */
112 
113 static const u16 srstclr[] = {
114 	0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C,
115 	0x960, 0x964, 0x968, 0x96C,
116 };
117 
118 static const u16 srstclr_for_gen4[] = {
119 	0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
120 	0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8, 0x2CBC,
121 	0x2CC0, 0x2CC4, 0x2CC8, 0x2CCC, 0x2CD0, 0x2CD4, 0x2CD8, 0x2CDC,
122 	0x2CE0, 0x2CE4, 0x2CE8, 0x2CEC, 0x2CF0, 0x2CF4,
123 };
124 
125 /**
126  * struct cpg_mssr_priv - Clock Pulse Generator / Module Standby
127  *                        and Software Reset Private Data
128  *
129  * @rcdev: Optional reset controller entity
130  * @dev: CPG/MSSR device
131  * @base: CPG/MSSR register block base address
132  * @reg_layout: CPG/MSSR register layout
133  * @rmw_lock: protects RMW register accesses
134  * @np: Device node in DT for this CPG/MSSR module
135  * @num_core_clks: Number of Core Clocks in clks[]
136  * @num_mod_clks: Number of Module Clocks in clks[]
137  * @last_dt_core_clk: ID of the last Core Clock exported to DT
138  * @notifiers: Notifier chain to save/restore clock state for system resume
139  * @status_regs: Pointer to status registers array
140  * @control_regs: Pointer to control registers array
141  * @reset_regs: Pointer to reset registers array
142  * @reset_clear_regs:  Pointer to reset clearing registers array
143  * @smstpcr_saved: [].mask: Mask of SMSTPCR[] bits under our control
144  *                 [].val: Saved values of SMSTPCR[]
145  * @reserved_ids: Temporary used, reserved id list
146  * @num_reserved_ids: Temporary used, number of reserved id list
147  * @clks: Array containing all Core and Module Clocks
148  */
149 struct cpg_mssr_priv {
150 #ifdef CONFIG_RESET_CONTROLLER
151 	struct reset_controller_dev rcdev;
152 #endif
153 	struct device *dev;
154 	void __iomem *base;
155 	enum clk_reg_layout reg_layout;
156 	spinlock_t rmw_lock;
157 	struct device_node *np;
158 
159 	unsigned int num_core_clks;
160 	unsigned int num_mod_clks;
161 	unsigned int last_dt_core_clk;
162 
163 	struct raw_notifier_head notifiers;
164 	const u16 *status_regs;
165 	const u16 *control_regs;
166 	const u16 *reset_regs;
167 	const u16 *reset_clear_regs;
168 	struct {
169 		u32 mask;
170 		u32 val;
171 	} smstpcr_saved[ARRAY_SIZE(mstpsr_for_gen4)];
172 
173 	unsigned int *reserved_ids;
174 	unsigned int num_reserved_ids;
175 
176 	struct clk *clks[];
177 };
178 
179 static struct cpg_mssr_priv *cpg_mssr_priv;
180 
181 /**
182  * struct mstp_clock - MSTP gating clock
183  * @hw: handle between common and hardware-specific interfaces
184  * @index: MSTP clock number
185  * @priv: CPG/MSSR private data
186  */
187 struct mstp_clock {
188 	struct clk_hw hw;
189 	u32 index;
190 	struct cpg_mssr_priv *priv;
191 };
192 
193 #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
194 
cpg_mstp_clock_endisable(struct clk_hw * hw,bool enable)195 static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
196 {
197 	struct mstp_clock *clock = to_mstp_clock(hw);
198 	struct cpg_mssr_priv *priv = clock->priv;
199 	unsigned int reg = clock->index / 32;
200 	unsigned int bit = clock->index % 32;
201 	struct device *dev = priv->dev;
202 	u32 bitmask = BIT(bit);
203 	unsigned long flags;
204 	u32 value;
205 	int error;
206 
207 	dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
208 		str_on_off(enable));
209 	spin_lock_irqsave(&priv->rmw_lock, flags);
210 
211 	if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
212 		value = readb(priv->base + priv->control_regs[reg]);
213 		if (enable)
214 			value &= ~bitmask;
215 		else
216 			value |= bitmask;
217 		writeb(value, priv->base + priv->control_regs[reg]);
218 
219 		/* dummy read to ensure write has completed */
220 		readb(priv->base + priv->control_regs[reg]);
221 		barrier_data(priv->base + priv->control_regs[reg]);
222 	} else {
223 		value = readl(priv->base + priv->control_regs[reg]);
224 		if (enable)
225 			value &= ~bitmask;
226 		else
227 			value |= bitmask;
228 		writel(value, priv->base + priv->control_regs[reg]);
229 	}
230 
231 	spin_unlock_irqrestore(&priv->rmw_lock, flags);
232 
233 	if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
234 		return 0;
235 
236 	error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
237 					  value, !(value & bitmask), 0, 10);
238 	if (error)
239 		dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
240 			priv->base + priv->control_regs[reg], bit);
241 
242 	return error;
243 }
244 
cpg_mstp_clock_enable(struct clk_hw * hw)245 static int cpg_mstp_clock_enable(struct clk_hw *hw)
246 {
247 	return cpg_mstp_clock_endisable(hw, true);
248 }
249 
cpg_mstp_clock_disable(struct clk_hw * hw)250 static void cpg_mstp_clock_disable(struct clk_hw *hw)
251 {
252 	cpg_mstp_clock_endisable(hw, false);
253 }
254 
cpg_mstp_clock_is_enabled(struct clk_hw * hw)255 static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
256 {
257 	struct mstp_clock *clock = to_mstp_clock(hw);
258 	struct cpg_mssr_priv *priv = clock->priv;
259 	u32 value;
260 
261 	if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
262 		value = readb(priv->base + priv->control_regs[clock->index / 32]);
263 	else
264 		value = readl(priv->base + priv->status_regs[clock->index / 32]);
265 
266 	return !(value & BIT(clock->index % 32));
267 }
268 
269 static const struct clk_ops cpg_mstp_clock_ops = {
270 	.enable = cpg_mstp_clock_enable,
271 	.disable = cpg_mstp_clock_disable,
272 	.is_enabled = cpg_mstp_clock_is_enabled,
273 };
274 
275 static
cpg_mssr_clk_src_twocell_get(struct of_phandle_args * clkspec,void * data)276 struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
277 					 void *data)
278 {
279 	unsigned int clkidx = clkspec->args[1];
280 	struct cpg_mssr_priv *priv = data;
281 	struct device *dev = priv->dev;
282 	unsigned int idx;
283 	const char *type;
284 	struct clk *clk;
285 	int range_check;
286 
287 	switch (clkspec->args[0]) {
288 	case CPG_CORE:
289 		type = "core";
290 		if (clkidx > priv->last_dt_core_clk) {
291 			dev_err(dev, "Invalid %s clock index %u\n", type,
292 			       clkidx);
293 			return ERR_PTR(-EINVAL);
294 		}
295 		clk = priv->clks[clkidx];
296 		break;
297 
298 	case CPG_MOD:
299 		type = "module";
300 		if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
301 			idx = MOD_CLK_PACK_10(clkidx);
302 			range_check = 7 - (clkidx % 10);
303 		} else {
304 			idx = MOD_CLK_PACK(clkidx);
305 			range_check = 31 - (clkidx % 100);
306 		}
307 		if (range_check < 0 || idx >= priv->num_mod_clks) {
308 			dev_err(dev, "Invalid %s clock index %u\n", type,
309 				clkidx);
310 			return ERR_PTR(-EINVAL);
311 		}
312 		clk = priv->clks[priv->num_core_clks + idx];
313 		break;
314 
315 	default:
316 		dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
317 		return ERR_PTR(-EINVAL);
318 	}
319 
320 	if (IS_ERR(clk))
321 		dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
322 		       PTR_ERR(clk));
323 	else
324 		dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
325 			clkspec->args[0], clkspec->args[1], clk,
326 			clk_get_rate(clk));
327 	return clk;
328 }
329 
cpg_mssr_register_core_clk(const struct cpg_core_clk * core,const struct cpg_mssr_info * info,struct cpg_mssr_priv * priv)330 static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
331 					      const struct cpg_mssr_info *info,
332 					      struct cpg_mssr_priv *priv)
333 {
334 	struct clk *clk = ERR_PTR(-ENOTSUPP), *parent;
335 	struct device *dev = priv->dev;
336 	unsigned int id = core->id, div = core->div;
337 	const char *parent_name;
338 
339 	WARN_DEBUG(id >= priv->num_core_clks);
340 	WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
341 
342 	switch (core->type) {
343 	case CLK_TYPE_IN:
344 		clk = of_clk_get_by_name(priv->np, core->name);
345 		break;
346 
347 	case CLK_TYPE_FF:
348 	case CLK_TYPE_DIV6P1:
349 	case CLK_TYPE_DIV6_RO:
350 		WARN_DEBUG(core->parent >= priv->num_core_clks);
351 		parent = priv->clks[core->parent];
352 		if (IS_ERR(parent)) {
353 			clk = parent;
354 			goto fail;
355 		}
356 
357 		parent_name = __clk_get_name(parent);
358 
359 		if (core->type == CLK_TYPE_DIV6_RO)
360 			/* Multiply with the DIV6 register value */
361 			div *= (readl(priv->base + core->offset) & 0x3f) + 1;
362 
363 		if (core->type == CLK_TYPE_DIV6P1) {
364 			clk = cpg_div6_register(core->name, 1, &parent_name,
365 						priv->base + core->offset,
366 						&priv->notifiers);
367 		} else {
368 			clk = clk_register_fixed_factor(NULL, core->name,
369 							parent_name, 0,
370 							core->mult, div);
371 		}
372 		break;
373 
374 	case CLK_TYPE_FR:
375 		clk = clk_register_fixed_rate(NULL, core->name, NULL, 0,
376 					      core->mult);
377 		break;
378 
379 	default:
380 		if (info->cpg_clk_register)
381 			clk = info->cpg_clk_register(dev, core, info,
382 						     priv->clks, priv->base,
383 						     &priv->notifiers);
384 		else
385 			dev_err(dev, "%s has unsupported core clock type %u\n",
386 				core->name, core->type);
387 		break;
388 	}
389 
390 	if (IS_ERR_OR_NULL(clk))
391 		goto fail;
392 
393 	dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
394 	priv->clks[id] = clk;
395 	return;
396 
397 fail:
398 	dev_err(dev, "Failed to register %s clock %s: %ld\n", "core",
399 		core->name, PTR_ERR(clk));
400 }
401 
cpg_mssr_register_mod_clk(const struct mssr_mod_clk * mod,const struct cpg_mssr_info * info,struct cpg_mssr_priv * priv)402 static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
403 					     const struct cpg_mssr_info *info,
404 					     struct cpg_mssr_priv *priv)
405 {
406 	struct mstp_clock *clock = NULL;
407 	struct device *dev = priv->dev;
408 	unsigned int id = mod->id;
409 	struct clk_init_data init = {};
410 	struct clk *parent, *clk;
411 	const char *parent_name;
412 	unsigned int i;
413 
414 	WARN_DEBUG(id < priv->num_core_clks);
415 	WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
416 	WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
417 	WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
418 
419 	if (!mod->name) {
420 		/* Skip NULLified clock */
421 		return;
422 	}
423 
424 	parent = priv->clks[mod->parent];
425 	if (IS_ERR(parent)) {
426 		clk = parent;
427 		goto fail;
428 	}
429 
430 	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
431 	if (!clock) {
432 		clk = ERR_PTR(-ENOMEM);
433 		goto fail;
434 	}
435 
436 	init.name = mod->name;
437 	init.ops = &cpg_mstp_clock_ops;
438 	init.flags = CLK_SET_RATE_PARENT;
439 	parent_name = __clk_get_name(parent);
440 	init.parent_names = &parent_name;
441 	init.num_parents = 1;
442 
443 	clock->index = id - priv->num_core_clks;
444 	clock->priv = priv;
445 	clock->hw.init = &init;
446 
447 	for (i = 0; i < info->num_crit_mod_clks; i++)
448 		if (id == info->crit_mod_clks[i] &&
449 		    cpg_mstp_clock_is_enabled(&clock->hw)) {
450 			dev_dbg(dev, "MSTP %s setting CLK_IS_CRITICAL\n",
451 				mod->name);
452 			init.flags |= CLK_IS_CRITICAL;
453 			break;
454 		}
455 
456 	/*
457 	 * Ignore reserved device.
458 	 * see
459 	 *	cpg_mssr_reserved_init()
460 	 */
461 	for (i = 0; i < priv->num_reserved_ids; i++) {
462 		if (id == priv->reserved_ids[i]) {
463 			dev_info(dev, "Ignore Linux non-assigned mod (%s)\n", mod->name);
464 			init.flags |= CLK_IGNORE_UNUSED;
465 			break;
466 		}
467 	}
468 
469 	clk = clk_register(NULL, &clock->hw);
470 	if (IS_ERR(clk))
471 		goto fail;
472 
473 	dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
474 	priv->clks[id] = clk;
475 	priv->smstpcr_saved[clock->index / 32].mask |= BIT(clock->index % 32);
476 	return;
477 
478 fail:
479 	dev_err(dev, "Failed to register %s clock %s: %ld\n", "module",
480 		mod->name, PTR_ERR(clk));
481 	kfree(clock);
482 }
483 
484 struct cpg_mssr_clk_domain {
485 	struct generic_pm_domain genpd;
486 	unsigned int num_core_pm_clks;
487 	unsigned int core_pm_clks[];
488 };
489 
490 static struct cpg_mssr_clk_domain *cpg_mssr_clk_domain;
491 
cpg_mssr_is_pm_clk(const struct of_phandle_args * clkspec,struct cpg_mssr_clk_domain * pd)492 static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
493 			       struct cpg_mssr_clk_domain *pd)
494 {
495 	unsigned int i;
496 
497 	if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2)
498 		return false;
499 
500 	switch (clkspec->args[0]) {
501 	case CPG_CORE:
502 		for (i = 0; i < pd->num_core_pm_clks; i++)
503 			if (clkspec->args[1] == pd->core_pm_clks[i])
504 				return true;
505 		return false;
506 
507 	case CPG_MOD:
508 		return true;
509 
510 	default:
511 		return false;
512 	}
513 }
514 
cpg_mssr_attach_dev(struct generic_pm_domain * unused,struct device * dev)515 int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev)
516 {
517 	struct cpg_mssr_clk_domain *pd = cpg_mssr_clk_domain;
518 	struct device_node *np = dev->of_node;
519 	struct of_phandle_args clkspec;
520 	struct clk *clk;
521 	int i = 0;
522 	int error;
523 
524 	if (!pd) {
525 		dev_dbg(dev, "CPG/MSSR clock domain not yet available\n");
526 		return -EPROBE_DEFER;
527 	}
528 
529 	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
530 					   &clkspec)) {
531 		if (cpg_mssr_is_pm_clk(&clkspec, pd))
532 			goto found;
533 
534 		of_node_put(clkspec.np);
535 		i++;
536 	}
537 
538 	return 0;
539 
540 found:
541 	clk = of_clk_get_from_provider(&clkspec);
542 	of_node_put(clkspec.np);
543 
544 	if (IS_ERR(clk))
545 		return PTR_ERR(clk);
546 
547 	error = pm_clk_create(dev);
548 	if (error)
549 		goto fail_put;
550 
551 	error = pm_clk_add_clk(dev, clk);
552 	if (error)
553 		goto fail_destroy;
554 
555 	return 0;
556 
557 fail_destroy:
558 	pm_clk_destroy(dev);
559 fail_put:
560 	clk_put(clk);
561 	return error;
562 }
563 
cpg_mssr_detach_dev(struct generic_pm_domain * unused,struct device * dev)564 void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
565 {
566 	if (!pm_clk_no_clocks(dev))
567 		pm_clk_destroy(dev);
568 }
569 
cpg_mssr_genpd_remove(void * data)570 static void cpg_mssr_genpd_remove(void *data)
571 {
572 	pm_genpd_remove(data);
573 }
574 
cpg_mssr_add_clk_domain(struct device * dev,const unsigned int * core_pm_clks,unsigned int num_core_pm_clks)575 static int __init cpg_mssr_add_clk_domain(struct device *dev,
576 					  const unsigned int *core_pm_clks,
577 					  unsigned int num_core_pm_clks)
578 {
579 	struct device_node *np = dev->of_node;
580 	struct generic_pm_domain *genpd;
581 	struct cpg_mssr_clk_domain *pd;
582 	size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]);
583 	int ret;
584 
585 	pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL);
586 	if (!pd)
587 		return -ENOMEM;
588 
589 	pd->num_core_pm_clks = num_core_pm_clks;
590 	memcpy(pd->core_pm_clks, core_pm_clks, pm_size);
591 
592 	genpd = &pd->genpd;
593 	genpd->name = np->name;
594 	genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
595 		       GENPD_FLAG_ACTIVE_WAKEUP;
596 	genpd->attach_dev = cpg_mssr_attach_dev;
597 	genpd->detach_dev = cpg_mssr_detach_dev;
598 	ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
599 	if (ret)
600 		return ret;
601 
602 	ret = devm_add_action_or_reset(dev, cpg_mssr_genpd_remove, genpd);
603 	if (ret)
604 		return ret;
605 
606 	cpg_mssr_clk_domain = pd;
607 
608 	return of_genpd_add_provider_simple(np, genpd);
609 }
610 
611 #ifdef CONFIG_RESET_CONTROLLER
612 
613 #define rcdev_to_priv(x)	container_of(x, struct cpg_mssr_priv, rcdev)
614 
cpg_mssr_reset(struct reset_controller_dev * rcdev,unsigned long id)615 static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
616 			  unsigned long id)
617 {
618 	struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
619 	unsigned int reg = id / 32;
620 	unsigned int bit = id % 32;
621 	u32 bitmask = BIT(bit);
622 
623 	dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
624 
625 	/* Reset module */
626 	writel(bitmask, priv->base + priv->reset_regs[reg]);
627 
628 	/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
629 	udelay(35);
630 
631 	/* Release module from reset state */
632 	writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
633 
634 	return 0;
635 }
636 
cpg_mssr_assert(struct reset_controller_dev * rcdev,unsigned long id)637 static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
638 {
639 	struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
640 	unsigned int reg = id / 32;
641 	unsigned int bit = id % 32;
642 	u32 bitmask = BIT(bit);
643 
644 	dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
645 
646 	writel(bitmask, priv->base + priv->reset_regs[reg]);
647 	return 0;
648 }
649 
cpg_mssr_deassert(struct reset_controller_dev * rcdev,unsigned long id)650 static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
651 			     unsigned long id)
652 {
653 	struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
654 	unsigned int reg = id / 32;
655 	unsigned int bit = id % 32;
656 	u32 bitmask = BIT(bit);
657 
658 	dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
659 
660 	writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
661 	return 0;
662 }
663 
cpg_mssr_status(struct reset_controller_dev * rcdev,unsigned long id)664 static int cpg_mssr_status(struct reset_controller_dev *rcdev,
665 			   unsigned long id)
666 {
667 	struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
668 	unsigned int reg = id / 32;
669 	unsigned int bit = id % 32;
670 	u32 bitmask = BIT(bit);
671 
672 	return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
673 }
674 
675 static const struct reset_control_ops cpg_mssr_reset_ops = {
676 	.reset = cpg_mssr_reset,
677 	.assert = cpg_mssr_assert,
678 	.deassert = cpg_mssr_deassert,
679 	.status = cpg_mssr_status,
680 };
681 
cpg_mssr_reset_xlate(struct reset_controller_dev * rcdev,const struct of_phandle_args * reset_spec)682 static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev,
683 				const struct of_phandle_args *reset_spec)
684 {
685 	struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
686 	unsigned int unpacked = reset_spec->args[0];
687 	unsigned int idx = MOD_CLK_PACK(unpacked);
688 
689 	if (unpacked % 100 > 31 || idx >= rcdev->nr_resets) {
690 		dev_err(priv->dev, "Invalid reset index %u\n", unpacked);
691 		return -EINVAL;
692 	}
693 
694 	return idx;
695 }
696 
cpg_mssr_reset_controller_register(struct cpg_mssr_priv * priv)697 static int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
698 {
699 	priv->rcdev.ops = &cpg_mssr_reset_ops;
700 	priv->rcdev.of_node = priv->dev->of_node;
701 	priv->rcdev.of_reset_n_cells = 1;
702 	priv->rcdev.of_xlate = cpg_mssr_reset_xlate;
703 	priv->rcdev.nr_resets = priv->num_mod_clks;
704 	return devm_reset_controller_register(priv->dev, &priv->rcdev);
705 }
706 
707 #else /* !CONFIG_RESET_CONTROLLER */
cpg_mssr_reset_controller_register(struct cpg_mssr_priv * priv)708 static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
709 {
710 	return 0;
711 }
712 #endif /* !CONFIG_RESET_CONTROLLER */
713 
714 static const struct of_device_id cpg_mssr_match[] = {
715 #ifdef CONFIG_CLK_R7S9210
716 	{
717 		.compatible = "renesas,r7s9210-cpg-mssr",
718 		.data = &r7s9210_cpg_mssr_info,
719 	},
720 #endif
721 #ifdef CONFIG_CLK_R8A7742
722 	{
723 		.compatible = "renesas,r8a7742-cpg-mssr",
724 		.data = &r8a7742_cpg_mssr_info,
725 	},
726 #endif
727 #ifdef CONFIG_CLK_R8A7743
728 	{
729 		.compatible = "renesas,r8a7743-cpg-mssr",
730 		.data = &r8a7743_cpg_mssr_info,
731 	},
732 	/* RZ/G1N is (almost) identical to RZ/G1M w.r.t. clocks. */
733 	{
734 		.compatible = "renesas,r8a7744-cpg-mssr",
735 		.data = &r8a7743_cpg_mssr_info,
736 	},
737 #endif
738 #ifdef CONFIG_CLK_R8A7745
739 	{
740 		.compatible = "renesas,r8a7745-cpg-mssr",
741 		.data = &r8a7745_cpg_mssr_info,
742 	},
743 #endif
744 #ifdef CONFIG_CLK_R8A77470
745 	{
746 		.compatible = "renesas,r8a77470-cpg-mssr",
747 		.data = &r8a77470_cpg_mssr_info,
748 	},
749 #endif
750 #ifdef CONFIG_CLK_R8A774A1
751 	{
752 		.compatible = "renesas,r8a774a1-cpg-mssr",
753 		.data = &r8a774a1_cpg_mssr_info,
754 	},
755 #endif
756 #ifdef CONFIG_CLK_R8A774B1
757 	{
758 		.compatible = "renesas,r8a774b1-cpg-mssr",
759 		.data = &r8a774b1_cpg_mssr_info,
760 	},
761 #endif
762 #ifdef CONFIG_CLK_R8A774C0
763 	{
764 		.compatible = "renesas,r8a774c0-cpg-mssr",
765 		.data = &r8a774c0_cpg_mssr_info,
766 	},
767 #endif
768 #ifdef CONFIG_CLK_R8A774E1
769 	{
770 		.compatible = "renesas,r8a774e1-cpg-mssr",
771 		.data = &r8a774e1_cpg_mssr_info,
772 	},
773 #endif
774 #ifdef CONFIG_CLK_R8A7790
775 	{
776 		.compatible = "renesas,r8a7790-cpg-mssr",
777 		.data = &r8a7790_cpg_mssr_info,
778 	},
779 #endif
780 #ifdef CONFIG_CLK_R8A7791
781 	{
782 		.compatible = "renesas,r8a7791-cpg-mssr",
783 		.data = &r8a7791_cpg_mssr_info,
784 	},
785 	/* R-Car M2-N is (almost) identical to R-Car M2-W w.r.t. clocks. */
786 	{
787 		.compatible = "renesas,r8a7793-cpg-mssr",
788 		.data = &r8a7791_cpg_mssr_info,
789 	},
790 #endif
791 #ifdef CONFIG_CLK_R8A7792
792 	{
793 		.compatible = "renesas,r8a7792-cpg-mssr",
794 		.data = &r8a7792_cpg_mssr_info,
795 	},
796 #endif
797 #ifdef CONFIG_CLK_R8A7794
798 	{
799 		.compatible = "renesas,r8a7794-cpg-mssr",
800 		.data = &r8a7794_cpg_mssr_info,
801 	},
802 #endif
803 #ifdef CONFIG_CLK_R8A7795
804 	{
805 		.compatible = "renesas,r8a7795-cpg-mssr",
806 		.data = &r8a7795_cpg_mssr_info,
807 	},
808 #endif
809 #ifdef CONFIG_CLK_R8A77960
810 	{
811 		.compatible = "renesas,r8a7796-cpg-mssr",
812 		.data = &r8a7796_cpg_mssr_info,
813 	},
814 #endif
815 #ifdef CONFIG_CLK_R8A77961
816 	{
817 		.compatible = "renesas,r8a77961-cpg-mssr",
818 		.data = &r8a7796_cpg_mssr_info,
819 	},
820 #endif
821 #ifdef CONFIG_CLK_R8A77965
822 	{
823 		.compatible = "renesas,r8a77965-cpg-mssr",
824 		.data = &r8a77965_cpg_mssr_info,
825 	},
826 #endif
827 #ifdef CONFIG_CLK_R8A77970
828 	{
829 		.compatible = "renesas,r8a77970-cpg-mssr",
830 		.data = &r8a77970_cpg_mssr_info,
831 	},
832 #endif
833 #ifdef CONFIG_CLK_R8A77980
834 	{
835 		.compatible = "renesas,r8a77980-cpg-mssr",
836 		.data = &r8a77980_cpg_mssr_info,
837 	},
838 #endif
839 #ifdef CONFIG_CLK_R8A77990
840 	{
841 		.compatible = "renesas,r8a77990-cpg-mssr",
842 		.data = &r8a77990_cpg_mssr_info,
843 	},
844 #endif
845 #ifdef CONFIG_CLK_R8A77995
846 	{
847 		.compatible = "renesas,r8a77995-cpg-mssr",
848 		.data = &r8a77995_cpg_mssr_info,
849 	},
850 #endif
851 #ifdef CONFIG_CLK_R8A779A0
852 	{
853 		.compatible = "renesas,r8a779a0-cpg-mssr",
854 		.data = &r8a779a0_cpg_mssr_info,
855 	},
856 #endif
857 #ifdef CONFIG_CLK_R8A779F0
858 	{
859 		.compatible = "renesas,r8a779f0-cpg-mssr",
860 		.data = &r8a779f0_cpg_mssr_info,
861 	},
862 #endif
863 #ifdef CONFIG_CLK_R8A779G0
864 	{
865 		.compatible = "renesas,r8a779g0-cpg-mssr",
866 		.data = &r8a779g0_cpg_mssr_info,
867 	},
868 #endif
869 #ifdef CONFIG_CLK_R8A779H0
870 	{
871 		.compatible = "renesas,r8a779h0-cpg-mssr",
872 		.data = &r8a779h0_cpg_mssr_info,
873 	},
874 #endif
875 	{ /* sentinel */ }
876 };
877 
cpg_mssr_del_clk_provider(void * data)878 static void cpg_mssr_del_clk_provider(void *data)
879 {
880 	of_clk_del_provider(data);
881 }
882 
883 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM_PSCI_FW)
cpg_mssr_suspend_noirq(struct device * dev)884 static int cpg_mssr_suspend_noirq(struct device *dev)
885 {
886 	struct cpg_mssr_priv *priv = dev_get_drvdata(dev);
887 	unsigned int reg;
888 
889 	/* This is the best we can do to check for the presence of PSCI */
890 	if (!psci_ops.cpu_suspend)
891 		return 0;
892 
893 	/* Save module registers with bits under our control */
894 	for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
895 		if (priv->smstpcr_saved[reg].mask)
896 			priv->smstpcr_saved[reg].val =
897 				priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
898 				readb(priv->base + priv->control_regs[reg]) :
899 				readl(priv->base + priv->control_regs[reg]);
900 	}
901 
902 	/* Save core clocks */
903 	raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL);
904 
905 	return 0;
906 }
907 
cpg_mssr_resume_noirq(struct device * dev)908 static int cpg_mssr_resume_noirq(struct device *dev)
909 {
910 	struct cpg_mssr_priv *priv = dev_get_drvdata(dev);
911 	unsigned int reg;
912 	u32 mask, oldval, newval;
913 	int error;
914 
915 	/* This is the best we can do to check for the presence of PSCI */
916 	if (!psci_ops.cpu_suspend)
917 		return 0;
918 
919 	/* Restore core clocks */
920 	raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL);
921 
922 	/* Restore module clocks */
923 	for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
924 		mask = priv->smstpcr_saved[reg].mask;
925 		if (!mask)
926 			continue;
927 
928 		if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
929 			oldval = readb(priv->base + priv->control_regs[reg]);
930 		else
931 			oldval = readl(priv->base + priv->control_regs[reg]);
932 		newval = oldval & ~mask;
933 		newval |= priv->smstpcr_saved[reg].val & mask;
934 		if (newval == oldval)
935 			continue;
936 
937 		if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
938 			writeb(newval, priv->base + priv->control_regs[reg]);
939 			/* dummy read to ensure write has completed */
940 			readb(priv->base + priv->control_regs[reg]);
941 			barrier_data(priv->base + priv->control_regs[reg]);
942 			continue;
943 		} else
944 			writel(newval, priv->base + priv->control_regs[reg]);
945 
946 		/* Wait until enabled clocks are really enabled */
947 		mask &= ~priv->smstpcr_saved[reg].val;
948 		if (!mask)
949 			continue;
950 
951 		error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
952 						oldval, !(oldval & mask), 0, 10);
953 		if (error)
954 			dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg,
955 				 oldval & mask);
956 	}
957 
958 	return 0;
959 }
960 
961 static const struct dev_pm_ops cpg_mssr_pm = {
962 	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cpg_mssr_suspend_noirq,
963 				      cpg_mssr_resume_noirq)
964 };
965 #define DEV_PM_OPS	&cpg_mssr_pm
966 #else
967 #define DEV_PM_OPS	NULL
968 #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
969 
cpg_mssr_reserved_exit(struct cpg_mssr_priv * priv)970 static void __init cpg_mssr_reserved_exit(struct cpg_mssr_priv *priv)
971 {
972 	kfree(priv->reserved_ids);
973 }
974 
cpg_mssr_reserved_init(struct cpg_mssr_priv * priv,const struct cpg_mssr_info * info)975 static int __init cpg_mssr_reserved_init(struct cpg_mssr_priv *priv,
976 					 const struct cpg_mssr_info *info)
977 {
978 	struct device_node *soc __free(device_node) = of_find_node_by_path("/soc");
979 	struct device_node *node;
980 	uint32_t args[MAX_PHANDLE_ARGS];
981 	unsigned int *ids = NULL;
982 	unsigned int num = 0;
983 
984 	/*
985 	 * Because clk_disable_unused() will disable all unused clocks, the device which is assigned
986 	 * to a non-Linux system will be disabled when Linux is booted.
987 	 *
988 	 * To avoid such situation, renesas-cpg-mssr assumes the device which has
989 	 * status = "reserved" is assigned to a non-Linux system, and adds CLK_IGNORE_UNUSED flag
990 	 * to its CPG_MOD clocks.
991 	 * see also
992 	 *	cpg_mssr_register_mod_clk()
993 	 *
994 	 *	scif5: serial@e6f30000 {
995 	 *		...
996 	 * =>		clocks = <&cpg CPG_MOD 202>,
997 	 *			 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
998 	 *			 <&scif_clk>;
999 	 *			 ...
1000 	 *		 status = "reserved";
1001 	 *	};
1002 	 */
1003 	for_each_reserved_child_of_node(soc, node) {
1004 		struct of_phandle_iterator it;
1005 		int rc;
1006 
1007 		of_for_each_phandle(&it, rc, node, "clocks", "#clock-cells", -1) {
1008 			int idx;
1009 
1010 			if (it.node != priv->np)
1011 				continue;
1012 
1013 			if (of_phandle_iterator_args(&it, args, MAX_PHANDLE_ARGS) != 2)
1014 				continue;
1015 
1016 			if (args[0] != CPG_MOD)
1017 				continue;
1018 
1019 			ids = krealloc_array(ids, (num + 1), sizeof(*ids), GFP_KERNEL);
1020 			if (!ids) {
1021 				of_node_put(it.node);
1022 				return -ENOMEM;
1023 			}
1024 
1025 			if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
1026 				idx = MOD_CLK_PACK_10(args[1]);	/* for DEF_MOD_STB() */
1027 			else
1028 				idx = MOD_CLK_PACK(args[1]);	/* for DEF_MOD() */
1029 
1030 			ids[num] = info->num_total_core_clks + idx;
1031 
1032 			num++;
1033 		}
1034 	}
1035 
1036 	priv->num_reserved_ids	= num;
1037 	priv->reserved_ids	= ids;
1038 
1039 	return 0;
1040 }
1041 
cpg_mssr_common_init(struct device * dev,struct device_node * np,const struct cpg_mssr_info * info)1042 static int __init cpg_mssr_common_init(struct device *dev,
1043 				       struct device_node *np,
1044 				       const struct cpg_mssr_info *info)
1045 {
1046 	struct cpg_mssr_priv *priv;
1047 	unsigned int nclks, i;
1048 	int error;
1049 
1050 	if (info->init) {
1051 		error = info->init(dev);
1052 		if (error)
1053 			return error;
1054 	}
1055 
1056 	nclks = info->num_total_core_clks + info->num_hw_mod_clks;
1057 	priv = kzalloc(struct_size(priv, clks, nclks), GFP_KERNEL);
1058 	if (!priv)
1059 		return -ENOMEM;
1060 
1061 	priv->np = np;
1062 	priv->dev = dev;
1063 	spin_lock_init(&priv->rmw_lock);
1064 
1065 	priv->base = of_iomap(np, 0);
1066 	if (!priv->base) {
1067 		error = -ENOMEM;
1068 		goto out_err;
1069 	}
1070 
1071 	priv->num_core_clks = info->num_total_core_clks;
1072 	priv->num_mod_clks = info->num_hw_mod_clks;
1073 	priv->last_dt_core_clk = info->last_dt_core_clk;
1074 	RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
1075 	priv->reg_layout = info->reg_layout;
1076 	if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
1077 		priv->status_regs = mstpsr;
1078 		priv->control_regs = smstpcr;
1079 		priv->reset_regs = srcr;
1080 		priv->reset_clear_regs = srstclr;
1081 	} else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
1082 		priv->control_regs = stbcr;
1083 	} else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
1084 		priv->status_regs = mstpsr_for_gen4;
1085 		priv->control_regs = mstpcr_for_gen4;
1086 		priv->reset_regs = srcr_for_gen4;
1087 		priv->reset_clear_regs = srstclr_for_gen4;
1088 	} else {
1089 		error = -EINVAL;
1090 		goto out_err;
1091 	}
1092 
1093 	for (i = 0; i < nclks; i++)
1094 		priv->clks[i] = ERR_PTR(-ENOENT);
1095 
1096 	error = cpg_mssr_reserved_init(priv, info);
1097 	if (error)
1098 		goto out_err;
1099 
1100 	error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
1101 	if (error)
1102 		goto reserve_err;
1103 
1104 	cpg_mssr_priv = priv;
1105 
1106 	return 0;
1107 
1108 reserve_err:
1109 	cpg_mssr_reserved_exit(priv);
1110 out_err:
1111 	if (priv->base)
1112 		iounmap(priv->base);
1113 	kfree(priv);
1114 
1115 	return error;
1116 }
1117 
cpg_mssr_early_init(struct device_node * np,const struct cpg_mssr_info * info)1118 void __init cpg_mssr_early_init(struct device_node *np,
1119 				const struct cpg_mssr_info *info)
1120 {
1121 	int error;
1122 	int i;
1123 
1124 	error = cpg_mssr_common_init(NULL, np, info);
1125 	if (error)
1126 		return;
1127 
1128 	for (i = 0; i < info->num_early_core_clks; i++)
1129 		cpg_mssr_register_core_clk(&info->early_core_clks[i], info,
1130 					   cpg_mssr_priv);
1131 
1132 	for (i = 0; i < info->num_early_mod_clks; i++)
1133 		cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info,
1134 					  cpg_mssr_priv);
1135 
1136 }
1137 
cpg_mssr_probe(struct platform_device * pdev)1138 static int __init cpg_mssr_probe(struct platform_device *pdev)
1139 {
1140 	struct device *dev = &pdev->dev;
1141 	struct device_node *np = dev->of_node;
1142 	const struct cpg_mssr_info *info;
1143 	struct cpg_mssr_priv *priv;
1144 	unsigned int i;
1145 	int error;
1146 
1147 	info = of_device_get_match_data(dev);
1148 
1149 	if (!cpg_mssr_priv) {
1150 		error = cpg_mssr_common_init(dev, dev->of_node, info);
1151 		if (error)
1152 			return error;
1153 	}
1154 
1155 	priv = cpg_mssr_priv;
1156 	priv->dev = dev;
1157 	dev_set_drvdata(dev, priv);
1158 
1159 	for (i = 0; i < info->num_core_clks; i++)
1160 		cpg_mssr_register_core_clk(&info->core_clks[i], info, priv);
1161 
1162 	for (i = 0; i < info->num_mod_clks; i++)
1163 		cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv);
1164 
1165 	error = devm_add_action_or_reset(dev,
1166 					 cpg_mssr_del_clk_provider,
1167 					 np);
1168 	if (error)
1169 		goto reserve_exit;
1170 
1171 	error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks,
1172 					info->num_core_pm_clks);
1173 	if (error)
1174 		goto reserve_exit;
1175 
1176 	/* Reset Controller not supported for Standby Control SoCs */
1177 	if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
1178 		goto reserve_exit;
1179 
1180 	error = cpg_mssr_reset_controller_register(priv);
1181 
1182 reserve_exit:
1183 	cpg_mssr_reserved_exit(priv);
1184 
1185 	return error;
1186 }
1187 
1188 static struct platform_driver cpg_mssr_driver = {
1189 	.driver		= {
1190 		.name	= "renesas-cpg-mssr",
1191 		.of_match_table = cpg_mssr_match,
1192 		.pm = DEV_PM_OPS,
1193 	},
1194 };
1195 
cpg_mssr_init(void)1196 static int __init cpg_mssr_init(void)
1197 {
1198 	return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe);
1199 }
1200 
1201 subsys_initcall(cpg_mssr_init);
1202 
mssr_mod_nullify(struct mssr_mod_clk * mod_clks,unsigned int num_mod_clks,const unsigned int * clks,unsigned int n)1203 void __init mssr_mod_nullify(struct mssr_mod_clk *mod_clks,
1204 			     unsigned int num_mod_clks,
1205 			     const unsigned int *clks, unsigned int n)
1206 {
1207 	unsigned int i, j;
1208 
1209 	for (i = 0, j = 0; i < num_mod_clks && j < n; i++)
1210 		if (mod_clks[i].id == clks[j]) {
1211 			mod_clks[i].name = NULL;
1212 			j++;
1213 		}
1214 }
1215 
1216 MODULE_DESCRIPTION("Renesas CPG/MSSR Driver");
1217