diff options
Diffstat (limited to 'drivers/power/reset')
-rw-r--r-- | drivers/power/reset/as3722-poweroff.c | 30 | ||||
-rw-r--r-- | drivers/power/reset/atc260x-poweroff.c | 55 | ||||
-rw-r--r-- | drivers/power/reset/axxia-reset.c | 16 | ||||
-rw-r--r-- | drivers/power/reset/brcm-kona-reset.c | 11 | ||||
-rw-r--r-- | drivers/power/reset/gemini-poweroff.c | 16 | ||||
-rw-r--r-- | drivers/power/reset/msm-poweroff.c | 21 | ||||
-rw-r--r-- | drivers/power/reset/mt6323-poweroff.c | 26 | ||||
-rw-r--r-- | drivers/power/reset/regulator-poweroff.c | 36 | ||||
-rw-r--r-- | drivers/power/reset/restart-poweroff.c | 25 | ||||
-rw-r--r-- | drivers/power/reset/rmobile-reset.c | 38 | ||||
-rw-r--r-- | drivers/power/reset/syscon-poweroff.c | 66 | ||||
-rw-r--r-- | drivers/power/reset/tps65086-restart.c | 58 | ||||
-rw-r--r-- | drivers/power/reset/xgene-reboot.c | 25 |
13 files changed, 154 insertions, 269 deletions
diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c index ab3350ce2d..bb26fa6fa6 100644 --- a/drivers/power/reset/as3722-poweroff.c +++ b/drivers/power/reset/as3722-poweroff.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/slab.h> struct as3722_poweroff { @@ -18,22 +19,18 @@ struct as3722_poweroff { struct as3722 *as3722; }; -static struct as3722_poweroff *as3722_pm_poweroff; - -static void as3722_pm_power_off(void) +static int as3722_pm_power_off(struct sys_off_data *data) { + struct as3722_poweroff *as3722_pm_poweroff = data->cb_data; int ret; - if (!as3722_pm_poweroff) { - pr_err("AS3722 poweroff is not initialised\n"); - return; - } - ret = as3722_update_bits(as3722_pm_poweroff->as3722, AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF); if (ret < 0) dev_err(as3722_pm_poweroff->dev, "RESET_CONTROL_REG update failed, %d\n", ret); + + return NOTIFY_DONE; } static int as3722_poweroff_probe(struct platform_device *pdev) @@ -54,18 +51,14 @@ static int as3722_poweroff_probe(struct platform_device *pdev) as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent); as3722_poweroff->dev = &pdev->dev; - as3722_pm_poweroff = as3722_poweroff; - if (!pm_power_off) - pm_power_off = as3722_pm_power_off; - return 0; -} + return devm_register_sys_off_handler(as3722_poweroff->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + as3722_pm_power_off, + as3722_poweroff); -static void as3722_poweroff_remove(struct platform_device *pdev) -{ - if (pm_power_off == as3722_pm_power_off) - pm_power_off = NULL; - as3722_pm_poweroff = NULL; + return 0; } static struct platform_driver as3722_poweroff_driver = { @@ -73,7 +66,6 @@ static struct platform_driver as3722_poweroff_driver = { .name = "as3722-power-off", }, .probe = as3722_poweroff_probe, - .remove_new = as3722_poweroff_remove, }; module_platform_driver(as3722_poweroff_driver); diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c index b4aa50e968..e3e4621ccb 100644 --- a/drivers/power/reset/atc260x-poweroff.c +++ b/drivers/power/reset/atc260x-poweroff.c @@ -16,13 +16,9 @@ struct atc260x_pwrc { struct device *dev; struct regmap *regmap; - struct notifier_block restart_nb; int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart); }; -/* Global variable needed only for pm_power_off */ -static struct atc260x_pwrc *atc260x_pwrc_data; - static int atc2603c_do_poweroff(const struct atc260x_pwrc *pwrc, bool restart) { int ret, deep_sleep = 0; @@ -165,18 +161,20 @@ static int atc2609a_init(const struct atc260x_pwrc *pwrc) return ret; } -static void atc260x_pwrc_pm_handler(void) +static int atc260x_pwrc_pm_handler(struct sys_off_data *data) { - atc260x_pwrc_data->do_poweroff(atc260x_pwrc_data, false); + struct atc260x_pwrc *pwrc = data->cb_data; + + pwrc->do_poweroff(pwrc, false); WARN_ONCE(1, "Unable to power off system\n"); + + return NOTIFY_DONE; } -static int atc260x_pwrc_restart_handler(struct notifier_block *nb, - unsigned long mode, void *cmd) +static int atc260x_pwrc_restart_handler(struct sys_off_data *data) { - struct atc260x_pwrc *pwrc = container_of(nb, struct atc260x_pwrc, - restart_nb); + struct atc260x_pwrc *pwrc = data->cb_data; pwrc->do_poweroff(pwrc, true); return NOTIFY_DONE; @@ -194,8 +192,6 @@ static int atc260x_pwrc_probe(struct platform_device *pdev) priv->dev = &pdev->dev; priv->regmap = atc260x->regmap; - priv->restart_nb.notifier_call = atc260x_pwrc_restart_handler; - priv->restart_nb.priority = 192; switch (atc260x->ic_type) { case ATC2603C: @@ -216,16 +212,20 @@ static int atc260x_pwrc_probe(struct platform_device *pdev) if (ret) return ret; - platform_set_drvdata(pdev, priv); - - if (!pm_power_off) { - atc260x_pwrc_data = priv; - pm_power_off = atc260x_pwrc_pm_handler; - } else { - dev_warn(priv->dev, "Poweroff callback already assigned\n"); - } + ret = devm_register_sys_off_handler(priv->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + atc260x_pwrc_pm_handler, + priv); + if (ret) + dev_err(priv->dev, "failed to register power-off handler: %d\n", + ret); - ret = register_restart_handler(&priv->restart_nb); + ret = devm_register_sys_off_handler(priv->dev, + SYS_OFF_MODE_RESTART, + SYS_OFF_PRIO_HIGH, + atc260x_pwrc_restart_handler, + priv); if (ret) dev_err(priv->dev, "failed to register restart handler: %d\n", ret); @@ -233,21 +233,8 @@ static int atc260x_pwrc_probe(struct platform_device *pdev) return ret; } -static void atc260x_pwrc_remove(struct platform_device *pdev) -{ - struct atc260x_pwrc *priv = platform_get_drvdata(pdev); - - if (atc260x_pwrc_data == priv) { - pm_power_off = NULL; - atc260x_pwrc_data = NULL; - } - - unregister_restart_handler(&priv->restart_nb); -} - static struct platform_driver atc260x_pwrc_driver = { .probe = atc260x_pwrc_probe, - .remove_new = atc260x_pwrc_remove, .driver = { .name = "atc260x-pwrc", }, diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c index 2494676676..797bf67738 100644 --- a/drivers/power/reset/axxia-reset.c +++ b/drivers/power/reset/axxia-reset.c @@ -26,11 +26,10 @@ #define SC_EFUSE_INT_STATUS 0x180c #define EFUSE_READ_DONE (1<<31) -static struct regmap *syscon; - -static int axxia_restart_handler(struct notifier_block *this, - unsigned long mode, void *cmd) +static int axxia_restart_handler(struct sys_off_data *data) { + struct regmap *syscon = data->cb_data; + /* Access Key (0xab) */ regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab); /* Select internal boot from 0xffff0000 */ @@ -44,14 +43,10 @@ static int axxia_restart_handler(struct notifier_block *this, return NOTIFY_DONE; } -static struct notifier_block axxia_restart_nb = { - .notifier_call = axxia_restart_handler, - .priority = 128, -}; - static int axxia_reset_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct regmap *syscon; int err; syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); @@ -60,7 +55,8 @@ static int axxia_reset_probe(struct platform_device *pdev) return PTR_ERR(syscon); } - err = register_restart_handler(&axxia_restart_nb); + err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, + 128, axxia_restart_handler, syscon); if (err) dev_err(dev, "cannot register restart handler (err=%d)\n", err); diff --git a/drivers/power/reset/brcm-kona-reset.c b/drivers/power/reset/brcm-kona-reset.c index d05728b1db..ee3f1bb976 100644 --- a/drivers/power/reset/brcm-kona-reset.c +++ b/drivers/power/reset/brcm-kona-reset.c @@ -15,8 +15,7 @@ static void __iomem *kona_reset_base; -static int kona_reset_handler(struct notifier_block *this, - unsigned long mode, void *cmd) +static int kona_reset_handler(struct sys_off_data *data) { /* * A soft reset is triggered by writing a 0 to bit 0 of the soft reset @@ -31,18 +30,14 @@ static int kona_reset_handler(struct notifier_block *this, return NOTIFY_DONE; } -static struct notifier_block kona_reset_nb = { - .notifier_call = kona_reset_handler, - .priority = 128, -}; - static int kona_reset_probe(struct platform_device *pdev) { kona_reset_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(kona_reset_base)) return PTR_ERR(kona_reset_base); - return register_restart_handler(&kona_reset_nb); + return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, + 128, kona_reset_handler, NULL); } static const struct of_device_id of_match[] = { diff --git a/drivers/power/reset/gemini-poweroff.c b/drivers/power/reset/gemini-poweroff.c index d309b61014..06d6992dec 100644 --- a/drivers/power/reset/gemini-poweroff.c +++ b/drivers/power/reset/gemini-poweroff.c @@ -70,12 +70,9 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data) return IRQ_HANDLED; } -/* This callback needs this static local as it has void as argument */ -static struct gemini_powercon *gpw_poweroff; - -static void gemini_poweroff(void) +static int gemini_poweroff(struct sys_off_data *data) { - struct gemini_powercon *gpw = gpw_poweroff; + struct gemini_powercon *gpw = data->cb_data; u32 val; dev_crit(gpw->dev, "Gemini power off\n"); @@ -86,6 +83,8 @@ static void gemini_poweroff(void) val &= ~GEMINI_CTRL_ENABLE; val |= GEMINI_CTRL_SHUTDOWN; writel(val, gpw->base + GEMINI_PWC_CTRLREG); + + return NOTIFY_DONE; } static int gemini_poweroff_probe(struct platform_device *pdev) @@ -148,8 +147,11 @@ static int gemini_poweroff_probe(struct platform_device *pdev) if (ret) return ret; - pm_power_off = gemini_poweroff; - gpw_poweroff = gpw; + ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + gemini_poweroff, gpw); + if (ret) + return ret; dev_info(dev, "Gemini poweroff driver registered\n"); diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index d96d248a6e..c7eb6dc8e9 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -14,8 +14,8 @@ #include <linux/pm.h> static void __iomem *msm_ps_hold; -static int deassert_pshold(struct notifier_block *nb, unsigned long action, - void *data) + +static int do_msm_poweroff(struct sys_off_data *data) { writel(0, msm_ps_hold); mdelay(10000); @@ -23,25 +23,18 @@ static int deassert_pshold(struct notifier_block *nb, unsigned long action, return NOTIFY_DONE; } -static struct notifier_block restart_nb = { - .notifier_call = deassert_pshold, - .priority = 128, -}; - -static void do_msm_poweroff(void) -{ - deassert_pshold(&restart_nb, 0, NULL); -} - static int msm_restart_probe(struct platform_device *pdev) { msm_ps_hold = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(msm_ps_hold)) return PTR_ERR(msm_ps_hold); - register_restart_handler(&restart_nb); + devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, + 128, do_msm_poweroff, NULL); - pm_power_off = do_msm_poweroff; + devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, do_msm_poweroff, + NULL); return 0; } diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c index 57a63c0ab7..c663347547 100644 --- a/drivers/power/reset/mt6323-poweroff.c +++ b/drivers/power/reset/mt6323-poweroff.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/mfd/mt6397/core.h> #include <linux/mfd/mt6397/rtc.h> +#include <linux/reboot.h> struct mt6323_pwrc { struct device *dev; @@ -21,11 +22,9 @@ struct mt6323_pwrc { u32 base; }; -static struct mt6323_pwrc *mt_pwrc; - -static void mt6323_do_pwroff(void) +static int mt6323_do_pwroff(struct sys_off_data *data) { - struct mt6323_pwrc *pwrc = mt_pwrc; + struct mt6323_pwrc *pwrc = data->cb_data; unsigned int val; int ret; @@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void) mdelay(1000); WARN_ONCE(1, "Unable to power off system\n"); + + return NOTIFY_DONE; } static int mt6323_pwrc_probe(struct platform_device *pdev) @@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev) struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); struct mt6323_pwrc *pwrc; struct resource *res; + int ret; pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); if (!pwrc) @@ -63,19 +65,18 @@ static int mt6323_pwrc_probe(struct platform_device *pdev) pwrc->base = res->start; pwrc->regmap = mt6397_chip->regmap; pwrc->dev = &pdev->dev; - mt_pwrc = pwrc; - pm_power_off = &mt6323_do_pwroff; + ret = devm_register_sys_off_handler(pwrc->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + mt6323_do_pwroff, + pwrc); + if (ret) + return dev_err_probe(pwrc->dev, ret, "failed to register power-off handler\n"); return 0; } -static void mt6323_pwrc_remove(struct platform_device *pdev) -{ - if (pm_power_off == &mt6323_do_pwroff) - pm_power_off = NULL; -} - static const struct of_device_id mt6323_pwrc_dt_match[] = { { .compatible = "mediatek,mt6323-pwrc" }, {}, @@ -84,7 +85,6 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match); static struct platform_driver mt6323_pwrc_driver = { .probe = mt6323_pwrc_probe, - .remove_new = mt6323_pwrc_remove, .driver = { .name = "mt6323-pwrc", .of_match_table = mt6323_pwrc_dt_match, diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c index 15160809c4..fed4978e38 100644 --- a/drivers/power/reset/regulator-poweroff.c +++ b/drivers/power/reset/regulator-poweroff.c @@ -13,18 +13,15 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm.h> +#include <linux/reboot.h> #include <linux/regulator/consumer.h> #define TIMEOUT_MS 3000 -/* - * Hold configuration here, cannot be more than one instance of the driver - * since pm_power_off itself is global. - */ -static struct regulator *cpu_regulator; - -static void regulator_poweroff_do_poweroff(void) +static int regulator_poweroff_do_poweroff(struct sys_off_data *data) { + struct regulator *cpu_regulator = data->cb_data; + if (cpu_regulator && regulator_is_enabled(cpu_regulator)) regulator_force_disable(cpu_regulator); @@ -32,30 +29,24 @@ static void regulator_poweroff_do_poweroff(void) mdelay(TIMEOUT_MS); WARN_ON(1); + + return NOTIFY_DONE; } static int regulator_poweroff_probe(struct platform_device *pdev) { - /* If a pm_power_off function has already been added, leave it alone */ - if (pm_power_off != NULL) { - dev_err(&pdev->dev, - "%s: pm_power_off function already registered\n", - __func__); - return -EBUSY; - } + struct regulator *cpu_regulator; cpu_regulator = devm_regulator_get(&pdev->dev, "cpu"); if (IS_ERR(cpu_regulator)) return PTR_ERR(cpu_regulator); - pm_power_off = ®ulator_poweroff_do_poweroff; - return 0; -} - -static void regulator_poweroff_remove(struct platform_device *pdev) -{ - if (pm_power_off == ®ulator_poweroff_do_poweroff) - pm_power_off = NULL; + /* Set this handler to low priority to not override an existing handler */ + return devm_register_sys_off_handler(&pdev->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_LOW, + regulator_poweroff_do_poweroff, + cpu_regulator); } static const struct of_device_id of_regulator_poweroff_match[] = { @@ -66,7 +57,6 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match); static struct platform_driver regulator_poweroff_driver = { .probe = regulator_poweroff_probe, - .remove_new = regulator_poweroff_remove, .driver = { .name = "poweroff-regulator", .of_match_table = of_regulator_poweroff_match, diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c index f4d6004793..fcd588f9ae 100644 --- a/drivers/power/reset/restart-poweroff.c +++ b/drivers/power/reset/restart-poweroff.c @@ -14,29 +14,21 @@ #include <linux/module.h> #include <linux/reboot.h> -static void restart_poweroff_do_poweroff(void) +static int restart_poweroff_do_poweroff(struct sys_off_data *data) { reboot_mode = REBOOT_HARD; machine_restart(NULL); + return NOTIFY_DONE; } static int restart_poweroff_probe(struct platform_device *pdev) { - /* If a pm_power_off function has already been added, leave it alone */ - if (pm_power_off != NULL) { - dev_err(&pdev->dev, - "pm_power_off function already registered"); - return -EBUSY; - } - - pm_power_off = &restart_poweroff_do_poweroff; - return 0; -} - -static void restart_poweroff_remove(struct platform_device *pdev) -{ - if (pm_power_off == &restart_poweroff_do_poweroff) - pm_power_off = NULL; + /* Set this handler to low priority to not override an existing handler */ + return devm_register_sys_off_handler(&pdev->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_LOW, + restart_poweroff_do_poweroff, + NULL); } static const struct of_device_id of_restart_poweroff_match[] = { @@ -47,7 +39,6 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match); static struct platform_driver restart_poweroff_driver = { .probe = restart_poweroff_probe, - .remove_new = restart_poweroff_remove, .driver = { .name = "poweroff-restart", .of_match_table = of_restart_poweroff_match, diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c index 5df9b41c68..7dbc51c32b 100644 --- a/drivers/power/reset/rmobile-reset.c +++ b/drivers/power/reset/rmobile-reset.c @@ -19,12 +19,9 @@ /* Reset Control Register 2 */ #define RESCNT2_PRES 0x80000000 /* Soft power-on reset */ -static void __iomem *sysc_base2; - -static int rmobile_reset_handler(struct notifier_block *this, - unsigned long mode, void *cmd) +static int rmobile_reset_handler(struct sys_off_data *data) { - pr_debug("%s %lu\n", __func__, mode); + void __iomem *sysc_base2 = (void __iomem *)data->cb_data; /* Let's assume we have acquired the HPB semaphore */ writel(RESCNT2_PRES, sysc_base2 + RESCNT2); @@ -32,37 +29,27 @@ static int rmobile_reset_handler(struct notifier_block *this, return NOTIFY_DONE; } -static struct notifier_block rmobile_reset_nb = { - .notifier_call = rmobile_reset_handler, - .priority = 192, -}; - static int rmobile_reset_probe(struct platform_device *pdev) { + void __iomem *sysc_base2; int error; - sysc_base2 = of_iomap(pdev->dev.of_node, 1); - if (!sysc_base2) - return -ENODEV; + sysc_base2 = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(sysc_base2)) + return PTR_ERR(sysc_base2); - error = register_restart_handler(&rmobile_reset_nb); + error = devm_register_sys_off_handler(&pdev->dev, + SYS_OFF_MODE_RESTART, + SYS_OFF_PRIO_HIGH, + rmobile_reset_handler, + (__force void *)sysc_base2); if (error) { dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n", error); - goto fail_unmap; + return error; } return 0; - -fail_unmap: - iounmap(sysc_base2); - return error; -} - -static void rmobile_reset_remove(struct platform_device *pdev) -{ - unregister_restart_handler(&rmobile_reset_nb); - iounmap(sysc_base2); } static const struct of_device_id rmobile_reset_of_match[] = { @@ -73,7 +60,6 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match); static struct platform_driver rmobile_reset_driver = { .probe = rmobile_reset_probe, - .remove_new = rmobile_reset_remove, .driver = { .name = "rmobile_reset", .of_match_table = rmobile_reset_of_match, diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c index 1b2ce77342..203936f4c5 100644 --- a/drivers/power/reset/syscon-poweroff.c +++ b/drivers/power/reset/syscon-poweroff.c @@ -13,44 +13,56 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm.h> +#include <linux/reboot.h> #include <linux/regmap.h> -static struct regmap *map; -static u32 offset; -static u32 value; -static u32 mask; +struct syscon_poweroff_data { + struct regmap *map; + u32 offset; + u32 value; + u32 mask; +}; -static void syscon_poweroff(void) +static int syscon_poweroff(struct sys_off_data *off_data) { + struct syscon_poweroff_data *data = off_data->cb_data; + /* Issue the poweroff */ - regmap_update_bits(map, offset, mask, value); + regmap_update_bits(data->map, data->offset, data->mask, data->value); mdelay(1000); pr_emerg("Unable to poweroff system\n"); + + return NOTIFY_DONE; } static int syscon_poweroff_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct syscon_poweroff_data *data; int mask_err, value_err; - map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap"); - if (IS_ERR(map)) { - map = syscon_node_to_regmap(dev->parent->of_node); - if (IS_ERR(map)) { + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap"); + if (IS_ERR(data->map)) { + data->map = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(data->map)) { dev_err(dev, "unable to get syscon"); - return PTR_ERR(map); + return PTR_ERR(data->map); } } - if (of_property_read_u32(dev->of_node, "offset", &offset)) { + if (of_property_read_u32(dev->of_node, "offset", &data->offset)) { dev_err(dev, "unable to read 'offset'"); return -EINVAL; } - value_err = of_property_read_u32(dev->of_node, "value", &value); - mask_err = of_property_read_u32(dev->of_node, "mask", &mask); + value_err = of_property_read_u32(dev->of_node, "value", &data->value); + mask_err = of_property_read_u32(dev->of_node, "mask", &data->mask); if (value_err && mask_err) { dev_err(dev, "unable to read 'value' and 'mask'"); return -EINVAL; @@ -58,28 +70,17 @@ static int syscon_poweroff_probe(struct platform_device *pdev) if (value_err) { /* support old binding */ - value = mask; - mask = 0xFFFFFFFF; + data->value = data->mask; + data->mask = 0xFFFFFFFF; } else if (mask_err) { /* support value without mask*/ - mask = 0xFFFFFFFF; - } - - if (pm_power_off) { - dev_err(dev, "pm_power_off already claimed for %ps", - pm_power_off); - return -EBUSY; + data->mask = 0xFFFFFFFF; } - pm_power_off = syscon_poweroff; - - return 0; -} - -static void syscon_poweroff_remove(struct platform_device *pdev) -{ - if (pm_power_off == syscon_poweroff) - pm_power_off = NULL; + return devm_register_sys_off_handler(&pdev->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + syscon_poweroff, data); } static const struct of_device_id syscon_poweroff_of_match[] = { @@ -89,7 +90,6 @@ static const struct of_device_id syscon_poweroff_of_match[] = { static struct platform_driver syscon_poweroff_driver = { .probe = syscon_poweroff_probe, - .remove_new = syscon_poweroff_remove, .driver = { .name = "syscon-poweroff", .of_match_table = syscon_poweroff_of_match, diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c index ee8e9f4b83..6976dbcac7 100644 --- a/drivers/power/reset/tps65086-restart.c +++ b/drivers/power/reset/tps65086-restart.c @@ -9,22 +9,14 @@ #include <linux/platform_device.h> #include <linux/reboot.h> -struct tps65086_restart { - struct notifier_block handler; - struct device *dev; -}; - -static int tps65086_restart_notify(struct notifier_block *this, - unsigned long mode, void *cmd) +static int tps65086_restart_notify(struct sys_off_data *data) { - struct tps65086_restart *tps65086_restart = - container_of(this, struct tps65086_restart, handler); - struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent); + struct tps65086 *tps65086 = data->cb_data; int ret; ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1); if (ret) { - dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n", + dev_err(tps65086->dev, "%s: error writing to tps65086 pmic: %d\n", __func__, ret); return NOTIFY_DONE; } @@ -39,44 +31,13 @@ static int tps65086_restart_notify(struct notifier_block *this, static int tps65086_restart_probe(struct platform_device *pdev) { - struct tps65086_restart *tps65086_restart; - int ret; - - tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL); - if (!tps65086_restart) - return -ENOMEM; - - platform_set_drvdata(pdev, tps65086_restart); - - tps65086_restart->handler.notifier_call = tps65086_restart_notify; - tps65086_restart->handler.priority = 192; - tps65086_restart->dev = &pdev->dev; - - ret = register_restart_handler(&tps65086_restart->handler); - if (ret) { - dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n", - __func__, ret); - return -ENODEV; - } - - return 0; -} - -static void tps65086_restart_remove(struct platform_device *pdev) -{ - struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev); - int ret; + struct tps65086 *tps65086 = dev_get_drvdata(pdev->dev.parent); - ret = unregister_restart_handler(&tps65086_restart->handler); - if (ret) { - /* - * tps65086_restart_probe() registered the restart handler. So - * unregistering should work fine. Checking the error code - * shouldn't be needed, still doing it for completeness. - */ - dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n", - __func__, ret); - } + return devm_register_sys_off_handler(&pdev->dev, + SYS_OFF_MODE_RESTART, + SYS_OFF_PRIO_HIGH, + tps65086_restart_notify, + tps65086); } static const struct platform_device_id tps65086_restart_id_table[] = { @@ -90,7 +51,6 @@ static struct platform_driver tps65086_restart_driver = { .name = "tps65086-restart", }, .probe = tps65086_restart_probe, - .remove_new = tps65086_restart_remove, .id_table = tps65086_restart_id_table, }; module_platform_driver(tps65086_restart_driver); diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index c2e5a99940..b5eee19bac 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -22,17 +22,13 @@ struct xgene_reboot_context { struct device *dev; - void *csr; + void __iomem *csr; u32 mask; - struct notifier_block restart_handler; }; -static int xgene_restart_handler(struct notifier_block *this, - unsigned long mode, void *cmd) +static int xgene_restart_handler(struct sys_off_data *data) { - struct xgene_reboot_context *ctx = - container_of(this, struct xgene_reboot_context, - restart_handler); + struct xgene_reboot_context *ctx = data->cb_data; /* Issue the reboot */ writel(ctx->mask, ctx->csr); @@ -54,23 +50,20 @@ static int xgene_reboot_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; - ctx->csr = of_iomap(dev->of_node, 0); - if (!ctx->csr) { + ctx->csr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ctx->csr)) { dev_err(dev, "can not map resource\n"); - return -ENODEV; + return PTR_ERR(ctx->csr); } if (of_property_read_u32(dev->of_node, "mask", &ctx->mask)) ctx->mask = 0xFFFFFFFF; ctx->dev = dev; - ctx->restart_handler.notifier_call = xgene_restart_handler; - ctx->restart_handler.priority = 128; - err = register_restart_handler(&ctx->restart_handler); - if (err) { - iounmap(ctx->csr); + err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128, + xgene_restart_handler, ctx); + if (err) dev_err(dev, "cannot register restart handler (err=%d)\n", err); - } return err; } |