aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/rtas_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/rtas_pci.c')
-rw-r--r--arch/ppc64/kernel/rtas_pci.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
index 1048817befb8..4a9719b48abe 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -48,7 +48,7 @@ static int write_pci_config;
48static int ibm_read_pci_config; 48static int ibm_read_pci_config;
49static int ibm_write_pci_config; 49static int ibm_write_pci_config;
50 50
51static int config_access_valid(struct device_node *dn, int where) 51static int config_access_valid(struct pci_dn *dn, int where)
52{ 52{
53 if (where < 256) 53 if (where < 256)
54 return 1; 54 return 1;
@@ -58,20 +58,37 @@ static int config_access_valid(struct device_node *dn, int where)
58 return 0; 58 return 0;
59} 59}
60 60
61static int of_device_available(struct device_node * dn)
62{
63 char * status;
64
65 status = get_property(dn, "status", NULL);
66
67 if (!status)
68 return 1;
69
70 if (!strcmp(status, "okay"))
71 return 1;
72
73 return 0;
74}
75
61static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) 76static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
62{ 77{
63 int returnval = -1; 78 int returnval = -1;
64 unsigned long buid, addr; 79 unsigned long buid, addr;
65 int ret; 80 int ret;
81 struct pci_dn *pdn;
66 82
67 if (!dn) 83 if (!dn || !dn->data)
68 return PCIBIOS_DEVICE_NOT_FOUND; 84 return PCIBIOS_DEVICE_NOT_FOUND;
69 if (!config_access_valid(dn, where)) 85 pdn = dn->data;
86 if (!config_access_valid(pdn, where))
70 return PCIBIOS_BAD_REGISTER_NUMBER; 87 return PCIBIOS_BAD_REGISTER_NUMBER;
71 88
72 addr = ((where & 0xf00) << 20) | (dn->busno << 16) | 89 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
73 (dn->devfn << 8) | (where & 0xff); 90 (pdn->devfn << 8) | (where & 0xff);
74 buid = dn->phb->buid; 91 buid = pdn->phb->buid;
75 if (buid) { 92 if (buid) {
76 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, 93 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
77 addr, buid >> 32, buid & 0xffffffff, size); 94 addr, buid >> 32, buid & 0xffffffff, size);
@@ -83,8 +100,8 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
83 if (ret) 100 if (ret)
84 return PCIBIOS_DEVICE_NOT_FOUND; 101 return PCIBIOS_DEVICE_NOT_FOUND;
85 102
86 if (returnval == EEH_IO_ERROR_VALUE(size) 103 if (returnval == EEH_IO_ERROR_VALUE(size) &&
87 && eeh_dn_check_failure (dn, NULL)) 104 eeh_dn_check_failure (dn, NULL))
88 return PCIBIOS_DEVICE_NOT_FOUND; 105 return PCIBIOS_DEVICE_NOT_FOUND;
89 106
90 return PCIBIOS_SUCCESSFUL; 107 return PCIBIOS_SUCCESSFUL;
@@ -103,24 +120,28 @@ static int rtas_pci_read_config(struct pci_bus *bus,
103 120
104 /* Search only direct children of the bus */ 121 /* Search only direct children of the bus */
105 for (dn = busdn->child; dn; dn = dn->sibling) 122 for (dn = busdn->child; dn; dn = dn->sibling)
106 if (dn->devfn == devfn) 123 if (dn->data && PCI_DN(dn)->devfn == devfn
124 && of_device_available(dn))
107 return rtas_read_config(dn, where, size, val); 125 return rtas_read_config(dn, where, size, val);
126
108 return PCIBIOS_DEVICE_NOT_FOUND; 127 return PCIBIOS_DEVICE_NOT_FOUND;
109} 128}
110 129
111static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) 130int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
112{ 131{
113 unsigned long buid, addr; 132 unsigned long buid, addr;
114 int ret; 133 int ret;
134 struct pci_dn *pdn;
115 135
116 if (!dn) 136 if (!dn || !dn->data)
117 return PCIBIOS_DEVICE_NOT_FOUND; 137 return PCIBIOS_DEVICE_NOT_FOUND;
118 if (!config_access_valid(dn, where)) 138 pdn = dn->data;
139 if (!config_access_valid(pdn, where))
119 return PCIBIOS_BAD_REGISTER_NUMBER; 140 return PCIBIOS_BAD_REGISTER_NUMBER;
120 141
121 addr = ((where & 0xf00) << 20) | (dn->busno << 16) | 142 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
122 (dn->devfn << 8) | (where & 0xff); 143 (pdn->devfn << 8) | (where & 0xff);
123 buid = dn->phb->buid; 144 buid = pdn->phb->buid;
124 if (buid) { 145 if (buid) {
125 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); 146 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
126 } else { 147 } else {
@@ -146,7 +167,8 @@ static int rtas_pci_write_config(struct pci_bus *bus,
146 167
147 /* Search only direct children of the bus */ 168 /* Search only direct children of the bus */
148 for (dn = busdn->child; dn; dn = dn->sibling) 169 for (dn = busdn->child; dn; dn = dn->sibling)
149 if (dn->devfn == devfn) 170 if (dn->data && PCI_DN(dn)->devfn == devfn
171 && of_device_available(dn))
150 return rtas_write_config(dn, where, size, val); 172 return rtas_write_config(dn, where, size, val);
151 return PCIBIOS_DEVICE_NOT_FOUND; 173 return PCIBIOS_DEVICE_NOT_FOUND;
152} 174}