]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/powerpc/sysdev/qe_lib/qe.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[net-next-2.6.git] / arch / powerpc / sysdev / qe_lib / qe.c
CommitLineData
98658538
LY
1/*
2 * Copyright (C) 2006 Freescale Semicondutor, 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>
09a3fba8 22#include <linux/spinlock.h>
98658538
LY
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>
bc556ba9 29#include <linux/crc32.h>
fdfde24e
AV
30#include <linux/mod_devicetable.h>
31#include <linux/of_platform.h>
98658538
LY
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
40static void qe_snums_init(void);
98658538
LY
41static int qe_sdma_init(void);
42
43static DEFINE_SPINLOCK(qe_lock);
09a3fba8
AV
44DEFINE_SPINLOCK(cmxgcr_lock);
45EXPORT_SYMBOL(cmxgcr_lock);
98658538
LY
46
47/* QE snum state */
48enum qe_snum_state {
49 QE_SNUM_STATE_USED,
50 QE_SNUM_STATE_FREE
51};
52
53/* QE snum */
54struct 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 */
0b51b02e 62struct qe_immap __iomem *qe_immr;
98658538
LY
63EXPORT_SYMBOL(qe_immr);
64
65static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
98ca77af 66static unsigned int qe_num_of_snum;
98658538
LY
67
68static phys_addr_t qebase = -1;
69
70phys_addr_t get_qe_base(void)
71{
72 struct device_node *qe;
7e1cc9c5 73 int size;
d8985fd2 74 const u32 *prop;
98658538
LY
75
76 if (qebase != -1)
77 return qebase;
78
a2dd70a1
AV
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);
d8985fd2
AV
87 if (prop && size >= sizeof(*prop))
88 qebase = of_translate_address(qe, prop);
a2dd70a1 89 of_node_put(qe);
98658538
LY
90
91 return qebase;
92}
93
94EXPORT_SYMBOL(get_qe_base);
95
0c7b87b0 96void qe_reset(void)
98658538
LY
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
113int 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;
f49156ea 117 u32 ret;
98658538
LY
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
302439d2 138 out_be32(&qe_immr->cp.cecdr, cmd_input);
98658538
LY
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 */
f49156ea
TT
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). */
98658538
LY
149 spin_unlock_irqrestore(&qe_lock, flags);
150
f49156ea 151 return ret == 1;
98658538
LY
152}
153EXPORT_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.
6b0b594b 159 * The BRG clock is the QE clock divided by 2.
98658538
LY
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 */
165static unsigned int brg_clk = 0;
166
7f0a6fc8 167unsigned int qe_get_brg_clk(void)
98658538
LY
168{
169 struct device_node *qe;
7e1cc9c5 170 int size;
a2dd70a1
AV
171 const u32 *prop;
172
98658538
LY
173 if (brg_clk)
174 return brg_clk;
175
a2dd70a1
AV
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);
d8985fd2
AV
184 if (prop && size == sizeof(*prop))
185 brg_clk = *prop;
a2dd70a1 186
a2dd70a1
AV
187 of_node_put(qe);
188
98658538
LY
189 return brg_clk;
190}
7f0a6fc8 191EXPORT_SYMBOL(qe_get_brg_clk);
98658538 192
6b0b594b
TT
193/* Program the BRG to the given sampling rate and multiplier
194 *
7264ec44 195 * @brg: the BRG, QE_BRG1 - QE_BRG16
6b0b594b
TT
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.
98658538 200 */
7264ec44 201int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
98658538 202{
98658538 203 u32 divisor, tempval;
6b0b594b 204 u32 div16 = 0;
98658538 205
7264ec44
TT
206 if ((brg < QE_BRG1) || (brg > QE_BRG16))
207 return -EINVAL;
208
7f0a6fc8 209 divisor = qe_get_brg_clk() / (rate * multiplier);
98658538 210
98658538 211 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
6b0b594b 212 div16 = QE_BRGC_DIV16;
98658538
LY
213 divisor /= 16;
214 }
215
6b0b594b
TT
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))
220 divisor++;
221
222 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
223 QE_BRGC_ENABLE | div16;
98658538 224
7264ec44
TT
225 out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
226
227 return 0;
98658538 228}
7264ec44 229EXPORT_SYMBOL(qe_setbrg);
98658538 230
174b0da2
TT
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*/
236enum 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}
261EXPORT_SYMBOL(qe_clock_source);
262
98658538
LY
263/* Initialize SNUMs (thread serial numbers) according to
264 * QE Module Control chapter, SNUM table
265 */
266static void qe_snums_init(void)
267{
268 int i;
269 static const u8 snum_init[] = {
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,
98ca77af
HW
273 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
274 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
275 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
98658538
LY
276 };
277
98ca77af
HW
278 qe_num_of_snum = qe_get_num_of_snums();
279
280 for (i = 0; i < qe_num_of_snum; i++) {
98658538
LY
281 snums[i].num = snum_init[i];
282 snums[i].state = QE_SNUM_STATE_FREE;
283 }
284}
285
286int qe_get_snum(void)
287{
288 unsigned long flags;
289 int snum = -EBUSY;
290 int i;
291
292 spin_lock_irqsave(&qe_lock, flags);
98ca77af 293 for (i = 0; i < qe_num_of_snum; i++) {
98658538
LY
294 if (snums[i].state == QE_SNUM_STATE_FREE) {
295 snums[i].state = QE_SNUM_STATE_USED;
296 snum = snums[i].num;
297 break;
298 }
299 }
300 spin_unlock_irqrestore(&qe_lock, flags);
301
302 return snum;
303}
304EXPORT_SYMBOL(qe_get_snum);
305
306void qe_put_snum(u8 snum)
307{
308 int i;
309
98ca77af 310 for (i = 0; i < qe_num_of_snum; i++) {
98658538
LY
311 if (snums[i].num == snum) {
312 snums[i].state = QE_SNUM_STATE_FREE;
313 break;
314 }
315 }
316}
317EXPORT_SYMBOL(qe_put_snum);
318
319static int qe_sdma_init(void)
320{
7e1cc9c5 321 struct sdma __iomem *sdma = &qe_immr->sdma;
0c7b87b0 322 static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
98658538
LY
323
324 if (!sdma)
325 return -ENODEV;
326
327 /* allocate 2 internal temporary buffers (512 bytes size each) for
328 * the SDMA */
0c7b87b0
AV
329 if (IS_ERR_VALUE(sdma_buf_offset)) {
330 sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
331 if (IS_ERR_VALUE(sdma_buf_offset))
332 return -ENOMEM;
333 }
98658538 334
4c35630c 335 out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
7f013bc9
CM
336 out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
337 (0x1 << QE_SDMR_CEN_SHIFT)));
98658538
LY
338
339 return 0;
340}
341
bc556ba9 342/* The maximum number of RISCs we support */
98eaa098 343#define MAX_QE_RISC 4
bc556ba9
TT
344
345/* Firmware information stored here for qe_get_firmware_info() */
346static struct qe_firmware_info qe_firmware_info;
347
348/*
349 * Set to 1 if QE firmware has been uploaded, and therefore
350 * qe_firmware_info contains valid data.
351 */
352static int qe_firmware_uploaded;
353
354/*
355 * Upload a QE microcode
356 *
357 * This function is a worker function for qe_upload_firmware(). It does
358 * the actual uploading of the microcode.
359 */
360static void qe_upload_microcode(const void *base,
361 const struct qe_microcode *ucode)
362{
363 const __be32 *code = base + be32_to_cpu(ucode->code_offset);
364 unsigned int i;
365
366 if (ucode->major || ucode->minor || ucode->revision)
367 printk(KERN_INFO "qe-firmware: "
368 "uploading microcode '%s' version %u.%u.%u\n",
369 ucode->id, ucode->major, ucode->minor, ucode->revision);
370 else
371 printk(KERN_INFO "qe-firmware: "
372 "uploading microcode '%s'\n", ucode->id);
373
374 /* Use auto-increment */
375 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
376 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
377
378 for (i = 0; i < be32_to_cpu(ucode->count); i++)
379 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
380}
381
382/*
383 * Upload a microcode to the I-RAM at a specific address.
384 *
385 * See Documentation/powerpc/qe-firmware.txt for information on QE microcode
386 * uploading.
387 *
388 * Currently, only version 1 is supported, so the 'version' field must be
389 * set to 1.
390 *
391 * The SOC model and revision are not validated, they are only displayed for
392 * informational purposes.
393 *
394 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
395 * all of the microcode structures, minus the CRC.
396 *
397 * 'length' is the size that the structure says it is, including the CRC.
398 */
399int qe_upload_firmware(const struct qe_firmware *firmware)
400{
401 unsigned int i;
402 unsigned int j;
403 u32 crc;
404 size_t calc_size = sizeof(struct qe_firmware);
405 size_t length;
406 const struct qe_header *hdr;
407
408 if (!firmware) {
409 printk(KERN_ERR "qe-firmware: invalid pointer\n");
410 return -EINVAL;
411 }
412
413 hdr = &firmware->header;
414 length = be32_to_cpu(hdr->length);
415
416 /* Check the magic */
417 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
418 (hdr->magic[2] != 'F')) {
419 printk(KERN_ERR "qe-firmware: not a microcode\n");
420 return -EPERM;
421 }
422
423 /* Check the version */
424 if (hdr->version != 1) {
425 printk(KERN_ERR "qe-firmware: unsupported version\n");
426 return -EPERM;
427 }
428
429 /* Validate some of the fields */
6f913160 430 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
bc556ba9
TT
431 printk(KERN_ERR "qe-firmware: invalid data\n");
432 return -EINVAL;
433 }
434
435 /* Validate the length and check if there's a CRC */
436 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
437
438 for (i = 0; i < firmware->count; i++)
439 /*
440 * For situations where the second RISC uses the same microcode
441 * as the first, the 'code_offset' and 'count' fields will be
442 * zero, so it's okay to add those.
443 */
444 calc_size += sizeof(__be32) *
445 be32_to_cpu(firmware->microcode[i].count);
446
447 /* Validate the length */
448 if (length != calc_size + sizeof(__be32)) {
449 printk(KERN_ERR "qe-firmware: invalid length\n");
450 return -EPERM;
451 }
452
453 /* Validate the CRC */
454 crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
455 if (crc != crc32(0, firmware, calc_size)) {
456 printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
457 return -EIO;
458 }
459
460 /*
461 * If the microcode calls for it, split the I-RAM.
462 */
463 if (!firmware->split)
464 setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
465
466 if (firmware->soc.model)
467 printk(KERN_INFO
468 "qe-firmware: firmware '%s' for %u V%u.%u\n",
469 firmware->id, be16_to_cpu(firmware->soc.model),
470 firmware->soc.major, firmware->soc.minor);
471 else
472 printk(KERN_INFO "qe-firmware: firmware '%s'\n",
473 firmware->id);
474
475 /*
476 * The QE only supports one microcode per RISC, so clear out all the
477 * saved microcode information and put in the new.
478 */
479 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
480 strcpy(qe_firmware_info.id, firmware->id);
481 qe_firmware_info.extended_modes = firmware->extended_modes;
482 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
483 sizeof(firmware->vtraps));
484
485 /* Loop through each microcode. */
486 for (i = 0; i < firmware->count; i++) {
487 const struct qe_microcode *ucode = &firmware->microcode[i];
488
489 /* Upload a microcode if it's present */
490 if (ucode->code_offset)
491 qe_upload_microcode(firmware, ucode);
492
493 /* Program the traps for this processor */
494 for (j = 0; j < 16; j++) {
495 u32 trap = be32_to_cpu(ucode->traps[j]);
496
497 if (trap)
498 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
499 }
500
501 /* Enable traps */
502 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
503 }
504
505 qe_firmware_uploaded = 1;
506
507 return 0;
508}
509EXPORT_SYMBOL(qe_upload_firmware);
510
511/*
512 * Get info on the currently-loaded firmware
513 *
514 * This function also checks the device tree to see if the boot loader has
515 * uploaded a firmware already.
516 */
517struct qe_firmware_info *qe_get_firmware_info(void)
518{
519 static int initialized;
520 struct property *prop;
521 struct device_node *qe;
522 struct device_node *fw = NULL;
523 const char *sprop;
524 unsigned int i;
525
526 /*
527 * If we haven't checked yet, and a driver hasn't uploaded a firmware
528 * yet, then check the device tree for information.
529 */
86f4e5d4
IN
530 if (qe_firmware_uploaded)
531 return &qe_firmware_info;
532
533 if (initialized)
bc556ba9
TT
534 return NULL;
535
536 initialized = 1;
537
538 /*
539 * Newer device trees have an "fsl,qe" compatible property for the QE
540 * node, but we still need to support older device trees.
541 */
542 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
543 if (!qe) {
544 qe = of_find_node_by_type(NULL, "qe");
545 if (!qe)
546 return NULL;
547 }
548
549 /* Find the 'firmware' child node */
550 for_each_child_of_node(qe, fw) {
551 if (strcmp(fw->name, "firmware") == 0)
552 break;
553 }
554
555 of_node_put(qe);
556
557 /* Did we find the 'firmware' node? */
558 if (!fw)
559 return NULL;
560
561 qe_firmware_uploaded = 1;
562
563 /* Copy the data into qe_firmware_info*/
564 sprop = of_get_property(fw, "id", NULL);
565 if (sprop)
566 strncpy(qe_firmware_info.id, sprop,
567 sizeof(qe_firmware_info.id) - 1);
568
569 prop = of_find_property(fw, "extended-modes", NULL);
570 if (prop && (prop->length == sizeof(u64))) {
571 const u64 *iprop = prop->value;
572
573 qe_firmware_info.extended_modes = *iprop;
574 }
575
576 prop = of_find_property(fw, "virtual-traps", NULL);
577 if (prop && (prop->length == 32)) {
578 const u32 *iprop = prop->value;
579
580 for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
581 qe_firmware_info.vtraps[i] = iprop[i];
582 }
583
584 of_node_put(fw);
585
586 return &qe_firmware_info;
587}
588EXPORT_SYMBOL(qe_get_firmware_info);
589
06c44350
HW
590unsigned int qe_get_num_of_risc(void)
591{
592 struct device_node *qe;
593 int size;
594 unsigned int num_of_risc = 0;
595 const u32 *prop;
596
597 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
598 if (!qe) {
599 /* Older devices trees did not have an "fsl,qe"
600 * compatible property, so we need to look for
601 * the QE node by name.
602 */
603 qe = of_find_node_by_type(NULL, "qe");
604 if (!qe)
605 return num_of_risc;
606 }
607
608 prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
609 if (prop && size == sizeof(*prop))
610 num_of_risc = *prop;
611
612 of_node_put(qe);
613
614 return num_of_risc;
615}
616EXPORT_SYMBOL(qe_get_num_of_risc);
617
98ca77af
HW
618unsigned int qe_get_num_of_snums(void)
619{
620 struct device_node *qe;
621 int size;
622 unsigned int num_of_snums;
623 const u32 *prop;
624
625 num_of_snums = 28; /* The default number of snum for threads is 28 */
626 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
627 if (!qe) {
628 /* Older devices trees did not have an "fsl,qe"
629 * compatible property, so we need to look for
630 * the QE node by name.
631 */
632 qe = of_find_node_by_type(NULL, "qe");
633 if (!qe)
634 return num_of_snums;
635 }
636
637 prop = of_get_property(qe, "fsl,qe-num-snums", &size);
638 if (prop && size == sizeof(*prop)) {
639 num_of_snums = *prop;
640 if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
641 /* No QE ever has fewer than 28 SNUMs */
642 pr_err("QE: number of snum is invalid\n");
5aac4d73 643 of_node_put(qe);
98ca77af
HW
644 return -EINVAL;
645 }
646 }
647
648 of_node_put(qe);
649
650 return num_of_snums;
651}
652EXPORT_SYMBOL(qe_get_num_of_snums);
fdfde24e
AV
653
654#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
a454dc50 655static int qe_resume(struct platform_device *ofdev)
fdfde24e
AV
656{
657 if (!qe_alive_during_sleep())
658 qe_reset();
659 return 0;
660}
661
a454dc50
GL
662static int qe_probe(struct platform_device *ofdev,
663 const struct of_device_id *id)
fdfde24e
AV
664{
665 return 0;
666}
667
668static const struct of_device_id qe_ids[] = {
669 { .compatible = "fsl,qe", },
670 { },
671};
672
673static struct of_platform_driver qe_driver = {
4018294b
GL
674 .driver = {
675 .name = "fsl-qe",
676 .owner = THIS_MODULE,
677 .of_match_table = qe_ids,
678 },
fdfde24e
AV
679 .probe = qe_probe,
680 .resume = qe_resume,
681};
682
683static int __init qe_drv_init(void)
684{
685 return of_register_platform_driver(&qe_driver);
686}
687device_initcall(qe_drv_init);
688#endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */