summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-04-26 20:50:00 +0300
committerTom Rini <trini@konsulko.com>2019-04-26 20:50:00 +0300
commit07b68b7843ad1fa15d63dcd26b5ca5a053fcc27f (patch)
treef9b57804a3f3c57efcb5a17c836396b3b04dbf5f /drivers
parent1c64692df20c1f491ea79de3a732428611bb0ba0 (diff)
parentb684d4031b38b6b6a9e22676c7c6e2770e767cc7 (diff)
downloadu-boot-07b68b7843ad1fa15d63dcd26b5ca5a053fcc27f.tar.xz
Merge git://git.denx.de/u-boot-marvell
- Add DM based generic watchdog start and reset implementation and remove all ad-hoc implementations (Stefan) - Move mv_sdhci to DM (Pierre) - Misc turris_omnia updates (Pierre) - Change openrd targets to correctly build again (size changes and fixes to the dts targets) and bring it back into Travis builds (Stefan) - Add Kirkwood db-88f6281-bp board (Chris)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/mv_sdhci.c67
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/at91sam9_wdt.c8
-rw-r--r--drivers/watchdog/cdns_wdt.c15
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c4
-rw-r--r--drivers/watchdog/wdt-uclass.c26
7 files changed, 101 insertions, 23 deletions
diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c
index de4ae0a0e7..bf26d2e4e2 100644
--- a/drivers/mmc/mv_sdhci.c
+++ b/drivers/mmc/mv_sdhci.c
@@ -4,10 +4,13 @@
*/
#include <common.h>
+#include <dm.h>
#include <malloc.h>
#include <sdhci.h>
#include <linux/mbus.h>
+#define MVSDH_NAME "mv_sdh"
+
#define SDHCI_WINDOW_CTRL(win) (0x4080 + ((win) << 4))
#define SDHCI_WINDOW_BASE(win) (0x4084 + ((win) << 4))
@@ -36,6 +39,8 @@ static void sdhci_mvebu_mbus_config(void __iomem *base)
}
}
+#ifndef CONFIG_DM_MMC
+
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
static struct sdhci_ops mv_ops;
@@ -63,7 +68,6 @@ static inline void mv_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
#endif /* CONFIG_SHEEVA_88SV331xV5 */
#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
-static char *MVSDH_NAME = "mv_sdh";
int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks)
{
struct sdhci_host *host = NULL;
@@ -90,3 +94,64 @@ int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks)
return add_sdhci(host, 0, min_clk);
}
+
+#else
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mv_sdhci_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+static int mv_sdhci_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct mv_sdhci_plat *plat = dev_get_platdata(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+ int ret;
+
+ host->name = MVSDH_NAME;
+ host->ioaddr = (void *)devfdt_get_addr(dev);
+ host->quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD;
+
+ ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
+ if (ret)
+ return ret;
+
+ if (CONFIG_IS_ENABLED(ARCH_MVEBU)) {
+ /* Configure SDHCI MBUS mbus bridge windows */
+ sdhci_mvebu_mbus_config(host->ioaddr);
+ }
+
+ host->mmc = &plat->mmc;
+ host->mmc->dev = dev;
+ host->mmc->priv = host;
+ upriv->mmc = host->mmc;
+
+ return sdhci_probe(dev);
+}
+
+static int mv_sdhci_bind(struct udevice *dev)
+{
+ struct mv_sdhci_plat *plat = dev_get_platdata(dev);
+
+ return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id mv_sdhci_ids[] = {
+ { .compatible = "marvell,armada-380-sdhci" },
+ { }
+};
+
+U_BOOT_DRIVER(mv_sdhci_drv) = {
+ .name = MVSDH_NAME,
+ .id = UCLASS_MMC,
+ .of_match = mv_sdhci_ids,
+ .bind = mv_sdhci_bind,
+ .probe = mv_sdhci_probe,
+ .ops = &sdhci_ops,
+ .priv_auto_alloc_size = sizeof(struct sdhci_host),
+ .platdata_auto_alloc_size = sizeof(struct mv_sdhci_plat),
+};
+#endif /* CONFIG_DM_MMC */
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 9d7f503b69..3bce0aa0b8 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -51,6 +51,7 @@ config ULP_WATCHDOG
config WDT
bool "Enable driver model for watchdog timer drivers"
depends on DM
+ imply WATCHDOG
help
Enable driver model for watchdog timer. At the moment the API
is very simple and only supports four operations:
@@ -150,7 +151,6 @@ config WDT_MT7621
config WDT_MPC8xx
bool "MPC8xx watchdog timer support"
depends on WDT && MPC8xx
- select CONFIG_MPC8xx_WATCHDOG
help
Select this to enable mpc8xx watchdog timer
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index d901240ad1..40b2f4bc66 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -24,6 +24,6 @@ obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
obj-$(CONFIG_WDT_ORION) += orion_wdt.o
obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
-obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o
+obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 000769d46d..48433cc158 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -107,14 +107,6 @@ static int at91_wdt_probe(struct udevice *dev)
if (!priv->regs)
return -EINVAL;
-#if CONFIG_IS_ENABLED(OF_CONTROL)
- priv->timeout = dev_read_u32_default(dev, "timeout-sec",
- WDT_DEFAULT_TIMEOUT);
- debug("%s: timeout %d", __func__, priv->timeout);
-#else
- priv->timeout = WDT_DEFAULT_TIMEOUT;
-#endif
-
debug("%s: Probing wdt%u\n", __func__, dev->seq);
return 0;
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c
index fc85fbcec2..6a608b6371 100644
--- a/drivers/watchdog/cdns_wdt.c
+++ b/drivers/watchdog/cdns_wdt.c
@@ -10,6 +10,7 @@
#include <dm.h>
#include <wdt.h>
#include <clk.h>
+#include <div64.h>
#include <linux/io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -23,7 +24,6 @@ struct cdns_regs {
struct cdns_wdt_priv {
bool rst;
- u32 timeout;
struct cdns_regs *regs;
};
@@ -142,10 +142,10 @@ static int cdns_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
return -1;
}
- if ((timeout < CDNS_WDT_MIN_TIMEOUT) ||
- (timeout > CDNS_WDT_MAX_TIMEOUT)) {
- timeout = priv->timeout;
- }
+ /* Calculate timeout in seconds and restrict to min and max value */
+ do_div(timeout, 1000);
+ timeout = max_t(u64, timeout, CDNS_WDT_MIN_TIMEOUT);
+ timeout = min_t(u64, timeout, CDNS_WDT_MAX_TIMEOUT);
debug("%s: CLK_FREQ %ld, timeout %lld\n", __func__, clk_f, timeout);
@@ -235,12 +235,9 @@ static int cdns_wdt_ofdata_to_platdata(struct udevice *dev)
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
- priv->timeout = dev_read_u32_default(dev, "timeout-sec",
- CDNS_WDT_DEFAULT_TIMEOUT);
-
priv->rst = dev_read_bool(dev, "reset-on-timeout");
- debug("%s: timeout %d, reset %d\n", __func__, priv->timeout, priv->rst);
+ debug("%s: reset %d\n", __func__, priv->rst);
return 0;
}
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index c24c2a9da6..675b62d8b3 100644
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
@@ -10,7 +10,7 @@
#include <asm/cpm_8xx.h>
#include <asm/io.h>
-void hw_watchdog_reset(void)
+static void hw_watchdog_reset(void)
{
immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
@@ -18,7 +18,6 @@ void hw_watchdog_reset(void)
out_be16(&immap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */
}
-#ifdef CONFIG_WDT_MPC8xx
static int mpc8xx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
@@ -66,4 +65,3 @@ U_BOOT_DRIVER(wdt_mpc8xx) = {
.of_match = mpc8xx_wdt_ids,
.ops = &mpc8xx_wdt_ops,
};
-#endif /* CONFIG_WDT_MPC8xx */
diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index 23b7e3360d..bbfac4f0f9 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -10,6 +10,8 @@
#include <dm/device-internal.h>
#include <dm/lists.h>
+DECLARE_GLOBAL_DATA_PTR;
+
int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
const struct wdt_ops *ops = device_get_ops(dev);
@@ -63,6 +65,30 @@ int wdt_expire_now(struct udevice *dev, ulong flags)
return ret;
}
+#if defined(CONFIG_WATCHDOG)
+/*
+ * Called by macro WATCHDOG_RESET. This function be called *very* early,
+ * so we need to make sure, that the watchdog driver is ready before using
+ * it in this function.
+ */
+void watchdog_reset(void)
+{
+ static ulong next_reset;
+ ulong now;
+
+ /* Exit if GD is not ready or watchdog is not initialized yet */
+ if (!gd || !(gd->flags & GD_FLG_WDT_READY))
+ return;
+
+ /* Do not reset the watchdog too often */
+ now = get_timer(0);
+ if (now > next_reset) {
+ next_reset = now + 1000; /* reset every 1000ms */
+ wdt_reset(gd->watchdog_dev);
+ }
+}
+#endif
+
static int wdt_post_bind(struct udevice *dev)
{
#if defined(CONFIG_NEEDS_MANUAL_RELOC)