diff options
Diffstat (limited to 'arch/powerpc/sysdev/qe_lib')
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 01bce3784b0a..b28b0e512d67 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
| @@ -61,6 +61,7 @@ struct qe_immap __iomem *qe_immr; | |||
| 61 | EXPORT_SYMBOL(qe_immr); | 61 | EXPORT_SYMBOL(qe_immr); |
| 62 | 62 | ||
| 63 | static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ | 63 | static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ |
| 64 | static unsigned int qe_num_of_snum; | ||
| 64 | 65 | ||
| 65 | static phys_addr_t qebase = -1; | 66 | static phys_addr_t qebase = -1; |
| 66 | 67 | ||
| @@ -264,10 +265,14 @@ static void qe_snums_init(void) | |||
| 264 | 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, | 265 | 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, |
| 265 | 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, | 266 | 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, |
| 266 | 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, | 267 | 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, |
| 267 | 0xD8, 0xD9, 0xE8, 0xE9, | 268 | 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19, |
| 269 | 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59, | ||
| 270 | 0x68, 0x69, 0x78, 0x79, 0x80, 0x81, | ||
| 268 | }; | 271 | }; |
| 269 | 272 | ||
| 270 | for (i = 0; i < QE_NUM_OF_SNUM; i++) { | 273 | qe_num_of_snum = qe_get_num_of_snums(); |
| 274 | |||
| 275 | for (i = 0; i < qe_num_of_snum; i++) { | ||
| 271 | snums[i].num = snum_init[i]; | 276 | snums[i].num = snum_init[i]; |
| 272 | snums[i].state = QE_SNUM_STATE_FREE; | 277 | snums[i].state = QE_SNUM_STATE_FREE; |
| 273 | } | 278 | } |
| @@ -280,7 +285,7 @@ int qe_get_snum(void) | |||
| 280 | int i; | 285 | int i; |
| 281 | 286 | ||
| 282 | spin_lock_irqsave(&qe_lock, flags); | 287 | spin_lock_irqsave(&qe_lock, flags); |
| 283 | for (i = 0; i < QE_NUM_OF_SNUM; i++) { | 288 | for (i = 0; i < qe_num_of_snum; i++) { |
| 284 | if (snums[i].state == QE_SNUM_STATE_FREE) { | 289 | if (snums[i].state == QE_SNUM_STATE_FREE) { |
| 285 | snums[i].state = QE_SNUM_STATE_USED; | 290 | snums[i].state = QE_SNUM_STATE_USED; |
| 286 | snum = snums[i].num; | 291 | snum = snums[i].num; |
| @@ -297,7 +302,7 @@ void qe_put_snum(u8 snum) | |||
| 297 | { | 302 | { |
| 298 | int i; | 303 | int i; |
| 299 | 304 | ||
| 300 | for (i = 0; i < QE_NUM_OF_SNUM; i++) { | 305 | for (i = 0; i < qe_num_of_snum; i++) { |
| 301 | if (snums[i].num == snum) { | 306 | if (snums[i].num == snum) { |
| 302 | snums[i].state = QE_SNUM_STATE_FREE; | 307 | snums[i].state = QE_SNUM_STATE_FREE; |
| 303 | break; | 308 | break; |
| @@ -575,3 +580,65 @@ struct qe_firmware_info *qe_get_firmware_info(void) | |||
| 575 | } | 580 | } |
| 576 | EXPORT_SYMBOL(qe_get_firmware_info); | 581 | EXPORT_SYMBOL(qe_get_firmware_info); |
| 577 | 582 | ||
| 583 | unsigned int qe_get_num_of_risc(void) | ||
| 584 | { | ||
| 585 | struct device_node *qe; | ||
| 586 | int size; | ||
| 587 | unsigned int num_of_risc = 0; | ||
| 588 | const u32 *prop; | ||
| 589 | |||
| 590 | qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
| 591 | if (!qe) { | ||
| 592 | /* Older devices trees did not have an "fsl,qe" | ||
| 593 | * compatible property, so we need to look for | ||
| 594 | * the QE node by name. | ||
| 595 | */ | ||
| 596 | qe = of_find_node_by_type(NULL, "qe"); | ||
| 597 | if (!qe) | ||
| 598 | return num_of_risc; | ||
| 599 | } | ||
| 600 | |||
| 601 | prop = of_get_property(qe, "fsl,qe-num-riscs", &size); | ||
| 602 | if (prop && size == sizeof(*prop)) | ||
| 603 | num_of_risc = *prop; | ||
| 604 | |||
| 605 | of_node_put(qe); | ||
| 606 | |||
| 607 | return num_of_risc; | ||
| 608 | } | ||
| 609 | EXPORT_SYMBOL(qe_get_num_of_risc); | ||
| 610 | |||
| 611 | unsigned int qe_get_num_of_snums(void) | ||
| 612 | { | ||
| 613 | struct device_node *qe; | ||
| 614 | int size; | ||
| 615 | unsigned int num_of_snums; | ||
| 616 | const u32 *prop; | ||
| 617 | |||
| 618 | num_of_snums = 28; /* The default number of snum for threads is 28 */ | ||
| 619 | qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
| 620 | if (!qe) { | ||
| 621 | /* Older devices trees did not have an "fsl,qe" | ||
| 622 | * compatible property, so we need to look for | ||
| 623 | * the QE node by name. | ||
| 624 | */ | ||
| 625 | qe = of_find_node_by_type(NULL, "qe"); | ||
| 626 | if (!qe) | ||
| 627 | return num_of_snums; | ||
| 628 | } | ||
| 629 | |||
| 630 | prop = of_get_property(qe, "fsl,qe-num-snums", &size); | ||
| 631 | if (prop && size == sizeof(*prop)) { | ||
| 632 | num_of_snums = *prop; | ||
| 633 | if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { | ||
| 634 | /* No QE ever has fewer than 28 SNUMs */ | ||
| 635 | pr_err("QE: number of snum is invalid\n"); | ||
| 636 | return -EINVAL; | ||
| 637 | } | ||
| 638 | } | ||
| 639 | |||
| 640 | of_node_put(qe); | ||
| 641 | |||
| 642 | return num_of_snums; | ||
| 643 | } | ||
| 644 | EXPORT_SYMBOL(qe_get_num_of_snums); | ||
