linux/arch/powerpc/sysdev/qe_lib/qe.c
<<
>>
Prefs
   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
  40static void qe_snums_init(void);
  41static int qe_sdma_init(void);
  42
  43static DEFINE_SPINLOCK(qe_lock);
  44DEFINE_SPINLOCK(cmxgcr_lock);
  45EXPORT_SYMBOL(cmxgcr_lock);
  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 */
  62struct qe_immap __iomem *qe_immr;
  63EXPORT_SYMBOL(qe_immr);
  64
  65static struct qe_snum snums[QE_NUM_OF_SNUM];    /* Dynamically allocated SNUMs */
  66static unsigned int qe_num_of_snum;
  67
  68static phys_addr_t qebase = -1;
  69
  70phys_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
  94EXPORT_SYMBOL(get_qe_base);
  95
  96void 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
 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;
 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}
 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.
 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 */
 165static unsigned int brg_clk = 0;
 166
 167unsigned 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}
 191EXPORT_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 */
 201int 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}
 229EXPORT_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*/
 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
 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_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
 304int 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}
 322EXPORT_SYMBOL(qe_get_snum);
 323
 324void 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}
 335EXPORT_SYMBOL(qe_put_snum);
 336
 337static 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() */
 364static 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 */
 370static 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 */
 378static 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 */
 420int 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}
 530EXPORT_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 */
 538struct 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}
 609EXPORT_SYMBOL(qe_get_firmware_info);
 610
 611unsigned 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}
 637EXPORT_SYMBOL(qe_get_num_of_risc);
 638
 639unsigned 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}
 673EXPORT_SYMBOL(qe_get_num_of_snums);
 674
 675#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
 676static int qe_resume(struct platform_device *ofdev)
 677{
 678        if (!qe_alive_during_sleep())
 679                qe_reset();
 680        return 0;
 681}
 682
 683static int qe_probe(struct platform_device *ofdev)
 684{
 685        return 0;
 686}
 687
 688static const struct of_device_id qe_ids[] = {
 689        { .compatible = "fsl,qe", },
 690        { },
 691};
 692
 693static 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
 703static int __init qe_drv_init(void)
 704{
 705        return platform_driver_register(&qe_driver);
 706}
 707device_initcall(qe_drv_init);
 708#endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
 709