cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qe.c (17008B)


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