diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 2bf1f9b5b34b..3650732639ed 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -282,6 +283,7 @@ static void prrn_work_fn(struct work_struct *work) * the RTAS event. */ pseries_devicetree_update(-prrn_update_scope); + arch_update_cpu_topology(); } static DECLARE_WORK(prrn_work, prrn_work_fn); @@ -434,7 +436,10 @@ static void do_event_scan(void) } if (error == 0) { - pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); + if (rtas_error_type((struct rtas_error_log *)logdata) != + RTAS_TYPE_PRRN) + pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, + 0); handle_rtas_event((struct rtas_error_log *)logdata); } diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index a560a98bcf3b..5a0c7ba429ce 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -39,6 +39,7 @@ struct update_props_workarea { #define ADD_DT_NODE 0x03000000 #define MIGRATION_SCOPE (1) +#define PRRN_SCOPE -2 static int mobility_rtas_call(int token, char *buf, s32 scope) { @@ -236,6 +237,35 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) return rc; } +static void prrn_update_node(__be32 phandle) +{ + struct pseries_hp_errorlog *hp_elog; + struct device_node *dn; + + /* + * If a node is found from a the given phandle, the phandle does not + * represent the drc index of an LMB and we can ignore. + */ + dn = of_find_node_by_phandle(be32_to_cpu(phandle)); + if (dn) { + of_node_put(dn); + return; + } + + hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL); + if(!hp_elog) + return; + + hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM; + hp_elog->action = PSERIES_HP_ELOG_ACTION_READD; + hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX; + hp_elog->_drc_u.drc_index = phandle; + + queue_hotplug_event(hp_elog, NULL, NULL); + + kfree(hp_elog); +} + int pseries_devicetree_update(s32 scope) { char *rtas_buf; @@ -274,6 +304,10 @@ int pseries_devicetree_update(s32 scope) break; case UPDATE_DT_NODE: update_dt_node(phandle, scope); + + if (scope == PRRN_SCOPE) + prrn_update_node(phandle); + break; case ADD_DT_NODE: drc_index = *data++;