brintos

brintos / linux-shallow public Read only

0
0
Text · 3.9 KiB · c82c1b7 Raw
172 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Watchdog driver for the wm83504 *5 * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com>6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/types.h>13#include <linux/kernel.h>14#include <linux/platform_device.h>15#include <linux/watchdog.h>16#include <linux/uaccess.h>17#include <linux/mfd/wm8350/core.h>18 19static bool nowayout = WATCHDOG_NOWAYOUT;20module_param(nowayout, bool, 0);21MODULE_PARM_DESC(nowayout,22		 "Watchdog cannot be stopped once started (default="23		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");24 25static DEFINE_MUTEX(wdt_mutex);26 27static struct {28	unsigned int time;  /* Seconds */29	u16 val;	    /* To be set in WM8350_SYSTEM_CONTROL_2 */30} wm8350_wdt_cfgs[] = {31	{ 1, 0x02 },32	{ 2, 0x04 },33	{ 4, 0x05 },34};35 36static int wm8350_wdt_set_timeout(struct watchdog_device *wdt_dev,37				  unsigned int timeout)38{39	struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);40	int ret, i;41	u16 reg;42 43	for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++)44		if (wm8350_wdt_cfgs[i].time == timeout)45			break;46	if (i == ARRAY_SIZE(wm8350_wdt_cfgs))47		return -EINVAL;48 49	mutex_lock(&wdt_mutex);50	wm8350_reg_unlock(wm8350);51 52	reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);53	reg &= ~WM8350_WDOG_TO_MASK;54	reg |= wm8350_wdt_cfgs[i].val;55	ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);56 57	wm8350_reg_lock(wm8350);58	mutex_unlock(&wdt_mutex);59 60	wdt_dev->timeout = timeout;61	return ret;62}63 64static int wm8350_wdt_start(struct watchdog_device *wdt_dev)65{66	struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);67	int ret;68	u16 reg;69 70	mutex_lock(&wdt_mutex);71	wm8350_reg_unlock(wm8350);72 73	reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);74	reg &= ~WM8350_WDOG_MODE_MASK;75	reg |= 0x20;76	ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);77 78	wm8350_reg_lock(wm8350);79	mutex_unlock(&wdt_mutex);80 81	return ret;82}83 84static int wm8350_wdt_stop(struct watchdog_device *wdt_dev)85{86	struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);87	int ret;88	u16 reg;89 90	mutex_lock(&wdt_mutex);91	wm8350_reg_unlock(wm8350);92 93	reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);94	reg &= ~WM8350_WDOG_MODE_MASK;95	ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);96 97	wm8350_reg_lock(wm8350);98	mutex_unlock(&wdt_mutex);99 100	return ret;101}102 103static int wm8350_wdt_ping(struct watchdog_device *wdt_dev)104{105	struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);106	int ret;107	u16 reg;108 109	mutex_lock(&wdt_mutex);110 111	reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);112	ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);113 114	mutex_unlock(&wdt_mutex);115 116	return ret;117}118 119static const struct watchdog_info wm8350_wdt_info = {120	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,121	.identity = "WM8350 Watchdog",122};123 124static const struct watchdog_ops wm8350_wdt_ops = {125	.owner = THIS_MODULE,126	.start = wm8350_wdt_start,127	.stop = wm8350_wdt_stop,128	.ping = wm8350_wdt_ping,129	.set_timeout = wm8350_wdt_set_timeout,130};131 132static struct watchdog_device wm8350_wdt = {133	.info = &wm8350_wdt_info,134	.ops = &wm8350_wdt_ops,135	.timeout = 4,136	.min_timeout = 1,137	.max_timeout = 4,138};139 140static int wm8350_wdt_probe(struct platform_device *pdev)141{142	struct wm8350 *wm8350 = platform_get_drvdata(pdev);143 144	if (!wm8350) {145		pr_err("No driver data supplied\n");146		return -ENODEV;147	}148 149	watchdog_set_nowayout(&wm8350_wdt, nowayout);150	watchdog_set_drvdata(&wm8350_wdt, wm8350);151	wm8350_wdt.parent = &pdev->dev;152 153	/* Default to 4s timeout */154	wm8350_wdt_set_timeout(&wm8350_wdt, 4);155 156	return devm_watchdog_register_device(&pdev->dev, &wm8350_wdt);157}158 159static struct platform_driver wm8350_wdt_driver = {160	.probe = wm8350_wdt_probe,161	.driver = {162		.name = "wm8350-wdt",163	},164};165 166module_platform_driver(wm8350_wdt_driver);167 168MODULE_AUTHOR("Mark Brown");169MODULE_DESCRIPTION("WM8350 Watchdog");170MODULE_LICENSE("GPL");171MODULE_ALIAS("platform:wm8350-wdt");172