• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
3  *
4  * Authors: 	Shlomi Gridish <gridish@freescale.com>
5  * 		Li Yang <leoli@freescale.com>
6  * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
7  *
8  * Description:
9  * General Purpose functions for the global management of the
10  * QUICC Engine (QE).
11  *
12  * This program is free software; you can redistribute  it and/or modify it
13  * under  the terms of  the GNU General  Public License as published by the
14  * Free Software Foundation;  either version 2 of the  License, or (at your
15  * option) any later version.
16  */
17 #include <linux/errno.h>
18 #include <linux/sched.h>
19 #include <linux/kernel.h>
20 #include <linux/param.h>
21 #include <linux/string.h>
22 #include <linux/spinlock.h>
23 #include <linux/mm.h>
24 #include <linux/interrupt.h>
25 #include <linux/module.h>
26 #include <linux/delay.h>
27 #include <linux/ioport.h>
28 #include <linux/crc32.h>
29 #include <linux/mod_devicetable.h>
30 #include <linux/of_platform.h>
31 #include <asm/irq.h>
32 #include <asm/page.h>
33 #include <asm/pgtable.h>
34 #include <asm/immap_qe.h>
35 #include <asm/qe.h>
36 #include <asm/prom.h>
37 #include <asm/rheap.h>
38 
39 static void qe_snums_init(void);
40 static int qe_sdma_init(void);
41 
42 static DEFINE_SPINLOCK(qe_lock);
43 DEFINE_SPINLOCK(cmxgcr_lock);
44 EXPORT_SYMBOL(cmxgcr_lock);
45 
46 /* QE snum state */
47 enum qe_snum_state {
48 	QE_SNUM_STATE_USED,
49 	QE_SNUM_STATE_FREE
50 };
51 
52 /* QE snum */
53 struct qe_snum {
54 	u8 num;
55 	enum qe_snum_state state;
56 };
57 
58 /* We allocate this here because it is used almost exclusively for
59  * the communication processor devices.
60  */
61 struct qe_immap __iomem *qe_immr;
62 EXPORT_SYMBOL(qe_immr);
63 
64 static struct qe_snum snums[QE_NUM_OF_SNUM];	/* Dynamically allocated SNUMs */
65 static unsigned int qe_num_of_snum;
66 
67 static phys_addr_t qebase = -1;
68 
get_qe_base(void)69 phys_addr_t get_qe_base(void)
70 {
71 	struct device_node *qe;
72 	int size;
73 	const u32 *prop;
74 
75 	if (qebase != -1)
76 		return qebase;
77 
78 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
79 	if (!qe) {
80 		qe = of_find_node_by_type(NULL, "qe");
81 		if (!qe)
82 			return qebase;
83 	}
84 
85 	prop = of_get_property(qe, "reg", &size);
86 	if (prop && size >= sizeof(*prop))
87 		qebase = of_translate_address(qe, prop);
88 	of_node_put(qe);
89 
90 	return qebase;
91 }
92 
93 EXPORT_SYMBOL(get_qe_base);
94 
qe_reset(void)95 void qe_reset(void)
96 {
97 	if (qe_immr == NULL)
98 		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
99 
100 	qe_snums_init();
101 
102 	qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
103 		     QE_CR_PROTOCOL_UNSPECIFIED, 0);
104 
105 	/* Reclaim the MURAM memory for our use. */
106 	qe_muram_init();
107 
108 	if (qe_sdma_init())
109 		panic("sdma init failed!");
110 }
111 
qe_issue_cmd(u32 cmd,u32 device,u8 mcn_protocol,u32 cmd_input)112 int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
113 {
114 	unsigned long flags;
115 	u8 mcn_shift = 0, dev_shift = 0;
116 	u32 ret;
117 
118 	spin_lock_irqsave(&qe_lock, flags);
119 	if (cmd == QE_RESET) {
120 		out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
121 	} else {
122 		if (cmd == QE_ASSIGN_PAGE) {
123 			/* Here device is the SNUM, not sub-block */
124 			dev_shift = QE_CR_SNUM_SHIFT;
125 		} else if (cmd == QE_ASSIGN_RISC) {
126 			/* Here device is the SNUM, and mcnProtocol is
127 			 * e_QeCmdRiscAssignment value */
128 			dev_shift = QE_CR_SNUM_SHIFT;
129 			mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
130 		} else {
131 			if (device == QE_CR_SUBBLOCK_USB)
132 				mcn_shift = QE_CR_MCN_USB_SHIFT;
133 			else
134 				mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
135 		}
136 
137 		out_be32(&qe_immr->cp.cecdr, cmd_input);
138 		out_be32(&qe_immr->cp.cecr,
139 			 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
140 			  mcn_protocol << mcn_shift));
141 	}
142 
143 	/* wait for the QE_CR_FLG to clear */
144 	ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0,
145 			   100, 0);
146 	/* On timeout (e.g. failure), the expression will be false (ret == 0),
147 	   otherwise it will be true (ret == 1). */
148 	spin_unlock_irqrestore(&qe_lock, flags);
149 
150 	return ret == 1;
151 }
152 EXPORT_SYMBOL(qe_issue_cmd);
153 
154 /* Set a baud rate generator. This needs lots of work. There are
155  * 16 BRGs, which can be connected to the QE channels or output
156  * as clocks. The BRGs are in two different block of internal
157  * memory mapped space.
158  * The BRG clock is the QE clock divided by 2.
159  * It was set up long ago during the initial boot phase and is
160  * is given to us.
161  * Baud rate clocks are zero-based in the driver code (as that maps
162  * to port numbers). Documentation uses 1-based numbering.
163  */
164 static unsigned int brg_clk = 0;
165 
qe_get_brg_clk(void)166 unsigned int qe_get_brg_clk(void)
167 {
168 	struct device_node *qe;
169 	int size;
170 	const u32 *prop;
171 
172 	if (brg_clk)
173 		return brg_clk;
174 
175 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
176 	if (!qe) {
177 		qe = of_find_node_by_type(NULL, "qe");
178 		if (!qe)
179 			return brg_clk;
180 	}
181 
182 	prop = of_get_property(qe, "brg-frequency", &size);
183 	if (prop && size == sizeof(*prop))
184 		brg_clk = *prop;
185 
186 	of_node_put(qe);
187 
188 	return brg_clk;
189 }
190 EXPORT_SYMBOL(qe_get_brg_clk);
191 
192 /* Program the BRG to the given sampling rate and multiplier
193  *
194  * @brg: the BRG, QE_BRG1 - QE_BRG16
195  * @rate: the desired sampling rate
196  * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
197  * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
198  * then 'multiplier' should be 8.
199  */
qe_setbrg(enum qe_clock brg,unsigned int rate,unsigned int multiplier)200 int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
201 {
202 	u32 divisor, tempval;
203 	u32 div16 = 0;
204 
205 	if ((brg < QE_BRG1) || (brg > QE_BRG16))
206 		return -EINVAL;
207 
208 	divisor = qe_get_brg_clk() / (rate * multiplier);
209 
210 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
211 		div16 = QE_BRGC_DIV16;
212 		divisor /= 16;
213 	}
214 
215 	/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
216 	   that the BRG divisor must be even if you're not using divide-by-16
217 	   mode. */
218 	if (!div16 && (divisor & 1) && (divisor > 3))
219 		divisor++;
220 
221 	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
222 		QE_BRGC_ENABLE | div16;
223 
224 	out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
225 
226 	return 0;
227 }
228 EXPORT_SYMBOL(qe_setbrg);
229 
230 /* Convert a string to a QE clock source enum
231  *
232  * This function takes a string, typically from a property in the device
233  * tree, and returns the corresponding "enum qe_clock" value.
234 */
qe_clock_source(const char * source)235 enum qe_clock qe_clock_source(const char *source)
236 {
237 	unsigned int i;
238 
239 	if (strcasecmp(source, "none") == 0)
240 		return QE_CLK_NONE;
241 
242 	if (strncasecmp(source, "brg", 3) == 0) {
243 		i = simple_strtoul(source + 3, NULL, 10);
244 		if ((i >= 1) && (i <= 16))
245 			return (QE_BRG1 - 1) + i;
246 		else
247 			return QE_CLK_DUMMY;
248 	}
249 
250 	if (strncasecmp(source, "clk", 3) == 0) {
251 		i = simple_strtoul(source + 3, NULL, 10);
252 		if ((i >= 1) && (i <= 24))
253 			return (QE_CLK1 - 1) + i;
254 		else
255 			return QE_CLK_DUMMY;
256 	}
257 
258 	return QE_CLK_DUMMY;
259 }
260 EXPORT_SYMBOL(qe_clock_source);
261 
262 /* Initialize SNUMs (thread serial numbers) according to
263  * QE Module Control chapter, SNUM table
264  */
qe_snums_init(void)265 static void qe_snums_init(void)
266 {
267 	int i;
268 	static const u8 snum_init_76[] = {
269 		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
270 		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
271 		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
272 		0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
273 		0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
274 		0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
275 		0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
276 		0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
277 		0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
278 		0xF4, 0xF5, 0xFC, 0xFD,
279 	};
280 	static const u8 snum_init_46[] = {
281 		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
282 		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
283 		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
284 		0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
285 		0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
286 		0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
287 	};
288 	static const u8 *snum_init;
289 
290 	qe_num_of_snum = qe_get_num_of_snums();
291 
292 	if (qe_num_of_snum == 76)
293 		snum_init = snum_init_76;
294 	else
295 		snum_init = snum_init_46;
296 
297 	for (i = 0; i < qe_num_of_snum; i++) {
298 		snums[i].num = snum_init[i];
299 		snums[i].state = QE_SNUM_STATE_FREE;
300 	}
301 }
302 
qe_get_snum(void)303 int qe_get_snum(void)
304 {
305 	unsigned long flags;
306 	int snum = -EBUSY;
307 	int i;
308 
309 	spin_lock_irqsave(&qe_lock, flags);
310 	for (i = 0; i < qe_num_of_snum; i++) {
311 		if (snums[i].state == QE_SNUM_STATE_FREE) {
312 			snums[i].state = QE_SNUM_STATE_USED;
313 			snum = snums[i].num;
314 			break;
315 		}
316 	}
317 	spin_unlock_irqrestore(&qe_lock, flags);
318 
319 	return snum;
320 }
321 EXPORT_SYMBOL(qe_get_snum);
322 
qe_put_snum(u8 snum)323 void qe_put_snum(u8 snum)
324 {
325 	int i;
326 
327 	for (i = 0; i < qe_num_of_snum; i++) {
328 		if (snums[i].num == snum) {
329 			snums[i].state = QE_SNUM_STATE_FREE;
330 			break;
331 		}
332 	}
333 }
334 EXPORT_SYMBOL(qe_put_snum);
335 
qe_sdma_init(void)336 static int qe_sdma_init(void)
337 {
338 	struct sdma __iomem *sdma = &qe_immr->sdma;
339 	static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
340 
341 	if (!sdma)
342 		return -ENODEV;
343 
344 	/* allocate 2 internal temporary buffers (512 bytes size each) for
345 	 * the SDMA */
346 	if (IS_ERR_VALUE(sdma_buf_offset)) {
347 		sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
348 		if (IS_ERR_VALUE(sdma_buf_offset))
349 			return -ENOMEM;
350 	}
351 
352 	out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
353  	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
354  					(0x1 << QE_SDMR_CEN_SHIFT)));
355 
356 	return 0;
357 }
358 
359 /* The maximum number of RISCs we support */
360 #define MAX_QE_RISC     4
361 
362 /* Firmware information stored here for qe_get_firmware_info() */
363 static struct qe_firmware_info qe_firmware_info;
364 
365 /*
366  * Set to 1 if QE firmware has been uploaded, and therefore
367  * qe_firmware_info contains valid data.
368  */
369 static int qe_firmware_uploaded;
370 
371 /*
372  * Upload a QE microcode
373  *
374  * This function is a worker function for qe_upload_firmware().  It does
375  * the actual uploading of the microcode.
376  */
qe_upload_microcode(const void * base,const struct qe_microcode * ucode)377 static void qe_upload_microcode(const void *base,
378 	const struct qe_microcode *ucode)
379 {
380 	const __be32 *code = base + be32_to_cpu(ucode->code_offset);
381 	unsigned int i;
382 
383 	if (ucode->major || ucode->minor || ucode->revision)
384 		printk(KERN_INFO "qe-firmware: "
385 			"uploading microcode '%s' version %u.%u.%u\n",
386 			ucode->id, ucode->major, ucode->minor, ucode->revision);
387 	else
388 		printk(KERN_INFO "qe-firmware: "
389 			"uploading microcode '%s'\n", ucode->id);
390 
391 	/* Use auto-increment */
392 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
393 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
394 
395 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
396 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
397 
398 	/* Set I-RAM Ready Register */
399 	out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY));
400 }
401 
402 /*
403  * Upload a microcode to the I-RAM at a specific address.
404  *
405  * See Documentation/powerpc/qe_firmware.txt for information on QE microcode
406  * uploading.
407  *
408  * Currently, only version 1 is supported, so the 'version' field must be
409  * set to 1.
410  *
411  * The SOC model and revision are not validated, they are only displayed for
412  * informational purposes.
413  *
414  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
415  * all of the microcode structures, minus the CRC.
416  *
417  * 'length' is the size that the structure says it is, including the CRC.
418  */
qe_upload_firmware(const struct qe_firmware * firmware)419 int qe_upload_firmware(const struct qe_firmware *firmware)
420 {
421 	unsigned int i;
422 	unsigned int j;
423 	u32 crc;
424 	size_t calc_size = sizeof(struct qe_firmware);
425 	size_t length;
426 	const struct qe_header *hdr;
427 
428 	if (!firmware) {
429 		printk(KERN_ERR "qe-firmware: invalid pointer\n");
430 		return -EINVAL;
431 	}
432 
433 	hdr = &firmware->header;
434 	length = be32_to_cpu(hdr->length);
435 
436 	/* Check the magic */
437 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
438 	    (hdr->magic[2] != 'F')) {
439 		printk(KERN_ERR "qe-firmware: not a microcode\n");
440 		return -EPERM;
441 	}
442 
443 	/* Check the version */
444 	if (hdr->version != 1) {
445 		printk(KERN_ERR "qe-firmware: unsupported version\n");
446 		return -EPERM;
447 	}
448 
449 	/* Validate some of the fields */
450 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
451 		printk(KERN_ERR "qe-firmware: invalid data\n");
452 		return -EINVAL;
453 	}
454 
455 	/* Validate the length and check if there's a CRC */
456 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
457 
458 	for (i = 0; i < firmware->count; i++)
459 		/*
460 		 * For situations where the second RISC uses the same microcode
461 		 * as the first, the 'code_offset' and 'count' fields will be
462 		 * zero, so it's okay to add those.
463 		 */
464 		calc_size += sizeof(__be32) *
465 			be32_to_cpu(firmware->microcode[i].count);
466 
467 	/* Validate the length */
468 	if (length != calc_size + sizeof(__be32)) {
469 		printk(KERN_ERR "qe-firmware: invalid length\n");
470 		return -EPERM;
471 	}
472 
473 	/* Validate the CRC */
474 	crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
475 	if (crc != crc32(0, firmware, calc_size)) {
476 		printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
477 		return -EIO;
478 	}
479 
480 	/*
481 	 * If the microcode calls for it, split the I-RAM.
482 	 */
483 	if (!firmware->split)
484 		setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
485 
486 	if (firmware->soc.model)
487 		printk(KERN_INFO
488 			"qe-firmware: firmware '%s' for %u V%u.%u\n",
489 			firmware->id, be16_to_cpu(firmware->soc.model),
490 			firmware->soc.major, firmware->soc.minor);
491 	else
492 		printk(KERN_INFO "qe-firmware: firmware '%s'\n",
493 			firmware->id);
494 
495 	/*
496 	 * The QE only supports one microcode per RISC, so clear out all the
497 	 * saved microcode information and put in the new.
498 	 */
499 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
500 	strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
501 	qe_firmware_info.extended_modes = firmware->extended_modes;
502 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
503 		sizeof(firmware->vtraps));
504 
505 	/* Loop through each microcode. */
506 	for (i = 0; i < firmware->count; i++) {
507 		const struct qe_microcode *ucode = &firmware->microcode[i];
508 
509 		/* Upload a microcode if it's present */
510 		if (ucode->code_offset)
511 			qe_upload_microcode(firmware, ucode);
512 
513 		/* Program the traps for this processor */
514 		for (j = 0; j < 16; j++) {
515 			u32 trap = be32_to_cpu(ucode->traps[j]);
516 
517 			if (trap)
518 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
519 		}
520 
521 		/* Enable traps */
522 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
523 	}
524 
525 	qe_firmware_uploaded = 1;
526 
527 	return 0;
528 }
529 EXPORT_SYMBOL(qe_upload_firmware);
530 
531 /*
532  * Get info on the currently-loaded firmware
533  *
534  * This function also checks the device tree to see if the boot loader has
535  * uploaded a firmware already.
536  */
qe_get_firmware_info(void)537 struct qe_firmware_info *qe_get_firmware_info(void)
538 {
539 	static int initialized;
540 	struct property *prop;
541 	struct device_node *qe;
542 	struct device_node *fw = NULL;
543 	const char *sprop;
544 	unsigned int i;
545 
546 	/*
547 	 * If we haven't checked yet, and a driver hasn't uploaded a firmware
548 	 * yet, then check the device tree for information.
549 	 */
550 	if (qe_firmware_uploaded)
551 		return &qe_firmware_info;
552 
553 	if (initialized)
554 		return NULL;
555 
556 	initialized = 1;
557 
558 	/*
559 	 * Newer device trees have an "fsl,qe" compatible property for the QE
560 	 * node, but we still need to support older device trees.
561 	*/
562 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
563 	if (!qe) {
564 		qe = of_find_node_by_type(NULL, "qe");
565 		if (!qe)
566 			return NULL;
567 	}
568 
569 	/* Find the 'firmware' child node */
570 	for_each_child_of_node(qe, fw) {
571 		if (strcmp(fw->name, "firmware") == 0)
572 			break;
573 	}
574 
575 	of_node_put(qe);
576 
577 	/* Did we find the 'firmware' node? */
578 	if (!fw)
579 		return NULL;
580 
581 	qe_firmware_uploaded = 1;
582 
583 	/* Copy the data into qe_firmware_info*/
584 	sprop = of_get_property(fw, "id", NULL);
585 	if (sprop)
586 		strlcpy(qe_firmware_info.id, sprop,
587 			sizeof(qe_firmware_info.id));
588 
589 	prop = of_find_property(fw, "extended-modes", NULL);
590 	if (prop && (prop->length == sizeof(u64))) {
591 		const u64 *iprop = prop->value;
592 
593 		qe_firmware_info.extended_modes = *iprop;
594 	}
595 
596 	prop = of_find_property(fw, "virtual-traps", NULL);
597 	if (prop && (prop->length == 32)) {
598 		const u32 *iprop = prop->value;
599 
600 		for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
601 			qe_firmware_info.vtraps[i] = iprop[i];
602 	}
603 
604 	of_node_put(fw);
605 
606 	return &qe_firmware_info;
607 }
608 EXPORT_SYMBOL(qe_get_firmware_info);
609 
qe_get_num_of_risc(void)610 unsigned int qe_get_num_of_risc(void)
611 {
612 	struct device_node *qe;
613 	int size;
614 	unsigned int num_of_risc = 0;
615 	const u32 *prop;
616 
617 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
618 	if (!qe) {
619 		/* Older devices trees did not have an "fsl,qe"
620 		 * compatible property, so we need to look for
621 		 * the QE node by name.
622 		 */
623 		qe = of_find_node_by_type(NULL, "qe");
624 		if (!qe)
625 			return num_of_risc;
626 	}
627 
628 	prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
629 	if (prop && size == sizeof(*prop))
630 		num_of_risc = *prop;
631 
632 	of_node_put(qe);
633 
634 	return num_of_risc;
635 }
636 EXPORT_SYMBOL(qe_get_num_of_risc);
637 
qe_get_num_of_snums(void)638 unsigned int qe_get_num_of_snums(void)
639 {
640 	struct device_node *qe;
641 	int size;
642 	unsigned int num_of_snums;
643 	const u32 *prop;
644 
645 	num_of_snums = 28; /* The default number of snum for threads is 28 */
646 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
647 	if (!qe) {
648 		/* Older devices trees did not have an "fsl,qe"
649 		 * compatible property, so we need to look for
650 		 * the QE node by name.
651 		 */
652 		qe = of_find_node_by_type(NULL, "qe");
653 		if (!qe)
654 			return num_of_snums;
655 	}
656 
657 	prop = of_get_property(qe, "fsl,qe-num-snums", &size);
658 	if (prop && size == sizeof(*prop)) {
659 		num_of_snums = *prop;
660 		if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
661 			/* No QE ever has fewer than 28 SNUMs */
662 			pr_err("QE: number of snum is invalid\n");
663 			of_node_put(qe);
664 			return -EINVAL;
665 		}
666 	}
667 
668 	of_node_put(qe);
669 
670 	return num_of_snums;
671 }
672 EXPORT_SYMBOL(qe_get_num_of_snums);
673 
674 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
qe_resume(struct platform_device * ofdev)675 static int qe_resume(struct platform_device *ofdev)
676 {
677 	if (!qe_alive_during_sleep())
678 		qe_reset();
679 	return 0;
680 }
681 
qe_probe(struct platform_device * ofdev)682 static int qe_probe(struct platform_device *ofdev)
683 {
684 	return 0;
685 }
686 
687 static const struct of_device_id qe_ids[] = {
688 	{ .compatible = "fsl,qe", },
689 	{ },
690 };
691 
692 static struct platform_driver qe_driver = {
693 	.driver = {
694 		.name = "fsl-qe",
695 		.of_match_table = qe_ids,
696 	},
697 	.probe = qe_probe,
698 	.resume = qe_resume,
699 };
700 
qe_drv_init(void)701 static int __init qe_drv_init(void)
702 {
703 	return platform_driver_register(&qe_driver);
704 }
705 device_initcall(qe_drv_init);
706 #endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
707