Graceful shutdown of Linux system to prevent hard disk ext2 file system corruption.
"/usr/local/bin/msp_int_handler" will call "init 0" to do graceful shutdown.
311 /************************************************************************
312
313 Previous
314 Implementation : Previously MSP was not generating the interrupt, and switching off
315 the power modules when Power button is switched off.
316
317 Description : Handling of the interrupt from MSP. When the power button is
318 off, then MSP generates an interrupt to MPC for gracefully shutdown.
319 The interrupt handler calls an userspace program called 'msp_int_handler'.
320
321
322
323 ************************************************************************/
324
325 static irqreturn_t msp_interrupt_handler(int gpio_irq,void *ignored);
326
327 static irqreturn_t msp_interrupt_handler(int gpio_irq,void *ignored) {
328
329 wake_up_interruptible(&msp_event);
330 msp_flag = 1;
331
332 return 1;
333 }
334
335 static int msp_interrupt_thread(void *ptr) {
336
337 char *argv[] = {"/usr/local/bin/gpio_test", "2", NULL };
338 char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/local/bin:", NULL };
339 int ret;
340
341 wait_event_interruptible(msp_event, msp_flag == 1);
342
343 printk("<msp-interrupt> got interrupt from MSP\n");
344
345 ret = call_usermodehelper("/usr/local/bin/msp_int_handler", argv, envp, UMH_WAIT_EXEC);
346
347 if (ret) {
348 printk("<msp-interrupt> call_usermodehelper is not successful \n");
349 } else {
350 printk("<msp-interrupt> call_usermodehelper is successful \n");
351 }
352
353 return 0;
354 }
355
356 static int msp_interrupt_thread_init(void)
357 {
358 int ret=0;
359 int virq;
360 #define SICRL_OFFSET 0x0114 /* SICR offset in IMMRBAR space */
361 __be32 __iomem *psicr = ioremap(get_immrbase() + SICRL_OFFSET, 4);
362 u32 sicr;
363 #define IRQ5_INTERRUPT_NUMBER 21
364
365 sicr = in_be32(psicr);
366
367 printk(" Before SICRL Register value : 0x%x \n",sicr);
368
369 sicr &= 0xFE7FFFFF; //clearing the bits 7 & 8 for IRQ5
370
371 out_be32(psicr, sicr);
372
373 sicr = in_be32(psicr);
374
375 printk(" After SICRL Register value : 0x%x \n",sicr);
376
377 // interrupt line from MSP to MPC for the power failure or power button press
378 virq = vinetic_map_irq(IRQ5_INTERRUPT_NUMBER);
379
380 if (request_irq(virq, &msp_interrupt_handler, 0, "MSP_IRQ", (void *)0))
381 printk(KERN_ERR "pmu: can't get irq %d" " (MSP to MPC)\n", virq);
382 else
383 printk("request_irq for IRQ5 is success with virtual IRQ %d",virq);
384
385 /* Wait Q initialization */
386
387 init_waitqueue_head(&msp_event);
388 printk(" msp interrupt thread init \n\n");
389 msp_interrupt_task = kthread_run(msp_interrupt_thread, NULL, "msp_interrupt_thread");
390
391 return ret;
392 }
393
394
395
396 static void __exit msp_interrupt_exit(void)
397 {
398 printk(" fact default module exit \n ");
399 }
400
401 module_init(msp_interrupt_thread_init);
402 module_exit(msp_interrupt_exit);