diff options
Diffstat (limited to 'arch/powerpc/platforms/iseries/pci.c')
-rw-r--r-- | arch/powerpc/platforms/iseries/pci.c | 289 |
1 files changed, 232 insertions, 57 deletions
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 35bcc98111f5..3eb12065df23 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/pci-bridge.h> | 34 | #include <asm/pci-bridge.h> |
35 | #include <asm/iommu.h> | 35 | #include <asm/iommu.h> |
36 | #include <asm/abs_addr.h> | 36 | #include <asm/abs_addr.h> |
37 | #include <asm/firmware.h> | ||
37 | 38 | ||
38 | #include <asm/iseries/hv_call_xm.h> | 39 | #include <asm/iseries/hv_call_xm.h> |
39 | #include <asm/iseries/mf.h> | 40 | #include <asm/iseries/mf.h> |
@@ -176,12 +177,12 @@ void iSeries_pcibios_init(void) | |||
176 | } | 177 | } |
177 | while ((node = of_get_next_child(root, node)) != NULL) { | 178 | while ((node = of_get_next_child(root, node)) != NULL) { |
178 | HvBusNumber bus; | 179 | HvBusNumber bus; |
179 | u32 *busp; | 180 | const u32 *busp; |
180 | 181 | ||
181 | if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) | 182 | if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) |
182 | continue; | 183 | continue; |
183 | 184 | ||
184 | busp = (u32 *)get_property(node, "bus-range", NULL); | 185 | busp = get_property(node, "bus-range", NULL); |
185 | if (busp == NULL) | 186 | if (busp == NULL) |
186 | continue; | 187 | continue; |
187 | bus = *busp; | 188 | bus = *busp; |
@@ -221,10 +222,9 @@ void __init iSeries_pci_final_fixup(void) | |||
221 | 222 | ||
222 | if (node != NULL) { | 223 | if (node != NULL) { |
223 | struct pci_dn *pdn = PCI_DN(node); | 224 | struct pci_dn *pdn = PCI_DN(node); |
224 | u32 *agent; | 225 | const u32 *agent; |
225 | 226 | ||
226 | agent = (u32 *)get_property(node, "linux,agent-id", | 227 | agent = get_property(node, "linux,agent-id", NULL); |
227 | NULL); | ||
228 | if ((pdn != NULL) && (agent != NULL)) { | 228 | if ((pdn != NULL) && (agent != NULL)) { |
229 | u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, | 229 | u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, |
230 | pdn->bussubno); | 230 | pdn->bussubno); |
@@ -271,46 +271,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev) | |||
271 | } | 271 | } |
272 | 272 | ||
273 | /* | 273 | /* |
274 | * I/0 Memory copy MUST use mmio commands on iSeries | ||
275 | * To do; For performance, include the hv call directly | ||
276 | */ | ||
277 | void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count) | ||
278 | { | ||
279 | u8 ByteValue = c; | ||
280 | long NumberOfBytes = Count; | ||
281 | |||
282 | while (NumberOfBytes > 0) { | ||
283 | iSeries_Write_Byte(ByteValue, dest++); | ||
284 | -- NumberOfBytes; | ||
285 | } | ||
286 | } | ||
287 | EXPORT_SYMBOL(iSeries_memset_io); | ||
288 | |||
289 | void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count) | ||
290 | { | ||
291 | char *src = source; | ||
292 | long NumberOfBytes = count; | ||
293 | |||
294 | while (NumberOfBytes > 0) { | ||
295 | iSeries_Write_Byte(*src++, dest++); | ||
296 | -- NumberOfBytes; | ||
297 | } | ||
298 | } | ||
299 | EXPORT_SYMBOL(iSeries_memcpy_toio); | ||
300 | |||
301 | void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count) | ||
302 | { | ||
303 | char *dst = dest; | ||
304 | long NumberOfBytes = count; | ||
305 | |||
306 | while (NumberOfBytes > 0) { | ||
307 | *dst++ = iSeries_Read_Byte(src++); | ||
308 | -- NumberOfBytes; | ||
309 | } | ||
310 | } | ||
311 | EXPORT_SYMBOL(iSeries_memcpy_fromio); | ||
312 | |||
313 | /* | ||
314 | * Look down the chain to find the matching Device Device | 274 | * Look down the chain to find the matching Device Device |
315 | */ | 275 | */ |
316 | static struct device_node *find_Device_Node(int bus, int devfn) | 276 | static struct device_node *find_Device_Node(int bus, int devfn) |
@@ -492,7 +452,7 @@ static inline struct device_node *xlate_iomm_address( | |||
492 | * iSeries_Read_Word = Read Word (16 bit) | 452 | * iSeries_Read_Word = Read Word (16 bit) |
493 | * iSeries_Read_Long = Read Long (32 bit) | 453 | * iSeries_Read_Long = Read Long (32 bit) |
494 | */ | 454 | */ |
495 | u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) | 455 | static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) |
496 | { | 456 | { |
497 | u64 BarOffset; | 457 | u64 BarOffset; |
498 | u64 dsa; | 458 | u64 dsa; |
@@ -519,9 +479,8 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) | |||
519 | 479 | ||
520 | return (u8)ret.value; | 480 | return (u8)ret.value; |
521 | } | 481 | } |
522 | EXPORT_SYMBOL(iSeries_Read_Byte); | ||
523 | 482 | ||
524 | u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) | 483 | static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) |
525 | { | 484 | { |
526 | u64 BarOffset; | 485 | u64 BarOffset; |
527 | u64 dsa; | 486 | u64 dsa; |
@@ -549,9 +508,8 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) | |||
549 | 508 | ||
550 | return swab16((u16)ret.value); | 509 | return swab16((u16)ret.value); |
551 | } | 510 | } |
552 | EXPORT_SYMBOL(iSeries_Read_Word); | ||
553 | 511 | ||
554 | u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) | 512 | static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) |
555 | { | 513 | { |
556 | u64 BarOffset; | 514 | u64 BarOffset; |
557 | u64 dsa; | 515 | u64 dsa; |
@@ -579,7 +537,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) | |||
579 | 537 | ||
580 | return swab32((u32)ret.value); | 538 | return swab32((u32)ret.value); |
581 | } | 539 | } |
582 | EXPORT_SYMBOL(iSeries_Read_Long); | ||
583 | 540 | ||
584 | /* | 541 | /* |
585 | * Write MM I/O Instructions for the iSeries | 542 | * Write MM I/O Instructions for the iSeries |
@@ -588,7 +545,7 @@ EXPORT_SYMBOL(iSeries_Read_Long); | |||
588 | * iSeries_Write_Word = Write Word(16 bit) | 545 | * iSeries_Write_Word = Write Word(16 bit) |
589 | * iSeries_Write_Long = Write Long(32 bit) | 546 | * iSeries_Write_Long = Write Long(32 bit) |
590 | */ | 547 | */ |
591 | void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) | 548 | static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) |
592 | { | 549 | { |
593 | u64 BarOffset; | 550 | u64 BarOffset; |
594 | u64 dsa; | 551 | u64 dsa; |
@@ -613,9 +570,8 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) | |||
613 | rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); | 570 | rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); |
614 | } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); | 571 | } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); |
615 | } | 572 | } |
616 | EXPORT_SYMBOL(iSeries_Write_Byte); | ||
617 | 573 | ||
618 | void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) | 574 | static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) |
619 | { | 575 | { |
620 | u64 BarOffset; | 576 | u64 BarOffset; |
621 | u64 dsa; | 577 | u64 dsa; |
@@ -640,9 +596,8 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) | |||
640 | rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); | 596 | rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); |
641 | } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); | 597 | } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); |
642 | } | 598 | } |
643 | EXPORT_SYMBOL(iSeries_Write_Word); | ||
644 | 599 | ||
645 | void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) | 600 | static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) |
646 | { | 601 | { |
647 | u64 BarOffset; | 602 | u64 BarOffset; |
648 | u64 dsa; | 603 | u64 dsa; |
@@ -667,4 +622,224 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) | |||
667 | rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); | 622 | rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); |
668 | } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); | 623 | } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); |
669 | } | 624 | } |
670 | EXPORT_SYMBOL(iSeries_Write_Long); | 625 | |
626 | extern unsigned char __raw_readb(const volatile void __iomem *addr) | ||
627 | { | ||
628 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
629 | |||
630 | return *(volatile unsigned char __force *)addr; | ||
631 | } | ||
632 | EXPORT_SYMBOL(__raw_readb); | ||
633 | |||
634 | extern unsigned short __raw_readw(const volatile void __iomem *addr) | ||
635 | { | ||
636 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
637 | |||
638 | return *(volatile unsigned short __force *)addr; | ||
639 | } | ||
640 | EXPORT_SYMBOL(__raw_readw); | ||
641 | |||
642 | extern unsigned int __raw_readl(const volatile void __iomem *addr) | ||
643 | { | ||
644 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
645 | |||
646 | return *(volatile unsigned int __force *)addr; | ||
647 | } | ||
648 | EXPORT_SYMBOL(__raw_readl); | ||
649 | |||
650 | extern unsigned long __raw_readq(const volatile void __iomem *addr) | ||
651 | { | ||
652 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
653 | |||
654 | return *(volatile unsigned long __force *)addr; | ||
655 | } | ||
656 | EXPORT_SYMBOL(__raw_readq); | ||
657 | |||
658 | extern void __raw_writeb(unsigned char v, volatile void __iomem *addr) | ||
659 | { | ||
660 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
661 | |||
662 | *(volatile unsigned char __force *)addr = v; | ||
663 | } | ||
664 | EXPORT_SYMBOL(__raw_writeb); | ||
665 | |||
666 | extern void __raw_writew(unsigned short v, volatile void __iomem *addr) | ||
667 | { | ||
668 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
669 | |||
670 | *(volatile unsigned short __force *)addr = v; | ||
671 | } | ||
672 | EXPORT_SYMBOL(__raw_writew); | ||
673 | |||
674 | extern void __raw_writel(unsigned int v, volatile void __iomem *addr) | ||
675 | { | ||
676 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
677 | |||
678 | *(volatile unsigned int __force *)addr = v; | ||
679 | } | ||
680 | EXPORT_SYMBOL(__raw_writel); | ||
681 | |||
682 | extern void __raw_writeq(unsigned long v, volatile void __iomem *addr) | ||
683 | { | ||
684 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
685 | |||
686 | *(volatile unsigned long __force *)addr = v; | ||
687 | } | ||
688 | EXPORT_SYMBOL(__raw_writeq); | ||
689 | |||
690 | int in_8(const volatile unsigned char __iomem *addr) | ||
691 | { | ||
692 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
693 | return iSeries_Read_Byte(addr); | ||
694 | return __in_8(addr); | ||
695 | } | ||
696 | EXPORT_SYMBOL(in_8); | ||
697 | |||
698 | void out_8(volatile unsigned char __iomem *addr, int val) | ||
699 | { | ||
700 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
701 | iSeries_Write_Byte(val, addr); | ||
702 | else | ||
703 | __out_8(addr, val); | ||
704 | } | ||
705 | EXPORT_SYMBOL(out_8); | ||
706 | |||
707 | int in_le16(const volatile unsigned short __iomem *addr) | ||
708 | { | ||
709 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
710 | return iSeries_Read_Word(addr); | ||
711 | return __in_le16(addr); | ||
712 | } | ||
713 | EXPORT_SYMBOL(in_le16); | ||
714 | |||
715 | int in_be16(const volatile unsigned short __iomem *addr) | ||
716 | { | ||
717 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
718 | |||
719 | return __in_be16(addr); | ||
720 | } | ||
721 | EXPORT_SYMBOL(in_be16); | ||
722 | |||
723 | void out_le16(volatile unsigned short __iomem *addr, int val) | ||
724 | { | ||
725 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
726 | iSeries_Write_Word(val, addr); | ||
727 | else | ||
728 | __out_le16(addr, val); | ||
729 | } | ||
730 | EXPORT_SYMBOL(out_le16); | ||
731 | |||
732 | void out_be16(volatile unsigned short __iomem *addr, int val) | ||
733 | { | ||
734 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
735 | |||
736 | __out_be16(addr, val); | ||
737 | } | ||
738 | EXPORT_SYMBOL(out_be16); | ||
739 | |||
740 | unsigned in_le32(const volatile unsigned __iomem *addr) | ||
741 | { | ||
742 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
743 | return iSeries_Read_Long(addr); | ||
744 | return __in_le32(addr); | ||
745 | } | ||
746 | EXPORT_SYMBOL(in_le32); | ||
747 | |||
748 | unsigned in_be32(const volatile unsigned __iomem *addr) | ||
749 | { | ||
750 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
751 | |||
752 | return __in_be32(addr); | ||
753 | } | ||
754 | EXPORT_SYMBOL(in_be32); | ||
755 | |||
756 | void out_le32(volatile unsigned __iomem *addr, int val) | ||
757 | { | ||
758 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
759 | iSeries_Write_Long(val, addr); | ||
760 | else | ||
761 | __out_le32(addr, val); | ||
762 | } | ||
763 | EXPORT_SYMBOL(out_le32); | ||
764 | |||
765 | void out_be32(volatile unsigned __iomem *addr, int val) | ||
766 | { | ||
767 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
768 | |||
769 | __out_be32(addr, val); | ||
770 | } | ||
771 | EXPORT_SYMBOL(out_be32); | ||
772 | |||
773 | unsigned long in_le64(const volatile unsigned long __iomem *addr) | ||
774 | { | ||
775 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
776 | |||
777 | return __in_le64(addr); | ||
778 | } | ||
779 | EXPORT_SYMBOL(in_le64); | ||
780 | |||
781 | unsigned long in_be64(const volatile unsigned long __iomem *addr) | ||
782 | { | ||
783 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
784 | |||
785 | return __in_be64(addr); | ||
786 | } | ||
787 | EXPORT_SYMBOL(in_be64); | ||
788 | |||
789 | void out_le64(volatile unsigned long __iomem *addr, unsigned long val) | ||
790 | { | ||
791 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
792 | |||
793 | __out_le64(addr, val); | ||
794 | } | ||
795 | EXPORT_SYMBOL(out_le64); | ||
796 | |||
797 | void out_be64(volatile unsigned long __iomem *addr, unsigned long val) | ||
798 | { | ||
799 | BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); | ||
800 | |||
801 | __out_be64(addr, val); | ||
802 | } | ||
803 | EXPORT_SYMBOL(out_be64); | ||
804 | |||
805 | void memset_io(volatile void __iomem *addr, int c, unsigned long n) | ||
806 | { | ||
807 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
808 | volatile char __iomem *d = addr; | ||
809 | |||
810 | while (n-- > 0) { | ||
811 | iSeries_Write_Byte(c, d++); | ||
812 | } | ||
813 | } else | ||
814 | eeh_memset_io(addr, c, n); | ||
815 | } | ||
816 | EXPORT_SYMBOL(memset_io); | ||
817 | |||
818 | void memcpy_fromio(void *dest, const volatile void __iomem *src, | ||
819 | unsigned long n) | ||
820 | { | ||
821 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
822 | char *d = dest; | ||
823 | const volatile char __iomem *s = src; | ||
824 | |||
825 | while (n-- > 0) { | ||
826 | *d++ = iSeries_Read_Byte(s++); | ||
827 | } | ||
828 | } else | ||
829 | eeh_memcpy_fromio(dest, src, n); | ||
830 | } | ||
831 | EXPORT_SYMBOL(memcpy_fromio); | ||
832 | |||
833 | void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) | ||
834 | { | ||
835 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
836 | const char *s = src; | ||
837 | volatile char __iomem *d = dest; | ||
838 | |||
839 | while (n-- > 0) { | ||
840 | iSeries_Write_Byte(*s++, d++); | ||
841 | } | ||
842 | } else | ||
843 | eeh_memcpy_toio(dest, src, n); | ||
844 | } | ||
845 | EXPORT_SYMBOL(memcpy_toio); | ||