summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/ata/disk_ata_drive.c2
-rw-r--r--drivers/base/driver.c12
-rw-r--r--drivers/base/resource.c14
-rw-r--r--drivers/eeprom/at25.c8
-rw-r--r--drivers/mci/imx-esdhc.c20
-rw-r--r--drivers/mci/imx-esdhc.h1
-rw-r--r--drivers/mfd/lp3972.c2
-rw-r--r--drivers/mfd/mc13xxx.c4
-rw-r--r--drivers/mfd/mc34704.c4
-rw-r--r--drivers/mfd/mc34708.c6
-rw-r--r--drivers/mfd/mc9sdz60.c4
-rw-r--r--drivers/mfd/twl-core.c4
-rw-r--r--drivers/mtd/core.c20
-rw-r--r--drivers/mtd/mtdoob.c3
-rw-r--r--drivers/mtd/mtdraw.c9
-rw-r--r--drivers/mtd/nand/nand-bb.c30
-rw-r--r--drivers/mtd/ubi/cdev.c8
-rw-r--r--drivers/mtd/ubi/ubi-barebox.h1
-rw-r--r--drivers/net/Kconfig16
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/designware.c436
-rw-r--r--drivers/net/designware.h230
-rw-r--r--drivers/net/miidev.c76
-rw-r--r--drivers/net/smc911x.c2
-rw-r--r--drivers/nor/cfi_flash.c18
-rw-r--r--drivers/nor/m25p80.c16
-rw-r--r--drivers/usb/core/usb.c100
-rw-r--r--drivers/usb/gadget/composite.c5
-rw-r--r--drivers/usb/gadget/dfu.c5
-rw-r--r--drivers/usb/gadget/fsl_udc.c7
-rw-r--r--drivers/usb/host/ehci-hcd.c108
-rw-r--r--drivers/usb/host/ehci.h10
-rw-r--r--drivers/usb/host/ohci-at91.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c40
-rw-r--r--drivers/usb/host/ohci.h2
-rw-r--r--drivers/usb/storage/transport.c11
-rw-r--r--drivers/video/fb.c4
-rw-r--r--drivers/watchdog/Kconfig15
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/im28wd.c124
-rw-r--r--drivers/watchdog/wd_core.c57
43 files changed, 1170 insertions, 272 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 037b0d47d9..883b0e7bc9 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -15,7 +15,7 @@ source "drivers/mfd/Kconfig"
source "drivers/led/Kconfig"
source "drivers/eeprom/Kconfig"
source "drivers/input/Kconfig"
-
+source "drivers/watchdog/Kconfig"
source "drivers/pwm/Kconfig"
source "drivers/dma/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index f40b321d3b..ea3263f615 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -16,3 +16,4 @@ obj-y += eeprom/
obj-$(CONFIG_PWM) += pwm/
obj-y += input/
obj-y += dma/
+obj-y += watchdog/
diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
index 4602af3c0d..d5c583790c 100644
--- a/drivers/ata/disk_ata_drive.c
+++ b/drivers/ata/disk_ata_drive.c
@@ -231,7 +231,7 @@ static void __maybe_unused ata_dump_id(uint16_t *id)
*/
static void ata_fix_endianess(uint16_t *buf, unsigned wds)
{
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef __BIG_ENDIAN
unsigned u;
for (u = 0; u < wds; u++)
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 81cedca1db..6cd428681f 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -241,15 +241,15 @@ static struct resource *dev_get_resource(struct device_d *dev, int num)
return NULL;
}
-void __iomem *dev_get_mem_region(struct device_d *dev, int num)
+void *dev_get_mem_region(struct device_d *dev, int num)
{
struct resource *res;
res = dev_get_resource(dev, num);
if (!res)
- return res;
+ return NULL;
- return (void __force __iomem *)res->start;
+ return (void __force *)res->start;
}
EXPORT_SYMBOL(dev_get_mem_region);
@@ -261,7 +261,7 @@ void __iomem *dev_request_mem_region(struct device_d *dev, int num)
if (!res)
return NULL;
- res = request_iomem_region(dev_name(dev), res->start, res->size);
+ res = request_iomem_region(dev_name(dev), res->start, res->end);
if (!res)
return NULL;
@@ -339,7 +339,7 @@ static int do_devinfo_subtree(struct device_d *dev, int depth)
list_for_each_entry(cdev, &dev->cdevs, devices_list) {
for (i = 0; i < depth + 1; i++)
printf(" ");
- printf("`---- 0x%08lx-0x%08lx: /dev/%s\n",
+ printf("`---- 0x%08llx-0x%08llx: /dev/%s\n",
cdev->offset,
cdev->offset + cdev->size - 1,
cdev->name);
@@ -392,7 +392,7 @@ static int do_devinfo(int argc, char *argv[])
printf("name : %s\n", res->name);
printf("start : " PRINTF_CONVERSION_RESOURCE "\nsize : "
PRINTF_CONVERSION_RESOURCE "\n",
- res->start, res->size);
+ res->start, resource_size(res));
}
printf("driver: %s\n\n", dev->driver ?
diff --git a/drivers/base/resource.c b/drivers/base/resource.c
index 347b2f01f0..988d27ea93 100644
--- a/drivers/base/resource.c
+++ b/drivers/base/resource.c
@@ -47,7 +47,7 @@ struct device_d *add_generic_device(const char* devname, int id, const char *res
if (resname)
res[0].name = xstrdup(resname);
res[0].start = start;
- res[0].size = size;
+ res[0].end = start + size - 1;
res[0].flags = flags;
return add_generic_device_res(devname, id, res, 1, pdata);
@@ -94,10 +94,10 @@ struct device_d *add_dm9000_device(int id, resource_size_t base,
}
res[0].start = base;
- res[0].size = size;
+ res[0].end = base + size - 1;
res[0].flags = IORESOURCE_MEM | flags;
res[1].start = data;
- res[1].size = size;
+ res[1].end = data + size - 1;
res[1].flags = IORESOURCE_MEM | flags;
return add_generic_device_res("dm9000", id, res, 2, pdata);
@@ -113,10 +113,10 @@ struct device_d *add_usb_ehci_device(int id, resource_size_t hccr,
res = xzalloc(sizeof(struct resource) * 2);
res[0].start = hccr;
- res[0].size = 0x40;
+ res[0].end = hccr + 0x10 - 1;
res[0].flags = IORESOURCE_MEM;
res[1].start = hcor;
- res[1].size = 0xc0;
+ res[1].end = hcor + 0xc0 - 1;
res[1].flags = IORESOURCE_MEM;
return add_generic_device_res("ehci", id, res, 2, pdata);
@@ -146,10 +146,10 @@ struct device_d *add_ks8851_device(int id, resource_size_t addr,
res = xzalloc(sizeof(struct resource) * 2);
res[0].start = addr;
- res[0].size = size;
+ res[0].end = addr + size - 1;
res[0].flags = IORESOURCE_MEM | flags;
res[1].start = addr_cmd;
- res[1].size = size;
+ res[1].end = addr_cmd + size - 1;
res[1].flags = IORESOURCE_MEM | flags;
return add_generic_device_res("ks8851_mll", id, res, 2, pdata);
diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c
index 8a979d53a1..03d191eb90 100644
--- a/drivers/eeprom/at25.c
+++ b/drivers/eeprom/at25.c
@@ -67,7 +67,7 @@ struct at25_data {
static ssize_t at25_ee_read(struct cdev *cdev,
void *buf,
size_t count,
- ulong offset,
+ loff_t offset,
ulong flags)
{
u8 command[EE_MAXADDRLEN + 1];
@@ -117,7 +117,7 @@ static ssize_t at25_ee_read(struct cdev *cdev,
*/
status = spi_sync(at25->spi, &m);
dev_dbg(at25->cdev.dev,
- "read %d bytes at %lu --> %d\n",
+ "read %d bytes at %llu --> %d\n",
count, offset, (int) status);
return status ? status : count;
@@ -126,7 +126,7 @@ static ssize_t at25_ee_read(struct cdev *cdev,
static ssize_t at25_ee_write(struct cdev *cdev,
const void *buf,
size_t count,
- ulong off,
+ loff_t off,
ulong flags)
{
ssize_t status = 0;
@@ -232,7 +232,7 @@ static ssize_t at25_ee_write(struct cdev *cdev,
return written ? written : status;
}
-static off_t at25_ee_lseek(struct cdev *cdev, off_t off)
+static loff_t at25_ee_lseek(struct cdev *cdev, loff_t off)
{
return off;
}
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index ae3c805997..585cab9e54 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -70,7 +70,7 @@ struct fsl_esdhc {
struct fsl_esdhc_host {
struct mci_host mci;
- struct fsl_esdhc *regs;
+ struct fsl_esdhc __iomem *regs;
u32 no_snoop;
unsigned long cur_clock;
struct device_d *dev;
@@ -81,7 +81,7 @@ struct fsl_esdhc_host {
#define SDHCI_CMD_ABORTCMD (0xC0 << 16)
/* Return the XFERTYP flags for a given command and data packet */
-u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
+static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
{
u32 xfertyp = 0;
@@ -185,7 +185,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc *regs = host->regs;
+ struct fsl_esdhc __iomem *regs = host->regs;
#ifndef CONFIG_MCI_IMX_ESDHC_PIO
u32 wml_value;
@@ -237,7 +237,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
u32 xfertyp, mixctrl;
u32 irqstat;
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc *regs = host->regs;
+ struct fsl_esdhc __iomem *regs = host->regs;
int ret;
esdhc_write32(&regs->irqstat, -1);
@@ -353,11 +353,11 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
return 0;
}
-void set_sysctl(struct mci_host *mci, u32 clock)
+static void set_sysctl(struct mci_host *mci, u32 clock)
{
int div, pre_div;
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc *regs = host->regs;
+ struct fsl_esdhc __iomem *regs = host->regs;
int sdhc_clk = imx_get_mmcclk();
u32 clk;
@@ -400,7 +400,7 @@ void set_sysctl(struct mci_host *mci, u32 clock)
static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc *regs = host->regs;
+ struct fsl_esdhc __iomem *regs = host->regs;
/* Set the clock speed */
set_sysctl(mci, ios->clock);
@@ -425,7 +425,7 @@ static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
static int esdhc_card_detect(struct fsl_esdhc_host *host)
{
- struct fsl_esdhc *regs = host->regs;
+ struct fsl_esdhc __iomem *regs = host->regs;
struct esdhc_platform_data *pdata = host->dev->platform_data;
int ret;
@@ -451,7 +451,7 @@ static int esdhc_card_detect(struct fsl_esdhc_host *host)
static int esdhc_init(struct mci_host *mci, struct device_d *dev)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc *regs = host->regs;
+ struct fsl_esdhc __iomem *regs = host->regs;
int timeout = 1000;
int ret = 0;
@@ -493,7 +493,7 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
return ret;
}
-static int esdhc_reset(struct fsl_esdhc *regs)
+static int esdhc_reset(struct fsl_esdhc __iomem *regs)
{
uint64_t start;
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
index 19fed5aebf..7d5ed85dfd 100644
--- a/drivers/mci/imx-esdhc.h
+++ b/drivers/mci/imx-esdhc.h
@@ -39,7 +39,6 @@
#define SYSCTL_PEREN 0x00000004
#define SYSCTL_HCKEN 0x00000002
#define SYSCTL_IPGEN 0x00000001
-#define SYSCTL_RSTA 0x01000000
#define IRQSTAT 0x0002e030
#define IRQSTAT_DMAE (0x10000000)
diff --git a/drivers/mfd/lp3972.c b/drivers/mfd/lp3972.c
index 98266990dc..0f3093bd15 100644
--- a/drivers/mfd/lp3972.c
+++ b/drivers/mfd/lp3972.c
@@ -58,7 +58,7 @@ static u32 lp_read_reg(struct lp_priv *lp, int reg)
return buf;
}
-static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
{
struct lp_priv *priv = to_lp_priv(cdev);
int i = count;
diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c
index f9477a3540..2934e9d9bd 100644
--- a/drivers/mfd/mc13xxx.c
+++ b/drivers/mfd/mc13xxx.c
@@ -160,7 +160,7 @@ int mc13xxx_set_bits(struct mc13xxx *mc13xxx, u8 reg, u32 mask, u32 val)
}
EXPORT_SYMBOL(mc13xxx_set_bits);
-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
{
struct mc13xxx *priv = to_mc13xxx(cdev);
u32 *buf = _buf;
@@ -181,7 +181,7 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset
return count;
}
-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
{
struct mc13xxx *mc13xxx = to_mc13xxx(cdev);
const u32 *buf = _buf;
diff --git a/drivers/mfd/mc34704.c b/drivers/mfd/mc34704.c
index a2171b35d1..20c01e2be6 100644
--- a/drivers/mfd/mc34704.c
+++ b/drivers/mfd/mc34704.c
@@ -65,7 +65,7 @@ int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val)
EXPORT_SYMBOL(mc34704_reg_write)
static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count,
- ulong offset, ulong flags)
+ loff_t offset, ulong flags)
{
struct mc34704 *priv = to_mc34704(cdev);
u8 *buf = _buf;
@@ -85,7 +85,7 @@ static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count,
}
static ssize_t mc34704_write(struct cdev *cdev, const void *_buf, size_t count,
- ulong offset, ulong flags)
+ loff_t offset, ulong flags)
{
struct mc34704 *mc34704 = to_mc34704(cdev);
const u8 *buf = _buf;
diff --git a/drivers/mfd/mc34708.c b/drivers/mfd/mc34708.c
index e7f40c02b7..02c58a997d 100644
--- a/drivers/mfd/mc34708.c
+++ b/drivers/mfd/mc34708.c
@@ -163,7 +163,8 @@ int mc34708_set_bits(struct mc34708 *mc34708, enum mc34708_reg reg, u32 mask, u3
}
EXPORT_SYMBOL(mc34708_set_bits);
-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count,
+ loff_t offset, ulong flags)
{
struct mc34708 *priv = to_mc34708(cdev);
u32 *buf = _buf;
@@ -184,7 +185,8 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset
return count;
}
-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count,
+ loff_t offset, ulong flags)
{
struct mc34708 *mc34708 = to_mc34708(cdev);
const u32 *buf = _buf;
diff --git a/drivers/mfd/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
index db208ec2db..0cd5007e1c 100644
--- a/drivers/mfd/mc9sdz60.c
+++ b/drivers/mfd/mc9sdz60.c
@@ -78,7 +78,7 @@ int mc9sdz60_set_bits(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 mask,
}
EXPORT_SYMBOL(mc9sdz60_set_bits);
-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
{
struct mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev);
u8 *buf = _buf;
@@ -97,7 +97,7 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset
return count;
}
-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
{
struct mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev);
const u8 *buf = _buf;
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index cb2c03dfca..20bde2cf89 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -112,7 +112,7 @@ int twlcore_set_bits(struct twlcore *twlcore, u16 reg, u8 mask, u8 val)
EXPORT_SYMBOL(twlcore_set_bits);
static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count,
- ulong offset, ulong flags)
+ loff_t offset, ulong flags)
{
struct twlcore *priv = to_twlcore(cdev);
u8 *buf = _buf;
@@ -131,7 +131,7 @@ static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count,
}
static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count,
- ulong offset, ulong flags)
+ loff_t offset, ulong flags)
{
struct twlcore *twlcore = to_twlcore(cdev);
const u8 *buf = _buf;
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 87dcba6801..5510439a87 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -31,11 +31,12 @@
static LIST_HEAD(mtd_register_hooks);
static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count,
- ulong offset, ulong flags)
+ loff_t _offset, ulong flags)
{
struct mtd_info *mtd = cdev->priv;
size_t retlen;
int ret;
+ unsigned long offset = _offset;
debug("mtd_read: 0x%08lx 0x%08x\n", offset, count);
@@ -64,13 +65,14 @@ static int all_ff(const void *buf, int len)
}
static ssize_t mtd_write(struct cdev* cdev, const void *buf, size_t _count,
- ulong offset, ulong flags)
+ loff_t _offset, ulong flags)
{
struct mtd_info *mtd = cdev->priv;
size_t retlen, now;
int ret = 0;
void *wrbuf = NULL;
size_t count = _count;
+ unsigned long offset = _offset;
if (NOTALIGNED(offset)) {
printf("offset 0x%0lx not page aligned\n", offset);
@@ -123,16 +125,17 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
struct mtd_ecc_stats *ecc = buf;
#endif
struct region_info_user *reg = buf;
+ loff_t *offset = buf;
switch (request) {
case MEMGETBADBLOCK:
- dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
- ret = mtd->block_isbad(mtd, (off_t)buf);
+ dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08llx\n", *offset);
+ ret = mtd->block_isbad(mtd, *offset);
break;
#ifdef CONFIG_MTD_WRITE
case MEMSETBADBLOCK:
- dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
- ret = mtd->block_markbad(mtd, (off_t)buf);
+ dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08llx\n", *offset);
+ ret = mtd->block_markbad(mtd, *offset);
break;
#endif
case MEMGETINFO:
@@ -156,9 +159,10 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
#endif
case MEMGETREGIONINFO:
if (cdev->mtd) {
+ unsigned long size = cdev->size;
reg->offset = cdev->offset;
reg->erasesize = cdev->mtd->erasesize;
- reg->numblocks = cdev->size/reg->erasesize;
+ reg->numblocks = size / reg->erasesize;
reg->regionindex = cdev->mtd->index;
}
break;
@@ -170,7 +174,7 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
}
#ifdef CONFIG_MTD_WRITE
-static ssize_t mtd_erase(struct cdev *cdev, size_t count, unsigned long offset)
+static ssize_t mtd_erase(struct cdev *cdev, size_t count, loff_t offset)
{
struct mtd_info *mtd = cdev->priv;
struct erase_info erase;
diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
index be656a4d33..e4dd1a00c8 100644
--- a/drivers/mtd/mtdoob.c
+++ b/drivers/mtd/mtdoob.c
@@ -38,11 +38,12 @@ static struct mtd_info *to_mtd(struct cdev *cdev)
}
static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
- ulong offset, ulong flags)
+ loff_t _offset, ulong flags)
{
struct mtd_info *mtd = to_mtd(cdev);
struct mtd_oob_ops ops;
int ret;
+ unsigned long offset = _offset;
if (count < mtd->oobsize)
return -EINVAL;
diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c
index 7abe2351a5..24f7358098 100644
--- a/drivers/mtd/mtdraw.c
+++ b/drivers/mtd/mtdraw.c
@@ -116,12 +116,13 @@ err:
}
static ssize_t mtdraw_read(struct cdev *cdev, void *buf, size_t count,
- ulong offset, ulong flags)
+ loff_t _offset, ulong flags)
{
struct mtd_info *mtd = to_mtd(cdev);
ssize_t retlen = 0, ret = 1, toread;
ulong numpage;
int skip;
+ unsigned long offset = _offset;
numpage = offset / (mtd->writesize + mtd->oobsize);
skip = offset % (mtd->writesize + mtd->oobsize);
@@ -167,13 +168,14 @@ static void mtdraw_fillbuf(struct mtdraw *mtdraw, const void *src, int nbbytes)
}
static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
- ulong offset, ulong flags)
+ loff_t _offset, ulong flags)
{
struct mtdraw *mtdraw = to_mtdraw(cdev);
struct mtd_info *mtd = to_mtd(cdev);
int bsz = mtd->writesize + mtd->oobsize;
ulong numpage;
size_t retlen = 0, tofill;
+ unsigned long offset = _offset;
int ret = 0;
if (mtdraw->write_fill &&
@@ -220,10 +222,11 @@ static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
}
}
-static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, ulong offset)
+static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, loff_t _offset)
{
struct mtd_info *mtd = to_mtd(cdev);
struct erase_info erase;
+ unsigned long offset = _offset;
int ret;
offset = offset / (mtd->writesize + mtd->oobsize) * mtd->writesize;
diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
index bd30438958..d27274924a 100644
--- a/drivers/mtd/nand/nand-bb.c
+++ b/drivers/mtd/nand/nand-bb.c
@@ -42,9 +42,9 @@ struct nand_bb {
struct mtd_info_user info;
- size_t raw_size;
- size_t size;
- off_t offset;
+ loff_t raw_size;
+ loff_t size;
+ loff_t offset;
unsigned long flags;
void *writebuf;
@@ -54,7 +54,7 @@ struct nand_bb {
};
static ssize_t nand_bb_read(struct cdev *cdev, void *buf, size_t count,
- unsigned long offset, ulong flags)
+ loff_t offset, ulong flags)
{
struct nand_bb *bb = cdev->priv;
struct cdev *parent = bb->cdev_parent;
@@ -63,18 +63,18 @@ static ssize_t nand_bb_read(struct cdev *cdev, void *buf, size_t count,
debug("%s %d %d\n", __func__, offset, count);
while(count) {
- ret = cdev_ioctl(parent, MEMGETBADBLOCK, (void *)bb->offset);
+ ret = cdev_ioctl(parent, MEMGETBADBLOCK, &bb->offset);
if (ret < 0)
return ret;
if (ret) {
- printf("skipping bad block at 0x%08lx\n", bb->offset);
+ printf("skipping bad block at 0x%08llx\n", bb->offset);
bb->offset += bb->info.erasesize;
continue;
}
now = min(count, (size_t)(bb->info.erasesize -
- (bb->offset % bb->info.erasesize)));
+ ((size_t)bb->offset % bb->info.erasesize)));
ret = cdev_read(parent, buf, now, bb->offset, 0);
if (ret < 0)
return ret;
@@ -96,10 +96,10 @@ static int nand_bb_write_buf(struct nand_bb *bb, size_t count)
int ret, now;
struct cdev *parent = bb->cdev_parent;
void *buf = bb->writebuf;
- int cur_ofs = bb->offset & ~(BB_WRITEBUF_SIZE - 1);
+ off_t cur_ofs = bb->offset & ~(BB_WRITEBUF_SIZE - 1);
while (count) {
- ret = cdev_ioctl(parent, MEMGETBADBLOCK, (void *)cur_ofs);
+ ret = cdev_ioctl(parent, MEMGETBADBLOCK, &cur_ofs);
if (ret < 0)
return ret;
@@ -123,12 +123,12 @@ static int nand_bb_write_buf(struct nand_bb *bb, size_t count)
}
static ssize_t nand_bb_write(struct cdev *cdev, const void *buf, size_t count,
- unsigned long offset, ulong flags)
+ loff_t offset, ulong flags)
{
struct nand_bb *bb = cdev->priv;
int bytes = count, now, wroffs, ret;
- debug("%s offset: 0x%08x count: 0x%08x\n", __func__, offset, count);
+ debug("%s offset: 0x%08llx count: 0x%08x\n", __func__, offset, count);
while (count) {
wroffs = bb->offset % BB_WRITEBUF_SIZE;
@@ -152,7 +152,7 @@ static ssize_t nand_bb_write(struct cdev *cdev, const void *buf, size_t count,
return bytes;
}
-static int nand_bb_erase(struct cdev *cdev, size_t count, unsigned long offset)
+static int nand_bb_erase(struct cdev *cdev, size_t count, loff_t offset)
{
struct nand_bb *bb = cdev->priv;
@@ -197,11 +197,11 @@ static int nand_bb_close(struct cdev *cdev)
static int nand_bb_calc_size(struct nand_bb *bb)
{
- ulong pos = 0;
+ loff_t pos = 0;
int ret;
while (pos < bb->raw_size) {
- ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, (void *)pos);
+ ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, &pos);
if (ret < 0)
return ret;
if (!ret)
@@ -213,7 +213,7 @@ static int nand_bb_calc_size(struct nand_bb *bb)
return 0;
}
-static off_t nand_bb_lseek(struct cdev *cdev, off_t __offset)
+static loff_t nand_bb_lseek(struct cdev *cdev, loff_t __offset)
{
struct nand_bb *bb = cdev->priv;
unsigned long raw_pos = 0;
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 95bef1f9e0..c99b64db21 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -12,7 +12,7 @@ struct ubi_volume_cdev_priv {
};
static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
- unsigned long offset, unsigned long flags)
+ loff_t offset, unsigned long flags)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
struct ubi_volume *vol = priv->vol;
@@ -23,7 +23,7 @@ static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
loff_t offp = offset;
int usable_leb_size = vol->usable_leb_size;
- printf("%s: %d @ 0x%08lx\n", __func__, size, offset);
+ printf("%s: %d @ 0x%08llx\n", __func__, size, offset);
len = size > usable_leb_size ? usable_leb_size : size;
@@ -56,7 +56,7 @@ static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
}
static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf,
- size_t size, unsigned long offset, unsigned long flags)
+ size_t size, loff_t offset, unsigned long flags)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
struct ubi_volume *vol = priv->vol;
@@ -121,7 +121,7 @@ static int ubi_volume_cdev_close(struct cdev *cdev)
return 0;
}
-static off_t ubi_volume_cdev_lseek(struct cdev *cdev, off_t ofs)
+static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
diff --git a/drivers/mtd/ubi/ubi-barebox.h b/drivers/mtd/ubi/ubi-barebox.h
index d23228f648..72f29a61e7 100644
--- a/drivers/mtd/ubi/ubi-barebox.h
+++ b/drivers/mtd/ubi/ubi-barebox.h
@@ -135,7 +135,6 @@ struct kmem_cache { int i; };
#define GFP_KERNEL 0
#define GFP_NOFS 1
-#define __user
#define __init
#define __exit
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 172cc39080..749ea6a9c0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -13,6 +13,9 @@ config HAS_AT91_ETHER
config HAS_NETX_ETHER
bool
+config HAS_DESIGNWARE_ETH
+ bool
+
config ARCH_HAS_FEC_IMX
bool
@@ -108,6 +111,19 @@ config DRIVER_NET_KS8851_MLL
This option enables support for the Micrel KS8851 MLL
ethernet chip.
+config DRIVER_NET_DESIGNWARE
+ bool "Designware Universal MAC ethernet driver"
+ select MIIDEV
+ depends on HAS_DESIGNWARE_ETH
+ help
+ This option enables support for the Synopsys
+ Designware Core Univesal MAC 10M/100M/1G ethernet IP.
+
+config DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR
+ bool
+ depends on DRIVER_NET_DESIGNWARE
+ default n
+
source "drivers/net/usb/Kconfig"
endmenu
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 34dbee9e13..29727b7d5b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_MIIDEV) += miidev.o
obj-$(CONFIG_NET_USB) += usb/
obj-$(CONFIG_DRIVER_NET_TSE) += altera_tse.o
obj-$(CONFIG_DRIVER_NET_KS8851_MLL) += ks8851_mll.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
new file mode 100644
index 0000000000..379b4e39a5
--- /dev/null
+++ b/drivers/net/designware.c
@@ -0,0 +1,436 @@
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Designware ethernet IP driver for u-boot
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <net.h>
+#include <miidev.h>
+#include <asm/mmu.h>
+#include <net/designware.h>
+#include "designware.h"
+
+
+struct dw_eth_dev {
+ struct eth_device netdev;
+ struct mii_device miidev;
+
+ void (*fix_mac_speed)(int speed);
+ u8 macaddr[6];
+ u32 tx_currdescnum;
+ u32 rx_currdescnum;
+
+ struct dmamacdescr *tx_mac_descrtable;
+ struct dmamacdescr *rx_mac_descrtable;
+
+ u8 *txbuffs;
+ u8 *rxbuffs;
+
+ struct eth_mac_regs *mac_regs_p;
+ struct eth_dma_regs *dma_regs_p;
+};
+
+/* Speed specific definitions */
+#define SPEED_10M 1
+#define SPEED_100M 2
+#define SPEED_1000M 3
+
+/* Duplex mode specific definitions */
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+
+static int dwc_ether_mii_read(struct mii_device *dev, int addr, int reg)
+{
+ struct dw_eth_dev *priv = dev->edev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ u64 start;
+ u32 miiaddr;
+
+ miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+ ((reg << MIIREGSHIFT) & MII_REGMSK);
+
+ writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+ start = get_time_ns();
+ while (readl(&mac_p->miiaddr) & MII_BUSY) {
+ if (is_timeout(start, 10 * MSECOND)) {
+ dev_err(&priv->netdev.dev, "MDIO timeout\n");
+ return -EIO;
+ }
+ }
+ return readl(&mac_p->miidata) & 0xffff;
+}
+
+static int dwc_ether_mii_write(struct mii_device *dev, int addr, int reg, int val)
+{
+ struct dw_eth_dev *priv = dev->edev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ u64 start;
+ u32 miiaddr;
+
+ writel(val, &mac_p->miidata);
+ miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+ ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
+
+ writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+ start = get_time_ns();
+ while (readl(&mac_p->miiaddr) & MII_BUSY) {
+ if (is_timeout(start, 10 * MSECOND)) {
+ dev_err(&priv->netdev.dev, "MDIO timeout\n");
+ return -EIO;
+ }
+ }
+
+ /* Needed as a fix for ST-Phy */
+ dwc_ether_mii_read(dev, addr, reg);
+ return 0;
+}
+
+
+static int mac_reset(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ u64 start;
+
+ writel(DMAMAC_SRST, &dma_p->busmode);
+ writel(MII_PORTSELECT, &mac_p->conf);
+
+ start = get_time_ns();
+ while (readl(&dma_p->busmode) & DMAMAC_SRST) {
+ if (is_timeout(start, 10 * MSECOND)) {
+ dev_err(&priv->netdev.dev, "MAC reset timeout\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+static void tx_descs_init(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
+ char *txbuffs = &priv->txbuffs[0];
+ struct dmamacdescr *desc_p;
+ u32 idx;
+
+ for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
+ desc_p = &desc_table_p[idx];
+ desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
+ desc_p->dmamac_next = &desc_table_p[idx + 1];
+
+#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
+ desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
+ DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
+ DESC_TXSTS_TXCHECKINSCTRL | \
+ DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
+
+ desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
+ desc_p->dmamac_cntl = 0;
+ desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
+#else
+ desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
+ desc_p->txrx_status = 0;
+#endif
+ }
+
+ /* Correcting the last pointer of the chain */
+ desc_p->dmamac_next = &desc_table_p[0];
+
+ writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
+}
+
+static void rx_descs_init(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
+ char *rxbuffs = &priv->rxbuffs[0];
+ struct dmamacdescr *desc_p;
+ u32 idx;
+
+ for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
+ desc_p = &desc_table_p[idx];
+ desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
+ desc_p->dmamac_next = &desc_table_p[idx + 1];
+
+ desc_p->dmamac_cntl =
+ (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \
+ DESC_RXCTRL_RXCHAIN;
+
+ dma_inv_range((unsigned long)desc_p->dmamac_addr,
+ (unsigned long)desc_p->dmamac_addr + CONFIG_ETH_BUFSIZE);
+ desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
+ }
+
+ /* Correcting the last pointer of the chain */
+ desc_p->dmamac_next = &desc_table_p[0];
+
+ writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
+}
+
+static void descs_init(struct eth_device *dev)
+{
+ tx_descs_init(dev);
+ rx_descs_init(dev);
+}
+
+static int dwc_ether_init(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+
+ if (mac_reset(dev) < 0)
+ return -1;
+
+ /* HW MAC address is lost during MAC reset */
+ dev->set_ethaddr(dev, priv->macaddr);
+
+ writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode);
+ writel(FLUSHTXFIFO | readl(&dma_p->opmode), &dma_p->opmode);
+ writel(STOREFORWARD | TXSECONDFRAME, &dma_p->opmode);
+ writel(FRAMEBURSTENABLE | DISABLERXOWN, &mac_p->conf);
+ return 0;
+}
+
+static int dwc_ether_open(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ u32 conf;
+ int link, speed;
+
+ miidev_wait_aneg(&priv->miidev);
+ miidev_print_status(&priv->miidev);
+ link = miidev_get_status(&priv->miidev);
+
+ if (priv->fix_mac_speed) {
+ speed = link & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
+ (link & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
+ priv->fix_mac_speed(speed);
+ }
+
+ conf = readl(&mac_p->conf);
+ if (link & MIIDEV_STATUS_IS_FULL_DUPLEX)
+ conf |= FULLDPLXMODE;
+ else
+ conf &= ~FULLDPLXMODE;
+ if (link & MIIDEV_STATUS_IS_1000MBIT)
+ conf &= ~MII_PORTSELECT;
+ else
+ conf |= MII_PORTSELECT;
+ writel(conf, &mac_p->conf);
+
+ descs_init(dev);
+
+ /*
+ * Start/Enable xfer at dma as well as mac level
+ */
+ writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
+ writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);
+ writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
+ return 0;
+}
+
+static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ u32 desc_num = priv->tx_currdescnum;
+ struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
+
+ /* Check if the descriptor is owned by CPU */
+ if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
+ dev_err(&dev->dev, "CPU not owner of tx frame\n");
+ return -1;
+ }
+
+ memcpy((void *)desc_p->dmamac_addr, packet, length);
+ dma_flush_range((unsigned long)desc_p->dmamac_addr,
+ (unsigned long)desc_p->dmamac_addr + length);
+
+#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
+ desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
+ desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \
+ DESC_TXCTRL_SIZE1MASK;
+
+ desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
+ desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
+#else
+ desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \
+ DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
+ DESC_TXCTRL_TXFIRST;
+
+ desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
+#endif
+
+ /* Test the wrap-around condition. */
+ if (++desc_num >= CONFIG_TX_DESCR_NUM)
+ desc_num = 0;
+
+ priv->tx_currdescnum = desc_num;
+
+ /* Start the transmission */
+ writel(POLL_DATA, &dma_p->txpolldemand);
+ return 0;
+}
+
+static int dwc_ether_rx(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ u32 desc_num = priv->rx_currdescnum;
+ struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
+
+ u32 status = desc_p->txrx_status;
+ int length = 0;
+
+ /* Check if the owner is the CPU */
+ if (status & DESC_RXSTS_OWNBYDMA)
+ return 0;
+
+ length = (status & DESC_RXSTS_FRMLENMSK) >> \
+ DESC_RXSTS_FRMLENSHFT;
+
+ net_receive(desc_p->dmamac_addr, length);
+
+ /*
+ * Make the current descriptor valid again and go to
+ * the next one
+ */
+ dma_inv_range((unsigned long)desc_p->dmamac_addr,
+ (unsigned long)desc_p->dmamac_addr + length);
+ desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
+
+ /* Test the wrap-around condition. */
+ if (++desc_num >= CONFIG_RX_DESCR_NUM)
+ desc_num = 0;
+
+ priv->rx_currdescnum = desc_num;
+
+ return length;
+}
+
+static void dwc_ether_halt (struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+
+ mac_reset(dev);
+ priv->tx_currdescnum = priv->rx_currdescnum = 0;
+}
+
+static int dwc_ether_get_ethaddr(struct eth_device *dev, u8 adr[6])
+{
+ /* we have no EEPROM */
+ return -1;
+}
+
+static int dwc_ether_set_ethaddr(struct eth_device *dev, u8 adr[6])
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ u32 macid_lo, macid_hi;
+
+ macid_lo = adr[0] + (adr[1] << 8) + \
+ (adr[2] << 16) + (adr[3] << 24);
+ macid_hi = adr[4] + (adr[5] << 8);
+ writel(macid_hi, &mac_p->macaddr0hi);
+ writel(macid_lo, &mac_p->macaddr0lo);
+ memcpy(priv->macaddr, adr, 6);
+ return 0;
+}
+
+static int dwc_ether_probe(struct device_d *dev)
+{
+ struct dw_eth_dev *priv;
+ struct eth_device *edev;
+ struct mii_device *miidev;
+ void __iomem *base;
+ struct dwc_ether_platform_data *pdata = dev->platform_data;
+
+ if (!pdata) {
+ printf("dwc_ether: no platform_data\n");
+ return -ENODEV;
+ }
+
+ priv = xzalloc(sizeof(struct dw_eth_dev));
+
+ base = dev_request_mem_region(dev, 0);
+ priv->mac_regs_p = base;
+ dev_info(dev, "MAC version %08x\n", readl(&priv->mac_regs_p->version));
+ priv->dma_regs_p = base + DW_DMA_BASE_OFFSET;
+ priv->tx_mac_descrtable = dma_alloc_coherent(
+ CONFIG_TX_DESCR_NUM * sizeof(struct dmamacdescr));
+ priv->rx_mac_descrtable = dma_alloc_coherent(
+ CONFIG_RX_DESCR_NUM * sizeof(struct dmamacdescr));
+ priv->txbuffs = malloc(TX_TOTAL_BUFSIZE);
+ priv->rxbuffs = malloc(RX_TOTAL_BUFSIZE);
+ priv->fix_mac_speed = pdata->fix_mac_speed;
+
+ edev = &priv->netdev;
+ miidev = &priv->miidev;
+ edev->priv = priv;
+
+ edev->init = dwc_ether_init;
+ edev->open = dwc_ether_open;
+ edev->send = dwc_ether_send;
+ edev->recv = dwc_ether_rx;
+ edev->halt = dwc_ether_halt;
+ edev->get_ethaddr = dwc_ether_get_ethaddr;
+ edev->set_ethaddr = dwc_ether_set_ethaddr;
+
+ miidev->address = pdata->phy_addr;
+ miidev->read = dwc_ether_mii_read;
+ miidev->write = dwc_ether_mii_write;
+ miidev->edev = edev;
+
+ mii_register(miidev);
+ eth_register(edev);
+ return 0;
+}
+
+static void dwc_ether_remove(struct device_d *dev)
+{
+}
+
+static struct driver_d dwc_ether_driver = {
+ .name = "designware_eth",
+ .probe = dwc_ether_probe,
+ .remove = dwc_ether_remove,
+};
+
+static int dwc_ether_driver_init(void)
+{
+ register_driver(&dwc_ether_driver);
+ return 0;
+}
+device_initcall(dwc_ether_driver_init);
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
new file mode 100644
index 0000000000..db2ead48aa
--- /dev/null
+++ b/drivers/net/designware.h
@@ -0,0 +1,230 @@
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __DESIGNWARE_ETH_H
+#define __DESIGNWARE_ETH_H
+
+#define CONFIG_TX_DESCR_NUM 16
+#define CONFIG_RX_DESCR_NUM 16
+#define CONFIG_ETH_BUFSIZE 2048
+#define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
+#define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
+
+struct eth_mac_regs {
+ u32 conf; /* 0x00 */
+ u32 framefilt; /* 0x04 */
+ u32 hashtablehigh; /* 0x08 */
+ u32 hashtablelow; /* 0x0c */
+ u32 miiaddr; /* 0x10 */
+ u32 miidata; /* 0x14 */
+ u32 flowcontrol; /* 0x18 */
+ u32 vlantag; /* 0x1c */
+ u32 version; /* 0x20 */
+ u8 reserved_1[20];
+ u32 intreg; /* 0x38 */
+ u32 intmask; /* 0x3c */
+ u32 macaddr0hi; /* 0x40 */
+ u32 macaddr0lo; /* 0x44 */
+};
+
+/* MAC configuration register definitions */
+#define FRAMEBURSTENABLE (1 << 21)
+#define MII_PORTSELECT (1 << 15)
+#define FES_100 (1 << 14)
+#define DISABLERXOWN (1 << 13)
+#define FULLDPLXMODE (1 << 11)
+#define RXENABLE (1 << 2)
+#define TXENABLE (1 << 3)
+
+/* MII address register definitions */
+#define MII_BUSY (1 << 0)
+#define MII_WRITE (1 << 1)
+#define MII_CLKRANGE_60_100M (0)
+#define MII_CLKRANGE_100_150M (0x4)
+#define MII_CLKRANGE_20_35M (0x8)
+#define MII_CLKRANGE_35_60M (0xC)
+#define MII_CLKRANGE_150_250M (0x10)
+#define MII_CLKRANGE_250_300M (0x14)
+
+#define MIIADDRSHIFT (11)
+#define MIIREGSHIFT (6)
+#define MII_REGMSK (0x1F << 6)
+#define MII_ADDRMSK (0x1F << 11)
+
+
+struct eth_dma_regs {
+ u32 busmode; /* 0x00 */
+ u32 txpolldemand; /* 0x04 */
+ u32 rxpolldemand; /* 0x08 */
+ u32 rxdesclistaddr; /* 0x0c */
+ u32 txdesclistaddr; /* 0x10 */
+ u32 status; /* 0x14 */
+ u32 opmode; /* 0x18 */
+ u32 intenable; /* 0x1c */
+ u8 reserved[40];
+ u32 currhosttxdesc; /* 0x48 */
+ u32 currhostrxdesc; /* 0x4c */
+ u32 currhosttxbuffaddr; /* 0x50 */
+ u32 currhostrxbuffaddr; /* 0x54 */
+};
+
+#define DW_DMA_BASE_OFFSET (0x1000)
+
+/* Bus mode register definitions */
+#define FIXEDBURST (1 << 16)
+#define PRIORXTX_41 (3 << 14)
+#define PRIORXTX_31 (2 << 14)
+#define PRIORXTX_21 (1 << 14)
+#define PRIORXTX_11 (0 << 14)
+#define BURST_1 (1 << 8)
+#define BURST_2 (2 << 8)
+#define BURST_4 (4 << 8)
+#define BURST_8 (8 << 8)
+#define BURST_16 (16 << 8)
+#define BURST_32 (32 << 8)
+#define RXHIGHPRIO (1 << 1)
+#define DMAMAC_SRST (1 << 0)
+
+/* Poll demand definitions */
+#define POLL_DATA (0xFFFFFFFF)
+
+/* Operation mode definitions */
+#define STOREFORWARD (1 << 21)
+#define FLUSHTXFIFO (1 << 20)
+#define TXSTART (1 << 13)
+#define TXSECONDFRAME (1 << 2)
+#define RXSTART (1 << 1)
+
+/* Descriptior related definitions */
+#define MAC_MAX_FRAME_SZ (1600)
+
+struct dmamacdescr {
+ u32 txrx_status;
+ u32 dmamac_cntl;
+ void *dmamac_addr;
+ struct dmamacdescr *dmamac_next;
+};
+
+/*
+ * txrx_status definitions
+ */
+
+/* tx status bits definitions */
+#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
+
+#define DESC_TXSTS_OWNBYDMA (1 << 31)
+#define DESC_TXSTS_TXINT (1 << 30)
+#define DESC_TXSTS_TXLAST (1 << 29)
+#define DESC_TXSTS_TXFIRST (1 << 28)
+#define DESC_TXSTS_TXCRCDIS (1 << 27)
+
+#define DESC_TXSTS_TXPADDIS (1 << 26)
+#define DESC_TXSTS_TXCHECKINSCTRL (3 << 22)
+#define DESC_TXSTS_TXRINGEND (1 << 21)
+#define DESC_TXSTS_TXCHAIN (1 << 20)
+#define DESC_TXSTS_MSK (0x1FFFF << 0)
+
+#else
+
+#define DESC_TXSTS_OWNBYDMA (1 << 31)
+#define DESC_TXSTS_MSK (0x1FFFF << 0)
+
+#endif
+
+/* rx status bits definitions */
+#define DESC_RXSTS_OWNBYDMA (1 << 31)
+#define DESC_RXSTS_DAFILTERFAIL (1 << 30)
+#define DESC_RXSTS_FRMLENMSK (0x3FFF << 16)
+#define DESC_RXSTS_FRMLENSHFT (16)
+
+#define DESC_RXSTS_ERROR (1 << 15)
+#define DESC_RXSTS_RXTRUNCATED (1 << 14)
+#define DESC_RXSTS_SAFILTERFAIL (1 << 13)
+#define DESC_RXSTS_RXIPC_GIANTFRAME (1 << 12)
+#define DESC_RXSTS_RXDAMAGED (1 << 11)
+#define DESC_RXSTS_RXVLANTAG (1 << 10)
+#define DESC_RXSTS_RXFIRST (1 << 9)
+#define DESC_RXSTS_RXLAST (1 << 8)
+#define DESC_RXSTS_RXIPC_GIANT (1 << 7)
+#define DESC_RXSTS_RXCOLLISION (1 << 6)
+#define DESC_RXSTS_RXFRAMEETHER (1 << 5)
+#define DESC_RXSTS_RXWATCHDOG (1 << 4)
+#define DESC_RXSTS_RXMIIERROR (1 << 3)
+#define DESC_RXSTS_RXDRIBBLING (1 << 2)
+#define DESC_RXSTS_RXCRC (1 << 1)
+
+/*
+ * dmamac_cntl definitions
+ */
+
+/* tx control bits definitions */
+#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
+
+#define DESC_TXCTRL_SIZE1MASK (0x1FFF << 0)
+#define DESC_TXCTRL_SIZE1SHFT (0)
+#define DESC_TXCTRL_SIZE2MASK (0x1FFF << 16)
+#define DESC_TXCTRL_SIZE2SHFT (16)
+
+#else
+
+#define DESC_TXCTRL_TXINT (1 << 31)
+#define DESC_TXCTRL_TXLAST (1 << 30)
+#define DESC_TXCTRL_TXFIRST (1 << 29)
+#define DESC_TXCTRL_TXCHECKINSCTRL (3 << 27)
+#define DESC_TXCTRL_TXCRCDIS (1 << 26)
+#define DESC_TXCTRL_TXRINGEND (1 << 25)
+#define DESC_TXCTRL_TXCHAIN (1 << 24)
+
+#define DESC_TXCTRL_SIZE1MASK (0x7FF << 0)
+#define DESC_TXCTRL_SIZE1SHFT (0)
+#define DESC_TXCTRL_SIZE2MASK (0x7FF << 11)
+#define DESC_TXCTRL_SIZE2SHFT (11)
+
+#endif
+
+/* rx control bits definitions */
+#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
+
+#define DESC_RXCTRL_RXINTDIS (1 << 31)
+#define DESC_RXCTRL_RXRINGEND (1 << 15)
+#define DESC_RXCTRL_RXCHAIN (1 << 14)
+
+#define DESC_RXCTRL_SIZE1MASK (0x1FFF << 0)
+#define DESC_RXCTRL_SIZE1SHFT (0)
+#define DESC_RXCTRL_SIZE2MASK (0x1FFF << 16)
+#define DESC_RXCTRL_SIZE2SHFT (16)
+
+#else
+
+#define DESC_RXCTRL_RXINTDIS (1 << 31)
+#define DESC_RXCTRL_RXRINGEND (1 << 25)
+#define DESC_RXCTRL_RXCHAIN (1 << 24)
+
+#define DESC_RXCTRL_SIZE1MASK (0x7FF << 0)
+#define DESC_RXCTRL_SIZE1SHFT (0)
+#define DESC_RXCTRL_SIZE2MASK (0x7FF << 11)
+#define DESC_RXCTRL_SIZE2SHFT (11)
+
+#endif
+
+#endif
diff --git a/drivers/net/miidev.c b/drivers/net/miidev.c
index f47fc9e65b..b49944bbfe 100644
--- a/drivers/net/miidev.c
+++ b/drivers/net/miidev.c
@@ -123,7 +123,7 @@ int miidev_wait_aneg(struct mii_device *mdev)
int miidev_get_status(struct mii_device *mdev)
{
- int ret, status;
+ int ret, status, adv, lpa;
ret = mii_read(mdev, mdev->address, MII_BMSR);
if (ret < 0)
@@ -136,13 +136,31 @@ int miidev_get_status(struct mii_device *mdev)
goto err_out;
if (ret & BMCR_ANENABLE) {
- ret = mii_read(mdev, mdev->address, MII_LPA);
- if (ret < 0)
+ if (mdev->capabilities & MIIDEV_CAPABLE_1000M) {
+ lpa = mii_read(mdev, mdev->address, MII_STAT1000);
+ if (lpa < 0)
+ goto err_out;
+ adv = mii_read(mdev, mdev->address, MII_CTRL1000);
+ if (adv < 0)
+ goto err_out;
+ lpa &= adv << 2;
+ if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
+ if (lpa & LPA_1000FULL)
+ status |= MIIDEV_STATUS_IS_FULL_DUPLEX;
+ status |= MIIDEV_STATUS_IS_1000MBIT;
+ return status;
+ }
+ }
+ lpa = mii_read(mdev, mdev->address, MII_LPA);
+ if (lpa < 0)
goto err_out;
-
- status |= ret & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
- status |= ret & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
- MIIDEV_STATUS_IS_10MBIT;
+ adv = mii_read(mdev, mdev->address, MII_ADVERTISE);
+ if (adv < 0)
+ goto err_out;
+ lpa &= adv;
+ status |= lpa & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
+ status |= lpa & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
+ MIIDEV_STATUS_IS_10MBIT;
} else {
status |= ret & BMCR_FULLDPLX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
status |= ret & BMCR_SPEED100 ? MIIDEV_STATUS_IS_100MBIT :
@@ -170,8 +188,8 @@ int miidev_print_status(struct mii_device *mdev)
return status;
duplex = status & MIIDEV_STATUS_IS_FULL_DUPLEX ? "Full" : "Half";
- speed = status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10;
-
+ speed = status & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
+ (status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
printf("%s: Link is %s", mdev->cdev.name,
status & MIIDEV_STATUS_IS_UP ? "up" : "down");
@@ -180,33 +198,33 @@ int miidev_print_status(struct mii_device *mdev)
return 0;
}
-static ssize_t miidev_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t miidev_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
{
int i = count;
uint16_t *buf = _buf;
struct mii_device *mdev = cdev->priv;
- while (i > 1) {
- *buf = mii_read(mdev, mdev->address, offset);
+ while (i > 0) {
+ *buf = mii_read(mdev, mdev->address, offset / 2);
buf++;
i -= 2;
- offset++;
+ offset += 2;
}
return count;
}
-static ssize_t miidev_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t miidev_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
{
int i = count;
const uint16_t *buf = _buf;
struct mii_device *mdev = cdev->priv;
- while (i > 1) {
- mii_write(mdev, mdev->address, offset, *buf);
+ while (i > 0) {
+ mii_write(mdev, mdev->address, offset / 2, *buf);
buf++;
i -= 2;
- offset++;
+ offset += 2;
}
return count;
@@ -221,7 +239,27 @@ static struct file_operations miidev_ops = {
static int miidev_probe(struct device_d *dev)
{
struct mii_device *mdev = dev->priv;
+ int val;
+ int caps = 0;
+ val = mii_read(mdev, mdev->address, MII_PHYSID1);
+ if (val < 0 || val == 0xffff)
+ goto err_out;
+ val = mii_read(mdev, mdev->address, MII_PHYSID2);
+ if (val < 0 || val == 0xffff)
+ goto err_out;
+ val = mii_read(mdev, mdev->address, MII_BMSR);
+ if (val < 0)
+ goto err_out;
+ if (val & BMSR_ESTATEN) {
+ val = mii_read(mdev, mdev->address, MII_ESTATUS);
+ if (val < 0)
+ goto err_out;
+ if (val & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
+ caps = MIIDEV_CAPABLE_1000M;
+ }
+
+ mdev->capabilities = caps;
mdev->cdev.name = asprintf("phy%d", dev->id);
mdev->cdev.size = 64;
mdev->cdev.ops = &miidev_ops;
@@ -230,6 +268,10 @@ static int miidev_probe(struct device_d *dev)
devfs_create(&mdev->cdev);
list_add_tail(&mdev->list, &miidev_list);
return 0;
+
+err_out:
+ dev_err(dev, "cannot read PHY registers (addr %d)\n", mdev->address);
+ return -ENODEV;
}
static void miidev_remove(struct device_d *dev)
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 800c1886ce..7dddbbcc38 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -691,7 +691,7 @@ static int smc911x_probe(struct device_d *dev)
struct smc911x_priv *priv;
uint32_t val;
int i;
- void *base;
+ void __iomem *base;
base = dev_request_mem_region(dev, 0);
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 654e6470c1..16885c0af9 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -82,9 +82,9 @@ static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
return;
}
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef __BIG_ENDIAN
*cword = (*cword << 8) | c;
-#else
+#elif defined __LITTLE_ENDIAN
if (bankwidth_is_2(info))
*cword = (*cword >> 8) | (u16)c << 8;
@@ -92,6 +92,8 @@ static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
*cword = (*cword >> 8) | (u32)c << 24;
else if (bankwidth_is_8(info))
*cword = (*cword >> 8) | (u64)c << 56;
+#else
+#error "could not determine byte order"
#endif
}
@@ -167,7 +169,7 @@ static void flash_printqry (struct cfi_qry *qry)
uchar flash_read_uchar (struct flash_info *info, uint offset)
{
uchar *cp = flash_make_addr(info, 0, offset);
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined __LITTLE_ENDIAN
return flash_read8(cp);
#else
return flash_read8(cp + info->portwidth - 1);
@@ -195,7 +197,7 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
}
#endif
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined __LITTLE_ENDIAN
retval = ((flash_read8(addr) << 16) |
(flash_read8(addr + info->portwidth) << 24) |
(flash_read8(addr + 2 * info->portwidth)) |
@@ -456,7 +458,7 @@ flash_sect_t find_sector (struct flash_info *info, ulong addr)
return sector;
}
-static int __cfi_erase(struct cdev *cdev, size_t count, unsigned long offset,
+static int __cfi_erase(struct cdev *cdev, size_t count, loff_t offset,
int verbose)
{
struct flash_info *finfo = (struct flash_info *)cdev->priv;
@@ -491,7 +493,7 @@ out:
return ret;
}
-static int cfi_erase(struct cdev *cdev, size_t count, unsigned long offset)
+static int cfi_erase(struct cdev *cdev, size_t count, loff_t offset)
{
return __cfi_erase(cdev, count, offset, 1);
}
@@ -628,7 +630,7 @@ static int flash_real_protect (struct flash_info *info, long sector, int prot)
return retcode;
}
-static int cfi_protect(struct cdev *cdev, size_t count, unsigned long offset, int prot)
+static int cfi_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
{
struct flash_info *finfo = (struct flash_info *)cdev->priv;
unsigned long start, end;
@@ -651,7 +653,7 @@ out:
return ret;
}
-static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, unsigned long offset, ulong flags)
+static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
{
struct flash_info *finfo = (struct flash_info *)cdev->priv;
int ret;
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 77669c2808..14402270bc 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -194,13 +194,14 @@ static int erase_sector(struct m25p *flash, u32 offset)
* Erase an address range on the flash chip. The address range may extend
* one or more erase sectors. Return an error is there is a problem erasing.
*/
-static ssize_t m25p80_erase(struct cdev *cdev, size_t count, unsigned long offset)
+static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
{
struct m25p *flash = cdev->priv;
u32 addr, len;
u32 start_sector;
u32 end_sector;
u32 progress = 0;
+ int eraseshift = ffs(flash->erasesize) - 1;
dev_dbg(&flash->spi->dev, "%s %s 0x%llx, len %lld\n",
__func__, "at", (long long)offset, (long long)count);
@@ -212,8 +213,8 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, unsigned long offse
addr = offset;
len = count;
- start_sector = offset / flash->erasesize;
- end_sector = (offset + count - 1) / flash->erasesize;
+ start_sector = offset >> eraseshift;
+ end_sector = (offset + count - 1) >> eraseshift;
init_progression_bar(end_sector - start_sector + 1);
/* whole-chip erase? */
@@ -250,7 +251,8 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, unsigned long offse
return 0;
}
-ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
+ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
+ ulong flags)
{
struct m25p *flash = cdev->priv;
struct spi_transfer t[2];
@@ -302,7 +304,8 @@ ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ul
return retlen;
}
-ssize_t m25p80_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
+ssize_t m25p80_write(struct cdev *cdev, const void *buf, size_t count,
+ loff_t offset, ulong flags)
{
struct m25p *flash = cdev->priv;
struct spi_transfer t[2];
@@ -381,7 +384,8 @@ ssize_t m25p80_write(struct cdev *cdev, const void *buf, size_t count, ulong off
return retlen;
}
#ifdef CONFIG_MTD_SST25L
-ssize_t sst_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
+ssize_t sst_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset,
+ ulong flags)
{
struct m25p *flash = cdev->priv;
struct spi_transfer t[2];
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index bd2938d2b7..a5075d5436 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -52,6 +52,7 @@
#include <asm/byteorder.h>
#include <xfuncs.h>
#include <init.h>
+#include <dma.h>
#include <usb/usb.h>
@@ -67,7 +68,6 @@
static int dev_index;
static int asynch_allowed;
-static struct devrequest setup_packet;
static int usb_hub_probe(struct usb_device *dev, int ifnum);
static int hub_port_reset(struct usb_device *dev, int port,
@@ -80,8 +80,8 @@ static void print_usb_device(struct usb_device *dev)
{
printf("Bus %03d Device %03d: ID %04x:%04x %s\n",
dev->host->busnum, dev->devnum,
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
+ dev->descriptor->idVendor,
+ dev->descriptor->idProduct,
dev->prod);
}
@@ -299,12 +299,14 @@ static int usb_new_device(struct usb_device *dev)
{
int addr, err;
int tmp;
- unsigned char tmpbuf[USB_BUFSIZ];
+ void *buf;
struct usb_device_descriptor *desc;
int port = -1;
struct usb_device *parent = dev->parent;
unsigned short portstatus;
+ buf = dma_alloc(USB_BUFSIZ);
+
/* We still haven't set the Address yet */
addr = dev->devnum;
dev->devnum = 0;
@@ -322,8 +324,8 @@ static int usb_new_device(struct usb_device *dev)
* the maxpacket size is 8 or 16 the device may be waiting to transmit
* some more, or keeps on retransmitting the 8 byte header. */
- desc = (struct usb_device_descriptor *)tmpbuf;
- dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
+ desc = buf;
+ dev->descriptor->bMaxPacketSize0 = 64; /* Start off at 64 bytes */
/* Default to 64 byte max packet size */
dev->maxpacketsize = PACKET_SIZE_64;
dev->epmaxpacketin[0] = 64;
@@ -332,10 +334,10 @@ static int usb_new_device(struct usb_device *dev)
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
if (err < 0) {
USB_PRINTF("%s: usb_get_descriptor() failed with %d\n", __func__, err);
- return 1;
+ goto err_out;
}
- dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
+ dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0;
/* find the port number we're at */
if (parent) {
@@ -349,20 +351,21 @@ static int usb_new_device(struct usb_device *dev)
}
if (port < 0) {
printf("%s: cannot locate device's port.\n", __func__);
- return 1;
+ err = -ENODEV;
+ goto err_out;
}
/* reset the port for the second time */
err = hub_port_reset(dev->parent, port, &portstatus);
if (err < 0) {
printf("\n Couldn't reset port %i\n", port);
- return 1;
+ goto err_out;
}
}
- dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
- dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
- switch (dev->descriptor.bMaxPacketSize0) {
+ dev->epmaxpacketin[0] = dev->descriptor->bMaxPacketSize0;
+ dev->epmaxpacketout[0] = dev->descriptor->bMaxPacketSize0;
+ switch (dev->descriptor->bMaxPacketSize0) {
case 8:
dev->maxpacketsize = PACKET_SIZE_8;
break;
@@ -383,15 +386,15 @@ static int usb_new_device(struct usb_device *dev)
if (err < 0) {
printf("\n USB device not accepting new address " \
"(error=%lX)\n", dev->status);
- return 1;
+ goto err_out;
}
wait_ms(10); /* Let the SET_ADDRESS settle */
- tmp = sizeof(dev->descriptor);
+ tmp = sizeof(*dev->descriptor);
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
- &dev->descriptor, sizeof(dev->descriptor));
+ dev->descriptor, sizeof(*dev->descriptor));
if (err < tmp) {
if (err < 0)
printf("unable to get device descriptor (error=%d)\n",
@@ -399,37 +402,37 @@ static int usb_new_device(struct usb_device *dev)
else
printf("USB device descriptor short read " \
"(expected %i, got %i)\n", tmp, err);
- return 1;
+ goto err_out;
}
/* correct le values */
- le16_to_cpus(&dev->descriptor.bcdUSB);
- le16_to_cpus(&dev->descriptor.idVendor);
- le16_to_cpus(&dev->descriptor.idProduct);
- le16_to_cpus(&dev->descriptor.bcdDevice);
+ le16_to_cpus(&dev->descriptor->bcdUSB);
+ le16_to_cpus(&dev->descriptor->idVendor);
+ le16_to_cpus(&dev->descriptor->idProduct);
+ le16_to_cpus(&dev->descriptor->bcdDevice);
/* only support for one config for now */
- usb_get_configuration_no(dev, &tmpbuf[0], 0);
- usb_parse_config(dev, &tmpbuf[0], 0);
+ usb_get_configuration_no(dev, buf, 0);
+ usb_parse_config(dev, buf, 0);
usb_set_maxpacket(dev);
/* we set the default configuration here */
if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
printf("failed to set default configuration " \
"len %d, status %lX\n", dev->act_len, dev->status);
- return -1;
+ goto err_out;
}
USB_PRINTF("new device: Mfr=%d, Product=%d, SerialNumber=%d\n",
- dev->descriptor.iManufacturer, dev->descriptor.iProduct,
- dev->descriptor.iSerialNumber);
+ dev->descriptor->iManufacturer, dev->descriptor->iProduct,
+ dev->descriptor->iSerialNumber);
memset(dev->mf, 0, sizeof(dev->mf));
memset(dev->prod, 0, sizeof(dev->prod));
memset(dev->serial, 0, sizeof(dev->serial));
- if (dev->descriptor.iManufacturer)
- usb_string(dev, dev->descriptor.iManufacturer,
+ if (dev->descriptor->iManufacturer)
+ usb_string(dev, dev->descriptor->iManufacturer,
dev->mf, sizeof(dev->mf));
- if (dev->descriptor.iProduct)
- usb_string(dev, dev->descriptor.iProduct,
+ if (dev->descriptor->iProduct)
+ usb_string(dev, dev->descriptor->iProduct,
dev->prod, sizeof(dev->prod));
- if (dev->descriptor.iSerialNumber)
- usb_string(dev, dev->descriptor.iSerialNumber,
+ if (dev->descriptor->iSerialNumber)
+ usb_string(dev, dev->descriptor->iSerialNumber,
dev->serial, sizeof(dev->serial));
/* now prode if the device is a hub */
usb_hub_probe(dev, 0);
@@ -441,7 +444,11 @@ static int usb_new_device(struct usb_device *dev)
register_device(&dev->dev);
list_add_tail(&dev->list, &usb_device_list);
- return 0;
+ err = 0;
+
+err_out:
+ dma_free(buf);
+ return err;
}
static struct usb_device *usb_alloc_new_device(void)
@@ -454,6 +461,8 @@ static struct usb_device *usb_alloc_new_device(void)
usbdev->devnum = dev_index + 1;
usbdev->maxchild = 0;
usbdev->dev.bus = &usb_bus_type;
+ usbdev->setup_packet = dma_alloc(sizeof(*usbdev->setup_packet));
+ usbdev->descriptor = dma_alloc(sizeof(*usbdev->descriptor));
dev_index++;
@@ -471,6 +480,8 @@ void usb_rescan(void)
unregister_device(&dev->dev);
if (dev->hub)
free(dev->hub);
+ dma_free(dev->setup_packet);
+ dma_free(dev->descriptor);
free(dev);
}
@@ -532,6 +543,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
{
struct usb_host *host = dev->host;
int ret;
+ struct devrequest *setup_packet = dev->setup_packet;
if ((timeout == 0) && (!asynch_allowed)) {
/* request for a asynch control pipe is not allowed */
@@ -539,17 +551,18 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
}
/* set setup command */
- setup_packet.requesttype = requesttype;
- setup_packet.request = request;
- setup_packet.value = cpu_to_le16(value);
- setup_packet.index = cpu_to_le16(index);
- setup_packet.length = cpu_to_le16(size);
+ setup_packet->requesttype = requesttype;
+ setup_packet->request = request;
+ setup_packet->value = cpu_to_le16(value);
+ setup_packet->index = cpu_to_le16(index);
+ setup_packet->length = cpu_to_le16(size);
USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
"value 0x%X index 0x%X length 0x%X\n",
request, requesttype, value, index, size);
dev->status = USB_ST_NOT_PROC; /*not yet processed */
- ret = host->submit_control_msg(dev, pipe, data, size, &setup_packet, timeout);
+ ret = host->submit_control_msg(dev, pipe, data, size, setup_packet,
+ timeout);
if (ret)
return ret;
@@ -1284,11 +1297,11 @@ int usb_driver_register(struct usb_driver *drv)
static int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
{
if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
- id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
+ id->idVendor != le16_to_cpu(dev->descriptor->idVendor))
return 0;
if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
- id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
+ id->idProduct != le16_to_cpu(dev->descriptor->idProduct))
return 0;
return 1;
@@ -1311,7 +1324,7 @@ static int usb_match_one_id(struct usb_device *usbdev,
/* The interface class, subclass, and protocol should never be
* checked for a match if the device class is Vendor Specific,
* unless the match record specifies the Vendor ID. */
- if (usbdev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+ if (usbdev->descriptor->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
(id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO))
return 0;
@@ -1371,7 +1384,8 @@ static int usb_match(struct device_d *dev, struct driver_d *drv)
struct usb_driver *usbdrv = container_of(dev->driver, struct usb_driver, driver);
const struct usb_device_id *id;
- debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
+ debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor->idVendor,
+ usbdev->descriptor->idProduct);
id = usb_match_id(usbdev, usbdrv->id_table);
if (id) {
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index fd70e623a6..44e58d7de0 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -22,6 +22,7 @@
#include <common.h>
#include <errno.h>
+#include <dma.h>
#include <usb/composite.h>
#include <asm/byteorder.h>
@@ -867,7 +868,7 @@ composite_unbind(struct usb_gadget *gadget)
composite->unbind(cdev);
if (cdev->req) {
- kfree(cdev->req->buf);
+ dma_free(cdev->req->buf);
usb_ep_free_request(gadget->ep0, cdev->req);
}
kfree(cdev);
@@ -911,7 +912,7 @@ static int __init composite_bind(struct usb_gadget *gadget)
cdev->req = usb_ep_alloc_request(gadget->ep0);
if (!cdev->req)
goto fail;
- cdev->req->buf = malloc(USB_BUFSIZ);
+ cdev->req->buf = dma_alloc(USB_BUFSIZ);
if (!cdev->req->buf)
goto fail;
cdev->req->complete = composite_setup_complete;
diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index f26c1e43d0..e205c65f32 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -40,6 +40,7 @@
* - make 'dnstate' attached to 'struct usb_device_instance'
*/
+#include <dma.h>
#include <asm/byteorder.h>
#include <usb/composite.h>
#include <linux/types.h>
@@ -183,7 +184,7 @@ dfu_unbind(struct usb_configuration *c, struct usb_function *f)
if (gadget_is_dualspeed(c->cdev->gadget))
free(f->hs_descriptors);
- free(dfu->dnreq->buf);
+ dma_free(dfu->dnreq->buf);
usb_ep_free_request(c->cdev->gadget->ep0, dfu->dnreq);
free(dfu);
}
@@ -602,7 +603,7 @@ static int dfu_bind_config(struct usb_configuration *c)
dfu->dnreq = usb_ep_alloc_request(c->cdev->gadget->ep0);
if (!dfu->dnreq)
printf("usb_ep_alloc_request failed\n");
- dfu->dnreq->buf = xmalloc(CONFIG_USBD_DFU_XFER_SIZE);
+ dfu->dnreq->buf = dma_alloc(CONFIG_USBD_DFU_XFER_SIZE);
dfu->dnreq->complete = dn_complete;
dfu->dnreq->zero = 0;
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 5b64ec2011..5537a0eb97 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -1,5 +1,6 @@
#include <common.h>
#include <errno.h>
+#include <dma.h>
#include <init.h>
#include <clock.h>
#include <usb/ch9.h>
@@ -8,7 +9,6 @@
#include <io.h>
#include <poller.h>
#include <asm/byteorder.h>
-#include <asm/mmu.h>
/* ### define USB registers here
*/
@@ -519,7 +519,7 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
* 2 + ((windex & USB_DIR_IN) ? 1 : 0))
#define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP))
-static struct usb_dr_device *dr_regs;
+static struct usb_dr_device __iomem *dr_regs;
static struct fsl_udc *udc_controller = NULL;
static const struct usb_endpoint_descriptor
@@ -2109,7 +2109,8 @@ static int struct_udc_setup(struct fsl_udc *udc,
udc->status_req = container_of(fsl_alloc_request(NULL),
struct fsl_req, req);
/* allocate a small amount of memory to get valid address */
- udc->status_req->req.buf = xmalloc(8);
+ udc->status_req->req.buf = dma_alloc(8);
+ udc->status_req->req.length = 8;
udc->resume_state = USB_STATE_NOTATTACHED;
udc->usb_state = USB_STATE_POWERED;
udc->ep0_dir = 0;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a2473a9141..c2f48ce428 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,63 +120,6 @@ static struct descriptor {
#define ehci_is_TDI() (ehci->flags & EHCI_HAS_TT)
-#ifdef CONFIG_MMU
-/*
- * Routines to handle (flush/invalidate) the dcache for the QH and qTD
- * structures and data buffers. This is needed on platforms using this
- * EHCI support with dcache enabled.
- */
-static void flush_invalidate(void *addr, int size, int flush)
-{
- if (flush) {
- dma_flush_range((unsigned long)addr, (unsigned long)(addr + size));
- } else {
- dma_inv_range((unsigned long)addr, (unsigned long)(addr + size));
- }
-}
-
-static void cache_qtd(struct qTD *qtd, int flush)
-{
- u32 *ptr = (u32 *)qtd->qt_buffer[0];
- int len = (qtd->qt_token & 0x7fff0000) >> 16;
-
- if (ptr && len)
- flush_invalidate(ptr, len, flush);
-}
-
-static void cache_qh(struct ehci_priv *ehci, int flush)
-{
- int i;
-
- flush_invalidate(ehci->qh_list, sizeof(struct QH) * NUM_QH, flush);
- flush_invalidate(ehci->td, sizeof(struct qTD) * NUM_TD, flush);
-
- for (i = 0; i < NUM_TD; i ++)
- cache_qtd(&ehci->td[i], flush);
-}
-
-static inline void ehci_flush_dcache(struct ehci_priv *ehci)
-{
- cache_qh(ehci, 1);
-}
-
-static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
-{
- cache_qh(ehci, 0);
-}
-#else /* CONFIG_MMU */
-/*
- *
- */
-static inline void ehci_flush_dcache(struct ehci_priv *ehci)
-{
-}
-
-static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
-{
-}
-#endif /* CONFIG_MMU */
-
static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
{
uint32_t result;
@@ -231,6 +174,9 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
int idx;
addr = (uint32_t) buf;
+ td->qtd_dma = addr;
+ td->length = sz;
+
idx = 0;
while (idx < 5) {
td->qt_buffer[idx] = cpu_to_hc32(addr);
@@ -264,7 +210,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
uint32_t endpt, token, usbsts;
uint32_t c, toggle;
uint32_t cmd;
- int ret = 0;
+ int ret = 0, i;
uint64_t start, timeout_val;
debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
@@ -296,11 +242,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
(dev->portnr << 23) |
(dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
qh->qh_endpt2 = cpu_to_hc32(endpt);
- qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
- qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+ qh->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+ qh->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
td = NULL;
- tdp = &qh->qh_overlay.qt_next;
+ tdp = &qh->qt_next;
toggle =
usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
@@ -363,7 +309,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
ehci->qh_list->qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
/* Flush dcache */
- ehci_flush_dcache(ehci);
+ if (IS_ENABLED(CONFIG_MMU)) {
+ for (i = 0; i < NUM_TD; i ++) {
+ struct qTD *qtd = &ehci->td[i];
+ if (!qtd->qtd_dma)
+ continue;
+ dma_flush_range(qtd->qtd_dma, qtd->qtd_dma + qtd->length);
+ }
+ }
usbsts = ehci_readl(&ehci->hcor->or_usbsts);
ehci_writel(&ehci->hcor->or_usbsts, (usbsts & 0x3f));
@@ -384,8 +337,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
start = get_time_ns();
vtd = td;
do {
- /* Invalidate dcache */
- ehci_invalidate_dcache(ehci);
token = hc32_to_cpu(vtd->qt_token);
if (is_timeout(start, timeout_val)) {
/* Disable async schedule. */
@@ -394,11 +345,20 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
ehci_writel(&ehci->hcor->or_usbcmd, cmd);
ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0, 100 * 1000);
- ehci_writel(&qh->qh_overlay.qt_token, 0);
+ ehci_writel(&qh->qt_token, 0);
return -ETIMEDOUT;
}
} while (token & 0x80);
+ if (IS_ENABLED(CONFIG_MMU)) {
+ for (i = 0; i < NUM_TD; i ++) {
+ struct qTD *qtd = &ehci->td[i];
+ if (!qtd->qtd_dma)
+ continue;
+ dma_inv_range(qtd->qtd_dma, qtd->qtd_dma + qtd->length);
+ }
+ }
+
/* Disable async schedule. */
cmd = ehci_readl(&ehci->hcor->or_usbcmd);
cmd &= ~CMD_ASE;
@@ -413,7 +373,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
- token = hc32_to_cpu(qh->qh_overlay.qt_token);
+ token = hc32_to_cpu(qh->qt_token);
if (!(token & 0x80)) {
debug("TOKEN=0x%08x\n", token);
switch (token & 0xfc) {
@@ -451,10 +411,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
fail:
printf("fail1\n");
- td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
+ td = (void *)hc32_to_cpu(qh->qt_next);
while (td != (void *)QT_NEXT_TERMINATE) {
- qh->qh_overlay.qt_next = td->qt_next;
- td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
+ qh->qt_next = td->qt_next;
+ td = (void *)hc32_to_cpu(qh->qt_next);
}
return -1;
}
@@ -770,9 +730,9 @@ static int ehci_init(struct usb_host *host)
ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
ehci->qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
ehci->qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
- ehci->qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
- ehci->qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
- ehci->qh_list->qh_overlay.qt_token = cpu_to_hc32(0x40);
+ ehci->qh_list->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+ ehci->qh_list->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+ ehci->qh_list->qt_token = cpu_to_hc32(0x40);
/* Set async. queue head pointer. */
ehci_writel(&ehci->hcor->or_asynclistaddr, (uint32_t)ehci->qh_list);
@@ -878,8 +838,8 @@ static int ehci_probe(struct device_d *dev)
ehci->hccr = dev_request_mem_region(dev, 0);
ehci->hcor = dev_request_mem_region(dev, 1);
- ehci->qh_list = xmemalign(32, sizeof(struct QH) * NUM_QH);
- ehci->td = xmemalign(32, sizeof(struct qTD) * NUM_TD);
+ ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD);
+ ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD);
host->init = ehci_init;
host->submit_int_msg = submit_int_msg;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index eac93db01c..b127b95bbe 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -166,7 +166,9 @@ struct qTD {
uint32_t qt_altnext;
uint32_t qt_token;
uint32_t qt_buffer[5];
-};
+ unsigned long qtd_dma;
+ size_t length;
+} __attribute__ ((aligned (32)));
/* Queue Head (QH). */
struct QH {
@@ -179,7 +181,11 @@ struct QH {
uint32_t qh_endpt1;
uint32_t qh_endpt2;
uint32_t qh_curtd;
- struct qTD qh_overlay;
+ /* qtd overlay (hardware parts of a struct qTD) */
+ uint32_t qt_next;
+ uint32_t qt_altnext;
+ uint32_t qt_token;
+ uint32_t qt_buffer[5];
/*
* Add dummy fill value to make the size of this struct
* aligned to 32 bytes
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 2ce7c6ecc5..b3e9909df0 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -64,7 +64,7 @@ static int at91_ohci_probe(struct device_d *dev)
writel(0, &regs->control);
add_generic_device("ohci", DEVICE_ID_DYNAMIC, NULL, dev->resource[0].start,
- dev->resource[0].size, IORESOURCE_MEM, NULL);
+ resource_size(&dev->resource[0]), IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 05e4094386..f10d827615 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -415,7 +415,7 @@ static void ohci_dump(struct ohci *controller, int verbose)
/* get a transfer request */
-int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
+static int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
{
struct ed *ed;
int i, size = 0;
@@ -498,7 +498,7 @@ int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
static inline int sohci_return_job(struct ohci *hc, struct urb_priv *urb)
{
#ifdef ENBALE_PIPE_INTERRUPT
- struct ohci_regs *regs = hc->regs;
+ struct ohci_regs __iomem *regs = hc->regs;
#endif
switch (usb_pipetype(urb->pipe)) {
@@ -848,7 +848,7 @@ static void td_fill(struct ohci *ohci, unsigned int info,
}
#endif
if (!len)
- data = 0;
+ data = NULL;
td->hwINFO = m32_swap(info);
td->hwCBP = virt_to_phys((void *)m32_swap((unsigned long)data));
@@ -894,7 +894,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe,
if (data_len)
data = buffer;
else
- data = 0;
+ data = NULL;
switch (usb_pipetype(pipe)) {
case PIPE_BULK:
@@ -1214,32 +1214,6 @@ static inline void wr_rh_portstat(struct ohci *ohci, int wIndex, __u32 value)
writel(value, &ohci->regs->roothub.portstatus[wIndex-1]);
}
-/* request to virtual root hub */
-
-int rh_check_port_status(struct ohci *controller)
-{
- __u32 temp, ndp, i;
- int res;
-
- res = -1;
- temp = roothub_a(controller);
- ndp = (temp & RH_A_NDP);
-#ifdef CONFIG_AT91C_PQFP_UHPBUG
- ndp = (ndp == 2) ? 1 : 0;
-#endif
- for (i = 0; i < ndp; i++) {
- temp = roothub_portstatus(controller, i);
- /* check for a device disconnect */
- if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
- (RH_PS_PESC | RH_PS_CSC)) &&
- ((temp & RH_PS_CCS) == 0)) {
- res = i;
- break;
- }
- }
- return res;
-}
-
static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int transfer_len, struct devrequest *cmd)
{
@@ -1502,7 +1476,7 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
/* common code for handling submit messages - used for all but root hub */
/* accesses. */
-int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+static int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, struct devrequest *setup, int interval,
int timeout)
{
@@ -1721,7 +1695,7 @@ static int hc_start(struct ohci *ohci)
static int hc_interrupt(struct ohci *ohci)
{
- struct ohci_regs *regs = ohci->regs;
+ struct ohci_regs __iomem *regs = ohci->regs;
int ints;
int stat = 0;
@@ -1840,7 +1814,7 @@ static int ohci_probe(struct device_d *dev)
usb_register_host(host);
- ohci->regs = (void *)dev->resource[0].start;
+ ohci->regs = dev_request_mem_region(dev, 0);
return 0;
}
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 913296319e..9c9b8375ce 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -408,7 +408,7 @@ struct ohci {
int disabled; /* e.g. got a UE, we're hung */
unsigned long flags; /* for HC bugs */
- struct ohci_regs *regs; /* OHCI controller's memory */
+ struct ohci_regs __iomem *regs; /* OHCI controller's memory */
int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/
struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e7a5972750..68170b65c0 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -26,6 +26,7 @@
#include <clock.h>
#include <scsi.h>
#include <errno.h>
+#include <dma.h>
#undef USB_STOR_DEBUG
@@ -65,8 +66,8 @@ int usb_stor_Bulk_clear_endpt_stall(struct us_data *us, unsigned int pipe)
/* Determine what the maximum LUN supported is */
int usb_stor_Bulk_max_lun(struct us_data *us)
{
- int len;
- unsigned char iobuf[1];
+ int len, ret = 0;
+ unsigned char *iobuf = dma_alloc(1);
/* issue the command */
iobuf[0] = 0;
@@ -81,7 +82,9 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
/* if we have a successful request, return the result */
if (len > 0)
- return (int)iobuf[0];
+ ret = iobuf[0];
+
+ dma_free(iobuf);
/*
* Some devices don't like GetMaxLUN. They may STALL the control
@@ -90,7 +93,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
* ways. In these cases the best approach is to use the default
* value: only one LUN.
*/
- return 0;
+ return ret;
}
int usb_stor_Bulk_transport(ccb *srb, struct us_data *us)
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index 0be465f892..d885570b24 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -86,7 +86,7 @@ static int fb_setup_mode(struct device_d *dev, struct param_d *param,
if (!ret) {
dev->resource[0].start = (resource_size_t)info->screen_base;
info->cdev.size = info->xres * info->yres * (info->bits_per_pixel >> 3);
- dev->resource[0].size = info->cdev.size;
+ dev->resource[0].end = info->cdev.size - 1;
dev_param_set_generic(dev, param, val);
} else
info->cdev.size = 0;
@@ -116,7 +116,7 @@ int register_framebuffer(struct fb_info *info)
info->cdev.priv = info;
dev->resource = xzalloc(sizeof(struct resource));
dev->resource[0].start = (resource_size_t)info->screen_base;
- dev->resource[0].size = info->cdev.size;
+ dev->resource[0].end = info->cdev.size - 1;
dev->resource[0].flags = IORESOURCE_MEM;
dev->num_resources = 1;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
new file mode 100644
index 0000000000..8fdc7a5aa8
--- /dev/null
+++ b/drivers/watchdog/Kconfig
@@ -0,0 +1,15 @@
+menuconfig WATCHDOG
+ bool "Watchdog support "
+ help
+ Many platforms support a watchdog to keep track of a working machine.
+ This framework provides routines to handle these watchdogs.
+
+if WATCHDOG
+
+config WATCHDOG_MXS28
+ bool "i.MX28"
+ depends on ARCH_IMX28
+ help
+ Add support for watchdog management for the i.MX28 SoC.
+
+endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
new file mode 100644
index 0000000000..b29103b6cc
--- /dev/null
+++ b/drivers/watchdog/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_WATCHDOG) += wd_core.o
+obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
diff --git a/drivers/watchdog/im28wd.c b/drivers/watchdog/im28wd.c
new file mode 100644
index 0000000000..b016910ec9
--- /dev/null
+++ b/drivers/watchdog/im28wd.c
@@ -0,0 +1,124 @@
+/*
+ * (c) 2012 Juergen Beisert <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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * Note: this driver works for the i.MX28 SoC. It might work for the
+ * i.MX23 Soc as well, but is not tested yet.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <errno.h>
+#include <malloc.h>
+#include <watchdog.h>
+
+#define MXS_RTC_CTRL 0x0
+#define MXS_RTC_SET_ADDR 0x4
+#define MXS_RTC_CLR_ADDR 0x8
+# define MXS_RTC_CTRL_WATCHDOGEN (1 << 4)
+
+#define MXS_RTC_STAT 0x10
+# define MXS_RTC_STAT_WD_PRESENT (1 << 29)
+
+#define MXS_RTC_WATCHDOG 0x50
+
+#define MXS_RTC_PERSISTENT0 0x60
+/* dubious meaning from inside the SoC's firmware ROM */
+# define MXS_RTC_PERSISTENT0_EXT_RST (1 << 21)
+/* dubious meaning from inside the SoC's firmware ROM */
+# define MXS_RTC_PERSISTENT0_THM_RST (1 << 20)
+
+#define MXS_RTC_PERSISTENT1 0x70
+/* dubious meaning from inside the SoC's firmware ROM */
+# define MXS_RTC_PERSISTENT1_FORCE_UPDATER (1 << 31)
+
+#define MXS_RTC_DEBUG 0xc0
+
+#define WDOG_TICK_RATE 1000 /* the watchdog uses a 1 kHz clock rate */
+
+struct imx28_wd {
+ struct watchdog wd;
+ void __iomem *regs;
+};
+
+#define to_imx28_wd(h) container_of(h, struct imx28_wd, wd)
+
+static int imx28_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
+{
+ struct imx28_wd *pwd = (struct imx28_wd *)to_imx28_wd(wd);
+ void __iomem *base;
+
+ if (timeout > (ULONG_MAX / WDOG_TICK_RATE))
+ return -EINVAL;
+
+ if (timeout) {
+ writel(timeout * WDOG_TICK_RATE, pwd->regs + MXS_RTC_WATCHDOG);
+ base = pwd->regs + MXS_RTC_SET_ADDR;
+ } else {
+ base = pwd->regs + MXS_RTC_CLR_ADDR;
+ }
+ writel(MXS_RTC_CTRL_WATCHDOGEN, base + MXS_RTC_CTRL);
+ writel(MXS_RTC_PERSISTENT1_FORCE_UPDATER, base + MXS_RTC_PERSISTENT1);
+
+ return 0;
+}
+
+static int imx28_wd_probe(struct device_d *dev)
+{
+ struct imx28_wd *priv;
+ int rc;
+
+ priv = xzalloc(sizeof(struct imx28_wd));
+ priv->regs = dev_request_mem_region(dev, 0);
+ priv->wd.set_timeout = imx28_watchdog_set_timeout;
+
+ if (!(readl(priv->regs + MXS_RTC_STAT) & MXS_RTC_STAT_WD_PRESENT)) {
+ rc = -ENODEV;
+ goto on_error;
+ }
+
+ /* disable the debug feature to ensure a working WD */
+ writel(0x00000000, priv->regs + MXS_RTC_DEBUG);
+
+ rc = watchdog_register(&priv->wd);
+ if (rc != 0)
+ goto on_error;
+
+ dev->priv = priv;
+ return 0;
+
+on_error:
+ free(priv);
+ return rc;
+}
+
+static void imx28_wd_remove(struct device_d *dev)
+{
+ struct imx28_wd *priv= dev->priv;
+ watchdog_deregister(&priv->wd);
+ free(priv);
+}
+
+static struct driver_d imx28_wd_driver = {
+ .name = "im28wd",
+ .probe = imx28_wd_probe,
+ .remove = imx28_wd_remove,
+};
+
+static int imx28_wd_init(void)
+{
+ register_driver(&imx28_wd_driver);
+ return 0;
+}
+
+device_initcall(imx28_wd_init);
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
new file mode 100644
index 0000000000..3d0cfc635d
--- /dev/null
+++ b/drivers/watchdog/wd_core.c
@@ -0,0 +1,57 @@
+/*
+ * (c) 2012 Juergen Beisert <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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/ctype.h>
+#include <watchdog.h>
+
+/*
+ * Note: this simple framework supports one watchdog only.
+ */
+static struct watchdog *watchdog;
+
+int watchdog_register(struct watchdog *wd)
+{
+ if (watchdog != NULL)
+ return -EBUSY;
+
+ watchdog = wd;
+ return 0;
+}
+EXPORT_SYMBOL(watchdog_register);
+
+int watchdog_deregister(struct watchdog *wd)
+{
+ if (watchdog == NULL || wd != watchdog)
+ return -ENODEV;
+
+ watchdog = NULL;
+ return 0;
+}
+EXPORT_SYMBOL(watchdog_deregister);
+
+/*
+ * start, stop or retrigger the watchdog
+ * timeout in [seconds]. timeout of '0' will disable the watchdog (if possible)
+ */
+int watchdog_set_timeout(unsigned timeout)
+{
+ if (watchdog == NULL)
+ return -ENODEV;
+
+ return watchdog->set_timeout(watchdog, timeout);
+}
+EXPORT_SYMBOL(watchdog_set_timeout);