1f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil/* 2f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net> 3f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * JZ4740 Watchdog driver 4f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * 5f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * This program is free software; you can redistribute it and/or modify it 6f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * under the terms of the GNU General Public License as published by the 7f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * Free Software Foundation; either version 2 of the License, or (at your 8f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * option) any later version. 9f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * 10f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * You should have received a copy of the GNU General Public License along 11f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * with this program; if not, write to the Free Software Foundation, Inc., 12f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * 675 Mass Ave, Cambridge, MA 02139, USA. 13f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * 14f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil */ 15f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 16f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/module.h> 17f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/moduleparam.h> 18f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/types.h> 19f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/kernel.h> 20f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/miscdevice.h> 21f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/watchdog.h> 22f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/init.h> 23f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/platform_device.h> 24f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/io.h> 25f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/device.h> 26f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/clk.h> 27f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <linux/slab.h> 2885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin#include <linux/err.h> 29f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 30f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#include <asm/mach-jz4740/timer.h> 31f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 32f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_REG_WDT_TIMER_DATA 0x0 33f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_REG_WDT_COUNTER_ENABLE 0x4 34f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_REG_WDT_TIMER_COUNTER 0x8 35f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_REG_WDT_TIMER_CONTROL 0xC 36f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 37f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_PCLK 0x1 38f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_RTC 0x2 39f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_EXT 0x4 40f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 41f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_SHIFT 3 42f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 43f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_1 (0 << JZ_WDT_CLOCK_DIV_SHIFT) 44f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_4 (1 << JZ_WDT_CLOCK_DIV_SHIFT) 45f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_16 (2 << JZ_WDT_CLOCK_DIV_SHIFT) 46f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_64 (3 << JZ_WDT_CLOCK_DIV_SHIFT) 47f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_256 (4 << JZ_WDT_CLOCK_DIV_SHIFT) 48f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define JZ_WDT_CLOCK_DIV_1024 (5 << JZ_WDT_CLOCK_DIV_SHIFT) 49f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 50f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define DEFAULT_HEARTBEAT 5 51f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil#define MAX_HEARTBEAT 2048 52f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 5385f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic bool nowayout = WATCHDOG_NOWAYOUT; 5485f6df1492ff8b620cf601a1509520d2b89858ddAxel Linmodule_param(nowayout, bool, 0); 5585f6df1492ff8b620cf601a1509520d2b89858ddAxel LinMODULE_PARM_DESC(nowayout, 5685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin "Watchdog cannot be stopped once started (default=" 5785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 58f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 5985f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic unsigned int heartbeat = DEFAULT_HEARTBEAT; 6085f6df1492ff8b620cf601a1509520d2b89858ddAxel Linmodule_param(heartbeat, uint, 0); 6185f6df1492ff8b620cf601a1509520d2b89858ddAxel LinMODULE_PARM_DESC(heartbeat, 6285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin "Watchdog heartbeat period in seconds from 1 to " 6385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin __MODULE_STRING(MAX_HEARTBEAT) ", default " 6485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin __MODULE_STRING(DEFAULT_HEARTBEAT)); 65f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 6685f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstruct jz4740_wdt_drvdata { 6785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct watchdog_device wdt; 6885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin void __iomem *base; 6985f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct clk *rtc_clk; 7085f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin}; 71f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 7285f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic int jz4740_wdt_ping(struct watchdog_device *wdt_dev) 73f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil{ 7485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); 7585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin 7685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writew(0x0, drvdata->base + JZ_REG_WDT_TIMER_COUNTER); 7785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin return 0; 78f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil} 79f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 8085f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev, 8185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin unsigned int new_timeout) 82f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil{ 8385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); 84f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil unsigned int rtc_clk_rate; 85f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil unsigned int timeout_value; 86f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil unsigned short clock_div = JZ_WDT_CLOCK_DIV_1; 87f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 8885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin rtc_clk_rate = clk_get_rate(drvdata->rtc_clk); 89f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 9085f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin timeout_value = rtc_clk_rate * new_timeout; 91f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil while (timeout_value > 0xffff) { 92f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil if (clock_div == JZ_WDT_CLOCK_DIV_1024) { 93f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil /* Requested timeout too high; 94f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil * use highest possible value. */ 95f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil timeout_value = 0xffff; 96f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil break; 97f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil } 98f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil timeout_value >>= 2; 99f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil clock_div += (1 << JZ_WDT_CLOCK_DIV_SHIFT); 100f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil } 101f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 10285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writeb(0x0, drvdata->base + JZ_REG_WDT_COUNTER_ENABLE); 10385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writew(clock_div, drvdata->base + JZ_REG_WDT_TIMER_CONTROL); 104f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 10585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writew((u16)timeout_value, drvdata->base + JZ_REG_WDT_TIMER_DATA); 10685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writew(0x0, drvdata->base + JZ_REG_WDT_TIMER_COUNTER); 107f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil writew(clock_div | JZ_WDT_CLOCK_RTC, 10885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin drvdata->base + JZ_REG_WDT_TIMER_CONTROL); 109f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 11085f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writeb(0x1, drvdata->base + JZ_REG_WDT_COUNTER_ENABLE); 111f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 1120197c1c49ef1ff386b2ebb6d3b0fc85a8e174b5cWim Van Sebroeck wdt_dev->timeout = new_timeout; 11385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin return 0; 114f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil} 115f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 11685f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic int jz4740_wdt_start(struct watchdog_device *wdt_dev) 117f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil{ 11885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_timer_enable_watchdog(); 11985f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt_set_timeout(wdt_dev, wdt_dev->timeout); 120f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 12185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin return 0; 122f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil} 123f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 12485f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic int jz4740_wdt_stop(struct watchdog_device *wdt_dev) 125f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil{ 12685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); 127742e4b630895d751812b0682750db76c8072bf37Wim Van Sebroeck 12885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_timer_disable_watchdog(); 12985f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin writeb(0x0, drvdata->base + JZ_REG_WDT_COUNTER_ENABLE); 130f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 13185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin return 0; 132f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil} 133f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 13485f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic const struct watchdog_info jz4740_wdt_info = { 13585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 136f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .identity = "jz4740 Watchdog", 137f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil}; 138f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 13985f6df1492ff8b620cf601a1509520d2b89858ddAxel Linstatic const struct watchdog_ops jz4740_wdt_ops = { 140f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .owner = THIS_MODULE, 14185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin .start = jz4740_wdt_start, 14285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin .stop = jz4740_wdt_stop, 14385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin .ping = jz4740_wdt_ping, 14485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin .set_timeout = jz4740_wdt_set_timeout, 145f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil}; 146f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 147f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueilstatic int __devinit jz4740_wdt_probe(struct platform_device *pdev) 148f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil{ 14985f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct jz4740_wdt_drvdata *drvdata; 15085f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct watchdog_device *jz4740_wdt; 15185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct resource *res; 15285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin int ret; 15385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin 15485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin drvdata = devm_kzalloc(&pdev->dev, sizeof(struct jz4740_wdt_drvdata), 15585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin GFP_KERNEL); 15685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin if (!drvdata) { 15785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin dev_err(&pdev->dev, "Unable to alloacate watchdog device\n"); 15885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin return -ENOMEM; 159f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil } 160f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 16185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) 16285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin heartbeat = DEFAULT_HEARTBEAT; 163f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 16485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt = &drvdata->wdt; 16585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt->info = &jz4740_wdt_info; 16685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt->ops = &jz4740_wdt_ops; 16785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt->timeout = heartbeat; 16885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt->min_timeout = 1; 16985f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt->max_timeout = MAX_HEARTBEAT; 17085f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin watchdog_set_nowayout(jz4740_wdt, nowayout); 17185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin watchdog_set_drvdata(jz4740_wdt, drvdata); 17285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin 17385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 17485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin drvdata->base = devm_request_and_ioremap(&pdev->dev, res); 17585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin if (drvdata->base == NULL) { 176f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil ret = -EBUSY; 17785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin goto err_out; 178f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil } 179f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 18085f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin drvdata->rtc_clk = clk_get(NULL, "rtc"); 18185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin if (IS_ERR(drvdata->rtc_clk)) { 18285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin dev_err(&pdev->dev, "cannot find RTC clock\n"); 18385f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin ret = PTR_ERR(drvdata->rtc_clk); 18485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin goto err_out; 185f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil } 186f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 18785f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin ret = watchdog_register_device(&drvdata->wdt); 18885f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin if (ret < 0) 189f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil goto err_disable_clk; 190f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 19185f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin platform_set_drvdata(pdev, drvdata); 192f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil return 0; 193f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 194f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueilerr_disable_clk: 19585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin clk_put(drvdata->rtc_clk); 19685f6df1492ff8b620cf601a1509520d2b89858ddAxel Linerr_out: 197f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil return ret; 198f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil} 199f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 200f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueilstatic int __devexit jz4740_wdt_remove(struct platform_device *pdev) 201f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil{ 20285f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin struct jz4740_wdt_drvdata *drvdata = platform_get_drvdata(pdev); 203f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 20485f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin jz4740_wdt_stop(&drvdata->wdt); 20585f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin watchdog_unregister_device(&drvdata->wdt); 20685f6df1492ff8b620cf601a1509520d2b89858ddAxel Lin clk_put(drvdata->rtc_clk); 207f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 208f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil return 0; 209f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil} 210f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 211f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueilstatic struct platform_driver jz4740_wdt_driver = { 212f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .probe = jz4740_wdt_probe, 213f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .remove = __devexit_p(jz4740_wdt_remove), 214f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .driver = { 215f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .name = "jz4740-wdt", 216f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil .owner = THIS_MODULE, 217f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil }, 218f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil}; 219f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 220b8ec61189f3b4cd9d1b2856342f5d7676151d01cAxel Linmodule_platform_driver(jz4740_wdt_driver); 221f865c35224bb310a1b464062ae1e946d261708e3Paul Cercueil 222f865c35224bb310a1b464062ae1e946d261708e3Paul CercueilMODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); 223f865c35224bb310a1b464062ae1e946d261708e3Paul CercueilMODULE_DESCRIPTION("jz4740 Watchdog Driver"); 224f865c35224bb310a1b464062ae1e946d261708e3Paul CercueilMODULE_LICENSE("GPL"); 225f865c35224bb310a1b464062ae1e946d261708e3Paul CercueilMODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 226f865c35224bb310a1b464062ae1e946d261708e3Paul CercueilMODULE_ALIAS("platform:jz4740-wdt"); 227