aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/iseries/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/iseries/pci.c')
-rw-r--r--arch/powerpc/platforms/iseries/pci.c289
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 */
277void 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}
287EXPORT_SYMBOL(iSeries_memset_io);
288
289void 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}
299EXPORT_SYMBOL(iSeries_memcpy_toio);
300
301void 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}
311EXPORT_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 */
316static struct device_node *find_Device_Node(int bus, int devfn) 276static 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 */
495u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) 455static 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}
522EXPORT_SYMBOL(iSeries_Read_Byte);
523 482
524u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) 483static 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}
552EXPORT_SYMBOL(iSeries_Read_Word);
553 511
554u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) 512static 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}
582EXPORT_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 */
591void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) 548static 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}
616EXPORT_SYMBOL(iSeries_Write_Byte);
617 573
618void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) 574static 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}
643EXPORT_SYMBOL(iSeries_Write_Word);
644 599
645void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) 600static 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}
670EXPORT_SYMBOL(iSeries_Write_Long); 625
626extern 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}
632EXPORT_SYMBOL(__raw_readb);
633
634extern 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}
640EXPORT_SYMBOL(__raw_readw);
641
642extern 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}
648EXPORT_SYMBOL(__raw_readl);
649
650extern 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}
656EXPORT_SYMBOL(__raw_readq);
657
658extern 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}
664EXPORT_SYMBOL(__raw_writeb);
665
666extern 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}
672EXPORT_SYMBOL(__raw_writew);
673
674extern 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}
680EXPORT_SYMBOL(__raw_writel);
681
682extern 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}
688EXPORT_SYMBOL(__raw_writeq);
689
690int 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}
696EXPORT_SYMBOL(in_8);
697
698void 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}
705EXPORT_SYMBOL(out_8);
706
707int 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}
713EXPORT_SYMBOL(in_le16);
714
715int 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}
721EXPORT_SYMBOL(in_be16);
722
723void 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}
730EXPORT_SYMBOL(out_le16);
731
732void 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}
738EXPORT_SYMBOL(out_be16);
739
740unsigned 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}
746EXPORT_SYMBOL(in_le32);
747
748unsigned in_be32(const volatile unsigned __iomem *addr)
749{
750 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
751
752 return __in_be32(addr);
753}
754EXPORT_SYMBOL(in_be32);
755
756void 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}
763EXPORT_SYMBOL(out_le32);
764
765void 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}
771EXPORT_SYMBOL(out_be32);
772
773unsigned 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}
779EXPORT_SYMBOL(in_le64);
780
781unsigned 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}
787EXPORT_SYMBOL(in_be64);
788
789void 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}
795EXPORT_SYMBOL(out_le64);
796
797void 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}
803EXPORT_SYMBOL(out_be64);
804
805void 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}
816EXPORT_SYMBOL(memset_io);
817
818void 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}
831EXPORT_SYMBOL(memcpy_fromio);
832
833void 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}
845EXPORT_SYMBOL(memcpy_toio);