From 99c9da2817ba1bcc3d33782e68ec6ceeeb2c4545 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 10 Nov 2015 08:58:16 +0100 Subject: ARM: omap: Use correct device to mount on /boot The current code tests if a partition (i.e. disk0.0) exists and instead of mounting boot from this partition it uses the whole device (disk0). This only works because the the FAT code accepts a MBR as input and automatically skips it. Let the code use the partition to mount /boot instead as it was intended. We don't have to stat() the partition device, since this error will be caught by mount() anyway, so remove the unnecessary stat(). Reported-by: Peter Mamonov Signed-off-by: Sascha Hauer --- arch/arm/mach-omap/omap_generic.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 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); -- cgit v1.2.3 From bc87f4399c6a290d820f2dd00ef772f0f3ef8767 Mon Sep 17 00:00:00 2001 From: Peter Mamonov Date: Mon, 9 Nov 2015 13:32:51 +0300 Subject: common: filetype: do not redetect MBR-type devices as a FAT-type Deleted pieces of code detect MBR-containig device as a FAT-type device, if it's first partition contains a FAT filesystem. This behaviour enabled one to mount the FAT FS which is either directly on the device (disk0) or on the first partition (disk0.0) using the same command: mount /dev/disk0 /fat However, the desired behaviour can be reached with a: mount /dev/disk0 /fat || mount /dev/disk0.0 /fat || echo "Mounting failed" Signed-off-by: Peter Mamonov Signed-off-by: Sascha Hauer --- common/filetype.c | 31 ------------------------------- 1 file changed, 31 deletions(-) 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); -- cgit v1.2.3 From 353065f934aad90adb6412ce9a8bbdd528ebc048 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 11 Nov 2015 08:49:16 +0100 Subject: driver: watchdog: Add support for omap_wdt Add support for OMAP Watchdog driver. Based on omap_wdt Linux driver (v4.3-rc1). Signed-off-by: Teresa Remmet Signed-off-by: Sascha Hauer --- drivers/watchdog/Kconfig | 6 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/omap_wdt.c | 199 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 drivers/watchdog/omap_wdt.c 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 + * + * Based on Linux Kernel OMAP WTD driver: + * + * Author: MontaVista Software, Inc. + * or + * + * 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 + * Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c + * (c) Copyright 2000 Oleg Drokin + * Based on SoftDog driver by Alan Cox + * + * 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 +#include +#include +#include +#include +#include +#include + +#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<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); -- cgit v1.2.3