HID: Add quirk for Microsoft PIXART OEM mouse
[sfrench/cifs-2.6.git] / drivers / watchdog / mpc8xxx_wdt.c
index aca2d6323f8ad14d11294895081e9a67178d11bd..069072e6747df321876e54c94410f2801bff0c7c 100644 (file)
@@ -17,8 +17,6 @@
  * option) any later version.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -49,6 +47,7 @@ struct mpc8xxx_wdt {
 struct mpc8xxx_wdt_type {
        int prescaler;
        bool hw_enabled;
+       u32 rsr_mask;
 };
 
 struct mpc8xxx_wdt_ddata {
@@ -137,36 +136,55 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
        struct mpc8xxx_wdt_ddata *ddata;
        u32 freq = fsl_get_sys_freq();
        bool enabled;
+       struct device *dev = &ofdev->dev;
 
-       wdt_type = of_device_get_match_data(&ofdev->dev);
+       wdt_type = of_device_get_match_data(dev);
        if (!wdt_type)
                return -EINVAL;
 
        if (!freq || freq == -1)
                return -EINVAL;
 
-       ddata = devm_kzalloc(&ofdev->dev, sizeof(*ddata), GFP_KERNEL);
+       ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
        if (!ddata)
                return -ENOMEM;
 
        res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
-       ddata->base = devm_ioremap_resource(&ofdev->dev, res);
+       ddata->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(ddata->base))
                return PTR_ERR(ddata->base);
 
        enabled = in_be32(&ddata->base->swcrr) & SWCRR_SWEN;
        if (!enabled && wdt_type->hw_enabled) {
-               pr_info("could not be enabled in software\n");
+               dev_info(dev, "could not be enabled in software\n");
                return -ENODEV;
        }
 
+       res = platform_get_resource(ofdev, IORESOURCE_MEM, 1);
+       if (res) {
+               bool status;
+               u32 __iomem *rsr = ioremap(res->start, resource_size(res));
+
+               if (!rsr)
+                       return -ENOMEM;
+
+               status = in_be32(rsr) & wdt_type->rsr_mask;
+               ddata->wdd.bootstatus = status ? WDIOF_CARDRESET : 0;
+                /* clear reset status bits related to watchdog timer */
+               out_be32(rsr, wdt_type->rsr_mask);
+               iounmap(rsr);
+
+               dev_info(dev, "Last boot was %scaused by watchdog\n",
+                        status ? "" : "not ");
+       }
+
        spin_lock_init(&ddata->lock);
 
        ddata->wdd.info = &mpc8xxx_wdt_info,
        ddata->wdd.ops = &mpc8xxx_wdt_ops,
 
        ddata->wdd.timeout = WATCHDOG_TIMEOUT;
-       watchdog_init_timeout(&ddata->wdd, timeout, &ofdev->dev);
+       watchdog_init_timeout(&ddata->wdd, timeout, dev);
 
        watchdog_set_nowayout(&ddata->wdd, nowayout);
 
@@ -189,12 +207,13 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
 
        ret = watchdog_register_device(&ddata->wdd);
        if (ret) {
-               pr_err("cannot register watchdog device (err=%d)\n", ret);
+               dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
                return ret;
        }
 
-       pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",
-               reset ? "reset" : "interrupt", ddata->wdd.timeout);
+       dev_info(dev,
+                "WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",
+                reset ? "reset" : "interrupt", ddata->wdd.timeout);
 
        platform_set_drvdata(ofdev, ddata);
        return 0;
@@ -204,8 +223,8 @@ static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
 {
        struct mpc8xxx_wdt_ddata *ddata = platform_get_drvdata(ofdev);
 
-       pr_crit("Watchdog removed, expect the %s soon!\n",
-               reset ? "reset" : "machine check exception");
+       dev_crit(&ofdev->dev, "Watchdog removed, expect the %s soon!\n",
+                reset ? "reset" : "machine check exception");
        watchdog_unregister_device(&ddata->wdd);
 
        return 0;
@@ -216,6 +235,7 @@ static const struct of_device_id mpc8xxx_wdt_match[] = {
                .compatible = "mpc83xx_wdt",
                .data = &(struct mpc8xxx_wdt_type) {
                        .prescaler = 0x10000,
+                       .rsr_mask = BIT(3), /* RSR Bit SWRS */
                },
        },
        {
@@ -223,6 +243,7 @@ static const struct of_device_id mpc8xxx_wdt_match[] = {
                .data = &(struct mpc8xxx_wdt_type) {
                        .prescaler = 0x10000,
                        .hw_enabled = true,
+                       .rsr_mask = BIT(20), /* RSTRSCR Bit WDT_RR */
                },
        },
        {
@@ -230,6 +251,7 @@ static const struct of_device_id mpc8xxx_wdt_match[] = {
                .data = &(struct mpc8xxx_wdt_type) {
                        .prescaler = 0x800,
                        .hw_enabled = true,
+                       .rsr_mask = BIT(28), /* RSR Bit SWRS */
                },
        },
        {},