aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/rtasd.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/rtasd.c')
-rw-r--r--arch/powerpc/kernel/rtasd.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 1045ff49cc6d..1130c53ad652 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -29,6 +29,7 @@
29#include <asm/nvram.h> 29#include <asm/nvram.h>
30#include <linux/atomic.h> 30#include <linux/atomic.h>
31#include <asm/machdep.h> 31#include <asm/machdep.h>
32#include <asm/topology.h>
32 33
33 34
34static DEFINE_SPINLOCK(rtasd_log_lock); 35static DEFINE_SPINLOCK(rtasd_log_lock);
@@ -87,6 +88,8 @@ static char *rtas_event_type(int type)
87 return "Resource Deallocation Event"; 88 return "Resource Deallocation Event";
88 case RTAS_TYPE_DUMP: 89 case RTAS_TYPE_DUMP:
89 return "Dump Notification Event"; 90 return "Dump Notification Event";
91 case RTAS_TYPE_PRRN:
92 return "Platform Resource Reassignment Event";
90 } 93 }
91 94
92 return rtas_type[0]; 95 return rtas_type[0];
@@ -265,9 +268,51 @@ void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
265 spin_unlock_irqrestore(&rtasd_log_lock, s); 268 spin_unlock_irqrestore(&rtasd_log_lock, s);
266 return; 269 return;
267 } 270 }
271}
272
273#ifdef CONFIG_PPC_PSERIES
274static s32 prrn_update_scope;
268 275
276static void prrn_work_fn(struct work_struct *work)
277{
278 /*
279 * For PRRN, we must pass the negative of the scope value in
280 * the RTAS event.
281 */
282 pseries_devicetree_update(-prrn_update_scope);
269} 283}
270 284
285static DECLARE_WORK(prrn_work, prrn_work_fn);
286
287void prrn_schedule_update(u32 scope)
288{
289 flush_work(&prrn_work);
290 prrn_update_scope = scope;
291 schedule_work(&prrn_work);
292}
293
294static void handle_rtas_event(const struct rtas_error_log *log)
295{
296 if (log->type == RTAS_TYPE_PRRN) {
297 /* For PRRN Events the extended log length is used to denote
298 * the scope for calling rtas update-nodes.
299 */
300 if (prrn_is_enabled())
301 prrn_schedule_update(log->extended_log_length);
302 }
303
304 return;
305}
306
307#else
308
309static void handle_rtas_event(const struct rtas_error_log *log)
310{
311 return;
312}
313
314#endif
315
271static int rtas_log_open(struct inode * inode, struct file * file) 316static int rtas_log_open(struct inode * inode, struct file * file)
272{ 317{
273 return 0; 318 return 0;
@@ -388,8 +433,10 @@ static void do_event_scan(void)
388 break; 433 break;
389 } 434 }
390 435
391 if (error == 0) 436 if (error == 0) {
392 pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); 437 pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
438 handle_rtas_event((struct rtas_error_log *)logdata);
439 }
393 440
394 } while(error == 0); 441 } while(error == 0);
395} 442}