watchdog: Convert Xilinx Axi watchdog driver to driver model

Xilinx Axi wdt driver conversion to driver model & Kconfig update
for the same.

Signed-off-by: Shreenidhi Shedi <yesshedi@gmail.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
Shreenidhi Shedi 2018-07-15 02:05:41 +05:30 committed by Michal Simek
parent 6ec6f5841d
commit e0e9caae6b
2 changed files with 94 additions and 27 deletions

View file

@ -103,4 +103,12 @@ config WDT_CDNS
Select this to enable Cadence watchdog timer, which can be found on some
Xilinx Microzed Platform.
config XILINX_TB_WATCHDOG
bool "Xilinx Axi watchdog timer support"
depends on WDT
imply WATCHDOG
help
Select this to enable Xilinx Axi watchdog timer, which can be found on some
Xilinx Microblaze Platforms.
endmenu

View file

@ -1,13 +1,17 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011-2013 Xilinx Inc.
* Xilinx AXI platforms watchdog timer driver.
*
* Author(s): Michal Simek <michal.simek@xilinx.com>
* Shreenidhi Shedi <yesshedi@gmail.com>
*
* Copyright (c) 2011-2018 Xilinx Inc.
*/
#include <common.h>
#include <asm/io.h>
#include <asm/microblaze_intc.h>
#include <asm/processor.h>
#include <watchdog.h>
#include <dm.h>
#include <wdt.h>
#include <linux/io.h>
#define XWT_CSR0_WRS_MASK 0x00000008 /* Reset status Mask */
#define XWT_CSR0_WDS_MASK 0x00000004 /* Timer state Mask */
@ -20,49 +24,104 @@ struct watchdog_regs {
u32 tbr; /* 0x8 */
};
static struct watchdog_regs *watchdog_base =
(struct watchdog_regs *)CONFIG_WATCHDOG_BASEADDR;
struct xlnx_wdt_platdata {
bool enable_once;
struct watchdog_regs *regs;
};
void hw_watchdog_reset(void)
static int xlnx_wdt_reset(struct udevice *dev)
{
u32 reg;
struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev);
debug("%s ", __func__);
/* Read the current contents of TCSR0 */
reg = readl(&watchdog_base->twcsr0);
reg = readl(&platdata->regs->twcsr0);
/* Clear the watchdog WDS bit */
if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK))
writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0);
writel(reg | XWT_CSR0_WDS_MASK, &platdata->regs->twcsr0);
return 0;
}
void hw_watchdog_disable(void)
static int xlnx_wdt_stop(struct udevice *dev)
{
u32 reg;
struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev);
if (platdata->enable_once) {
debug("Can't stop Xilinx watchdog.\n");
return -EBUSY;
}
/* Read the current contents of TCSR0 */
reg = readl(&watchdog_base->twcsr0);
reg = readl(&platdata->regs->twcsr0);
writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0);
writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1);
writel(reg & ~XWT_CSR0_EWDT1_MASK, &platdata->regs->twcsr0);
writel(~XWT_CSRX_EWDT2_MASK, &platdata->regs->twcsr1);
puts("Watchdog disabled!\n");
debug("Watchdog disabled!\n");
return 0;
}
static void hw_watchdog_isr(void *arg)
static int xlnx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
hw_watchdog_reset();
}
struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev);
void hw_watchdog_init(void)
{
int ret;
debug("%s:\n", __func__);
writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK),
&watchdog_base->twcsr0);
writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1);
&platdata->regs->twcsr0);
ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ,
hw_watchdog_isr, NULL);
if (ret)
puts("Watchdog IRQ registration failed.");
writel(XWT_CSRX_EWDT2_MASK, &platdata->regs->twcsr1);
return 0;
}
static int xlnx_wdt_probe(struct udevice *dev)
{
debug("%s: Probing wdt%u\n", __func__, dev->seq);
return 0;
}
static int xlnx_wdt_ofdata_to_platdata(struct udevice *dev)
{
struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev);
platdata->regs = (struct watchdog_regs *)dev_read_addr(dev);
if (IS_ERR(platdata->regs))
return PTR_ERR(platdata->regs);
platdata->enable_once = dev_read_u32_default(dev,
"xlnx,wdt-enable-once", 0);
debug("%s: wdt-enable-once %d\n", __func__, platdata->enable_once);
return 0;
}
static const struct wdt_ops xlnx_wdt_ops = {
.start = xlnx_wdt_start,
.reset = xlnx_wdt_reset,
.stop = xlnx_wdt_stop,
};
static const struct udevice_id xlnx_wdt_ids[] = {
{ .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
{ .compatible = "xlnx,xps-timebase-wdt-1.01.a", },
{},
};
U_BOOT_DRIVER(xlnx_wdt) = {
.name = "xlnx_wdt",
.id = UCLASS_WDT,
.of_match = xlnx_wdt_ids,
.probe = xlnx_wdt_probe,
.platdata_auto_alloc_size = sizeof(struct xlnx_wdt_platdata),
.ofdata_to_platdata = xlnx_wdt_ofdata_to_platdata,
.ops = &xlnx_wdt_ops,
};