aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/db8500-prcmu.c
diff options
context:
space:
mode:
authorJonas Aberg <jonas.aberg@stericsson.com>2011-08-12 04:28:33 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-10-24 08:09:18 -0400
commit84165b805972320050892e34fa28d09fe86a25eb (patch)
treedaa6a0cbbef2d7677469eb40bb82dbfef7a8d3d5 /drivers/mfd/db8500-prcmu.c
parent0b9199e3186e1998a8e066fbcf15bcf18cdbfc42 (diff)
mfd: Add db8500-pcmu watchdog accessor functions for watchdog
This implements the watchdog accessor functions for the DB8500 PRCMU, making it possible to implement the watchdog driver. Signed-off-by: Jonas Aberg <jonas.aberg@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r--drivers/mfd/db8500-prcmu.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 28a60906f5f7..95498f80c905 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -1543,6 +1543,78 @@ int prcmu_stop_temp_sense(void)
1543 return config_hot_period(0xFFFF); 1543 return config_hot_period(0xFFFF);
1544} 1544}
1545 1545
1546static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)
1547{
1548
1549 mutex_lock(&mb4_transfer.lock);
1550
1551 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
1552 cpu_relax();
1553
1554 writeb(d0, (tcdm_base + PRCM_REQ_MB4_A9WDOG_0));
1555 writeb(d1, (tcdm_base + PRCM_REQ_MB4_A9WDOG_1));
1556 writeb(d2, (tcdm_base + PRCM_REQ_MB4_A9WDOG_2));
1557 writeb(d3, (tcdm_base + PRCM_REQ_MB4_A9WDOG_3));
1558
1559 writeb(cmd, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
1560
1561 writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);
1562 wait_for_completion(&mb4_transfer.work);
1563
1564 mutex_unlock(&mb4_transfer.lock);
1565
1566 return 0;
1567
1568}
1569
1570int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
1571{
1572 BUG_ON(num == 0 || num > 0xf);
1573 return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0,
1574 sleep_auto_off ? A9WDOG_AUTO_OFF_EN :
1575 A9WDOG_AUTO_OFF_DIS);
1576}
1577
1578int prcmu_enable_a9wdog(u8 id)
1579{
1580 return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0);
1581}
1582
1583int prcmu_disable_a9wdog(u8 id)
1584{
1585 return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0);
1586}
1587
1588int prcmu_kick_a9wdog(u8 id)
1589{
1590 return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0);
1591}
1592
1593/*
1594 * timeout is 28 bit, in ms.
1595 */
1596#define MAX_WATCHDOG_TIMEOUT 131000
1597int prcmu_load_a9wdog(u8 id, u32 timeout)
1598{
1599 if (timeout > MAX_WATCHDOG_TIMEOUT)
1600 /*
1601 * Due to calculation bug in prcmu fw, timeouts
1602 * can't be bigger than 131 seconds.
1603 */
1604 return -EINVAL;
1605
1606 return prcmu_a9wdog(MB4H_A9WDOG_LOAD,
1607 (id & A9WDOG_ID_MASK) |
1608 /*
1609 * Put the lowest 28 bits of timeout at
1610 * offset 4. Four first bits are used for id.
1611 */
1612 (u8)((timeout << 4) & 0xf0),
1613 (u8)((timeout >> 4) & 0xff),
1614 (u8)((timeout >> 12) & 0xff),
1615 (u8)((timeout >> 20) & 0xff));
1616}
1617
1546/** 1618/**
1547 * prcmu_set_clock_divider() - Configure the clock divider. 1619 * prcmu_set_clock_divider() - Configure the clock divider.
1548 * @clock: The clock for which the request is made. 1620 * @clock: The clock for which the request is made.