Commit 371a395d authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/eeh: Make EEH operations based on PE

Originally, all the EEH operations were implemented based on OF node.

Actually, it explicitly breaks the rules that the operation target
is PE instead of device. Therefore, the patch makes all the operations
based on PE instead of device.

Unfortunately, the backend for config space has to be kept as original
because it doesn't depend on PE.
Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 66523d9f
......@@ -136,13 +136,13 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
struct eeh_ops {
char *name;
int (*init)(void);
int (*set_option)(struct device_node *dn, int option);
int (*get_pe_addr)(struct device_node *dn);
int (*get_state)(struct device_node *dn, int *state);
int (*reset)(struct device_node *dn, int option);
int (*wait_state)(struct device_node *dn, int max_wait);
int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len);
int (*configure_bridge)(struct device_node *dn);
int (*set_option)(struct eeh_pe *pe, int option);
int (*get_pe_addr)(struct eeh_pe *pe);
int (*get_state)(struct eeh_pe *pe, int *state);
int (*reset)(struct eeh_pe *pe, int option);
int (*wait_state)(struct eeh_pe *pe, int max_wait);
int (*get_log)(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len);
int (*configure_bridge)(struct eeh_pe *pe);
int (*read_config)(struct device_node *dn, int where, int size, u32 *val);
int (*write_config)(struct device_node *dn, int where, int size, u32 val);
};
......
......@@ -729,6 +729,7 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
const u32 *regs;
int enable;
struct eeh_dev *edev = of_node_to_eeh_dev(dn);
struct eeh_pe pe;
edev->class_code = 0;
edev->mode = 0;
......@@ -755,9 +756,14 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
*/
regs = of_get_property(dn, "reg", NULL);
if (regs) {
/* Initialize the fake PE */
memset(&pe, 0, sizeof(struct eeh_pe));
pe.phb = edev->phb;
pe.config_addr = regs[0];
/* First register entry is addr (00BBSS00) */
/* Try to enable eeh */
ret = eeh_ops->set_option(dn, EEH_OPT_ENABLE);
ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE);
enable = 0;
if (ret == 0) {
......@@ -766,14 +772,15 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
/* If the newer, better, ibm,get-config-addr-info is supported,
* then use that instead.
*/
edev->pe_config_addr = eeh_ops->get_pe_addr(dn);
edev->pe_config_addr = eeh_ops->get_pe_addr(&pe);
pe.addr = edev->pe_config_addr;
/* Some older systems (Power4) allow the
* ibm,set-eeh-option call to succeed even on nodes
* where EEH is not supported. Verify support
* explicitly.
*/
ret = eeh_ops->get_state(dn, NULL);
ret = eeh_ops->get_state(&pe, NULL);
if (ret > 0 && ret != EEH_STATE_NOT_SUPPORT)
enable = 1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment