Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aec1d96c authored by Heiko Stuebner's avatar Heiko Stuebner
Browse files

Merge tag 'tags/restart-handler-for-v3.18' into v3.18-next/cpuclk

Immutable branch with restart handler patches for v3.18
parents fc69ed70 6cd6d94d
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -114,18 +114,13 @@ void soft_restart(unsigned long addr)
	BUG();
}

static void null_restart(enum reboot_mode reboot_mode, const char *cmd)
{
}

/*
 * Function pointers to optional machine specific functions
 */
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);

void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd) = null_restart;
EXPORT_SYMBOL_GPL(arm_pm_restart);
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);

/*
 * This is our default idle handler.
@@ -230,7 +225,10 @@ void machine_restart(char *cmd)
	local_irq_disable();
	smp_send_stop();

	if (arm_pm_restart)
		arm_pm_restart(reboot_mode, cmd);
	else
		do_kernel_restart(cmd);

	/* Give a grace period for failure to restart of 1s */
	mdelay(1000);
+2 −1
Original line number Diff line number Diff line
@@ -98,7 +98,6 @@ void (*pm_power_off)(void);
EXPORT_SYMBOL_GPL(pm_power_off);

void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
EXPORT_SYMBOL_GPL(arm_pm_restart);

/*
 * This is our default idle handler.
@@ -180,6 +179,8 @@ void machine_restart(char *cmd)
	/* Now call the architecture specific reboot code. */
	if (arm_pm_restart)
		arm_pm_restart(reboot_mode, cmd);
	else
		do_kernel_restart(cmd);

	/*
	 * Whoops - the architecture was unable to reboot.
+2 −1
Original line number Diff line number Diff line
@@ -20,7 +20,8 @@

static void restart_poweroff_do_poweroff(void)
{
	arm_pm_restart(REBOOT_HARD, NULL);
	reboot_mode = REBOOT_HARD;
	machine_restart(NULL);
}

static int restart_poweroff_probe(struct platform_device *pdev)
+32 −10
Original line number Diff line number Diff line
@@ -301,6 +301,28 @@ static struct miscdevice wdt_miscdev = {
	.fops	=	&wdt_fops,
};

static int wdt_restart_handle(struct notifier_block *this, unsigned long mode,
			      void *cmd)
{
	/*
	 * Cobalt devices have no way of rebooting themselves other
	 * than getting the watchdog to pull reset, so we restart the
	 * watchdog on reboot with no heartbeat.
	 */
	wdt_change(WDT_ENABLE);

	/* loop until the watchdog fires */
	while (true)
		;

	return NOTIFY_DONE;
}

static struct notifier_block wdt_restart_handler = {
	.notifier_call = wdt_restart_handle,
	.priority = 128,
};

/*
 *	Notifier for system down
 */
@@ -311,15 +333,6 @@ static int wdt_notify_sys(struct notifier_block *this,
	if (code == SYS_DOWN || code == SYS_HALT)
		wdt_turnoff();

	if (code == SYS_RESTART) {
		/*
		 * Cobalt devices have no way of rebooting themselves other
		 * than getting the watchdog to pull reset, so we restart the
		 * watchdog on reboot with no heartbeat
		 */
		wdt_change(WDT_ENABLE);
		pr_info("Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second\n");
	}
	return NOTIFY_DONE;
}

@@ -338,6 +351,7 @@ static void __exit alim7101_wdt_unload(void)
	/* Deregister */
	misc_deregister(&wdt_miscdev);
	unregister_reboot_notifier(&wdt_notifier);
	unregister_restart_handler(&wdt_restart_handler);
	pci_dev_put(alim7101_pmu);
}

@@ -390,11 +404,17 @@ static int __init alim7101_wdt_init(void)
		goto err_out;
	}

	rc = register_restart_handler(&wdt_restart_handler);
	if (rc) {
		pr_err("cannot register restart handler (err=%d)\n", rc);
		goto err_out_reboot;
	}

	rc = misc_register(&wdt_miscdev);
	if (rc) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       wdt_miscdev.minor, rc);
		goto err_out_reboot;
		goto err_out_restart;
	}

	if (nowayout)
@@ -404,6 +424,8 @@ static int __init alim7101_wdt_init(void)
		timeout, nowayout);
	return 0;

err_out_restart:
	unregister_restart_handler(&wdt_restart_handler);
err_out_reboot:
	unregister_reboot_notifier(&wdt_notifier);
err_out:
+20 −12
Original line number Diff line number Diff line
@@ -15,12 +15,12 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/watchdog.h>
#include <linux/moduleparam.h>

#include <asm/system_misc.h>

#define REG_COUNT			0x4
#define REG_MODE			0x8
#define REG_ENABLE			0xC
@@ -29,17 +29,22 @@ struct moxart_wdt_dev {
	struct watchdog_device dev;
	void __iomem *base;
	unsigned int clock_frequency;
	struct notifier_block restart_handler;
};

static struct moxart_wdt_dev *moxart_restart_ctx;

static int heartbeat;

static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
static int moxart_restart_handle(struct notifier_block *this,
				 unsigned long mode, void *cmd)
{
	writel(1, moxart_restart_ctx->base + REG_COUNT);
	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
	struct moxart_wdt_dev *moxart_wdt = container_of(this,
							 struct moxart_wdt_dev,
							 restart_handler);
	writel(1, moxart_wdt->base + REG_COUNT);
	writel(0x5ab9, moxart_wdt->base + REG_MODE);
	writel(0x03, moxart_wdt->base + REG_ENABLE);

	return NOTIFY_DONE;
}

static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
@@ -136,8 +141,12 @@ static int moxart_wdt_probe(struct platform_device *pdev)
	if (err)
		return err;

	moxart_restart_ctx = moxart_wdt;
	arm_pm_restart = moxart_wdt_restart;
	moxart_wdt->restart_handler.notifier_call = moxart_restart_handle;
	moxart_wdt->restart_handler.priority = 128;
	err = register_restart_handler(&moxart_wdt->restart_handler);
	if (err)
		dev_err(dev, "cannot register restart notifier (err=%d)\n",
			err);

	dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
		moxart_wdt->dev.timeout, nowayout);
@@ -149,9 +158,8 @@ static int moxart_wdt_remove(struct platform_device *pdev)
{
	struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);

	arm_pm_restart = NULL;
	unregister_restart_handler(&moxart_wdt->restart_handler);
	moxart_wdt_stop(&moxart_wdt->dev);
	watchdog_unregister_device(&moxart_wdt->dev);

	return 0;
}
Loading