aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/eeh.h2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c32
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c40
3 files changed, 57 insertions, 17 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index daaad91ed576..d60f99814ffb 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -102,6 +102,8 @@ struct eeh_ops {
102 int (*wait_state)(struct device_node *dn, int max_wait); 102 int (*wait_state)(struct device_node *dn, int max_wait);
103 int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len); 103 int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len);
104 int (*configure_bridge)(struct device_node *dn); 104 int (*configure_bridge)(struct device_node *dn);
105 int (*read_config)(struct device_node *dn, int where, int size, u32 *val);
106 int (*write_config)(struct device_node *dn, int where, int size, u32 val);
105}; 107};
106 108
107extern struct eeh_ops *eeh_ops; 109extern struct eeh_ops *eeh_ops;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 1d08cd76e68d..8011088392d3 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -141,11 +141,11 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
141 n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); 141 n += scnprintf(buf+n, len-n, "%s\n", dn->full_name);
142 printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name); 142 printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name);
143 143
144 rtas_read_config(PCI_DN(dn), PCI_VENDOR_ID, 4, &cfg); 144 eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg);
145 n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg); 145 n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg);
146 printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg); 146 printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg);
147 147
148 rtas_read_config(PCI_DN(dn), PCI_COMMAND, 4, &cfg); 148 eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg);
149 n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); 149 n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
150 printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg); 150 printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
151 151
@@ -156,11 +156,11 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
156 156
157 /* Gather bridge-specific registers */ 157 /* Gather bridge-specific registers */
158 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { 158 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
159 rtas_read_config(PCI_DN(dn), PCI_SEC_STATUS, 2, &cfg); 159 eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg);
160 n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg); 160 n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
161 printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg); 161 printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg);
162 162
163 rtas_read_config(PCI_DN(dn), PCI_BRIDGE_CONTROL, 2, &cfg); 163 eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg);
164 n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg); 164 n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
165 printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg); 165 printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg);
166 } 166 }
@@ -168,11 +168,11 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
168 /* Dump out the PCI-X command and status regs */ 168 /* Dump out the PCI-X command and status regs */
169 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 169 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
170 if (cap) { 170 if (cap) {
171 rtas_read_config(PCI_DN(dn), cap, 4, &cfg); 171 eeh_ops->read_config(dn, cap, 4, &cfg);
172 n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg); 172 n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
173 printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg); 173 printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg);
174 174
175 rtas_read_config(PCI_DN(dn), cap+4, 4, &cfg); 175 eeh_ops->read_config(dn, cap+4, 4, &cfg);
176 n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg); 176 n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg);
177 printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg); 177 printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg);
178 } 178 }
@@ -185,7 +185,7 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
185 "EEH: PCI-E capabilities and status follow:\n"); 185 "EEH: PCI-E capabilities and status follow:\n");
186 186
187 for (i=0; i<=8; i++) { 187 for (i=0; i<=8; i++) {
188 rtas_read_config(PCI_DN(dn), cap+4*i, 4, &cfg); 188 eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
189 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); 189 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
190 printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); 190 printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
191 } 191 }
@@ -197,7 +197,7 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
197 "EEH: PCI-E AER capability register set follows:\n"); 197 "EEH: PCI-E AER capability register set follows:\n");
198 198
199 for (i=0; i<14; i++) { 199 for (i=0; i<14; i++) {
200 rtas_read_config(PCI_DN(dn), cap+4*i, 4, &cfg); 200 eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
201 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); 201 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
202 printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg); 202 printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg);
203 } 203 }
@@ -746,28 +746,28 @@ static inline void eeh_restore_one_device_bars(struct eeh_dev *edev)
746 return; 746 return;
747 747
748 for (i=4; i<10; i++) { 748 for (i=4; i<10; i++) {
749 rtas_write_config(PCI_DN(dn), i*4, 4, edev->config_space[i]); 749 eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
750 } 750 }
751 751
752 /* 12 == Expansion ROM Address */ 752 /* 12 == Expansion ROM Address */
753 rtas_write_config(PCI_DN(dn), 12*4, 4, edev->config_space[12]); 753 eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);
754 754
755#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) 755#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
756#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)]) 756#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
757 757
758 rtas_write_config(PCI_DN(dn), PCI_CACHE_LINE_SIZE, 1, 758 eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
759 SAVED_BYTE(PCI_CACHE_LINE_SIZE)); 759 SAVED_BYTE(PCI_CACHE_LINE_SIZE));
760 760
761 rtas_write_config(PCI_DN(dn), PCI_LATENCY_TIMER, 1, 761 eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
762 SAVED_BYTE(PCI_LATENCY_TIMER)); 762 SAVED_BYTE(PCI_LATENCY_TIMER));
763 763
764 /* max latency, min grant, interrupt pin and line */ 764 /* max latency, min grant, interrupt pin and line */
765 rtas_write_config(PCI_DN(dn), 15*4, 4, edev->config_space[15]); 765 eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
766 766
767 /* Restore PERR & SERR bits, some devices require it, 767 /* Restore PERR & SERR bits, some devices require it,
768 * don't touch the other command bits 768 * don't touch the other command bits
769 */ 769 */
770 rtas_read_config(PCI_DN(dn), PCI_COMMAND, 4, &cmd); 770 eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
771 if (edev->config_space[1] & PCI_COMMAND_PARITY) 771 if (edev->config_space[1] & PCI_COMMAND_PARITY)
772 cmd |= PCI_COMMAND_PARITY; 772 cmd |= PCI_COMMAND_PARITY;
773 else 773 else
@@ -776,7 +776,7 @@ static inline void eeh_restore_one_device_bars(struct eeh_dev *edev)
776 cmd |= PCI_COMMAND_SERR; 776 cmd |= PCI_COMMAND_SERR;
777 else 777 else
778 cmd &= ~PCI_COMMAND_SERR; 778 cmd &= ~PCI_COMMAND_SERR;
779 rtas_write_config(PCI_DN(dn), PCI_COMMAND, 4, cmd); 779 eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);
780} 780}
781 781
782/** 782/**
@@ -818,7 +818,7 @@ static void eeh_save_bars(struct eeh_dev *edev)
818 dn = eeh_dev_to_of_node(edev); 818 dn = eeh_dev_to_of_node(edev);
819 819
820 for (i = 0; i < 16; i++) 820 for (i = 0; i < 16; i++)
821 rtas_read_config(PCI_DN(dn), i * 4, 4, &edev->config_space[i]); 821 eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
822} 822}
823 823
824/** 824/**
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 36a1af1d1140..8752f79a6af8 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -503,6 +503,42 @@ static int pseries_eeh_configure_bridge(struct device_node *dn)
503 return ret; 503 return ret;
504} 504}
505 505
506/**
507 * pseries_eeh_read_config - Read PCI config space
508 * @dn: device node
509 * @where: PCI address
510 * @size: size to read
511 * @val: return value
512 *
513 * Read config space from the speicifed device
514 */
515static int pseries_eeh_read_config(struct device_node *dn, int where, int size, u32 *val)
516{
517 struct pci_dn *pdn;
518
519 pdn = PCI_DN(dn);
520
521 return rtas_read_config(pdn, where, size, val);
522}
523
524/**
525 * pseries_eeh_write_config - Write PCI config space
526 * @dn: device node
527 * @where: PCI address
528 * @size: size to write
529 * @val: value to be written
530 *
531 * Write config space to the specified device
532 */
533static int pseries_eeh_write_config(struct device_node *dn, int where, int size, u32 val)
534{
535 struct pci_dn *pdn;
536
537 pdn = PCI_DN(dn);
538
539 return rtas_write_config(pdn, where, size, val);
540}
541
506static struct eeh_ops pseries_eeh_ops = { 542static struct eeh_ops pseries_eeh_ops = {
507 .name = "pseries", 543 .name = "pseries",
508 .init = pseries_eeh_init, 544 .init = pseries_eeh_init,
@@ -512,7 +548,9 @@ static struct eeh_ops pseries_eeh_ops = {
512 .reset = pseries_eeh_reset, 548 .reset = pseries_eeh_reset,
513 .wait_state = pseries_eeh_wait_state, 549 .wait_state = pseries_eeh_wait_state,
514 .get_log = pseries_eeh_get_log, 550 .get_log = pseries_eeh_get_log,
515 .configure_bridge = pseries_eeh_configure_bridge 551 .configure_bridge = pseries_eeh_configure_bridge,
552 .read_config = pseries_eeh_read_config,
553 .write_config = pseries_eeh_write_config
516}; 554};
517 555
518/** 556/**