1664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam/* 2664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * System monitoring driver for DA9052 PMICs. 3664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * 4664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * Copyright(c) 2012 Dialog Semiconductor Ltd. 5664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * 6664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * Author: Anthony Olech <Anthony.Olech@diasemi.com> 7664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * 8664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * This program is free software; you can redistribute it and/or modify 9664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * it under the terms of the GNU General Public License as published by 10664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * the Free Software Foundation; either version 2 of the License, or 11664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * (at your option) any later version. 12664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * 13664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam */ 14664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 15664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/module.h> 16664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/delay.h> 17664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/uaccess.h> 18664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/platform_device.h> 19664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/time.h> 20664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/watchdog.h> 21664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/types.h> 22664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/kernel.h> 23664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/jiffies.h> 24664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 25664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/mfd/da9052/reg.h> 26664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#include <linux/mfd/da9052/da9052.h> 27664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 28664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#define DA9052_DEF_TIMEOUT 4 29664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam#define DA9052_TWDMIN 256 30664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 31664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstruct da9052_wdt_data { 32664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct watchdog_device wdt; 33664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052 *da9052; 34664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct kref kref; 35664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam unsigned long jpast; 36664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam}; 37664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 38664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic const struct { 39664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam u8 reg_val; 40664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam int time; /* Seconds */ 41664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} da9052_wdt_maps[] = { 42664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 1, 2 }, 43664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 2, 4 }, 44664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 3, 8 }, 45664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 4, 16 }, 46664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 5, 32 }, 47664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 5, 33 }, /* Actual time 32.768s so included both 32s and 33s */ 48664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 6, 65 }, 49664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 6, 66 }, /* Actual time 65.536s so include both, 65s and 66s */ 50664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam { 7, 131 }, 51664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam}; 52664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 53664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 54664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic void da9052_wdt_release_resources(struct kref *r) 55664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 56664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 57664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 58664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev, 59664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam unsigned int timeout) 60664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 61664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); 62664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052 *da9052 = driver_data->da9052; 63664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam int ret, i; 64664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 65664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam /* 66664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * Disable the Watchdog timer before setting 67664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * new time out. 68664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam */ 69664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 70664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam DA9052_CONTROLD_TWDSCALE, 0); 71664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (ret < 0) { 72664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam dev_err(da9052->dev, "Failed to disable watchdog bit, %d\n", 73664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret); 74664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return ret; 75664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam } 76664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (timeout) { 77664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam /* 78664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * To change the timeout, da9052 needs to 79664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * be disabled for at least 150 us. 80664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam */ 81664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam udelay(150); 82664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 83664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam /* Set the desired timeout */ 84664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam for (i = 0; i < ARRAY_SIZE(da9052_wdt_maps); i++) 85664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (da9052_wdt_maps[i].time == timeout) 86664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam break; 87664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 88664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (i == ARRAY_SIZE(da9052_wdt_maps)) 89664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = -EINVAL; 90664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam else 91664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 92664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam DA9052_CONTROLD_TWDSCALE, 93664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam da9052_wdt_maps[i].reg_val); 94664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (ret < 0) { 95664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam dev_err(da9052->dev, 96664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam "Failed to update timescale bit, %d\n", ret); 97664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return ret; 98664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam } 99664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 100664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam wdt_dev->timeout = timeout; 101664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam driver_data->jpast = jiffies; 102664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam } 103664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 104664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return 0; 105664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 106664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 107664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic void da9052_wdt_ref(struct watchdog_device *wdt_dev) 108664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 109664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); 110664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 111664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam kref_get(&driver_data->kref); 112664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 113664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 114664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic void da9052_wdt_unref(struct watchdog_device *wdt_dev) 115664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 116664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); 117664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 118664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam kref_put(&driver_data->kref, da9052_wdt_release_resources); 119664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 120664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 121664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic int da9052_wdt_start(struct watchdog_device *wdt_dev) 122664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 123664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return da9052_wdt_set_timeout(wdt_dev, wdt_dev->timeout); 124664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 125664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 126664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic int da9052_wdt_stop(struct watchdog_device *wdt_dev) 127664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 128664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return da9052_wdt_set_timeout(wdt_dev, 0); 129664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 130664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 131664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic int da9052_wdt_ping(struct watchdog_device *wdt_dev) 132664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 133664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); 134664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052 *da9052 = driver_data->da9052; 135664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam unsigned long msec, jnow = jiffies; 136664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam int ret; 137664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 138664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam /* 139664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * We have a minimum time for watchdog window called TWDMIN. A write 140664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * to the watchdog before this elapsed time should cause an error. 141664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam */ 142664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam msec = (jnow - driver_data->jpast) * 1000/HZ; 143664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (msec < DA9052_TWDMIN) 144664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam mdelay(msec); 145664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 146664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam /* Reset the watchdog timer */ 147664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 148664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam DA9052_CONTROLD_WATCHDOG, 1 << 7); 149664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (ret < 0) 150664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam goto err_strobe; 151664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 152664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam /* 153664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * FIXME: Reset the watchdog core, in general PMIC 154664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam * is supposed to do this 155664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam */ 156664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 157664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam DA9052_CONTROLD_WATCHDOG, 0 << 7); 158664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamerr_strobe: 159664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return ret; 160664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 161664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 162664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic struct watchdog_info da9052_wdt_info = { 163664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 164664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .identity = "DA9052 Watchdog", 165664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam}; 166664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 167664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic const struct watchdog_ops da9052_wdt_ops = { 168664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .owner = THIS_MODULE, 169664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .start = da9052_wdt_start, 170664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .stop = da9052_wdt_stop, 171664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .ping = da9052_wdt_ping, 172664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .set_timeout = da9052_wdt_set_timeout, 173664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .ref = da9052_wdt_ref, 174664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .unref = da9052_wdt_unref, 175664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam}; 176664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 177664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 1782d991a164a61858012651e13c59521975504e260Bill Pembertonstatic int da9052_wdt_probe(struct platform_device *pdev) 179664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 180664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent); 181664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct da9052_wdt_data *driver_data; 182664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam struct watchdog_device *da9052_wdt; 183664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam int ret; 184664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 185664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), 186664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam GFP_KERNEL); 187664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (!driver_data) { 188664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = -ENOMEM; 189664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam goto err; 190664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam } 191664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam driver_data->da9052 = da9052; 192664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 193664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam da9052_wdt = &driver_data->wdt; 194664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 195664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam da9052_wdt->timeout = DA9052_DEF_TIMEOUT; 196664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam da9052_wdt->info = &da9052_wdt_info; 197664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam da9052_wdt->ops = &da9052_wdt_ops; 198664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam watchdog_set_drvdata(da9052_wdt, driver_data); 199664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 200664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam kref_init(&driver_data->kref); 201664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 202664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 203664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam DA9052_CONTROLD_TWDSCALE, 0); 204664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (ret < 0) { 205664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam dev_err(&pdev->dev, "Failed to disable watchdog bits, %d\n", 206664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret); 207664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam goto err; 208664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam } 209664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 210664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret = watchdog_register_device(&driver_data->wdt); 211664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam if (ret != 0) { 212664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam dev_err(da9052->dev, "watchdog_register_device() failed: %d\n", 213664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam ret); 214664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam goto err; 215664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam } 216664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 217552a96415ff297475c20a05d384398ef1c729794Jingoo Han platform_set_drvdata(pdev, driver_data); 218664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamerr: 219664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return ret; 220664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 221664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 2224b12b896c27c3b54592816606679f5b02f638930Bill Pembertonstatic int da9052_wdt_remove(struct platform_device *pdev) 223664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam{ 224552a96415ff297475c20a05d384398ef1c729794Jingoo Han struct da9052_wdt_data *driver_data = platform_get_drvdata(pdev); 225664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 226664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam watchdog_unregister_device(&driver_data->wdt); 227664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam kref_put(&driver_data->kref, da9052_wdt_release_resources); 228664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 229664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam return 0; 230664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam} 231664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 232664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangamstatic struct platform_driver da9052_wdt_driver = { 233664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .probe = da9052_wdt_probe, 23482268714bdf06bc06135efb707a9de590ab2d294Bill Pemberton .remove = da9052_wdt_remove, 235664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .driver = { 236664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam .name = "da9052-watchdog", 237664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam }, 238664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam}; 239664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 240664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangammodule_platform_driver(da9052_wdt_driver); 241664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish Jangam 242664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish JangamMODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>"); 243664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish JangamMODULE_DESCRIPTION("DA9052 SM Device Driver"); 244664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish JangamMODULE_LICENSE("GPL"); 245664a0d7862a6b10c709d4b4a3655fe2c59a20064Ashish JangamMODULE_ALIAS("platform:da9052-watchdog"); 246