forked from Minki/linux
powerpc/pseries: Add support for hotplug interrupt source
Add handler for new hotplug interrupt. For memory and CPU hotplug events, we will add the hotplug errorlog to the hotplug workqueue. Since PCI hotplug is not currently supported in the kernel, PCI hotplug events are written to the rtas_log_bug and are handled by rtas_errd. Signed-off-by: John Allen <jallen@linux.vnet.ibm.com> Reviewed-by: Nathan Fontenot <nfont@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
9054619ef5
commit
b7d9eb397b
@ -56,6 +56,8 @@ extern int dlpar_detach_node(struct device_node *);
|
||||
extern int dlpar_acquire_drc(u32 drc_index);
|
||||
extern int dlpar_release_drc(u32 drc_index);
|
||||
|
||||
void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
|
||||
struct completion *hotplug_done, int *rc);
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
|
||||
#else
|
||||
|
@ -43,6 +43,7 @@ static int ras_check_exception_token;
|
||||
/* EPOW events counter variable */
|
||||
static int num_epow_events;
|
||||
|
||||
static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id);
|
||||
static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
|
||||
static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
|
||||
|
||||
@ -65,6 +66,14 @@ static int __init init_ras_IRQ(void)
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
/* Hotplug Events */
|
||||
np = of_find_node_by_path("/event-sources/hot-plug-events");
|
||||
if (np != NULL) {
|
||||
request_event_sources_irqs(np, ras_hotplug_interrupt,
|
||||
"RAS_HOTPLUG");
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
/* EPOW Events */
|
||||
np = of_find_node_by_path("/event-sources/epow-events");
|
||||
if (np != NULL) {
|
||||
@ -190,6 +199,36 @@ static void rtas_parse_epow_errlog(struct rtas_error_log *log)
|
||||
num_epow_events++;
|
||||
}
|
||||
|
||||
static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct pseries_errorlog *pseries_log;
|
||||
struct pseries_hp_errorlog *hp_elog;
|
||||
|
||||
spin_lock(&ras_log_buf_lock);
|
||||
|
||||
rtas_call(ras_check_exception_token, 6, 1, NULL,
|
||||
RTAS_VECTOR_EXTERNAL_INTERRUPT, virq_to_hw(irq),
|
||||
RTAS_HOTPLUG_EVENTS, 0, __pa(&ras_log_buf),
|
||||
rtas_get_error_log_max());
|
||||
|
||||
pseries_log = get_pseries_errorlog((struct rtas_error_log *)ras_log_buf,
|
||||
PSERIES_ELOG_SECT_ID_HOTPLUG);
|
||||
hp_elog = (struct pseries_hp_errorlog *)pseries_log->data;
|
||||
|
||||
/*
|
||||
* Since PCI hotplug is not currently supported on pseries, put PCI
|
||||
* hotplug events on the ras_log_buf to be handled by rtas_errd.
|
||||
*/
|
||||
if (hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_MEM ||
|
||||
hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_CPU)
|
||||
queue_hotplug_event(hp_elog, NULL, NULL);
|
||||
else
|
||||
log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
|
||||
|
||||
spin_unlock(&ras_log_buf_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Handle environmental and power warning (EPOW) interrupts. */
|
||||
static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user