diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-10 01:20:01 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:12 -0500 |
commit | 7eae642f75e0f7fbce7c37b2dfe0641ff1e9ebfd (patch) | |
tree | bc308c82a5670163470b44b6f339d1b379a97347 | |
parent | bade5622167181844cd4e60087971c1f949e149f (diff) |
[SPARC64]: Implement SUN4V PCI config space access.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 40 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.h | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v_asm.S | 48 |
3 files changed, 93 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 1d61353e2644..abd9bfb245cb 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -74,15 +74,47 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { | |||
74 | static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | 74 | static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, |
75 | int where, int size, u32 *value) | 75 | int where, int size, u32 *value) |
76 | { | 76 | { |
77 | /* XXX Implement me! XXX */ | 77 | struct pci_pbm_info *pbm = bus_dev->sysdata; |
78 | return 0; | 78 | unsigned long devhandle = pbm->devhandle; |
79 | unsigned int bus = bus_dev->number; | ||
80 | unsigned int device = PCI_SLOT(devfn); | ||
81 | unsigned int func = PCI_FUNC(devfn); | ||
82 | unsigned long ret; | ||
83 | |||
84 | ret = pci_sun4v_config_get(devhandle, | ||
85 | HV_PCI_DEVICE_BUILD(bus, device, func), | ||
86 | where, size); | ||
87 | switch (size) { | ||
88 | case 1: | ||
89 | *value = ret & 0xff; | ||
90 | break; | ||
91 | case 2: | ||
92 | *value = ret & 0xffff; | ||
93 | break; | ||
94 | case 4: | ||
95 | *value = ret & 0xffffffff; | ||
96 | break; | ||
97 | }; | ||
98 | |||
99 | |||
100 | return PCIBIOS_SUCCESSFUL; | ||
79 | } | 101 | } |
80 | 102 | ||
81 | static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | 103 | static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, |
82 | int where, int size, u32 value) | 104 | int where, int size, u32 value) |
83 | { | 105 | { |
84 | /* XXX Implement me! XXX */ | 106 | struct pci_pbm_info *pbm = bus_dev->sysdata; |
85 | return 0; | 107 | unsigned long devhandle = pbm->devhandle; |
108 | unsigned int bus = bus_dev->number; | ||
109 | unsigned int device = PCI_SLOT(devfn); | ||
110 | unsigned int func = PCI_FUNC(devfn); | ||
111 | unsigned long ret; | ||
112 | |||
113 | ret = pci_sun4v_config_put(devhandle, | ||
114 | HV_PCI_DEVICE_BUILD(bus, device, func), | ||
115 | where, size, value); | ||
116 | |||
117 | return PCIBIOS_SUCCESSFUL; | ||
86 | } | 118 | } |
87 | 119 | ||
88 | static struct pci_ops pci_sun4v_ops = { | 120 | static struct pci_ops pci_sun4v_ops = { |
diff --git a/arch/sparc64/kernel/pci_sun4v.h b/arch/sparc64/kernel/pci_sun4v.h index d3ac7ece4b31..5c7ed2ca1505 100644 --- a/arch/sparc64/kernel/pci_sun4v.h +++ b/arch/sparc64/kernel/pci_sun4v.h | |||
@@ -16,5 +16,14 @@ extern unsigned long pci_sun4v_iommu_map(unsigned long devhandle, | |||
16 | extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, | 16 | extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, |
17 | unsigned long tsbid, | 17 | unsigned long tsbid, |
18 | unsigned long num_ttes); | 18 | unsigned long num_ttes); |
19 | extern unsigned long pci_sun4v_config_get(unsigned long devhandle, | ||
20 | unsigned long pci_device, | ||
21 | unsigned long config_offset, | ||
22 | unsigned long size); | ||
23 | extern int pci_sun4v_config_put(unsigned long devhandle, | ||
24 | unsigned long pci_device, | ||
25 | unsigned long config_offset, | ||
26 | unsigned long size, | ||
27 | unsigned long data); | ||
19 | 28 | ||
20 | #endif /* !(_PCI_SUN4V_H) */ | 29 | #endif /* !(_PCI_SUN4V_H) */ |
diff --git a/arch/sparc64/kernel/pci_sun4v_asm.S b/arch/sparc64/kernel/pci_sun4v_asm.S index fd2fe0edf168..2f1147146abe 100644 --- a/arch/sparc64/kernel/pci_sun4v_asm.S +++ b/arch/sparc64/kernel/pci_sun4v_asm.S | |||
@@ -54,3 +54,51 @@ pci_sun4v_iommu_demap: | |||
54 | ta HV_FAST_TRAP | 54 | ta HV_FAST_TRAP |
55 | retl | 55 | retl |
56 | mov %o1, %o0 | 56 | mov %o1, %o0 |
57 | |||
58 | /* %o0: devhandle | ||
59 | * %o1: pci_device | ||
60 | * %o2: pci_config_offset | ||
61 | * %o3: size | ||
62 | * | ||
63 | * returns %o0: data | ||
64 | * | ||
65 | * If there is an error, the data will be returned | ||
66 | * as all 1's. | ||
67 | */ | ||
68 | .globl pci_sun4v_config_get | ||
69 | pci_sun4v_config_get: | ||
70 | mov %o3, %o4 | ||
71 | mov %o2, %o3 | ||
72 | mov %o1, %o2 | ||
73 | mov %o0, %o1 | ||
74 | mov HV_FAST_PCI_CONFIG_GET, %o0 | ||
75 | ta HV_FAST_TRAP | ||
76 | brnz,a,pn %o1, 1f | ||
77 | mov -1, %o2 | ||
78 | 1: retl | ||
79 | mov %o2, %o0 | ||
80 | |||
81 | /* %o0: devhandle | ||
82 | * %o1: pci_device | ||
83 | * %o2: pci_config_offset | ||
84 | * %o3: size | ||
85 | * %o4: data | ||
86 | * | ||
87 | * returns %o0: status | ||
88 | * | ||
89 | * status will be zero if the operation completed | ||
90 | * successfully, else -1 if not | ||
91 | */ | ||
92 | .globl pci_sun4v_config_put | ||
93 | pci_sun4v_config_put: | ||
94 | mov %o3, %o4 | ||
95 | mov %o2, %o3 | ||
96 | mov %o1, %o2 | ||
97 | mov %o0, %o1 | ||
98 | mov HV_FAST_PCI_CONFIG_PUT, %o0 | ||
99 | ta HV_FAST_TRAP | ||
100 | brnz,a,pn %o1, 1f | ||
101 | mov -1, %o1 | ||
102 | 1: retl | ||
103 | mov %o1, %o0 | ||
104 | |||