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