xref: /openbmc/linux/drivers/soc/fsl/qe/qe.c (revision 1c2dd16a)
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 <soc/fsl/qe/immap_qe.h>
35 #include <soc/fsl/qe/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 
69 phys_addr_t get_qe_base(void)
70 {
71 	struct device_node *qe;
72 	int ret;
73 	struct resource res;
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 	ret = of_address_to_resource(qe, 0, &res);
86 	if (!ret)
87 		qebase = res.start;
88 	of_node_put(qe);
89 
90 	return qebase;
91 }
92 
93 EXPORT_SYMBOL(get_qe_base);
94 
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 
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 
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  */
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 */
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 (strcmp(source, "tsync_pin") == 0)
243 		return QE_TSYNC_PIN;
244 
245 	if (strcmp(source, "rsync_pin") == 0)
246 		return QE_RSYNC_PIN;
247 
248 	if (strncasecmp(source, "brg", 3) == 0) {
249 		i = simple_strtoul(source + 3, NULL, 10);
250 		if ((i >= 1) && (i <= 16))
251 			return (QE_BRG1 - 1) + i;
252 		else
253 			return QE_CLK_DUMMY;
254 	}
255 
256 	if (strncasecmp(source, "clk", 3) == 0) {
257 		i = simple_strtoul(source + 3, NULL, 10);
258 		if ((i >= 1) && (i <= 24))
259 			return (QE_CLK1 - 1) + i;
260 		else
261 			return QE_CLK_DUMMY;
262 	}
263 
264 	return QE_CLK_DUMMY;
265 }
266 EXPORT_SYMBOL(qe_clock_source);
267 
268 /* Initialize SNUMs (thread serial numbers) according to
269  * QE Module Control chapter, SNUM table
270  */
271 static void qe_snums_init(void)
272 {
273 	int i;
274 	static const u8 snum_init_76[] = {
275 		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
276 		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
277 		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
278 		0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
279 		0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
280 		0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
281 		0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
282 		0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
283 		0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
284 		0xF4, 0xF5, 0xFC, 0xFD,
285 	};
286 	static const u8 snum_init_46[] = {
287 		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
288 		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
289 		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
290 		0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
291 		0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
292 		0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
293 	};
294 	static const u8 *snum_init;
295 
296 	qe_num_of_snum = qe_get_num_of_snums();
297 
298 	if (qe_num_of_snum == 76)
299 		snum_init = snum_init_76;
300 	else
301 		snum_init = snum_init_46;
302 
303 	for (i = 0; i < qe_num_of_snum; i++) {
304 		snums[i].num = snum_init[i];
305 		snums[i].state = QE_SNUM_STATE_FREE;
306 	}
307 }
308 
309 int qe_get_snum(void)
310 {
311 	unsigned long flags;
312 	int snum = -EBUSY;
313 	int i;
314 
315 	spin_lock_irqsave(&qe_lock, flags);
316 	for (i = 0; i < qe_num_of_snum; i++) {
317 		if (snums[i].state == QE_SNUM_STATE_FREE) {
318 			snums[i].state = QE_SNUM_STATE_USED;
319 			snum = snums[i].num;
320 			break;
321 		}
322 	}
323 	spin_unlock_irqrestore(&qe_lock, flags);
324 
325 	return snum;
326 }
327 EXPORT_SYMBOL(qe_get_snum);
328 
329 void qe_put_snum(u8 snum)
330 {
331 	int i;
332 
333 	for (i = 0; i < qe_num_of_snum; i++) {
334 		if (snums[i].num == snum) {
335 			snums[i].state = QE_SNUM_STATE_FREE;
336 			break;
337 		}
338 	}
339 }
340 EXPORT_SYMBOL(qe_put_snum);
341 
342 static int qe_sdma_init(void)
343 {
344 	struct sdma __iomem *sdma = &qe_immr->sdma;
345 	static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
346 
347 	if (!sdma)
348 		return -ENODEV;
349 
350 	/* allocate 2 internal temporary buffers (512 bytes size each) for
351 	 * the SDMA */
352 	if (IS_ERR_VALUE(sdma_buf_offset)) {
353 		sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
354 		if (IS_ERR_VALUE(sdma_buf_offset))
355 			return -ENOMEM;
356 	}
357 
358 	out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
359  	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
360  					(0x1 << QE_SDMR_CEN_SHIFT)));
361 
362 	return 0;
363 }
364 
365 /* The maximum number of RISCs we support */
366 #define MAX_QE_RISC     4
367 
368 /* Firmware information stored here for qe_get_firmware_info() */
369 static struct qe_firmware_info qe_firmware_info;
370 
371 /*
372  * Set to 1 if QE firmware has been uploaded, and therefore
373  * qe_firmware_info contains valid data.
374  */
375 static int qe_firmware_uploaded;
376 
377 /*
378  * Upload a QE microcode
379  *
380  * This function is a worker function for qe_upload_firmware().  It does
381  * the actual uploading of the microcode.
382  */
383 static void qe_upload_microcode(const void *base,
384 	const struct qe_microcode *ucode)
385 {
386 	const __be32 *code = base + be32_to_cpu(ucode->code_offset);
387 	unsigned int i;
388 
389 	if (ucode->major || ucode->minor || ucode->revision)
390 		printk(KERN_INFO "qe-firmware: "
391 			"uploading microcode '%s' version %u.%u.%u\n",
392 			ucode->id, ucode->major, ucode->minor, ucode->revision);
393 	else
394 		printk(KERN_INFO "qe-firmware: "
395 			"uploading microcode '%s'\n", ucode->id);
396 
397 	/* Use auto-increment */
398 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
399 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
400 
401 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
402 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
403 
404 	/* Set I-RAM Ready Register */
405 	out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY));
406 }
407 
408 /*
409  * Upload a microcode to the I-RAM at a specific address.
410  *
411  * See Documentation/powerpc/qe_firmware.txt for information on QE microcode
412  * uploading.
413  *
414  * Currently, only version 1 is supported, so the 'version' field must be
415  * set to 1.
416  *
417  * The SOC model and revision are not validated, they are only displayed for
418  * informational purposes.
419  *
420  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
421  * all of the microcode structures, minus the CRC.
422  *
423  * 'length' is the size that the structure says it is, including the CRC.
424  */
425 int qe_upload_firmware(const struct qe_firmware *firmware)
426 {
427 	unsigned int i;
428 	unsigned int j;
429 	u32 crc;
430 	size_t calc_size = sizeof(struct qe_firmware);
431 	size_t length;
432 	const struct qe_header *hdr;
433 
434 	if (!firmware) {
435 		printk(KERN_ERR "qe-firmware: invalid pointer\n");
436 		return -EINVAL;
437 	}
438 
439 	hdr = &firmware->header;
440 	length = be32_to_cpu(hdr->length);
441 
442 	/* Check the magic */
443 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
444 	    (hdr->magic[2] != 'F')) {
445 		printk(KERN_ERR "qe-firmware: not a microcode\n");
446 		return -EPERM;
447 	}
448 
449 	/* Check the version */
450 	if (hdr->version != 1) {
451 		printk(KERN_ERR "qe-firmware: unsupported version\n");
452 		return -EPERM;
453 	}
454 
455 	/* Validate some of the fields */
456 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
457 		printk(KERN_ERR "qe-firmware: invalid data\n");
458 		return -EINVAL;
459 	}
460 
461 	/* Validate the length and check if there's a CRC */
462 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
463 
464 	for (i = 0; i < firmware->count; i++)
465 		/*
466 		 * For situations where the second RISC uses the same microcode
467 		 * as the first, the 'code_offset' and 'count' fields will be
468 		 * zero, so it's okay to add those.
469 		 */
470 		calc_size += sizeof(__be32) *
471 			be32_to_cpu(firmware->microcode[i].count);
472 
473 	/* Validate the length */
474 	if (length != calc_size + sizeof(__be32)) {
475 		printk(KERN_ERR "qe-firmware: invalid length\n");
476 		return -EPERM;
477 	}
478 
479 	/* Validate the CRC */
480 	crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
481 	if (crc != crc32(0, firmware, calc_size)) {
482 		printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
483 		return -EIO;
484 	}
485 
486 	/*
487 	 * If the microcode calls for it, split the I-RAM.
488 	 */
489 	if (!firmware->split)
490 		setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
491 
492 	if (firmware->soc.model)
493 		printk(KERN_INFO
494 			"qe-firmware: firmware '%s' for %u V%u.%u\n",
495 			firmware->id, be16_to_cpu(firmware->soc.model),
496 			firmware->soc.major, firmware->soc.minor);
497 	else
498 		printk(KERN_INFO "qe-firmware: firmware '%s'\n",
499 			firmware->id);
500 
501 	/*
502 	 * The QE only supports one microcode per RISC, so clear out all the
503 	 * saved microcode information and put in the new.
504 	 */
505 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
506 	strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
507 	qe_firmware_info.extended_modes = firmware->extended_modes;
508 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
509 		sizeof(firmware->vtraps));
510 
511 	/* Loop through each microcode. */
512 	for (i = 0; i < firmware->count; i++) {
513 		const struct qe_microcode *ucode = &firmware->microcode[i];
514 
515 		/* Upload a microcode if it's present */
516 		if (ucode->code_offset)
517 			qe_upload_microcode(firmware, ucode);
518 
519 		/* Program the traps for this processor */
520 		for (j = 0; j < 16; j++) {
521 			u32 trap = be32_to_cpu(ucode->traps[j]);
522 
523 			if (trap)
524 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
525 		}
526 
527 		/* Enable traps */
528 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
529 	}
530 
531 	qe_firmware_uploaded = 1;
532 
533 	return 0;
534 }
535 EXPORT_SYMBOL(qe_upload_firmware);
536 
537 /*
538  * Get info on the currently-loaded firmware
539  *
540  * This function also checks the device tree to see if the boot loader has
541  * uploaded a firmware already.
542  */
543 struct qe_firmware_info *qe_get_firmware_info(void)
544 {
545 	static int initialized;
546 	struct property *prop;
547 	struct device_node *qe;
548 	struct device_node *fw = NULL;
549 	const char *sprop;
550 	unsigned int i;
551 
552 	/*
553 	 * If we haven't checked yet, and a driver hasn't uploaded a firmware
554 	 * yet, then check the device tree for information.
555 	 */
556 	if (qe_firmware_uploaded)
557 		return &qe_firmware_info;
558 
559 	if (initialized)
560 		return NULL;
561 
562 	initialized = 1;
563 
564 	/*
565 	 * Newer device trees have an "fsl,qe" compatible property for the QE
566 	 * node, but we still need to support older device trees.
567 	*/
568 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
569 	if (!qe) {
570 		qe = of_find_node_by_type(NULL, "qe");
571 		if (!qe)
572 			return NULL;
573 	}
574 
575 	/* Find the 'firmware' child node */
576 	for_each_child_of_node(qe, fw) {
577 		if (strcmp(fw->name, "firmware") == 0)
578 			break;
579 	}
580 
581 	of_node_put(qe);
582 
583 	/* Did we find the 'firmware' node? */
584 	if (!fw)
585 		return NULL;
586 
587 	qe_firmware_uploaded = 1;
588 
589 	/* Copy the data into qe_firmware_info*/
590 	sprop = of_get_property(fw, "id", NULL);
591 	if (sprop)
592 		strlcpy(qe_firmware_info.id, sprop,
593 			sizeof(qe_firmware_info.id));
594 
595 	prop = of_find_property(fw, "extended-modes", NULL);
596 	if (prop && (prop->length == sizeof(u64))) {
597 		const u64 *iprop = prop->value;
598 
599 		qe_firmware_info.extended_modes = *iprop;
600 	}
601 
602 	prop = of_find_property(fw, "virtual-traps", NULL);
603 	if (prop && (prop->length == 32)) {
604 		const u32 *iprop = prop->value;
605 
606 		for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
607 			qe_firmware_info.vtraps[i] = iprop[i];
608 	}
609 
610 	of_node_put(fw);
611 
612 	return &qe_firmware_info;
613 }
614 EXPORT_SYMBOL(qe_get_firmware_info);
615 
616 unsigned int qe_get_num_of_risc(void)
617 {
618 	struct device_node *qe;
619 	int size;
620 	unsigned int num_of_risc = 0;
621 	const u32 *prop;
622 
623 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
624 	if (!qe) {
625 		/* Older devices trees did not have an "fsl,qe"
626 		 * compatible property, so we need to look for
627 		 * the QE node by name.
628 		 */
629 		qe = of_find_node_by_type(NULL, "qe");
630 		if (!qe)
631 			return num_of_risc;
632 	}
633 
634 	prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
635 	if (prop && size == sizeof(*prop))
636 		num_of_risc = *prop;
637 
638 	of_node_put(qe);
639 
640 	return num_of_risc;
641 }
642 EXPORT_SYMBOL(qe_get_num_of_risc);
643 
644 unsigned int qe_get_num_of_snums(void)
645 {
646 	struct device_node *qe;
647 	int size;
648 	unsigned int num_of_snums;
649 	const u32 *prop;
650 
651 	num_of_snums = 28; /* The default number of snum for threads is 28 */
652 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
653 	if (!qe) {
654 		/* Older devices trees did not have an "fsl,qe"
655 		 * compatible property, so we need to look for
656 		 * the QE node by name.
657 		 */
658 		qe = of_find_node_by_type(NULL, "qe");
659 		if (!qe)
660 			return num_of_snums;
661 	}
662 
663 	prop = of_get_property(qe, "fsl,qe-num-snums", &size);
664 	if (prop && size == sizeof(*prop)) {
665 		num_of_snums = *prop;
666 		if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
667 			/* No QE ever has fewer than 28 SNUMs */
668 			pr_err("QE: number of snum is invalid\n");
669 			of_node_put(qe);
670 			return -EINVAL;
671 		}
672 	}
673 
674 	of_node_put(qe);
675 
676 	return num_of_snums;
677 }
678 EXPORT_SYMBOL(qe_get_num_of_snums);
679 
680 static int __init qe_init(void)
681 {
682 	struct device_node *np;
683 
684 	np = of_find_compatible_node(NULL, NULL, "fsl,qe");
685 	if (!np)
686 		return -ENODEV;
687 	qe_reset();
688 	of_node_put(np);
689 	return 0;
690 }
691 subsys_initcall(qe_init);
692 
693 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
694 static int qe_resume(struct platform_device *ofdev)
695 {
696 	if (!qe_alive_during_sleep())
697 		qe_reset();
698 	return 0;
699 }
700 
701 static int qe_probe(struct platform_device *ofdev)
702 {
703 	return 0;
704 }
705 
706 static const struct of_device_id qe_ids[] = {
707 	{ .compatible = "fsl,qe", },
708 	{ },
709 };
710 
711 static struct platform_driver qe_driver = {
712 	.driver = {
713 		.name = "fsl-qe",
714 		.of_match_table = qe_ids,
715 	},
716 	.probe = qe_probe,
717 	.resume = qe_resume,
718 };
719 
720 builtin_platform_driver(qe_driver);
721 #endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
722