summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/disk_ata_drive.c3
-rw-r--r--drivers/ata/ide-sff.c54
-rw-r--r--drivers/clk/clk-fixed-factor.c2
-rw-r--r--drivers/clk/clk-fixed.c2
-rw-r--r--drivers/clocksource/mvebu.c2
-rw-r--r--drivers/net/phy/mdio-gpio.c2
-rw-r--r--drivers/usb/gadget/Kconfig11
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/autostart.c70
-rw-r--r--drivers/video/edid.c2
-rw-r--r--drivers/watchdog/Kconfig6
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/orion_wdt.c123
13 files changed, 261 insertions, 18 deletions
diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
index 1aa1bb1456..5ebddbdec8 100644
--- a/drivers/ata/disk_ata_drive.c
+++ b/drivers/ata/disk_ata_drive.c
@@ -237,6 +237,9 @@ static int ata_port_init(struct ata_port *port)
#ifdef DEBUG
ata_dump_id(port->id);
#endif
+
+ port->lba48 = ata_id_has_lba48(port->id);
+
if (port->devname) {
port->blk.cdev.name = xstrdup(port->devname);
} else {
diff --git a/drivers/ata/ide-sff.c b/drivers/ata/ide-sff.c
index 6dc89d79a5..b7c8847266 100644
--- a/drivers/ata/ide-sff.c
+++ b/drivers/ata/ide-sff.c
@@ -136,17 +136,33 @@ static int ata_wait_ready(struct ide_port *ide, unsigned timeout)
* @param io Register file
* @param drive 0 master drive, 1 slave drive
* @param num Sector number
- *
- * @todo LBA48 support
*/
-static int ata_set_lba_sector(struct ide_port *ide, unsigned drive, uint64_t num)
+static int ata_set_lba_sector(struct ata_port *port, unsigned drive,
+ uint64_t num)
{
- if (num > 0x0FFFFFFF || drive > 1)
+ struct ide_port *ide = to_ata_drive_access(port);
+
+ if (drive > 1)
return -EINVAL;
- ata_wr_byte(ide, 0xA0 | LBA_FLAG | drive << 4 | num >> 24,
- ide->io.device_addr);
- ata_wr_byte(ide, 0x00, ide->io.error_addr);
+ if (port->lba48) {
+ if (num > (1ULL << 48) - 1)
+ return -EINVAL;
+
+ ata_wr_byte(ide, LBA_FLAG | drive << 4, ide->io.device_addr);
+
+ ata_wr_byte(ide, 0x00, ide->io.nsect_addr);
+ ata_wr_byte(ide, num >> 24, ide->io.lbal_addr);
+ ata_wr_byte(ide, num >> 32, ide->io.lbam_addr);
+ ata_wr_byte(ide, num >> 40, ide->io.lbah_addr);
+ } else {
+ if (num > (1ULL << 28) - 1)
+ return -EINVAL;
+
+ ata_wr_byte(ide, 0xA0 | LBA_FLAG | drive << 4 | num >> 24,
+ ide->io.device_addr);
+ }
+
ata_wr_byte(ide, 0x01, ide->io.nsect_addr);
ata_wr_byte(ide, num, ide->io.lbal_addr); /* 0 ... 7 */
ata_wr_byte(ide, num >> 8, ide->io.lbam_addr); /* 8 ... 15 */
@@ -316,10 +332,18 @@ static int ide_read(struct ata_port *port, void *buffer, unsigned int block,
struct ide_port *ide = to_ata_drive_access(port);
while (num_blocks) {
- rc = ata_set_lba_sector(ide, DISK_MASTER, sector);
+ uint8_t cmd;
+
+ rc = ata_set_lba_sector(port, DISK_MASTER, sector);
if (rc != 0)
return rc;
- rc = ata_wr_cmd(ide, ATA_CMD_READ);
+
+ if (port->lba48)
+ cmd = ATA_CMD_PIO_READ_EXT;
+ else
+ cmd = ATA_CMD_READ;
+
+ rc = ata_wr_cmd(ide, cmd);
if (rc != 0)
return rc;
rc = ata_wait_ready(ide, MAX_TIMEOUT);
@@ -355,10 +379,18 @@ static int __maybe_unused ide_write(struct ata_port *port,
struct ide_port *ide = to_ata_drive_access(port);
while (num_blocks) {
- rc = ata_set_lba_sector(ide, DISK_MASTER, sector);
+ uint8_t cmd;
+
+ rc = ata_set_lba_sector(port, DISK_MASTER, sector);
if (rc != 0)
return rc;
- rc = ata_wr_cmd(ide, ATA_CMD_WRITE);
+
+ if (port->lba48)
+ cmd = ATA_CMD_PIO_WRITE_EXT;
+ else
+ cmd = ATA_CMD_WRITE;
+
+ rc = ata_wr_cmd(ide, cmd);
if (rc != 0)
return rc;
rc = ata_wait_ready(ide, MAX_TIMEOUT);
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a3dbf334a8..0be48558e6 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -93,7 +93,6 @@ struct clk *clk_fixed_factor(const char *name,
return &f->clk;
}
-#if defined(CONFIG_COMMON_CLK_OF_PROVIDER)
/**
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
*/
@@ -127,4 +126,3 @@ static int of_fixed_factor_clk_setup(struct device_node *node)
}
CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock",
of_fixed_factor_clk_setup);
-#endif
diff --git a/drivers/clk/clk-fixed.c b/drivers/clk/clk-fixed.c
index f0f7fbaed5..57bf36b39e 100644
--- a/drivers/clk/clk-fixed.c
+++ b/drivers/clk/clk-fixed.c
@@ -55,7 +55,6 @@ struct clk *clk_fixed(const char *name, int rate)
return &fix->clk;
}
-#if defined(CONFIG_COMMON_CLK_OF_PROVIDER)
/**
* of_fixed_clk_setup() - Setup function for simple fixed rate clock
*/
@@ -76,4 +75,3 @@ static int of_fixed_clk_setup(struct device_node *node)
return of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
-#endif
diff --git a/drivers/clocksource/mvebu.c b/drivers/clocksource/mvebu.c
index cf80571263..59bbc4be22 100644
--- a/drivers/clocksource/mvebu.c
+++ b/drivers/clocksource/mvebu.c
@@ -60,7 +60,7 @@ static int mvebu_timer_probe(struct device_d *dev)
struct clk *clk;
u32 rate, div, val;
- iores = dev_request_mem_resource(dev, 0);
+ iores = dev_get_resource(dev, IORESOURCE_MEM, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
timer_base = IOMEM(iores->start);
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index a839f2dee8..a846fb28e2 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -45,7 +45,7 @@ struct mdio_gpio_info {
int mdc_active_low, mdio_active_low, mdo_active_low;
};
-struct mdio_gpio_info *mdio_gpio_of_get_info(struct device_d *dev)
+static struct mdio_gpio_info *mdio_gpio_of_get_info(struct device_d *dev)
{
int ret;
enum of_gpio_flags flags;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index eb279ae8df..4292371f09 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -30,6 +30,17 @@ config USB_GADGET_DRIVER_PXA27X
default y
select USB_GADGET_DUALSPEED
+config USB_GADGET_AUTOSTART
+ bool
+ default y
+ select ENVIRONMENT_VARIABLES
+ select FILE_LIST
+ prompt "Automatically start usbgadget on boot"
+ help
+ Enabling this option allows to automatically start a fastboot
+ gadget during boot. This behaviour is controlled with the
+ global.usbgadget.fastboot_function variable.
+
comment "USB Gadget drivers"
config USB_GADGET_DFU
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 9ef594575b..e74cf02664 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_USB_GADGET) += composite.o config.o usbstring.o epautoconf.o udc-core.o functions.o config.o multi.o
+obj-$(CONFIG_USB_GADGET_AUTOSTART) += autostart.o
obj-$(CONFIG_USB_GADGET_SERIAL) += u_serial.o serial.o f_serial.o f_acm.o
obj-$(CONFIG_USB_GADGET_DFU) += dfu.o
obj-$(CONFIG_USB_GADGET_FASTBOOT) += f_fastboot.o
diff --git a/drivers/usb/gadget/autostart.c b/drivers/usb/gadget/autostart.c
new file mode 100644
index 0000000000..4ad1dd6be1
--- /dev/null
+++ b/drivers/usb/gadget/autostart.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 Oleksij Rempel <o.rempel@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+#include <environment.h>
+#include <malloc.h>
+#include <getopt.h>
+#include <fs.h>
+#include <xfuncs.h>
+#include <usb/usbserial.h>
+#include <usb/dfu.h>
+#include <usb/gadget-multi.h>
+#include <globalvar.h>
+#include <magicvar.h>
+
+static int autostart;
+static int acm;
+static char *fastboot_function;
+
+static int usbgadget_autostart(void)
+{
+ struct f_multi_opts opts = {};
+
+ if (!autostart)
+ return 0;
+
+ setenv("otg.mode", "peripheral");
+
+ if (fastboot_function)
+ opts.fastboot_opts.files = file_list_parse(fastboot_function);
+
+ opts.create_acm = acm;
+
+ return usb_multi_register(&opts);
+}
+postenvironment_initcall(usbgadget_autostart);
+
+static int usbgadget_globalvars_init(void)
+{
+
+ globalvar_add_simple_bool("usbgadget.autostart", &autostart);
+ globalvar_add_simple_bool("usbgadget.acm", &acm);
+ globalvar_add_simple_string("usbgadget.fastboot_function",
+ &fastboot_function);
+
+ return 0;
+}
+device_initcall(usbgadget_globalvars_init);
+
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_autostart,
+ global.usbgadget.autostart,
+ "usbgadget: Automatically start usbgadget on boot");
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_acm,
+ global.usbgadget.acm,
+ "usbgadget: Create CDC ACM function");
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_fastboot_function,
+ global.usbgadget.fastboot_function,
+ "usbgadget: Create Android Fastboot function");
diff --git a/drivers/video/edid.c b/drivers/video/edid.c
index 258526433e..bee4594118 100644
--- a/drivers/video/edid.c
+++ b/drivers/video/edid.c
@@ -387,7 +387,7 @@ static void fb_timings_vfreq(struct __fb_timings *timings)
* REQUIRES:
* A valid info->monspecs, otherwise 'safe numbers' will be used.
*/
-int fb_get_mode(int flags, u32 val, struct fb_videomode *var)
+static int fb_get_mode(int flags, u32 val, struct fb_videomode *var)
{
struct __fb_timings *timings;
u32 interlace = 1, dscan = 1;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 63fb1a8c57..83b6528a5f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -46,4 +46,10 @@ config WATCHDOG_OMAP
help
Add support for watchdog on the TI OMAP SoC.
+config WATCHDOG_ORION
+ bool "Watchdog for Armada XP"
+ depends on ARCH_ARMADA_XP
+ help
+ Add support for watchdog on the Marvall Armada XP
+
endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5fca4c368c..a3b26675ce 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
obj-$(CONFIG_WATCHDOG_DW) += dw_wdt.o
obj-$(CONFIG_WATCHDOG_JZ4740) += jz4740.o
obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o
+obj-$(CONFIG_WATCHDOG_ORION) += orion_wdt.o
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
new file mode 100644
index 0000000000..2802033f71
--- /dev/null
+++ b/drivers/watchdog/orion_wdt.c
@@ -0,0 +1,123 @@
+/*
+ * Watchdog driver for Marvell Armada XP.
+ *
+ * Copyright (C) 2017 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <init.h>
+#include <io.h>
+#include <malloc.h>
+#include <of.h>
+#include <watchdog.h>
+
+#define CLKRATE 25000000
+
+/* registers relative to timer_base (i.e. first reg property) */
+#define TIMER_CTRL 0x00
+#define TIMER_CTRL_WD_TIMER_25MHZ_EN BIT(10)
+#define TIMER_CTRL_WD_TIMER_EN BIT(8)
+
+#define TIMER_STATUS 0x04
+#define TIMER_STATUS_WD_EXPIRED BIT(31)
+
+#define TIMER_WD_TIMER 0x34
+
+/* registers relative to rstout_base (i.e. second reg property) */
+#define WD_RSTOUTn_MASK 0x00
+#define WD_RSTOUTn_MASK_GLOBAL_WD BIT(8)
+
+struct orion_wdt_ddata {
+ struct watchdog wd;
+ void __iomem *timer_base;
+ void __iomem *rstout_base;
+};
+
+static int armada_xp_set_timeout(struct watchdog *wd, unsigned timeout)
+{
+ struct orion_wdt_ddata *ddata =
+ container_of(wd, struct orion_wdt_ddata, wd);
+ u32 ctrl;
+
+ if (0xffffffff / CLKRATE < timeout)
+ return -EINVAL;
+
+ ctrl = readl(ddata->timer_base + TIMER_CTRL);
+
+ if (timeout == 0) {
+ /* disable timer */
+ ctrl &= ~TIMER_CTRL_WD_TIMER_EN;
+ writel(ctrl, ddata->timer_base + TIMER_CTRL);
+
+ return 0;
+ }
+
+ /* setup duration */
+ writel(CLKRATE * timeout, ddata->timer_base + TIMER_WD_TIMER);
+
+ /* clear expiration status */
+ writel(readl(ddata->timer_base + TIMER_STATUS) & ~TIMER_STATUS_WD_EXPIRED,
+ ddata->timer_base + TIMER_STATUS);
+
+ /* assert reset on expiration */
+ writel(WD_RSTOUTn_MASK_GLOBAL_WD, ddata->rstout_base + WD_RSTOUTn_MASK);
+
+ /* enable */
+ ctrl |= TIMER_CTRL_WD_TIMER_25MHZ_EN | TIMER_CTRL_WD_TIMER_EN;
+ writel(ctrl, ddata->timer_base + TIMER_CTRL);
+
+ return 0;
+}
+
+static int orion_wdt_probe(struct device_d *dev)
+{
+ struct orion_wdt_ddata* ddata;
+ struct resource *res_timer, *res_rstout;
+
+ ddata = xzalloc(sizeof(*ddata));
+
+ ddata->wd.set_timeout = armada_xp_set_timeout;
+ ddata->wd.name = "orion_wdt";
+ ddata->wd.dev = dev;
+
+ res_timer = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(res_timer)) {
+ dev_err(dev, "could not get timer memory region\n");
+ return PTR_ERR(res_timer);
+ }
+ ddata->timer_base = IOMEM(res_timer->start);
+
+ res_rstout = dev_request_mem_resource(dev, 1);
+ if (IS_ERR(res_rstout)) {
+ dev_err(dev, "could not get rstout memory region\n");
+ release_region(res_timer);
+
+ return PTR_ERR(res_rstout);
+ }
+ ddata->rstout_base = IOMEM(res_rstout->start);
+
+ return watchdog_register(&ddata->wd);
+}
+
+static const struct of_device_id orion_wdt_of_match[] = {
+ {
+ .compatible = "marvell,armada-xp-wdt",
+ }, { /* sentinel */ }
+};
+
+static struct driver_d orion_wdt_driver = {
+ .probe = orion_wdt_probe,
+ .name = "orion_wdt",
+ .of_compatible = DRV_OF_COMPAT(orion_wdt_of_match),
+};
+device_platform_driver(orion_wdt_driver);