diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 13:04:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 13:04:20 -0500 |
commit | 21eb4fa1700112d1420d72e1de708af671a251c8 (patch) | |
tree | 3afd9f526da50108c27e05ac69826be5e7c2ad6e /arch/powerpc/platforms/ps3/repository.c | |
parent | 0c0e8caf9fd6c9a49fb9fbdba14a8b7b4239adde (diff) | |
parent | d003e7a1a569501cbe9a5ca14748177498c4893a (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
* master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc: (116 commits)
[POWERPC] Add export of vgacon_remap_base
[POWERPC] Remove bogus comment about page_is_ram
[POWERPC] windfarm: don't die on suspend thread signal
[POWERPC] Fix comment in kernel/irq.c
[POWERPC] ppc: Fix booke watchdog initialization
[POWERPC] PPC: Use ARRAY_SIZE macro when appropriate
[POWERPC] Use ARRAY_SIZE macro when appropriate
[POWERPC] Fix ppc64's writing to struct file_operations
[POWERPC] ppc: use syslog macro for the printk log level
[POWERPC] ppc: cs4218_tdm remove extra brace
[POWERPC] Add mpc52xx/lite5200 PCI support
[POWERPC] Only use H_BULK_REMOVE if the firmware supports it
[POWERPC] Fixup error handling when emulating a floating point instruction
[POWERPC] Enable interrupts if we are doing fp math emulation
[POWERPC] Added kprobes support to ppc32
[POWERPC] Make pSeries use the H_BULK_REMOVE hypervisor call
[POWERPC] Clear RI bit in MSR before restoring r13 when returning to userspace
[POWERPC] Fix performance monitor exception
[POWERPC] Compile fixes for arch/powerpc dcr code
[POWERPC] Maple: use mmio nvram
...
Diffstat (limited to 'arch/powerpc/platforms/ps3/repository.c')
-rw-r--r-- | arch/powerpc/platforms/ps3/repository.c | 220 |
1 files changed, 204 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 273a0d621bd..ae586a0e5d3 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c | |||
@@ -18,9 +18,10 @@ | |||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <asm/ps3.h> | ||
22 | #include <asm/lv1call.h> | 21 | #include <asm/lv1call.h> |
23 | 22 | ||
23 | #include "platform.h" | ||
24 | |||
24 | enum ps3_vendor_id { | 25 | enum ps3_vendor_id { |
25 | PS3_VENDOR_ID_NONE = 0, | 26 | PS3_VENDOR_ID_NONE = 0, |
26 | PS3_VENDOR_ID_SONY = 0x8000000000000000UL, | 27 | PS3_VENDOR_ID_SONY = 0x8000000000000000UL, |
@@ -257,7 +258,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index, | |||
257 | 258 | ||
258 | int ps3_repository_read_dev_intr(unsigned int bus_index, | 259 | int ps3_repository_read_dev_intr(unsigned int bus_index, |
259 | unsigned int dev_index, unsigned int intr_index, | 260 | unsigned int dev_index, unsigned int intr_index, |
260 | unsigned int *intr_type, unsigned int* interrupt_id) | 261 | enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id) |
261 | { | 262 | { |
262 | int result; | 263 | int result; |
263 | u64 v1; | 264 | u64 v1; |
@@ -275,7 +276,8 @@ int ps3_repository_read_dev_intr(unsigned int bus_index, | |||
275 | } | 276 | } |
276 | 277 | ||
277 | int ps3_repository_read_dev_reg_type(unsigned int bus_index, | 278 | int ps3_repository_read_dev_reg_type(unsigned int bus_index, |
278 | unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type) | 279 | unsigned int dev_index, unsigned int reg_index, |
280 | enum ps3_reg_type *reg_type) | ||
279 | { | 281 | { |
280 | int result; | 282 | int result; |
281 | u64 v1; | 283 | u64 v1; |
@@ -302,8 +304,8 @@ int ps3_repository_read_dev_reg_addr(unsigned int bus_index, | |||
302 | } | 304 | } |
303 | 305 | ||
304 | int ps3_repository_read_dev_reg(unsigned int bus_index, | 306 | int ps3_repository_read_dev_reg(unsigned int bus_index, |
305 | unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type, | 307 | unsigned int dev_index, unsigned int reg_index, |
306 | u64 *bus_addr, u64 *len) | 308 | enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len) |
307 | { | 309 | { |
308 | int result = ps3_repository_read_dev_reg_type(bus_index, dev_index, | 310 | int result = ps3_repository_read_dev_reg_type(bus_index, dev_index, |
309 | reg_index, reg_type); | 311 | reg_index, reg_type); |
@@ -343,7 +345,7 @@ int ps3_repository_dump_resource_info(unsigned int bus_index, | |||
343 | } | 345 | } |
344 | 346 | ||
345 | for (res_index = 0; res_index < 10; res_index++) { | 347 | for (res_index = 0; res_index < 10; res_index++) { |
346 | enum ps3_region_type reg_type; | 348 | enum ps3_reg_type reg_type; |
347 | u64 bus_addr; | 349 | u64 bus_addr; |
348 | u64 len; | 350 | u64 len; |
349 | 351 | ||
@@ -367,7 +369,55 @@ int ps3_repository_dump_resource_info(unsigned int bus_index, | |||
367 | return result; | 369 | return result; |
368 | } | 370 | } |
369 | 371 | ||
370 | static int dump_device_info(unsigned int bus_index, unsigned int num_dev) | 372 | static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index) |
373 | { | ||
374 | int result = 0; | ||
375 | unsigned int num_regions, region_index; | ||
376 | u64 port, blk_size, num_blocks; | ||
377 | |||
378 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | ||
379 | bus_index, dev_index); | ||
380 | |||
381 | result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port, | ||
382 | &blk_size, &num_blocks, &num_regions); | ||
383 | if (result) { | ||
384 | pr_debug("%s:%d ps3_repository_read_stor_dev_info" | ||
385 | " (%u:%u) failed\n", __func__, __LINE__, | ||
386 | bus_index, dev_index); | ||
387 | goto out; | ||
388 | } | ||
389 | |||
390 | pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " | ||
391 | "%lu, num_regions %u\n", | ||
392 | __func__, __LINE__, bus_index, dev_index, port, | ||
393 | blk_size, num_blocks, num_regions); | ||
394 | |||
395 | for (region_index = 0; region_index < num_regions; region_index++) { | ||
396 | unsigned int region_id; | ||
397 | u64 region_start, region_size; | ||
398 | |||
399 | result = ps3_repository_read_stor_dev_region(bus_index, | ||
400 | dev_index, region_index, ®ion_id, ®ion_start, | ||
401 | ®ion_size); | ||
402 | if (result) { | ||
403 | pr_debug("%s:%d ps3_repository_read_stor_dev_region" | ||
404 | " (%u:%u) failed\n", __func__, __LINE__, | ||
405 | bus_index, dev_index); | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", | ||
410 | __func__, __LINE__, bus_index, dev_index, region_id, | ||
411 | region_start, region_size); | ||
412 | } | ||
413 | |||
414 | out: | ||
415 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
416 | return result; | ||
417 | } | ||
418 | |||
419 | static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type, | ||
420 | unsigned int num_dev) | ||
371 | { | 421 | { |
372 | int result = 0; | 422 | int result = 0; |
373 | unsigned int dev_index; | 423 | unsigned int dev_index; |
@@ -402,6 +452,9 @@ static int dump_device_info(unsigned int bus_index, unsigned int num_dev) | |||
402 | __LINE__, bus_index, dev_index, dev_type, dev_id); | 452 | __LINE__, bus_index, dev_index, dev_type, dev_id); |
403 | 453 | ||
404 | ps3_repository_dump_resource_info(bus_index, dev_index); | 454 | ps3_repository_dump_resource_info(bus_index, dev_index); |
455 | |||
456 | if (bus_type == PS3_BUS_TYPE_STORAGE) | ||
457 | dump_stor_dev_info(bus_index, dev_index); | ||
405 | } | 458 | } |
406 | 459 | ||
407 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 460 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
@@ -452,7 +505,7 @@ int ps3_repository_dump_bus_info(void) | |||
452 | __func__, __LINE__, bus_index, bus_type, bus_id, | 505 | __func__, __LINE__, bus_index, bus_type, bus_id, |
453 | num_dev); | 506 | num_dev); |
454 | 507 | ||
455 | dump_device_info(bus_index, num_dev); | 508 | dump_device_info(bus_index, bus_type, num_dev); |
456 | } | 509 | } |
457 | 510 | ||
458 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 511 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
@@ -487,7 +540,8 @@ static int find_device(unsigned int bus_index, unsigned int num_dev, | |||
487 | break; | 540 | break; |
488 | } | 541 | } |
489 | 542 | ||
490 | BUG_ON(dev_index == num_dev); | 543 | if (dev_index == num_dev) |
544 | return -1; | ||
491 | 545 | ||
492 | pr_debug("%s:%d: found dev_type %u at dev_index %u\n", | 546 | pr_debug("%s:%d: found dev_type %u at dev_index %u\n", |
493 | __func__, __LINE__, dev_type, dev_index); | 547 | __func__, __LINE__, dev_type, dev_index); |
@@ -521,7 +575,7 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type, | |||
521 | pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__, | 575 | pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__, |
522 | bus_type, dev_type); | 576 | bus_type, dev_type); |
523 | 577 | ||
524 | dev->bus_index = UINT_MAX; | 578 | BUG_ON(start_dev && start_dev->bus_index > 10); |
525 | 579 | ||
526 | for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10; | 580 | for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10; |
527 | bus_index++) { | 581 | bus_index++) { |
@@ -532,13 +586,15 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type, | |||
532 | if (result) { | 586 | if (result) { |
533 | pr_debug("%s:%d read_bus_type failed\n", | 587 | pr_debug("%s:%d read_bus_type failed\n", |
534 | __func__, __LINE__); | 588 | __func__, __LINE__); |
589 | dev->bus_index = UINT_MAX; | ||
535 | return result; | 590 | return result; |
536 | } | 591 | } |
537 | if (x == bus_type) | 592 | if (x == bus_type) |
538 | break; | 593 | break; |
539 | } | 594 | } |
540 | 595 | ||
541 | BUG_ON(bus_index == 10); | 596 | if (bus_index >= 10) |
597 | return -ENODEV; | ||
542 | 598 | ||
543 | pr_debug("%s:%d: found bus_type %u at bus_index %u\n", | 599 | pr_debug("%s:%d: found bus_type %u at bus_index %u\n", |
544 | __func__, __LINE__, bus_type, bus_index); | 600 | __func__, __LINE__, bus_type, bus_index); |
@@ -604,7 +660,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, | |||
604 | } | 660 | } |
605 | } | 661 | } |
606 | 662 | ||
607 | BUG_ON(res_index == 10); | 663 | if (res_index == 10) |
664 | return -ENODEV; | ||
608 | 665 | ||
609 | pr_debug("%s:%d: found intr_type %u at res_index %u\n", | 666 | pr_debug("%s:%d: found intr_type %u at res_index %u\n", |
610 | __func__, __LINE__, intr_type, res_index); | 667 | __func__, __LINE__, intr_type, res_index); |
@@ -612,8 +669,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, | |||
612 | return result; | 669 | return result; |
613 | } | 670 | } |
614 | 671 | ||
615 | int ps3_repository_find_region(const struct ps3_repository_device *dev, | 672 | int ps3_repository_find_reg(const struct ps3_repository_device *dev, |
616 | enum ps3_region_type reg_type, u64 *bus_addr, u64 *len) | 673 | enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) |
617 | { | 674 | { |
618 | int result = 0; | 675 | int result = 0; |
619 | unsigned int res_index; | 676 | unsigned int res_index; |
@@ -623,7 +680,7 @@ int ps3_repository_find_region(const struct ps3_repository_device *dev, | |||
623 | *bus_addr = *len = 0; | 680 | *bus_addr = *len = 0; |
624 | 681 | ||
625 | for (res_index = 0; res_index < 10; res_index++) { | 682 | for (res_index = 0; res_index < 10; res_index++) { |
626 | enum ps3_region_type t; | 683 | enum ps3_reg_type t; |
627 | u64 a; | 684 | u64 a; |
628 | u64 l; | 685 | u64 l; |
629 | 686 | ||
@@ -643,7 +700,8 @@ int ps3_repository_find_region(const struct ps3_repository_device *dev, | |||
643 | } | 700 | } |
644 | } | 701 | } |
645 | 702 | ||
646 | BUG_ON(res_index == 10); | 703 | if (res_index == 10) |
704 | return -ENODEV; | ||
647 | 705 | ||
648 | pr_debug("%s:%d: found reg_type %u at res_index %u\n", | 706 | pr_debug("%s:%d: found reg_type %u at res_index %u\n", |
649 | __func__, __LINE__, reg_type, res_index); | 707 | __func__, __LINE__, reg_type, res_index); |
@@ -651,6 +709,136 @@ int ps3_repository_find_region(const struct ps3_repository_device *dev, | |||
651 | return result; | 709 | return result; |
652 | } | 710 | } |
653 | 711 | ||
712 | int ps3_repository_read_stor_dev_port(unsigned int bus_index, | ||
713 | unsigned int dev_index, u64 *port) | ||
714 | { | ||
715 | return read_node(PS3_LPAR_ID_PME, | ||
716 | make_first_field("bus", bus_index), | ||
717 | make_field("dev", dev_index), | ||
718 | make_field("port", 0), | ||
719 | 0, port, 0); | ||
720 | } | ||
721 | |||
722 | int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, | ||
723 | unsigned int dev_index, u64 *blk_size) | ||
724 | { | ||
725 | return read_node(PS3_LPAR_ID_PME, | ||
726 | make_first_field("bus", bus_index), | ||
727 | make_field("dev", dev_index), | ||
728 | make_field("blk_size", 0), | ||
729 | 0, blk_size, 0); | ||
730 | } | ||
731 | |||
732 | int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, | ||
733 | unsigned int dev_index, u64 *num_blocks) | ||
734 | { | ||
735 | return read_node(PS3_LPAR_ID_PME, | ||
736 | make_first_field("bus", bus_index), | ||
737 | make_field("dev", dev_index), | ||
738 | make_field("n_blocks", 0), | ||
739 | 0, num_blocks, 0); | ||
740 | } | ||
741 | |||
742 | int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, | ||
743 | unsigned int dev_index, unsigned int *num_regions) | ||
744 | { | ||
745 | int result; | ||
746 | u64 v1; | ||
747 | |||
748 | result = read_node(PS3_LPAR_ID_PME, | ||
749 | make_first_field("bus", bus_index), | ||
750 | make_field("dev", dev_index), | ||
751 | make_field("n_regs", 0), | ||
752 | 0, &v1, 0); | ||
753 | *num_regions = v1; | ||
754 | return result; | ||
755 | } | ||
756 | |||
757 | int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, | ||
758 | unsigned int dev_index, unsigned int region_index, | ||
759 | unsigned int *region_id) | ||
760 | { | ||
761 | int result; | ||
762 | u64 v1; | ||
763 | |||
764 | result = read_node(PS3_LPAR_ID_PME, | ||
765 | make_first_field("bus", bus_index), | ||
766 | make_field("dev", dev_index), | ||
767 | make_field("region", region_index), | ||
768 | make_field("id", 0), | ||
769 | &v1, 0); | ||
770 | *region_id = v1; | ||
771 | return result; | ||
772 | } | ||
773 | |||
774 | int ps3_repository_read_stor_dev_region_size(unsigned int bus_index, | ||
775 | unsigned int dev_index, unsigned int region_index, u64 *region_size) | ||
776 | { | ||
777 | return read_node(PS3_LPAR_ID_PME, | ||
778 | make_first_field("bus", bus_index), | ||
779 | make_field("dev", dev_index), | ||
780 | make_field("region", region_index), | ||
781 | make_field("size", 0), | ||
782 | region_size, 0); | ||
783 | } | ||
784 | |||
785 | int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, | ||
786 | unsigned int dev_index, unsigned int region_index, u64 *region_start) | ||
787 | { | ||
788 | return read_node(PS3_LPAR_ID_PME, | ||
789 | make_first_field("bus", bus_index), | ||
790 | make_field("dev", dev_index), | ||
791 | make_field("region", region_index), | ||
792 | make_field("start", 0), | ||
793 | region_start, 0); | ||
794 | } | ||
795 | |||
796 | int ps3_repository_read_stor_dev_info(unsigned int bus_index, | ||
797 | unsigned int dev_index, u64 *port, u64 *blk_size, | ||
798 | u64 *num_blocks, unsigned int *num_regions) | ||
799 | { | ||
800 | int result; | ||
801 | |||
802 | result = ps3_repository_read_stor_dev_port(bus_index, dev_index, port); | ||
803 | if (result) | ||
804 | return result; | ||
805 | |||
806 | result = ps3_repository_read_stor_dev_blk_size(bus_index, dev_index, | ||
807 | blk_size); | ||
808 | if (result) | ||
809 | return result; | ||
810 | |||
811 | result = ps3_repository_read_stor_dev_num_blocks(bus_index, dev_index, | ||
812 | num_blocks); | ||
813 | if (result) | ||
814 | return result; | ||
815 | |||
816 | result = ps3_repository_read_stor_dev_num_regions(bus_index, dev_index, | ||
817 | num_regions); | ||
818 | return result; | ||
819 | } | ||
820 | |||
821 | int ps3_repository_read_stor_dev_region(unsigned int bus_index, | ||
822 | unsigned int dev_index, unsigned int region_index, | ||
823 | unsigned int *region_id, u64 *region_start, u64 *region_size) | ||
824 | { | ||
825 | int result; | ||
826 | |||
827 | result = ps3_repository_read_stor_dev_region_id(bus_index, dev_index, | ||
828 | region_index, region_id); | ||
829 | if (result) | ||
830 | return result; | ||
831 | |||
832 | result = ps3_repository_read_stor_dev_region_start(bus_index, dev_index, | ||
833 | region_index, region_start); | ||
834 | if (result) | ||
835 | return result; | ||
836 | |||
837 | result = ps3_repository_read_stor_dev_region_size(bus_index, dev_index, | ||
838 | region_index, region_size); | ||
839 | return result; | ||
840 | } | ||
841 | |||
654 | int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) | 842 | int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) |
655 | { | 843 | { |
656 | return read_node(PS3_LPAR_ID_CURRENT, | 844 | return read_node(PS3_LPAR_ID_CURRENT, |