File Index
Files and directories
Sign in
FILE

armada-37xx-cpufreq.c

File preview with syntax highlighting.

linux-6.19.14/drivers/cpufreq/armada-37xx-cpufreq.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * CPU frequency scaling support for Armada 37xx platform.
  4 *
  5 * Copyright (C) 2017 Marvell
  6 *
  7 * Gregory CLEMENT <gregory.clement@free-electrons.com>
  8 */
  9
 10#include <linux/clk.h>
 11#include <linux/cpu.h>
 12#include <linux/cpufreq.h>
 13#include <linux/err.h>
 14#include <linux/interrupt.h>
 15#include <linux/io.h>
 16#include <linux/mfd/syscon.h>
 17#include <linux/mod_devicetable.h>
 18#include <linux/module.h>
 19#include <linux/platform_device.h>
 20#include <linux/pm_opp.h>
 21#include <linux/regmap.h>
 22#include <linux/slab.h>
 23
 24#include "cpufreq-dt.h"
 25
 26/* Clk register set */
 27#define ARMADA_37XX_CLK_TBG_SEL		0
 28#define ARMADA_37XX_CLK_TBG_SEL_CPU_OFF	22
 29
 30/* Power management in North Bridge register set */
 31#define ARMADA_37XX_NB_L0L1	0x18
 32#define ARMADA_37XX_NB_L2L3	0x1C
 33#define  ARMADA_37XX_NB_TBG_DIV_OFF	13
 34#define  ARMADA_37XX_NB_TBG_DIV_MASK	0x7
 35#define  ARMADA_37XX_NB_CLK_SEL_OFF	11
 36#define  ARMADA_37XX_NB_CLK_SEL_MASK	0x1
 37#define  ARMADA_37XX_NB_CLK_SEL_TBG	0x1
 38#define  ARMADA_37XX_NB_TBG_SEL_OFF	9
 39#define  ARMADA_37XX_NB_TBG_SEL_MASK	0x3
 40#define  ARMADA_37XX_NB_VDD_SEL_OFF	6
 41#define  ARMADA_37XX_NB_VDD_SEL_MASK	0x3
 42#define  ARMADA_37XX_NB_CONFIG_SHIFT	16
 43#define ARMADA_37XX_NB_DYN_MOD	0x24
 44#define  ARMADA_37XX_NB_CLK_SEL_EN	BIT(26)
 45#define  ARMADA_37XX_NB_TBG_EN		BIT(28)
 46#define  ARMADA_37XX_NB_DIV_EN		BIT(29)
 47#define  ARMADA_37XX_NB_VDD_EN		BIT(30)
 48#define  ARMADA_37XX_NB_DFS_EN		BIT(31)
 49#define ARMADA_37XX_NB_CPU_LOAD 0x30
 50#define  ARMADA_37XX_NB_CPU_LOAD_MASK	0x3
 51#define  ARMADA_37XX_DVFS_LOAD_0	0
 52#define  ARMADA_37XX_DVFS_LOAD_1	1
 53#define  ARMADA_37XX_DVFS_LOAD_2	2
 54#define  ARMADA_37XX_DVFS_LOAD_3	3
 55
 56/* AVS register set */
 57#define ARMADA_37XX_AVS_CTL0		0x0
 58#define	 ARMADA_37XX_AVS_ENABLE		BIT(30)
 59#define	 ARMADA_37XX_AVS_HIGH_VDD_LIMIT	16
 60#define	 ARMADA_37XX_AVS_LOW_VDD_LIMIT	22
 61#define	 ARMADA_37XX_AVS_VDD_MASK	0x3F
 62#define ARMADA_37XX_AVS_CTL2		0x8
 63#define	 ARMADA_37XX_AVS_LOW_VDD_EN	BIT(6)
 64#define ARMADA_37XX_AVS_VSET(x)	    (0x1C + 4 * (x))
 65
 66/*
 67 * On Armada 37xx the Power management manages 4 level of CPU load,
 68 * each level can be associated with a CPU clock source, a CPU
 69 * divider, a VDD level, etc...
 70 */
 71#define LOAD_LEVEL_NR	4
 72
 73#define MIN_VOLT_MV 1000
 74#define MIN_VOLT_MV_FOR_L1_1000MHZ 1108
 75#define MIN_VOLT_MV_FOR_L1_1200MHZ 1155
 76
 77/*  AVS value for the corresponding voltage (in mV) */
 78static int avs_map[] = {
 79	747, 758, 770, 782, 793, 805, 817, 828, 840, 852, 863, 875, 887, 898,
 80	910, 922, 933, 945, 957, 968, 980, 992, 1003, 1015, 1027, 1038, 1050,
 81	1062, 1073, 1085, 1097, 1108, 1120, 1132, 1143, 1155, 1167, 1178, 1190,
 82	1202, 1213, 1225, 1237, 1248, 1260, 1272, 1283, 1295, 1307, 1318, 1330,
 83	1342
 84};
 85
 86struct armada37xx_cpufreq_state {
 87	struct platform_device *pdev;
 88	struct device *cpu_dev;
 89	struct regmap *regmap;
 90	u32 nb_l0l1;
 91	u32 nb_l2l3;
 92	u32 nb_dyn_mod;
 93	u32 nb_cpu_load;
 94};
 95
 96static struct armada37xx_cpufreq_state *armada37xx_cpufreq_state;
 97
 98struct armada_37xx_dvfs {
 99	u32 cpu_freq_max;
100	u8 divider[LOAD_LEVEL_NR];
101	u32 avs[LOAD_LEVEL_NR];
102};
103
104static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
105	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
106	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
107	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} },
108	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} },
109};
110
111static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)
112{
113	int i;
114
115	for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) {
116		if (freq == armada_37xx_dvfs[i].cpu_freq_max)
117			return &armada_37xx_dvfs[i];
118	}
119
120	pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000);
121	return NULL;
122}
123
124/*
125 * Setup the four level managed by the hardware. Once the four level
126 * will be configured then the DVFS will be enabled.
127 */
128static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
129						 struct regmap *clk_base, u8 *divider)
130{
131	u32 cpu_tbg_sel;
132	int load_lvl;
133
134	/* Determine to which TBG clock is CPU connected */
135	regmap_read(clk_base, ARMADA_37XX_CLK_TBG_SEL, &cpu_tbg_sel);
136	cpu_tbg_sel >>= ARMADA_37XX_CLK_TBG_SEL_CPU_OFF;
137	cpu_tbg_sel &= ARMADA_37XX_NB_TBG_SEL_MASK;
138
139	for (load_lvl = 0; load_lvl < LOAD_LEVEL_NR; load_lvl++) {
140		unsigned int reg, mask, val, offset = 0;
141
142		if (load_lvl <= ARMADA_37XX_DVFS_LOAD_1)
143			reg = ARMADA_37XX_NB_L0L1;
144		else
145			reg = ARMADA_37XX_NB_L2L3;
146
147		if (load_lvl == ARMADA_37XX_DVFS_LOAD_0 ||
148		    load_lvl == ARMADA_37XX_DVFS_LOAD_2)
149			offset += ARMADA_37XX_NB_CONFIG_SHIFT;
150
151		/* Set cpu clock source, for all the level we use TBG */
152		val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF;
153		mask = (ARMADA_37XX_NB_CLK_SEL_MASK
154			<< ARMADA_37XX_NB_CLK_SEL_OFF);
155
156		/* Set TBG index, for all levels we use the same TBG */
157		val = cpu_tbg_sel << ARMADA_37XX_NB_TBG_SEL_OFF;
158		mask = (ARMADA_37XX_NB_TBG_SEL_MASK
159			<< ARMADA_37XX_NB_TBG_SEL_OFF);
160
161		/*
162		 * Set cpu divider based on the pre-computed array in
163		 * order to have balanced step.
164		 */
165		val |= divider[load_lvl] << ARMADA_37XX_NB_TBG_DIV_OFF;
166		mask |= (ARMADA_37XX_NB_TBG_DIV_MASK
167			<< ARMADA_37XX_NB_TBG_DIV_OFF);
168
169		/* Set VDD divider which is actually the load level. */
170		val |= load_lvl << ARMADA_37XX_NB_VDD_SEL_OFF;
171		mask |= (ARMADA_37XX_NB_VDD_SEL_MASK
172			<< ARMADA_37XX_NB_VDD_SEL_OFF);
173
174		val <<= offset;
175		mask <<= offset;
176
177		regmap_update_bits(base, reg, mask, val);
178	}
179}
180
181/*
182 * Find out the armada 37x supported AVS value whose voltage value is
183 * the round-up closest to the target voltage value.
184 */
185static u32 armada_37xx_avs_val_match(int target_vm)
186{
187	u32 avs;
188
189	/* Find out the round-up closest supported voltage value */
190	for (avs = 0; avs < ARRAY_SIZE(avs_map); avs++)
191		if (avs_map[avs] >= target_vm)
192			break;
193
194	/*
195	 * If all supported voltages are smaller than target one,
196	 * choose the largest supported voltage
197	 */
198	if (avs == ARRAY_SIZE(avs_map))
199		avs = ARRAY_SIZE(avs_map) - 1;
200
201	return avs;
202}
203
204/*
205 * For Armada 37xx soc, L0(VSET0) VDD AVS value is set to SVC revision
206 * value or a default value when SVC is not supported.
207 * - L0 can be read out from the register of AVS_CTRL_0 and L0 voltage
208 *   can be got from the mapping table of avs_map.
209 * - L1 voltage should be about 100mv smaller than L0 voltage
210 * - L2 & L3 voltage should be about 150mv smaller than L0 voltage.
211 * This function calculates L1 & L2 & L3 AVS values dynamically based
212 * on L0 voltage and fill all AVS values to the AVS value table.
213 * When base CPU frequency is 1000 or 1200 MHz then there is additional
214 * minimal avs value for load L1.
215 */
216static void __init armada37xx_cpufreq_avs_configure(struct regmap *base,
217						struct armada_37xx_dvfs *dvfs)
218{
219	unsigned int target_vm;
220	int load_level = 0;
221	u32 l0_vdd_min;
222
223	if (base == NULL)
224		return;
225
226	/* Get L0 VDD min value */
227	regmap_read(base, ARMADA_37XX_AVS_CTL0, &l0_vdd_min);
228	l0_vdd_min = (l0_vdd_min >> ARMADA_37XX_AVS_LOW_VDD_LIMIT) &
229		ARMADA_37XX_AVS_VDD_MASK;
230	if (l0_vdd_min >= ARRAY_SIZE(avs_map))  {
231		pr_err("L0 VDD MIN %d is not correct.\n", l0_vdd_min);
232		return;
233	}
234	dvfs->avs[0] = l0_vdd_min;
235
236	if (avs_map[l0_vdd_min] <= MIN_VOLT_MV) {
237		/*
238		 * If L0 voltage is smaller than 1000mv, then all VDD sets
239		 * use L0 voltage;
240		 */
241		u32 avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV);
242
243		for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++)
244			dvfs->avs[load_level] = avs_min;
245
246		/*
247		 * Set the avs values for load L0 and L1 when base CPU frequency
248		 * is 1000/1200 MHz to its typical initial values according to
249		 * the Armada 3700 Hardware Specifications.
250		 */
251		if (dvfs->cpu_freq_max >= 1000*1000*1000) {
252			if (dvfs->cpu_freq_max >= 1200*1000*1000)
253				avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1200MHZ);
254			else
255				avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1000MHZ);
256			dvfs->avs[0] = dvfs->avs[1] = avs_min;
257		}
258
259		return;
260	}
261
262	/*
263	 * L1 voltage is equal to L0 voltage - 100mv and it must be
264	 * larger than 1000mv
265	 */
266
267	target_vm = avs_map[l0_vdd_min] - 100;
268	target_vm = max(target_vm, MIN_VOLT_MV);
269	dvfs->avs[1] = armada_37xx_avs_val_match(target_vm);
270
271	/*
272	 * L2 & L3 voltage is equal to L0 voltage - 150mv and it must
273	 * be larger than 1000mv
274	 */
275	target_vm = avs_map[l0_vdd_min] - 150;
276	target_vm = max(target_vm, MIN_VOLT_MV);
277	dvfs->avs[2] = dvfs->avs[3] = armada_37xx_avs_val_match(target_vm);
278
279	/*
280	 * Fix the avs value for load L1 when base CPU frequency is 1000/1200 MHz,
281	 * otherwise the CPU gets stuck when switching from load L1 to load L0.
282	 * Also ensure that avs value for load L1 is not higher than for L0.
283	 */
284	if (dvfs->cpu_freq_max >= 1000*1000*1000) {
285		u32 avs_min_l1;
286
287		if (dvfs->cpu_freq_max >= 1200*1000*1000)
288			avs_min_l1 = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1200MHZ);
289		else
290			avs_min_l1 = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1000MHZ);
291
292		if (avs_min_l1 > dvfs->avs[0])
293			avs_min_l1 = dvfs->avs[0];
294
295		if (dvfs->avs[1] < avs_min_l1)
296			dvfs->avs[1] = avs_min_l1;
297	}
298}
299
300static void __init armada37xx_cpufreq_avs_setup(struct regmap *base,
301						struct armada_37xx_dvfs *dvfs)
302{
303	unsigned int avs_val = 0;
304	int load_level = 0;
305
306	if (base == NULL)
307		return;
308
309	/* Disable AVS before the configuration */
310	regmap_update_bits(base, ARMADA_37XX_AVS_CTL0,
311			   ARMADA_37XX_AVS_ENABLE, 0);
312
313
314	/* Enable low voltage mode */
315	regmap_update_bits(base, ARMADA_37XX_AVS_CTL2,
316			   ARMADA_37XX_AVS_LOW_VDD_EN,
317			   ARMADA_37XX_AVS_LOW_VDD_EN);
318
319
320	for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++) {
321		avs_val = dvfs->avs[load_level];
322		regmap_update_bits(base, ARMADA_37XX_AVS_VSET(load_level-1),
323		    ARMADA_37XX_AVS_VDD_MASK << ARMADA_37XX_AVS_HIGH_VDD_LIMIT |
324		    ARMADA_37XX_AVS_VDD_MASK << ARMADA_37XX_AVS_LOW_VDD_LIMIT,
325		    avs_val << ARMADA_37XX_AVS_HIGH_VDD_LIMIT |
326		    avs_val << ARMADA_37XX_AVS_LOW_VDD_LIMIT);
327	}
328
329	/* Enable AVS after the configuration */
330	regmap_update_bits(base, ARMADA_37XX_AVS_CTL0,
331			   ARMADA_37XX_AVS_ENABLE,
332			   ARMADA_37XX_AVS_ENABLE);
333
334}
335
336static void armada37xx_cpufreq_disable_dvfs(struct regmap *base)
337{
338	unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
339		mask = ARMADA_37XX_NB_DFS_EN;
340
341	regmap_update_bits(base, reg, mask, 0);
342}
343
344static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
345{
346	unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD,
347		mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
348
349	/* Start with the highest load (0) */
350	val = ARMADA_37XX_DVFS_LOAD_0;
351	regmap_update_bits(base, reg, mask, val);
352
353	/* Now enable DVFS for the CPUs */
354	reg = ARMADA_37XX_NB_DYN_MOD;
355	mask =	ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN |
356		ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN |
357		ARMADA_37XX_NB_DFS_EN;
358
359	regmap_update_bits(base, reg, mask, mask);
360}
361
362static int armada37xx_cpufreq_suspend(struct cpufreq_policy *policy)
363{
364	struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state;
365
366	regmap_read(state->regmap, ARMADA_37XX_NB_L0L1, &state->nb_l0l1);
367	regmap_read(state->regmap, ARMADA_37XX_NB_L2L3, &state->nb_l2l3);
368	regmap_read(state->regmap, ARMADA_37XX_NB_CPU_LOAD,
369		    &state->nb_cpu_load);
370	regmap_read(state->regmap, ARMADA_37XX_NB_DYN_MOD, &state->nb_dyn_mod);
371
372	return 0;
373}
374
375static int armada37xx_cpufreq_resume(struct cpufreq_policy *policy)
376{
377	struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state;
378
379	/* Ensure DVFS is disabled otherwise the following registers are RO */
380	armada37xx_cpufreq_disable_dvfs(state->regmap);
381
382	regmap_write(state->regmap, ARMADA_37XX_NB_L0L1, state->nb_l0l1);
383	regmap_write(state->regmap, ARMADA_37XX_NB_L2L3, state->nb_l2l3);
384	regmap_write(state->regmap, ARMADA_37XX_NB_CPU_LOAD,
385		     state->nb_cpu_load);
386
387	/*
388	 * NB_DYN_MOD register is the one that actually enable back DVFS if it
389	 * was enabled before the suspend operation. This must be done last
390	 * otherwise other registers are not writable.
391	 */
392	regmap_write(state->regmap, ARMADA_37XX_NB_DYN_MOD, state->nb_dyn_mod);
393
394	return 0;
395}
396
397static int __init armada37xx_cpufreq_driver_init(void)
398{
399	struct cpufreq_dt_platform_data pdata;
400	struct armada_37xx_dvfs *dvfs;
401	struct platform_device *pdev;
402	unsigned long freq;
403	unsigned int base_frequency;
404	struct regmap *nb_clk_base, *nb_pm_base, *avs_base;
405	struct device *cpu_dev;
406	int load_lvl, ret;
407	struct clk *clk, *parent;
408
409	nb_clk_base =
410		syscon_regmap_lookup_by_compatible("marvell,armada-3700-periph-clock-nb");
411	if (IS_ERR(nb_clk_base))
412		return -ENODEV;
413
414	nb_pm_base =
415		syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
416
417	if (IS_ERR(nb_pm_base))
418		return -ENODEV;
419
420	avs_base =
421		syscon_regmap_lookup_by_compatible("marvell,armada-3700-avs");
422
423	/* if AVS is not present don't use it but still try to setup dvfs */
424	if (IS_ERR(avs_base)) {
425		pr_info("Syscon failed for Adapting Voltage Scaling: skip it\n");
426		avs_base = NULL;
427	}
428	/* Before doing any configuration on the DVFS first, disable it */
429	armada37xx_cpufreq_disable_dvfs(nb_pm_base);
430
431	/*
432	 * On CPU 0 register the operating points supported (which are
433	 * the nominal CPU frequency and full integer divisions of
434	 * it).
435	 */
436	cpu_dev = get_cpu_device(0);
437	if (!cpu_dev) {
438		dev_err(cpu_dev, "Cannot get CPU\n");
439		return -ENODEV;
440	}
441
442	clk = clk_get(cpu_dev, NULL);
443	if (IS_ERR(clk)) {
444		dev_err(cpu_dev, "Cannot get clock for CPU0\n");
445		return PTR_ERR(clk);
446	}
447
448	parent = clk_get_parent(clk);
449	if (IS_ERR(parent)) {
450		dev_err(cpu_dev, "Cannot get parent clock for CPU0\n");
451		clk_put(clk);
452		return PTR_ERR(parent);
453	}
454
455	/* Get parent CPU frequency */
456	base_frequency =  clk_get_rate(parent);
457
458	if (!base_frequency) {
459		dev_err(cpu_dev, "Failed to get parent clock rate for CPU\n");
460		clk_put(clk);
461		return -EINVAL;
462	}
463
464	dvfs = armada_37xx_cpu_freq_info_get(base_frequency);
465	if (!dvfs) {
466		clk_put(clk);
467		return -EINVAL;
468	}
469
470	armada37xx_cpufreq_state = kmalloc(sizeof(*armada37xx_cpufreq_state),
471					   GFP_KERNEL);
472	if (!armada37xx_cpufreq_state) {
473		clk_put(clk);
474		return -ENOMEM;
475	}
476
477	armada37xx_cpufreq_state->regmap = nb_pm_base;
478
479	armada37xx_cpufreq_avs_configure(avs_base, dvfs);
480	armada37xx_cpufreq_avs_setup(avs_base, dvfs);
481
482	armada37xx_cpufreq_dvfs_setup(nb_pm_base, nb_clk_base, dvfs->divider);
483	clk_put(clk);
484
485	for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
486	     load_lvl++) {
487		unsigned long u_volt = avs_map[dvfs->avs[load_lvl]] * 1000;
488		freq = base_frequency / dvfs->divider[load_lvl];
489		ret = dev_pm_opp_add(cpu_dev, freq, u_volt);
490		if (ret)
491			goto remove_opp;
492
493
494	}
495
496	/* Now that everything is setup, enable the DVFS at hardware level */
497	armada37xx_cpufreq_enable_dvfs(nb_pm_base);
498
499	memset(&pdata, 0, sizeof(pdata));
500	pdata.suspend = armada37xx_cpufreq_suspend;
501	pdata.resume = armada37xx_cpufreq_resume;
502
503	pdev = platform_device_register_data(NULL, "cpufreq-dt", -1, &pdata,
504					     sizeof(pdata));
505	ret = PTR_ERR_OR_ZERO(pdev);
506	if (ret)
507		goto disable_dvfs;
508
509	armada37xx_cpufreq_state->cpu_dev = cpu_dev;
510	armada37xx_cpufreq_state->pdev = pdev;
511	platform_set_drvdata(pdev, dvfs);
512	return 0;
513
514disable_dvfs:
515	armada37xx_cpufreq_disable_dvfs(nb_pm_base);
516remove_opp:
517	/* clean-up the already added opp before leaving */
518	while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
519		freq = base_frequency / dvfs->divider[load_lvl];
520		dev_pm_opp_remove(cpu_dev, freq);
521	}
522
523	kfree(armada37xx_cpufreq_state);
524
525	return ret;
526}
527/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
528late_initcall(armada37xx_cpufreq_driver_init);
529
530static void __exit armada37xx_cpufreq_driver_exit(void)
531{
532	struct platform_device *pdev = armada37xx_cpufreq_state->pdev;
533	struct armada_37xx_dvfs *dvfs = platform_get_drvdata(pdev);
534	unsigned long freq;
535	int load_lvl;
536
537	platform_device_unregister(pdev);
538
539	armada37xx_cpufreq_disable_dvfs(armada37xx_cpufreq_state->regmap);
540
541	for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; load_lvl++) {
542		freq = dvfs->cpu_freq_max / dvfs->divider[load_lvl];
543		dev_pm_opp_remove(armada37xx_cpufreq_state->cpu_dev, freq);
544	}
545
546	kfree(armada37xx_cpufreq_state);
547}
548module_exit(armada37xx_cpufreq_driver_exit);
549
550static const struct of_device_id __maybe_unused armada37xx_cpufreq_of_match[] = {
551	{ .compatible = "marvell,armada-3700-nb-pm" },
552	{ },
553};
554MODULE_DEVICE_TABLE(of, armada37xx_cpufreq_of_match);
555
556MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
557MODULE_DESCRIPTION("Armada 37xx cpufreq driver");
558MODULE_LICENSE("GPL");
~/ Read-only file preview.