summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-12-08 08:28:41 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2015-12-08 08:28:41 +0100
commit9fdf56c8d47d1084fef065f2a234a9b42c694279 (patch)
tree578156bbfb3cdf2508b80c6fa1ba7efd79507c6f
parent31860b483182e06201000aabb35348dbe5011b3e (diff)
parent353065f934aad90adb6412ce9a8bbdd528ebc048 (diff)
downloadbarebox-9fdf56c8d47d1084fef065f2a234a9b42c694279.tar.gz
barebox-9fdf56c8d47d1084fef065f2a234a9b42c694279.tar.xz
Merge branch 'for-next/omap'
-rw-r--r--arch/arm/mach-omap/omap_generic.c21
-rw-r--r--common/filetype.c31
-rw-r--r--drivers/watchdog/Kconfig6
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/omap_wdt.c199
5 files changed, 213 insertions, 45 deletions
diff --git a/arch/arm/mach-omap/omap_generic.c b/arch/arm/mach-omap/omap_generic.c
index 071a1bfced..4e26c6ba0b 100644
--- a/arch/arm/mach-omap/omap_generic.c
+++ b/arch/arm/mach-omap/omap_generic.c
@@ -111,7 +111,6 @@ const char *omap_get_bootmmc_devname(void)
#define ENV_PATH "/boot/barebox.env"
static int omap_env_init(void)
{
- struct stat s;
char *partname;
const char *diskdev;
int ret;
@@ -128,25 +127,19 @@ static int omap_env_init(void)
partname = asprintf("/dev/%s.0", diskdev);
- ret = stat(partname, &s);
-
- free(partname);
-
- if (ret) {
- pr_err("Failed to load environment: no device '%s'\n", diskdev);
- return 0;
- }
-
mkdir("/boot", 0666);
- ret = mount(diskdev, "fat", "/boot", NULL);
+ ret = mount(partname, "fat", "/boot", NULL);
if (ret) {
- pr_err("Failed to load environment: mount %s failed (%d)\n", diskdev, ret);
- return 0;
+ pr_err("Failed to load environment: mount %s failed (%d)\n", partname, ret);
+ goto out;
}
- pr_debug("Loading default env from %s on device %s\n", ENV_PATH, diskdev);
+ pr_debug("Loading default env from %s on device %s\n", ENV_PATH, partname);
default_environment_path_set(ENV_PATH);
+out:
+ free(partname);
+
return 0;
}
late_initcall(omap_env_init);
diff --git a/common/filetype.c b/common/filetype.c
index 9ec8ebf7c2..8cfae88aeb 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -326,7 +326,6 @@ enum filetype file_name_detect_type(const char *filename)
int fd, ret;
void *buf;
enum filetype type = filetype_unknown;
- unsigned long bootsec;
fd = open(filename, O_RDONLY);
if (fd < 0)
@@ -340,21 +339,6 @@ enum filetype file_name_detect_type(const char *filename)
type = file_detect_type(buf, ret);
- if (type == filetype_mbr) {
- /*
- * Get the first partition start sector
- * and check for FAT in it
- */
- is_fat_or_mbr(buf, &bootsec);
- ret = lseek(fd, (bootsec) * 512, SEEK_SET);
- if (ret < 0)
- goto err_out;
- ret = read(fd, buf, 512);
- if (ret < 0)
- goto err_out;
- type = is_fat_or_mbr((u8 *)buf, NULL);
- }
-
err_out:
close(fd);
free(buf);
@@ -380,21 +364,6 @@ enum filetype cdev_detect_type(const char *name)
type = file_detect_type(buf, ret);
- if (type == filetype_mbr) {
- unsigned long bootsec;
- /*
- * Get the first partition start sector
- * and check for FAT in it
- */
- is_fat_or_mbr(buf, &bootsec);
-
- ret = cdev_read(cdev, buf, 512, bootsec * 512, 0);
- if (ret < 0)
- goto err_out;
-
- type = is_fat_or_mbr((u8 *)buf, NULL);
- }
-
err_out:
free(buf);
cdev_close(cdev);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 582c6154e4..60a56bf4b0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -34,4 +34,10 @@ config WATCHDOG_JZ4740
help
Hardware driver for the built-in watchdog timer on Ingenic jz4740 SoCs.
+config WATCHDOG_OMAP
+ bool "TI OMAP"
+ depends on ARCH_OMAP
+ help
+ Add support for watchdog on the TI OMAP SoC.
+
endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 1e63c493fe..e3afe1c27e 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_WATCHDOG) += wd_core.o
obj-$(CONFIG_WATCHDOG_DAVINCI) += davinci_wdt.o
+obj-$(CONFIG_WATCHDOG_OMAP) += omap_wdt.o
obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
obj-$(CONFIG_WATCHDOG_JZ4740) += jz4740.o
obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
new file mode 100644
index 0000000000..06301b3b9e
--- /dev/null
+++ b/drivers/watchdog/omap_wdt.c
@@ -0,0 +1,199 @@
+/*
+ * omap_wdt.c
+ *
+ * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
+ *
+ * Copyright (c) 2015 Phytec Messtechnik GmbH
+ * Author: Teresa Remmet <t.remmet@phytec.de>
+ *
+ * Based on Linux Kernel OMAP WTD driver:
+ *
+ * Author: MontaVista Software, Inc.
+ * <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * 2003 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * History:
+ *
+ * 20030527: George G. Davis <gdavis@mvista.com>
+ * Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ * Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * Copyright (c) 2004 Texas Instruments.
+ * 1. Modified to support OMAP1610 32-KHz watchdog timer
+ * 2. Ported to 2.6 kernel
+ *
+ * Copyright (c) 2005 David Brownell
+ * Use the driver model and standard identifiers; handle bigger timeouts.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <errno.h>
+#include <malloc.h>
+#include <watchdog.h>
+
+#define OMAP_WATCHDOG_REV (0x00)
+#define OMAP_WATCHDOG_SYS_CONFIG (0x10)
+#define OMAP_WATCHDOG_STATUS (0x14)
+#define OMAP_WATCHDOG_CNTRL (0x24)
+#define OMAP_WATCHDOG_CRR (0x28)
+#define OMAP_WATCHDOG_LDR (0x2c)
+#define OMAP_WATCHDOG_TGR (0x30)
+#define OMAP_WATCHDOG_WPS (0x34)
+#define OMAP_WATCHDOG_SPR (0x48)
+
+#define TIMER_MARGIN_DEFAULT 60 /* 60 secs */
+
+#define PTV 0 /* prescale */
+#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+#define GET_WCCR_SECS(val) ((0xffffffff - (val) + 1) / (32768/(1<<PTV)))
+
+#define to_omap_wdt_dev(_wdog) container_of(_wdog, struct omap_wdt_dev, wdog)
+
+struct omap_wdt_dev {
+ struct watchdog wdog;
+ void __iomem *base;
+ int wdt_trgr_pattern;
+ unsigned timeout;
+};
+
+static void omap_wdt_reload(struct omap_wdt_dev *wdev)
+{
+ void __iomem *base = wdev->base;
+
+ /* wait for posted write to complete */
+ while ((readl(base + OMAP_WATCHDOG_WPS)) & 0x08);
+
+ wdev->wdt_trgr_pattern = ~wdev->wdt_trgr_pattern;
+ writel(wdev->wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
+
+ /* wait for posted write to complete */
+ while ((readl(base + OMAP_WATCHDOG_WPS)) & 0x08);
+ /* reloaded WCRR from WLDR */
+}
+
+static void omap_wdt_enable(struct omap_wdt_dev *wdev)
+{
+ void __iomem *base = wdev->base;
+
+ /* Sequence to enable the watchdog */
+ writel(0xBBBB, base + OMAP_WATCHDOG_SPR);
+ while ((readl(base + OMAP_WATCHDOG_WPS)) & 0x10);
+
+ writel(0x4444, base + OMAP_WATCHDOG_SPR);
+ while ((readl(base + OMAP_WATCHDOG_WPS)) & 0x10);
+}
+
+static void omap_wdt_disable(struct omap_wdt_dev *wdev)
+{
+ void __iomem *base = wdev->base;
+
+ /* sequence required to disable watchdog */
+ writel(0xAAAA, base + OMAP_WATCHDOG_SPR); /* TIMER_MODE */
+ while (readl(base + OMAP_WATCHDOG_WPS) & 0x10);
+
+ writel(0x5555, base + OMAP_WATCHDOG_SPR); /* TIMER_MODE */
+ while (readl(base + OMAP_WATCHDOG_WPS) & 0x10);
+}
+
+static void omap_wdt_set_timer(struct omap_wdt_dev *wdev,
+ unsigned int timeout)
+{
+ u32 pre_margin = GET_WLDR_VAL(timeout);
+ void __iomem *base = wdev->base;
+
+ /* just count up at 32 KHz */
+ while (readl(base + OMAP_WATCHDOG_WPS) & 0x04);
+
+ writel(pre_margin, base + OMAP_WATCHDOG_LDR);
+ while (readl(base + OMAP_WATCHDOG_WPS) & 0x04);
+
+}
+
+static void omap_wdt_init(struct omap_wdt_dev *wdev)
+{
+ void __iomem *base = wdev->base;
+
+ /*
+ * Make sure the watchdog is disabled. This is unfortunately required
+ * because writing to various registers with the watchdog running has no
+ * effect.
+ */
+ omap_wdt_disable(wdev);
+
+ /* initialize prescaler */
+ while (readl(base + OMAP_WATCHDOG_WPS) & 0x01);
+
+ writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
+ while (readl(base + OMAP_WATCHDOG_WPS) & 0x01);
+
+ omap_wdt_set_timer(wdev, wdev->timeout);
+ omap_wdt_reload(wdev); /* trigger loading of new timeout value */
+}
+
+static int omap_wdt_set_timeout(struct watchdog *wdog,
+ unsigned int timeout)
+{
+ struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog);
+
+ omap_wdt_disable(wdev);
+ omap_wdt_set_timer(wdev, timeout);
+ omap_wdt_enable(wdev);
+ omap_wdt_reload(wdev);
+ wdev->timeout = timeout;
+
+ return 0;
+}
+
+static int omap_wdt_probe(struct device_d *dev)
+{
+ struct omap_wdt_dev *wdev;
+ int ret;
+
+ wdev = xzalloc(sizeof(*wdev));
+ wdev->wdog.set_timeout = omap_wdt_set_timeout;
+ wdev->wdt_trgr_pattern = 0x1234;
+
+ /* reserve static register mappings */
+ wdev->base = dev_request_mem_region(dev, 0);
+ if (IS_ERR(wdev->base)) {
+ ret = PTR_ERR(wdev->base);
+ goto error;
+ }
+
+ wdev->timeout = TIMER_MARGIN_DEFAULT;
+
+ ret = watchdog_register(&wdev->wdog);
+ if (ret)
+ goto error;
+
+ dev_info(dev, "OMAP Watchdog Timer Rev 0x%02x\n",
+ readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF);
+
+ omap_wdt_init(wdev);
+
+ return 0;
+
+error:
+ free(wdev);
+ return ret;
+}
+
+static const struct of_device_id omap_wdt_of_match[] = {
+ { .compatible = "ti,omap3-wdt", },
+ {},
+};
+
+static struct driver_d omap_wdt_driver = {
+ .probe = omap_wdt_probe,
+ .name = "omap_wdt",
+ .of_compatible = DRV_OF_COMPAT(omap_wdt_of_match),
+};
+device_platform_driver(omap_wdt_driver);