powerpc/eeh: Platform dependent EEH operations
EEH has been implemented on RTAS-compliant pSeries platform. That's to say, the EEH operations will be implemented through RTAS calls eventually. The situation limited feasible extension on EEH. In order to support EEH on multiple platforms like pseries and powernv simutaneously. We have to split the platform dependent EEH options up out of current implementation. The patch addresses supporting EEH on multiple platforms. The pseries platform dependent EEH operations will be abstracted by struct eeh_ops. EEH core components will be built based on the registered EEH operations. With the mechanism, what the individual platform needs to do is implement platform dependent EEH operations. For now, the pseries platform is covered under the mechanism. That means we have to think about other platforms to support EEH, like powernv. Besides, we only have framework for the mechanism and we have to implement it for pseries platform later. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:

committed by
Benjamin Herrenschmidt

orang tua
cce4b2d243
melakukan
aa1e6374ae
@@ -97,6 +97,9 @@ static int ibm_get_config_addr_info2;
|
||||
static int ibm_configure_bridge;
|
||||
static int ibm_configure_pe;
|
||||
|
||||
/* Platform dependent EEH operations */
|
||||
struct eeh_ops *eeh_ops = NULL;
|
||||
|
||||
int eeh_subsystem_enabled;
|
||||
EXPORT_SYMBOL(eeh_subsystem_enabled);
|
||||
|
||||
@@ -1207,6 +1210,56 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* eeh_ops_register - Register platform dependent EEH operations
|
||||
* @ops: platform dependent EEH operations
|
||||
*
|
||||
* Register the platform dependent EEH operation callback
|
||||
* functions. The platform should call this function before
|
||||
* any other EEH operations.
|
||||
*/
|
||||
int __init eeh_ops_register(struct eeh_ops *ops)
|
||||
{
|
||||
if (!ops->name) {
|
||||
pr_warning("%s: Invalid EEH ops name for %p\n",
|
||||
__func__, ops);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (eeh_ops && eeh_ops != ops) {
|
||||
pr_warning("%s: EEH ops of platform %s already existing (%s)\n",
|
||||
__func__, eeh_ops->name, ops->name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
eeh_ops = ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* eeh_ops_unregister - Unreigster platform dependent EEH operations
|
||||
* @name: name of EEH platform operations
|
||||
*
|
||||
* Unregister the platform dependent EEH operation callback
|
||||
* functions.
|
||||
*/
|
||||
int __exit eeh_ops_unregister(const char *name)
|
||||
{
|
||||
if (!name || !strlen(name)) {
|
||||
pr_warning("%s: Invalid EEH ops name\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (eeh_ops && !strcmp(eeh_ops->name, name)) {
|
||||
eeh_ops = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* eeh_init - EEH initialization
|
||||
*
|
||||
|
Reference in New Issue
Block a user