diff --git a/drivers/seco/ectrl_msp430.c b/drivers/seco/ectrl_msp430.c index d7c468d77c170006651848f4bd5c4b07a5c143c6..cf98ef65916e57c7f28fc751b4e11e10587dd634 100644 --- a/drivers/seco/ectrl_msp430.c +++ b/drivers/seco/ectrl_msp430.c @@ -12,6 +12,7 @@ #include <linux/uaccess.h> #include <linux/workqueue.h> #include <linux/reboot.h> +#include <linux/of_gpio.h> #include <linux/ectrl_msp430.h> @@ -387,6 +388,7 @@ struct econtroller { unsigned long orig_jiffies; //used only for the power button snooping struct mutex fs_lock; struct mutex ioctl_lock; + int rb_poff_gpio; }; @@ -1275,9 +1277,9 @@ static int ectrl_SystemHalt (struct i2c_client *client) { int retval; retval = ectrl_mem_op (client, reg_halt, NULL); if (!(retval < 0)) { - printk (KERN_INFO "Seco halt performed!\n"); + printk (KERN_INFO "Seco halt prepared!\n"); } else { - printk (KERN_ERR "Seco halt not performed!\n"); + printk (KERN_ERR "Seco halt not prepared!\n"); } return retval; } @@ -1287,9 +1289,9 @@ static int ectrl_SystemReboot (struct i2c_client *client) { int retval; retval = ectrl_mem_op (client, reg_reboot, NULL); if (!(retval < 0)) { - printk (KERN_INFO "Seco reboot performed!\n"); + printk (KERN_INFO "Seco reboot prepared!\n"); } else { - printk (KERN_ERR "Seco reboot not performed!\n"); + printk (KERN_ERR "Seco reboot not prepared!\n"); } return retval; } @@ -4489,9 +4491,35 @@ static int ectrl_notify_sys (struct notifier_block *this, unsigned long code, vo return NOTIFY_DONE; } +static int ectrl_restart_handler (struct notifier_block *this, unsigned long unused_type, void *unused) { + int retval; + if(gpio_is_valid(ectrl->rb_poff_gpio)) { + printk (KERN_INFO "Seco reboot performed!\n"); + retval = gpio_request_one (ectrl->rb_poff_gpio, GPIOF_OUT_INIT_LOW, "seco reboot gpio"); + msleep(500); + } else + printk (KERN_ERR "Seco reboot not performed!\n"); + return NOTIFY_DONE; +} + +static void ectrl_pm_poweroff(void){ + int retval; + if(gpio_is_valid(ectrl->rb_poff_gpio)) { + printk (KERN_INFO "Seco halt performed!\n"); + retval = gpio_request_one (ectrl->rb_poff_gpio, GPIOF_OUT_INIT_LOW, "seco halt gpio"); + msleep(500); + } else + printk (KERN_ERR "Seco halt not performed!\n"); +} + +static struct notifier_block ectrl_handler = { + .notifier_call = ectrl_restart_handler, + .priority = 255, +}; static struct notifier_block ectrl_notifier = { .notifier_call = ectrl_notify_sys, + .priority = 128, }; @@ -4681,6 +4709,10 @@ static int ectrl_parse_dt (struct econtroller *ectrl, int board_id) { } } + + ectrl->rb_poff_gpio = of_get_named_gpio(np, "rb-poff-gpio", 0); + if (!gpio_is_valid(ectrl->rb_poff_gpio)) + ECTRL_ERR("reboot poweroff pin unavailable"); ectrl->irq = irq_of_parse_and_map (np, 0); @@ -4921,6 +4953,17 @@ static int ectrl_probe(struct i2c_client *client, const struct i2c_device_id *id goto err_notifier_register; } + ret = register_restart_handler(&ectrl_handler); + if ( ret != 0 ) { + pr_err("cannot register restart handler (err=%d)\n", ret); + goto err_notifier_register; + } + + if (!pm_power_off) + pm_power_off = ectrl_pm_poweroff; + else + ECTRL_INFO("pm_power_off function already registered\n"); + ECTRL_INFO (" probe done"); dev_set_drvdata (&client->dev, ectrl); @@ -4963,6 +5006,7 @@ static int ectrl_remove(struct i2c_client *client) { ectrl_free_irq (ectrl); ectrl_remove_proc_fs (ectrl); unregister_reboot_notifier (&ectrl_notifier); + unregister_restart_handler (&ectrl_handler); kfree (entry_list); for ( i = 0 ; i < ectrl->nr_evnt ; i++ )