.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved. |
---|
3 | 4 | * |
---|
.. | .. |
---|
8 | 9 | * Description: |
---|
9 | 10 | * General Purpose functions for the global management of the |
---|
10 | 11 | * 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 | 12 | */ |
---|
| 13 | +#include <linux/bitmap.h> |
---|
17 | 14 | #include <linux/errno.h> |
---|
18 | 15 | #include <linux/sched.h> |
---|
19 | 16 | #include <linux/kernel.h> |
---|
.. | .. |
---|
25 | 22 | #include <linux/module.h> |
---|
26 | 23 | #include <linux/delay.h> |
---|
27 | 24 | #include <linux/ioport.h> |
---|
| 25 | +#include <linux/iopoll.h> |
---|
28 | 26 | #include <linux/crc32.h> |
---|
29 | 27 | #include <linux/mod_devicetable.h> |
---|
30 | 28 | #include <linux/of_platform.h> |
---|
31 | | -#include <asm/irq.h> |
---|
32 | | -#include <asm/page.h> |
---|
33 | | -#include <asm/pgtable.h> |
---|
34 | 29 | #include <soc/fsl/qe/immap_qe.h> |
---|
35 | 30 | #include <soc/fsl/qe/qe.h> |
---|
36 | | -#include <asm/prom.h> |
---|
37 | | -#include <asm/rheap.h> |
---|
38 | 31 | |
---|
39 | 32 | static void qe_snums_init(void); |
---|
40 | 33 | static int qe_sdma_init(void); |
---|
.. | .. |
---|
43 | 36 | DEFINE_SPINLOCK(cmxgcr_lock); |
---|
44 | 37 | EXPORT_SYMBOL(cmxgcr_lock); |
---|
45 | 38 | |
---|
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 | 39 | /* We allocate this here because it is used almost exclusively for |
---|
59 | 40 | * the communication processor devices. |
---|
60 | 41 | */ |
---|
61 | 42 | struct qe_immap __iomem *qe_immr; |
---|
62 | 43 | EXPORT_SYMBOL(qe_immr); |
---|
63 | 44 | |
---|
64 | | -static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ |
---|
| 45 | +static u8 snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ |
---|
| 46 | +static DECLARE_BITMAP(snum_state, QE_NUM_OF_SNUM); |
---|
65 | 47 | static unsigned int qe_num_of_snum; |
---|
66 | 48 | |
---|
67 | 49 | static phys_addr_t qebase = -1; |
---|
| 50 | + |
---|
| 51 | +static 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 | +} |
---|
68 | 64 | |
---|
69 | 65 | static phys_addr_t get_qe_base(void) |
---|
70 | 66 | { |
---|
.. | .. |
---|
75 | 71 | if (qebase != -1) |
---|
76 | 72 | return qebase; |
---|
77 | 73 | |
---|
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 | | - } |
---|
| 74 | + qe = qe_get_device_node(); |
---|
| 75 | + if (!qe) |
---|
| 76 | + return qebase; |
---|
84 | 77 | |
---|
85 | 78 | ret = of_address_to_resource(qe, 0, &res); |
---|
86 | 79 | if (!ret) |
---|
.. | .. |
---|
111 | 104 | { |
---|
112 | 105 | unsigned long flags; |
---|
113 | 106 | u8 mcn_shift = 0, dev_shift = 0; |
---|
114 | | - u32 ret; |
---|
| 107 | + u32 val; |
---|
| 108 | + int ret; |
---|
115 | 109 | |
---|
116 | 110 | spin_lock_irqsave(&qe_lock, flags); |
---|
117 | 111 | if (cmd == QE_RESET) { |
---|
118 | | - out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG)); |
---|
| 112 | + qe_iowrite32be((u32)(cmd | QE_CR_FLG), &qe_immr->cp.cecr); |
---|
119 | 113 | } else { |
---|
120 | 114 | if (cmd == QE_ASSIGN_PAGE) { |
---|
121 | 115 | /* Here device is the SNUM, not sub-block */ |
---|
.. | .. |
---|
132 | 126 | mcn_shift = QE_CR_MCN_NORMAL_SHIFT; |
---|
133 | 127 | } |
---|
134 | 128 | |
---|
135 | | - out_be32(&qe_immr->cp.cecdr, cmd_input); |
---|
136 | | - out_be32(&qe_immr->cp.cecr, |
---|
137 | | - (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) |
---|
138 | | - mcn_protocol << mcn_shift)); |
---|
| 129 | + qe_iowrite32be(cmd_input, &qe_immr->cp.cecdr); |
---|
| 130 | + qe_iowrite32be((cmd | QE_CR_FLG | ((u32)device << dev_shift) | (u32)mcn_protocol << mcn_shift), |
---|
| 131 | + &qe_immr->cp.cecr); |
---|
139 | 132 | } |
---|
140 | 133 | |
---|
141 | 134 | /* wait for the QE_CR_FLG to clear */ |
---|
142 | | - ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0, |
---|
143 | | - 100, 0); |
---|
144 | | - /* On timeout (e.g. failure), the expression will be false (ret == 0), |
---|
145 | | - otherwise it will be true (ret == 1). */ |
---|
| 135 | + ret = readx_poll_timeout_atomic(qe_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. */ |
---|
146 | 138 | spin_unlock_irqrestore(&qe_lock, flags); |
---|
147 | 139 | |
---|
148 | | - return ret == 1; |
---|
| 140 | + return ret == 0; |
---|
149 | 141 | } |
---|
150 | 142 | EXPORT_SYMBOL(qe_issue_cmd); |
---|
151 | 143 | |
---|
.. | .. |
---|
167 | 159 | unsigned int qe_get_brg_clk(void) |
---|
168 | 160 | { |
---|
169 | 161 | struct device_node *qe; |
---|
170 | | - int size; |
---|
171 | | - const u32 *prop; |
---|
| 162 | + u32 brg; |
---|
172 | 163 | unsigned int mod; |
---|
173 | 164 | |
---|
174 | 165 | if (brg_clk) |
---|
175 | 166 | return brg_clk; |
---|
176 | 167 | |
---|
177 | | - qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
---|
178 | | - if (!qe) { |
---|
179 | | - qe = of_find_node_by_type(NULL, "qe"); |
---|
180 | | - if (!qe) |
---|
181 | | - return brg_clk; |
---|
182 | | - } |
---|
| 168 | + qe = qe_get_device_node(); |
---|
| 169 | + if (!qe) |
---|
| 170 | + return brg_clk; |
---|
183 | 171 | |
---|
184 | | - prop = of_get_property(qe, "brg-frequency", &size); |
---|
185 | | - if (prop && size == sizeof(*prop)) |
---|
186 | | - brg_clk = *prop; |
---|
| 172 | + if (!of_property_read_u32(qe, "brg-frequency", &brg)) |
---|
| 173 | + brg_clk = brg; |
---|
187 | 174 | |
---|
188 | 175 | of_node_put(qe); |
---|
189 | 176 | |
---|
.. | .. |
---|
202 | 189 | |
---|
203 | 190 | #define PVR_VER_836x 0x8083 |
---|
204 | 191 | #define PVR_VER_832x 0x8084 |
---|
| 192 | + |
---|
| 193 | +static 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 | +} |
---|
205 | 200 | |
---|
206 | 201 | /* Program the BRG to the given sampling rate and multiplier |
---|
207 | 202 | * |
---|
.. | .. |
---|
229 | 224 | /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says |
---|
230 | 225 | that the BRG divisor must be even if you're not using divide-by-16 |
---|
231 | 226 | mode. */ |
---|
232 | | - if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x)) |
---|
| 227 | + if (qe_general4_errata()) |
---|
233 | 228 | if (!div16 && (divisor & 1) && (divisor > 3)) |
---|
234 | 229 | divisor++; |
---|
235 | 230 | |
---|
236 | 231 | tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | |
---|
237 | 232 | QE_BRGC_ENABLE | div16; |
---|
238 | 233 | |
---|
239 | | - out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval); |
---|
| 234 | + qe_iowrite32be(tempval, &qe_immr->brg.brgc[brg - QE_BRG1]); |
---|
240 | 235 | |
---|
241 | 236 | return 0; |
---|
242 | 237 | } |
---|
.. | .. |
---|
285 | 280 | */ |
---|
286 | 281 | static void qe_snums_init(void) |
---|
287 | 282 | { |
---|
288 | | - int i; |
---|
289 | 283 | static const u8 snum_init_76[] = { |
---|
290 | 284 | 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, |
---|
291 | 285 | 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, |
---|
.. | .. |
---|
306 | 300 | 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59, |
---|
307 | 301 | 0x68, 0x69, 0x78, 0x79, 0x80, 0x81, |
---|
308 | 302 | }; |
---|
309 | | - static const u8 *snum_init; |
---|
| 303 | + struct device_node *qe; |
---|
| 304 | + const u8 *snum_init; |
---|
| 305 | + int i; |
---|
310 | 306 | |
---|
311 | | - qe_num_of_snum = qe_get_num_of_snums(); |
---|
312 | | - |
---|
313 | | - if (qe_num_of_snum == 76) |
---|
314 | | - snum_init = snum_init_76; |
---|
315 | | - else |
---|
316 | | - snum_init = snum_init_46; |
---|
317 | | - |
---|
318 | | - for (i = 0; i < qe_num_of_snum; i++) { |
---|
319 | | - snums[i].num = snum_init[i]; |
---|
320 | | - snums[i].state = QE_SNUM_STATE_FREE; |
---|
| 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); |
---|
321 | 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); |
---|
322 | 336 | } |
---|
323 | 337 | |
---|
324 | 338 | int qe_get_snum(void) |
---|
.. | .. |
---|
328 | 342 | int i; |
---|
329 | 343 | |
---|
330 | 344 | spin_lock_irqsave(&qe_lock, flags); |
---|
331 | | - for (i = 0; i < qe_num_of_snum; i++) { |
---|
332 | | - if (snums[i].state == QE_SNUM_STATE_FREE) { |
---|
333 | | - snums[i].state = QE_SNUM_STATE_USED; |
---|
334 | | - snum = snums[i].num; |
---|
335 | | - break; |
---|
336 | | - } |
---|
| 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]; |
---|
337 | 349 | } |
---|
338 | 350 | spin_unlock_irqrestore(&qe_lock, flags); |
---|
339 | 351 | |
---|
.. | .. |
---|
343 | 355 | |
---|
344 | 356 | void qe_put_snum(u8 snum) |
---|
345 | 357 | { |
---|
346 | | - int i; |
---|
| 358 | + const u8 *p = memchr(snums, snum, qe_num_of_snum); |
---|
347 | 359 | |
---|
348 | | - for (i = 0; i < qe_num_of_snum; i++) { |
---|
349 | | - if (snums[i].num == snum) { |
---|
350 | | - snums[i].state = QE_SNUM_STATE_FREE; |
---|
351 | | - break; |
---|
352 | | - } |
---|
353 | | - } |
---|
| 360 | + if (p) |
---|
| 361 | + clear_bit(p - snums, snum_state); |
---|
354 | 362 | } |
---|
355 | 363 | EXPORT_SYMBOL(qe_put_snum); |
---|
356 | 364 | |
---|
357 | 365 | static int qe_sdma_init(void) |
---|
358 | 366 | { |
---|
359 | 367 | struct sdma __iomem *sdma = &qe_immr->sdma; |
---|
360 | | - static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM; |
---|
361 | | - |
---|
362 | | - if (!sdma) |
---|
363 | | - return -ENODEV; |
---|
| 368 | + static s32 sdma_buf_offset = -ENOMEM; |
---|
364 | 369 | |
---|
365 | 370 | /* allocate 2 internal temporary buffers (512 bytes size each) for |
---|
366 | 371 | * the SDMA */ |
---|
367 | | - if (IS_ERR_VALUE(sdma_buf_offset)) { |
---|
| 372 | + if (sdma_buf_offset < 0) { |
---|
368 | 373 | sdma_buf_offset = qe_muram_alloc(512 * 2, 4096); |
---|
369 | | - if (IS_ERR_VALUE(sdma_buf_offset)) |
---|
| 374 | + if (sdma_buf_offset < 0) |
---|
370 | 375 | return -ENOMEM; |
---|
371 | 376 | } |
---|
372 | 377 | |
---|
373 | | - out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK); |
---|
374 | | - out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | |
---|
375 | | - (0x1 << QE_SDMR_CEN_SHIFT))); |
---|
| 378 | + qe_iowrite32be((u32)sdma_buf_offset & QE_SDEBCR_BA_MASK, |
---|
| 379 | + &sdma->sdebcr); |
---|
| 380 | + qe_iowrite32be((QE_SDMR_GLB_1_MSK | (0x1 << QE_SDMR_CEN_SHIFT)), |
---|
| 381 | + &sdma->sdmr); |
---|
376 | 382 | |
---|
377 | 383 | return 0; |
---|
378 | 384 | } |
---|
.. | .. |
---|
410 | 416 | "uploading microcode '%s'\n", ucode->id); |
---|
411 | 417 | |
---|
412 | 418 | /* Use auto-increment */ |
---|
413 | | - out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) | |
---|
414 | | - QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); |
---|
| 419 | + qe_iowrite32be(be32_to_cpu(ucode->iram_offset) | QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR, |
---|
| 420 | + &qe_immr->iram.iadd); |
---|
415 | 421 | |
---|
416 | 422 | for (i = 0; i < be32_to_cpu(ucode->count); i++) |
---|
417 | | - out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i])); |
---|
| 423 | + qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata); |
---|
418 | 424 | |
---|
419 | 425 | /* Set I-RAM Ready Register */ |
---|
420 | | - out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY)); |
---|
| 426 | + qe_iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready); |
---|
421 | 427 | } |
---|
422 | 428 | |
---|
423 | 429 | /* |
---|
424 | 430 | * Upload a microcode to the I-RAM at a specific address. |
---|
425 | 431 | * |
---|
426 | | - * See Documentation/powerpc/qe_firmware.txt for information on QE microcode |
---|
| 432 | + * See Documentation/powerpc/qe_firmware.rst for information on QE microcode |
---|
427 | 433 | * uploading. |
---|
428 | 434 | * |
---|
429 | 435 | * Currently, only version 1 is supported, so the 'version' field must be |
---|
.. | .. |
---|
442 | 448 | unsigned int i; |
---|
443 | 449 | unsigned int j; |
---|
444 | 450 | u32 crc; |
---|
445 | | - size_t calc_size = sizeof(struct qe_firmware); |
---|
| 451 | + size_t calc_size; |
---|
446 | 452 | size_t length; |
---|
447 | 453 | const struct qe_header *hdr; |
---|
448 | 454 | |
---|
.. | .. |
---|
474 | 480 | } |
---|
475 | 481 | |
---|
476 | 482 | /* Validate the length and check if there's a CRC */ |
---|
477 | | - calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); |
---|
| 483 | + calc_size = struct_size(firmware, microcode, firmware->count); |
---|
478 | 484 | |
---|
479 | 485 | for (i = 0; i < firmware->count; i++) |
---|
480 | 486 | /* |
---|
.. | .. |
---|
502 | 508 | * If the microcode calls for it, split the I-RAM. |
---|
503 | 509 | */ |
---|
504 | 510 | if (!firmware->split) |
---|
505 | | - setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR); |
---|
| 511 | + qe_setbits_be16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR); |
---|
506 | 512 | |
---|
507 | 513 | if (firmware->soc.model) |
---|
508 | 514 | printk(KERN_INFO |
---|
.. | .. |
---|
519 | 525 | */ |
---|
520 | 526 | memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); |
---|
521 | 527 | strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id)); |
---|
522 | | - qe_firmware_info.extended_modes = firmware->extended_modes; |
---|
| 528 | + qe_firmware_info.extended_modes = be64_to_cpu(firmware->extended_modes); |
---|
523 | 529 | memcpy(qe_firmware_info.vtraps, firmware->vtraps, |
---|
524 | 530 | sizeof(firmware->vtraps)); |
---|
525 | 531 | |
---|
.. | .. |
---|
536 | 542 | u32 trap = be32_to_cpu(ucode->traps[j]); |
---|
537 | 543 | |
---|
538 | 544 | if (trap) |
---|
539 | | - out_be32(&qe_immr->rsp[i].tibcr[j], trap); |
---|
| 545 | + qe_iowrite32be(trap, |
---|
| 546 | + &qe_immr->rsp[i].tibcr[j]); |
---|
540 | 547 | } |
---|
541 | 548 | |
---|
542 | 549 | /* Enable traps */ |
---|
543 | | - out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); |
---|
| 550 | + qe_iowrite32be(be32_to_cpu(ucode->eccr), |
---|
| 551 | + &qe_immr->rsp[i].eccr); |
---|
544 | 552 | } |
---|
545 | 553 | |
---|
546 | 554 | qe_firmware_uploaded = 1; |
---|
.. | .. |
---|
558 | 566 | struct qe_firmware_info *qe_get_firmware_info(void) |
---|
559 | 567 | { |
---|
560 | 568 | static int initialized; |
---|
561 | | - struct property *prop; |
---|
562 | 569 | struct device_node *qe; |
---|
563 | 570 | struct device_node *fw = NULL; |
---|
564 | 571 | const char *sprop; |
---|
565 | | - unsigned int i; |
---|
566 | 572 | |
---|
567 | 573 | /* |
---|
568 | 574 | * If we haven't checked yet, and a driver hasn't uploaded a firmware |
---|
.. | .. |
---|
576 | 582 | |
---|
577 | 583 | initialized = 1; |
---|
578 | 584 | |
---|
579 | | - /* |
---|
580 | | - * Newer device trees have an "fsl,qe" compatible property for the QE |
---|
581 | | - * node, but we still need to support older device trees. |
---|
582 | | - */ |
---|
583 | | - qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
---|
584 | | - if (!qe) { |
---|
585 | | - qe = of_find_node_by_type(NULL, "qe"); |
---|
586 | | - if (!qe) |
---|
587 | | - return NULL; |
---|
588 | | - } |
---|
| 585 | + qe = qe_get_device_node(); |
---|
| 586 | + if (!qe) |
---|
| 587 | + return NULL; |
---|
589 | 588 | |
---|
590 | 589 | /* Find the 'firmware' child node */ |
---|
591 | | - for_each_child_of_node(qe, fw) { |
---|
592 | | - if (strcmp(fw->name, "firmware") == 0) |
---|
593 | | - break; |
---|
594 | | - } |
---|
595 | | - |
---|
| 590 | + fw = of_get_child_by_name(qe, "firmware"); |
---|
596 | 591 | of_node_put(qe); |
---|
597 | 592 | |
---|
598 | 593 | /* Did we find the 'firmware' node? */ |
---|
.. | .. |
---|
607 | 602 | strlcpy(qe_firmware_info.id, sprop, |
---|
608 | 603 | sizeof(qe_firmware_info.id)); |
---|
609 | 604 | |
---|
610 | | - prop = of_find_property(fw, "extended-modes", NULL); |
---|
611 | | - if (prop && (prop->length == sizeof(u64))) { |
---|
612 | | - const u64 *iprop = prop->value; |
---|
| 605 | + of_property_read_u64(fw, "extended-modes", |
---|
| 606 | + &qe_firmware_info.extended_modes); |
---|
613 | 607 | |
---|
614 | | - qe_firmware_info.extended_modes = *iprop; |
---|
615 | | - } |
---|
616 | | - |
---|
617 | | - prop = of_find_property(fw, "virtual-traps", NULL); |
---|
618 | | - if (prop && (prop->length == 32)) { |
---|
619 | | - const u32 *iprop = prop->value; |
---|
620 | | - |
---|
621 | | - for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++) |
---|
622 | | - qe_firmware_info.vtraps[i] = iprop[i]; |
---|
623 | | - } |
---|
| 608 | + of_property_read_u32_array(fw, "virtual-traps", qe_firmware_info.vtraps, |
---|
| 609 | + ARRAY_SIZE(qe_firmware_info.vtraps)); |
---|
624 | 610 | |
---|
625 | 611 | of_node_put(fw); |
---|
626 | 612 | |
---|
.. | .. |
---|
631 | 617 | unsigned int qe_get_num_of_risc(void) |
---|
632 | 618 | { |
---|
633 | 619 | struct device_node *qe; |
---|
634 | | - int size; |
---|
635 | 620 | unsigned int num_of_risc = 0; |
---|
636 | | - const u32 *prop; |
---|
637 | 621 | |
---|
638 | | - qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
---|
639 | | - if (!qe) { |
---|
640 | | - /* Older devices trees did not have an "fsl,qe" |
---|
641 | | - * compatible property, so we need to look for |
---|
642 | | - * the QE node by name. |
---|
643 | | - */ |
---|
644 | | - qe = of_find_node_by_type(NULL, "qe"); |
---|
645 | | - if (!qe) |
---|
646 | | - return num_of_risc; |
---|
647 | | - } |
---|
| 622 | + qe = qe_get_device_node(); |
---|
| 623 | + if (!qe) |
---|
| 624 | + return num_of_risc; |
---|
648 | 625 | |
---|
649 | | - prop = of_get_property(qe, "fsl,qe-num-riscs", &size); |
---|
650 | | - if (prop && size == sizeof(*prop)) |
---|
651 | | - num_of_risc = *prop; |
---|
| 626 | + of_property_read_u32(qe, "fsl,qe-num-riscs", &num_of_risc); |
---|
652 | 627 | |
---|
653 | 628 | of_node_put(qe); |
---|
654 | 629 | |
---|
.. | .. |
---|
658 | 633 | |
---|
659 | 634 | unsigned int qe_get_num_of_snums(void) |
---|
660 | 635 | { |
---|
661 | | - struct device_node *qe; |
---|
662 | | - int size; |
---|
663 | | - unsigned int num_of_snums; |
---|
664 | | - const u32 *prop; |
---|
665 | | - |
---|
666 | | - num_of_snums = 28; /* The default number of snum for threads is 28 */ |
---|
667 | | - qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
---|
668 | | - if (!qe) { |
---|
669 | | - /* Older devices trees did not have an "fsl,qe" |
---|
670 | | - * compatible property, so we need to look for |
---|
671 | | - * the QE node by name. |
---|
672 | | - */ |
---|
673 | | - qe = of_find_node_by_type(NULL, "qe"); |
---|
674 | | - if (!qe) |
---|
675 | | - return num_of_snums; |
---|
676 | | - } |
---|
677 | | - |
---|
678 | | - prop = of_get_property(qe, "fsl,qe-num-snums", &size); |
---|
679 | | - if (prop && size == sizeof(*prop)) { |
---|
680 | | - num_of_snums = *prop; |
---|
681 | | - if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { |
---|
682 | | - /* No QE ever has fewer than 28 SNUMs */ |
---|
683 | | - pr_err("QE: number of snum is invalid\n"); |
---|
684 | | - of_node_put(qe); |
---|
685 | | - return -EINVAL; |
---|
686 | | - } |
---|
687 | | - } |
---|
688 | | - |
---|
689 | | - of_node_put(qe); |
---|
690 | | - |
---|
691 | | - return num_of_snums; |
---|
| 636 | + return qe_num_of_snum; |
---|
692 | 637 | } |
---|
693 | 638 | EXPORT_SYMBOL(qe_get_num_of_snums); |
---|
694 | 639 | |
---|