===================================================================
@@ -143,6 +143,8 @@
#define RTAS_TYPE_PMGM_TIME_ALARM 0x6f
#define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70
#define RTAS_TYPE_PMGM_SERVICE_PROC 0x71
+/* Platform Resource Reassignment Notification */
+#define RTAS_TYPE_PRRN 0xA0
/* RTAS check-exception vector offset */
#define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500
===================================================================
@@ -87,6 +87,8 @@
return "Resource Deallocation Event";
case RTAS_TYPE_DUMP:
return "Dump Notification Event";
+ case RTAS_TYPE_PRRN:
+ return "Platform Resource Reassignment Event";
}
return rtas_type[0];
@@ -265,7 +267,40 @@
spin_unlock_irqrestore(&rtasd_log_lock, s);
return;
}
+}
+
+static s32 update_scope;
+
+static void prrn_work_fn(struct work_struct *work)
+{
+ /*
+ * For PRRN, we must pass the negative of the scope value in
+ * the RTAS event.
+ */
+ if (ppc_md.update_devicetree)
+ ppc_md.update_devicetree(-update_scope);
+}
+
+static DECLARE_WORK(prrn_work, prrn_work_fn);
+
+void prrn_schedule_update(u32 scope)
+{
+ flush_work(&prrn_work);
+ update_scope = scope;
+ schedule_work(&prrn_work);
+}
+
+static void pseries_handle_event(const struct rtas_error_log *log)
+{
+ pSeries_log_error((char *)log, ERR_TYPE_RTAS_LOG, 0);
+
+ if (log->type == RTAS_TYPE_PRRN)
+ /* For PRRN Events the extended log length is used to denote
+ * the scope for calling rtas update-nodes.
+ */
+ prrn_schedule_update(log->extended_log_length);
+ return;
}
static int rtas_log_open(struct inode * inode, struct file * file)
@@ -389,7 +424,7 @@
}
if (error == 0)
- pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
+ pseries_handle_event((struct rtas_error_log *)logdata);
} while(error == 0);
}