summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-06-25 10:39:58 +0200
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-06-25 10:39:58 +0200
commited1d98d801dfb6384d0f2fff45ce1ebf884944ca (patch)
tree5a9487c67b75606d3a723b7acb9eda8da200c871 /drivers
parent754466ac95e92ebf40e25c6af6f13ab9b4d7c87b (diff)
parentba9b42c81b0734d53edfbb1fe4a6ded7de78c5ab (diff)
downloadtalos-obmc-uboot-ed1d98d801dfb6384d0f2fff45ce1ebf884944ca.tar.gz
talos-obmc-uboot-ed1d98d801dfb6384d0f2fff45ce1ebf884944ca.zip
Merge branch 'u-boot/master' into 'u-boot-arm/master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/device.c32
-rw-r--r--drivers/core/lists.c11
-rw-r--r--drivers/core/root.c9
-rw-r--r--drivers/core/uclass.c33
-rw-r--r--drivers/crypto/ace_sha.c4
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c5
-rw-r--r--drivers/ddr/fsl/interactive.c10
-rw-r--r--drivers/demo/demo-shape.c8
-rw-r--r--drivers/demo/demo-simple.c6
-rw-r--r--drivers/demo/demo-uclass.c6
-rw-r--r--drivers/dfu/dfu.c46
-rw-r--r--drivers/fpga/altera.c6
-rw-r--r--drivers/fpga/xilinx.c6
-rw-r--r--drivers/gpio/gpio-uclass.c30
-rw-r--r--drivers/gpio/sandbox.c36
-rw-r--r--drivers/i2c/kona_i2c.c2
-rw-r--r--drivers/misc/cros_ec_sandbox.c2
-rw-r--r--drivers/mmc/kona_sdhci.c8
-rw-r--r--drivers/mmc/mmc.c7
-rw-r--r--drivers/mmc/rpmb.c2
-rw-r--r--drivers/mtd/spi/sf_params.c1
-rw-r--r--drivers/mtd/spi/sf_probe.c20
-rw-r--r--drivers/net/phy/phy.c4
-rw-r--r--drivers/net/sh_eth.c45
-rw-r--r--drivers/net/sh_eth.h92
-rw-r--r--drivers/power/pmic/pmic_tps65090.c2
-rw-r--r--drivers/spi/fsl_espi.c138
-rw-r--r--drivers/spi/soft_spi.c18
-rw-r--r--drivers/usb/gadget/ci_udc.c173
-rw-r--r--drivers/usb/gadget/ci_udc.h2
30 files changed, 528 insertions, 236 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 55ba281be0..c73c339d18 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -30,9 +30,9 @@
* @dev: The device that is to be stripped of its children
* @return 0 on success, -ve on error
*/
-static int device_chld_unbind(struct device *dev)
+static int device_chld_unbind(struct udevice *dev)
{
- struct device *pos, *n;
+ struct udevice *pos, *n;
int ret, saved_ret = 0;
assert(dev);
@@ -51,9 +51,9 @@ static int device_chld_unbind(struct device *dev)
* @dev: The device whose children are to be removed
* @return 0 on success, -ve on error
*/
-static int device_chld_remove(struct device *dev)
+static int device_chld_remove(struct udevice *dev)
{
- struct device *pos, *n;
+ struct udevice *pos, *n;
int ret;
assert(dev);
@@ -67,10 +67,10 @@ static int device_chld_remove(struct device *dev)
return 0;
}
-int device_bind(struct device *parent, struct driver *drv, const char *name,
- void *platdata, int of_offset, struct device **devp)
+int device_bind(struct udevice *parent, struct driver *drv, const char *name,
+ void *platdata, int of_offset, struct udevice **devp)
{
- struct device *dev;
+ struct udevice *dev;
struct uclass *uc;
int ret = 0;
@@ -82,7 +82,7 @@ int device_bind(struct device *parent, struct driver *drv, const char *name,
if (ret)
return ret;
- dev = calloc(1, sizeof(struct device));
+ dev = calloc(1, sizeof(struct udevice));
if (!dev)
return -ENOMEM;
@@ -129,8 +129,8 @@ fail_bind:
return ret;
}
-int device_bind_by_name(struct device *parent, const struct driver_info *info,
- struct device **devp)
+int device_bind_by_name(struct udevice *parent, const struct driver_info *info,
+ struct udevice **devp)
{
struct driver *drv;
@@ -142,7 +142,7 @@ int device_bind_by_name(struct device *parent, const struct driver_info *info,
-1, devp);
}
-int device_unbind(struct device *dev)
+int device_unbind(struct udevice *dev)
{
struct driver *drv;
int ret;
@@ -181,7 +181,7 @@ int device_unbind(struct device *dev)
* device_free() - Free memory buffers allocated by a device
* @dev: Device that is to be started
*/
-static void device_free(struct device *dev)
+static void device_free(struct udevice *dev)
{
int size;
@@ -200,7 +200,7 @@ static void device_free(struct device *dev)
}
}
-int device_probe(struct device *dev)
+int device_probe(struct udevice *dev)
{
struct driver *drv;
int size = 0;
@@ -279,7 +279,7 @@ fail:
return ret;
}
-int device_remove(struct device *dev)
+int device_remove(struct udevice *dev)
{
struct driver *drv;
int ret;
@@ -327,7 +327,7 @@ err:
return ret;
}
-void *dev_get_platdata(struct device *dev)
+void *dev_get_platdata(struct udevice *dev)
{
if (!dev) {
dm_warn("%s: null device", __func__);
@@ -337,7 +337,7 @@ void *dev_get_platdata(struct device *dev)
return dev->platdata;
}
-void *dev_get_priv(struct device *dev)
+void *dev_get_priv(struct udevice *dev)
{
if (!dev) {
dm_warn("%s: null device", __func__);
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 4f2c12631d..afb59d1d8d 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -14,6 +14,7 @@
#include <dm/platdata.h>
#include <dm/uclass.h>
#include <dm/util.h>
+#include <fdtdec.h>
#include <linux/compiler.h>
struct driver *lists_driver_lookup_name(const char *name)
@@ -60,13 +61,13 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
return NULL;
}
-int lists_bind_drivers(struct device *parent)
+int lists_bind_drivers(struct udevice *parent)
{
struct driver_info *info =
ll_entry_start(struct driver_info, driver_info);
const int n_ents = ll_entry_count(struct driver_info, driver_info);
struct driver_info *entry;
- struct device *dev;
+ struct udevice *dev;
int result = 0;
int ret;
@@ -94,7 +95,7 @@ int lists_bind_drivers(struct device *parent)
* tree error
*/
static int driver_check_compatible(const void *blob, int offset,
- const struct device_id *of_match)
+ const struct udevice_id *of_match)
{
int ret;
@@ -116,12 +117,12 @@ static int driver_check_compatible(const void *blob, int offset,
return -ENOENT;
}
-int lists_bind_fdt(struct device *parent, const void *blob, int offset)
+int lists_bind_fdt(struct udevice *parent, const void *blob, int offset)
{
struct driver *driver = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver);
struct driver *entry;
- struct device *dev;
+ struct udevice *dev;
const char *name;
int result = 0;
int ret;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 407bc0d046..1cbb096494 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <errno.h>
#include <malloc.h>
+#include <libfdt.h>
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
@@ -24,7 +25,7 @@ static const struct driver_info root_info = {
.name = "root_driver",
};
-struct device *dm_root(void)
+struct udevice *dm_root(void)
{
if (!gd->dm_root) {
dm_warn("Virtual root driver does not exist!\n");
@@ -42,9 +43,9 @@ int dm_init(void)
dm_warn("Virtual root driver already exists!\n");
return -EINVAL;
}
- INIT_LIST_HEAD(&gd->uclass_root);
+ INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
- ret = device_bind_by_name(NULL, &root_info, &gd->dm_root);
+ ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST);
if (ret)
return ret;
@@ -55,7 +56,7 @@ int dm_scan_platdata(void)
{
int ret;
- ret = lists_bind_drivers(gd->dm_root);
+ ret = lists_bind_drivers(DM_ROOT_NON_CONST);
if (ret == -ENOENT) {
dm_warn("Some drivers were not found\n");
ret = 0;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 4df5a8bd39..34723ec42a 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -75,7 +75,7 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp)
uc->uc_drv = uc_drv;
INIT_LIST_HEAD(&uc->sibling_node);
INIT_LIST_HEAD(&uc->dev_head);
- list_add(&uc->sibling_node, &gd->uclass_root);
+ list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);
if (uc_drv->init) {
ret = uc_drv->init(uc);
@@ -101,7 +101,7 @@ fail_mem:
int uclass_destroy(struct uclass *uc)
{
struct uclass_driver *uc_drv;
- struct device *dev, *tmp;
+ struct udevice *dev, *tmp;
int ret;
list_for_each_entry_safe(dev, tmp, &uc->dev_head, uclass_node) {
@@ -137,10 +137,10 @@ int uclass_get(enum uclass_id id, struct uclass **ucp)
return 0;
}
-int uclass_find_device(enum uclass_id id, int index, struct device **devp)
+int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
{
struct uclass *uc;
- struct device *dev;
+ struct udevice *dev;
int ret;
*devp = NULL;
@@ -158,9 +158,9 @@ int uclass_find_device(enum uclass_id id, int index, struct device **devp)
return -ENODEV;
}
-int uclass_get_device(enum uclass_id id, int index, struct device **devp)
+int uclass_get_device(enum uclass_id id, int index, struct udevice **devp)
{
- struct device *dev;
+ struct udevice *dev;
int ret;
*devp = NULL;
@@ -177,10 +177,10 @@ int uclass_get_device(enum uclass_id id, int index, struct device **devp)
return 0;
}
-int uclass_first_device(enum uclass_id id, struct device **devp)
+int uclass_first_device(enum uclass_id id, struct udevice **devp)
{
struct uclass *uc;
- struct device *dev;
+ struct udevice *dev;
int ret;
*devp = NULL;
@@ -190,7 +190,7 @@ int uclass_first_device(enum uclass_id id, struct device **devp)
if (list_empty(&uc->dev_head))
return 0;
- dev = list_first_entry(&uc->dev_head, struct device, uclass_node);
+ dev = list_first_entry(&uc->dev_head, struct udevice, uclass_node);
ret = device_probe(dev);
if (ret)
return ret;
@@ -199,16 +199,17 @@ int uclass_first_device(enum uclass_id id, struct device **devp)
return 0;
}
-int uclass_next_device(struct device **devp)
+int uclass_next_device(struct udevice **devp)
{
- struct device *dev = *devp;
+ struct udevice *dev = *devp;
int ret;
*devp = NULL;
if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head))
return 0;
- dev = list_entry(dev->uclass_node.next, struct device, uclass_node);
+ dev = list_entry(dev->uclass_node.next, struct udevice,
+ uclass_node);
ret = device_probe(dev);
if (ret)
return ret;
@@ -217,7 +218,7 @@ int uclass_next_device(struct device **devp)
return 0;
}
-int uclass_bind_device(struct device *dev)
+int uclass_bind_device(struct udevice *dev)
{
struct uclass *uc;
int ret;
@@ -237,7 +238,7 @@ int uclass_bind_device(struct device *dev)
return 0;
}
-int uclass_unbind_device(struct device *dev)
+int uclass_unbind_device(struct udevice *dev)
{
struct uclass *uc;
int ret;
@@ -253,7 +254,7 @@ int uclass_unbind_device(struct device *dev)
return 0;
}
-int uclass_post_probe_device(struct device *dev)
+int uclass_post_probe_device(struct udevice *dev)
{
struct uclass_driver *uc_drv = dev->uclass->uc_drv;
@@ -263,7 +264,7 @@ int uclass_post_probe_device(struct device *dev)
return 0;
}
-int uclass_pre_remove_device(struct device *dev)
+int uclass_pre_remove_device(struct udevice *dev)
{
struct uclass_driver *uc_drv;
struct uclass *uc;
diff --git a/drivers/crypto/ace_sha.c b/drivers/crypto/ace_sha.c
index ed4f541823..efef491123 100644
--- a/drivers/crypto/ace_sha.c
+++ b/drivers/crypto/ace_sha.c
@@ -8,8 +8,8 @@
#include "ace_sha.h"
#ifdef CONFIG_SHA_HW_ACCEL
-#include <sha256.h>
-#include <sha1.h>
+#include <u-boot/sha256.h>
+#include <u-boot/sha1.h>
#include <asm/errno.h>
/* SHA1 value for the message of zero length */
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 78e82bba3d..dcf6287f66 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -2304,5 +2304,10 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
ddr->debug[2] = 0x00000400;
ddr->debug[4] = 0xff800000;
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004508
+ if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))
+ ddr->debug[2] |= 0x00000200; /* set bit 22 */
+#endif
+
return check_fsl_memctl_config_regs(ddr);
}
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index cfe1e1f55a..7fb418744e 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -12,6 +12,7 @@
*/
#include <common.h>
+#include <cli.h>
#include <linux/ctype.h>
#include <asm/types.h>
#include <asm/io.h>
@@ -1578,7 +1579,7 @@ void ddr4_spd_dump(const struct ddr4_spd_eeprom_s *spd)
printf("%-3d-%3d: ", 128, 255);
for (i = 128; i <= 255; i++)
- printf("%02x", spd->mod_section.uc[i - 60]);
+ printf("%02x", spd->mod_section.uc[i - 128]);
break;
}
@@ -1864,11 +1865,12 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set)
} else {
/*
* No need to worry for buffer overflow here in
- * this function; readline() maxes out at CFG_CBSIZE
+ * this function; cli_readline() maxes out at
+ * CFG_CBSIZE
*/
- readline_into_buffer(prompt, buffer, 0);
+ cli_readline_into_buffer(prompt, buffer, 0);
}
- argc = parse_line(buffer, argv);
+ argc = cli_simple_parse_line(buffer, argv);
if (argc == 0)
continue;
diff --git a/drivers/demo/demo-shape.c b/drivers/demo/demo-shape.c
index 2f0eb96bb6..3fa9c59947 100644
--- a/drivers/demo/demo-shape.c
+++ b/drivers/demo/demo-shape.c
@@ -23,7 +23,7 @@ struct shape_data {
};
/* Crazy little function to draw shapes on the console */
-static int shape_hello(struct device *dev, int ch)
+static int shape_hello(struct udevice *dev, int ch)
{
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
struct shape_data *data = dev_get_priv(dev);
@@ -81,7 +81,7 @@ static int shape_hello(struct device *dev, int ch)
return 0;
}
-static int shape_status(struct device *dev, int *status)
+static int shape_status(struct udevice *dev, int *status)
{
struct shape_data *data = dev_get_priv(dev);
@@ -94,7 +94,7 @@ static const struct demo_ops shape_ops = {
.status = shape_status,
};
-static int shape_ofdata_to_platdata(struct device *dev)
+static int shape_ofdata_to_platdata(struct udevice *dev)
{
struct dm_demo_pdata *pdata = dev_get_platdata(dev);
int ret;
@@ -111,7 +111,7 @@ static int shape_ofdata_to_platdata(struct device *dev)
return 0;
}
-static const struct device_id demo_shape_id[] = {
+static const struct udevice_id demo_shape_id[] = {
{ "demo-shape", 0 },
{ },
};
diff --git a/drivers/demo/demo-simple.c b/drivers/demo/demo-simple.c
index 6ba8131728..2bcb7dfb47 100644
--- a/drivers/demo/demo-simple.c
+++ b/drivers/demo/demo-simple.c
@@ -12,7 +12,7 @@
#include <dm-demo.h>
#include <asm/io.h>
-static int simple_hello(struct device *dev, int ch)
+static int simple_hello(struct udevice *dev, int ch)
{
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
@@ -26,13 +26,13 @@ static const struct demo_ops simple_ops = {
.hello = simple_hello,
};
-static int demo_shape_ofdata_to_platdata(struct device *dev)
+static int demo_shape_ofdata_to_platdata(struct udevice *dev)
{
/* Parse the data that is common with all demo devices */
return demo_parse_dt(dev);
}
-static const struct device_id demo_shape_id[] = {
+static const struct udevice_id demo_shape_id[] = {
{ "demo-simple", 0 },
{ },
};
diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c
index 48588be907..636fd8831f 100644
--- a/drivers/demo/demo-uclass.c
+++ b/drivers/demo/demo-uclass.c
@@ -22,7 +22,7 @@ UCLASS_DRIVER(demo) = {
.id = UCLASS_DEMO,
};
-int demo_hello(struct device *dev, int ch)
+int demo_hello(struct udevice *dev, int ch)
{
const struct demo_ops *ops = device_get_ops(dev);
@@ -32,7 +32,7 @@ int demo_hello(struct device *dev, int ch)
return ops->hello(dev, ch);
}
-int demo_status(struct device *dev, int *status)
+int demo_status(struct udevice *dev, int *status)
{
const struct demo_ops *ops = device_get_ops(dev);
@@ -42,7 +42,7 @@ int demo_status(struct device *dev, int *status)
return ops->status(dev, status);
}
-int demo_parse_dt(struct device *dev)
+int demo_parse_dt(struct udevice *dev)
{
struct dm_demo_pdata *pdata = dev_get_platdata(dev);
int dn = dev->of_offset;
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index a93810934a..dc09ff6466 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -13,6 +13,7 @@
#include <mmc.h>
#include <fat.h>
#include <dfu.h>
+#include <hash.h>
#include <linux/list.h>
#include <linux/compiler.h>
@@ -20,6 +21,7 @@ static bool dfu_reset_request;
static LIST_HEAD(dfu_list);
static int dfu_alt_num;
static int alt_num_cnt;
+static struct hash_algo *dfu_hash_algo;
bool dfu_reset(void)
{
@@ -99,6 +101,23 @@ unsigned char *dfu_get_buf(void)
return dfu_buf;
}
+static char *dfu_get_hash_algo(void)
+{
+ char *s;
+
+ s = getenv("dfu_hash_algo");
+ if (!s)
+ return NULL;
+
+ if (!strcmp(s, "crc32")) {
+ debug("%s: DFU hash method: %s\n", __func__, s);
+ return s;
+ }
+
+ error("DFU hash method: %s not supported!\n", s);
+ return NULL;
+}
+
static int dfu_write_buffer_drain(struct dfu_entity *dfu)
{
long w_size;
@@ -109,8 +128,9 @@ static int dfu_write_buffer_drain(struct dfu_entity *dfu)
if (w_size == 0)
return 0;
- /* update CRC32 */
- dfu->crc = crc32(dfu->crc, dfu->i_buf_start, w_size);
+ if (dfu_hash_algo)
+ dfu_hash_algo->hash_update(dfu_hash_algo, &dfu->crc,
+ dfu->i_buf_start, w_size, 0);
ret = dfu->write_medium(dfu, dfu->offset, dfu->i_buf_start, &w_size);
if (ret)
@@ -138,7 +158,9 @@ int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
if (dfu->flush_medium)
ret = dfu->flush_medium(dfu);
- printf("\nDFU complete CRC32: 0x%08x\n", dfu->crc);
+ if (dfu_hash_algo)
+ printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name,
+ dfu->crc);
/* clear everything */
dfu_free_buf();
@@ -238,7 +260,11 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
/* consume */
if (chunk > 0) {
memcpy(buf, dfu->i_buf, chunk);
- dfu->crc = crc32(dfu->crc, buf, chunk);
+ if (dfu_hash_algo)
+ dfu_hash_algo->hash_update(dfu_hash_algo,
+ &dfu->crc, buf,
+ chunk, 0);
+
dfu->i_buf += chunk;
dfu->b_left -= chunk;
dfu->r_left -= chunk;
@@ -322,7 +348,9 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
}
if (ret < size) {
- debug("%s: %s CRC32: 0x%x\n", __func__, dfu->name, dfu->crc);
+ if (dfu_hash_algo)
+ debug("%s: %s %s: 0x%x\n", __func__, dfu->name,
+ dfu_hash_algo->name, dfu->crc);
puts("\nUPLOAD ... done\nCtrl+C to exit ...\n");
dfu_free_buf();
@@ -397,6 +425,14 @@ int dfu_config_entities(char *env, char *interface, int num)
dfu_alt_num = dfu_find_alt_num(env);
debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num);
+ dfu_hash_algo = NULL;
+ s = dfu_get_hash_algo();
+ if (s) {
+ ret = hash_lookup_algo(s, &dfu_hash_algo);
+ if (ret)
+ error("Hash algorithm %s not supported\n", s);
+ }
+
dfu = calloc(sizeof(*dfu), dfu_alt_num);
if (!dfu)
return -1;
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index af189f4ef4..6e34a8e56e 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -153,9 +153,9 @@ int altera_info( Altera_desc *desc )
printf ("Unsupported interface type, %d\n", desc->iface);
}
- printf ("Device Size: \t%d bytes\n"
- "Cookie: \t0x%x (%d)\n",
- desc->size, desc->cookie, desc->cookie);
+ printf("Device Size: \t%zd bytes\n"
+ "Cookie: \t0x%x (%d)\n",
+ desc->size, desc->cookie, desc->cookie);
if (desc->iface_fns) {
printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index 3795c1aff6..adb4b8cd25 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -220,9 +220,9 @@ int xilinx_info(xilinx_desc *desc)
printf ("Unsupported interface type, %d\n", desc->iface);
}
- printf ("Device Size: \t%d bytes\n"
- "Cookie: \t0x%x (%d)\n",
- desc->size, desc->cookie, desc->cookie);
+ printf("Device Size: \t%zd bytes\n"
+ "Cookie: \t0x%x (%d)\n",
+ desc->size, desc->cookie, desc->cookie);
if (desc->name)
printf("Device name: \t%s\n", desc->name);
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 56bfd11466..f1bbc58796 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -17,11 +17,11 @@
* or GPIO blocks registered with the GPIO controller. Returns
* entry on success, NULL on error.
*/
-static int gpio_to_device(unsigned int gpio, struct device **devp,
+static int gpio_to_device(unsigned int gpio, struct udevice **devp,
unsigned int *offset)
{
struct gpio_dev_priv *uc_priv;
- struct device *dev;
+ struct udevice *dev;
int ret;
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
@@ -40,11 +40,11 @@ static int gpio_to_device(unsigned int gpio, struct device **devp,
return ret ? ret : -EINVAL;
}
-int gpio_lookup_name(const char *name, struct device **devp,
+int gpio_lookup_name(const char *name, struct udevice **devp,
unsigned int *offsetp, unsigned int *gpiop)
{
struct gpio_dev_priv *uc_priv;
- struct device *dev;
+ struct udevice *dev;
int ret;
if (devp)
@@ -58,7 +58,7 @@ int gpio_lookup_name(const char *name, struct device **devp,
uc_priv = dev->uclass_priv;
len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
- if (!strncmp(name, uc_priv->bank_name, len)) {
+ if (!strncasecmp(name, uc_priv->bank_name, len)) {
if (strict_strtoul(name + len, 10, &offset))
continue;
if (devp)
@@ -86,7 +86,7 @@ int gpio_lookup_name(const char *name, struct device **devp,
int gpio_request(unsigned gpio, const char *label)
{
unsigned int offset;
- struct device *dev;
+ struct udevice *dev;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
@@ -110,7 +110,7 @@ int gpio_request(unsigned gpio, const char *label)
int gpio_free(unsigned gpio)
{
unsigned int offset;
- struct device *dev;
+ struct udevice *dev;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
@@ -133,7 +133,7 @@ int gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio)
{
unsigned int offset;
- struct device *dev;
+ struct udevice *dev;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
@@ -155,7 +155,7 @@ int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value)
{
unsigned int offset;
- struct device *dev;
+ struct udevice *dev;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
@@ -177,7 +177,7 @@ int gpio_direction_output(unsigned gpio, int value)
int gpio_get_value(unsigned gpio)
{
unsigned int offset;
- struct device *dev;
+ struct udevice *dev;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
@@ -199,7 +199,7 @@ int gpio_get_value(unsigned gpio)
int gpio_set_value(unsigned gpio, int value)
{
unsigned int offset;
- struct device *dev;
+ struct udevice *dev;
int ret;
ret = gpio_to_device(gpio, &dev, &offset);
@@ -209,7 +209,7 @@ int gpio_set_value(unsigned gpio, int value)
return gpio_get_ops(dev)->set_value(dev, offset, value);
}
-const char *gpio_get_bank_info(struct device *dev, int *bit_count)
+const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
{
struct gpio_dev_priv *priv;
@@ -225,7 +225,7 @@ const char *gpio_get_bank_info(struct device *dev, int *bit_count)
static int gpio_renumber(void)
{
struct gpio_dev_priv *uc_priv;
- struct device *dev;
+ struct udevice *dev;
struct uclass *uc;
unsigned base;
int ret;
@@ -247,12 +247,12 @@ static int gpio_renumber(void)
return 0;
}
-static int gpio_post_probe(struct device *dev)
+static int gpio_post_probe(struct udevice *dev)
{
return gpio_renumber();
}
-static int gpio_pre_remove(struct device *dev)
+static int gpio_pre_remove(struct udevice *dev)
{
return gpio_renumber();
}
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 22b6a5f794..75ada5d387 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -22,7 +22,7 @@ struct gpio_state {
};
/* Access routines for GPIO state */
-static u8 *get_gpio_flags(struct device *dev, unsigned offset)
+static u8 *get_gpio_flags(struct udevice *dev, unsigned offset)
{
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
struct gpio_state *state = dev_get_priv(dev);
@@ -36,12 +36,12 @@ static u8 *get_gpio_flags(struct device *dev, unsigned offset)
return &state[offset].flags;
}
-static int get_gpio_flag(struct device *dev, unsigned offset, int flag)
+static int get_gpio_flag(struct udevice *dev, unsigned offset, int flag)
{
return (*get_gpio_flags(dev, offset) & flag) != 0;
}
-static int set_gpio_flag(struct device *dev, unsigned offset, int flag,
+static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag,
int value)
{
u8 *gpio = get_gpio_flags(dev, offset);
@@ -54,7 +54,7 @@ static int set_gpio_flag(struct device *dev, unsigned offset, int flag,
return 0;
}
-static int check_reserved(struct device *dev, unsigned offset,
+static int check_reserved(struct udevice *dev, unsigned offset,
const char *func)
{
if (!get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
@@ -70,24 +70,24 @@ static int check_reserved(struct device *dev, unsigned offset,
* Back-channel sandbox-internal-only access to GPIO state
*/
-int sandbox_gpio_get_value(struct device *dev, unsigned offset)
+int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
{
if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
debug("sandbox_gpio: get_value on output gpio %u\n", offset);
return get_gpio_flag(dev, offset, GPIOF_HIGH);
}
-int sandbox_gpio_set_value(struct device *dev, unsigned offset, int value)
+int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
return set_gpio_flag(dev, offset, GPIOF_HIGH, value);
}
-int sandbox_gpio_get_direction(struct device *dev, unsigned offset)
+int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
{
return get_gpio_flag(dev, offset, GPIOF_OUTPUT);
}
-int sandbox_gpio_set_direction(struct device *dev, unsigned offset, int output)
+int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
{
return set_gpio_flag(dev, offset, GPIOF_OUTPUT, output);
}
@@ -97,7 +97,7 @@ int sandbox_gpio_set_direction(struct device *dev, unsigned offset, int output)
*/
/* set GPIO port 'offset' as an input */
-static int sb_gpio_direction_input(struct device *dev, unsigned offset)
+static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
{
debug("%s: offset:%u\n", __func__, offset);
@@ -108,7 +108,7 @@ static int sb_gpio_direction_input(struct device *dev, unsigned offset)
}
/* set GPIO port 'offset' as an output, with polarity 'value' */
-static int sb_gpio_direction_output(struct device *dev, unsigned offset,
+static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
@@ -121,7 +121,7 @@ static int sb_gpio_direction_output(struct device *dev, unsigned offset,
}
/* read GPIO IN value of port 'offset' */
-static int sb_gpio_get_value(struct device *dev, unsigned offset)
+static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
{
debug("%s: offset:%u\n", __func__, offset);
@@ -132,7 +132,7 @@ static int sb_gpio_get_value(struct device *dev, unsigned offset)
}
/* write GPIO OUT value to port 'offset' */
-static int sb_gpio_set_value(struct device *dev, unsigned offset, int value)
+static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
@@ -148,7 +148,7 @@ static int sb_gpio_set_value(struct device *dev, unsigned offset, int value)
return sandbox_gpio_set_value(dev, offset, value);
}
-static int sb_gpio_request(struct device *dev, unsigned offset,
+static int sb_gpio_request(struct udevice *dev, unsigned offset,
const char *label)
{
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
@@ -171,7 +171,7 @@ static int sb_gpio_request(struct device *dev, unsigned offset,
return set_gpio_flag(dev, offset, GPIOF_RESERVED, 1);
}
-static int sb_gpio_free(struct device *dev, unsigned offset)
+static int sb_gpio_free(struct udevice *dev, unsigned offset)
{
struct gpio_state *state = dev_get_priv(dev);
@@ -184,7 +184,7 @@ static int sb_gpio_free(struct device *dev, unsigned offset)
return set_gpio_flag(dev, offset, GPIOF_RESERVED, 0);
}
-static int sb_gpio_get_state(struct device *dev, unsigned int offset,
+static int sb_gpio_get_state(struct udevice *dev, unsigned int offset,
char *buf, int bufsize)
{
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
@@ -213,7 +213,7 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
.get_state = sb_gpio_get_state,
};
-static int sandbox_gpio_ofdata_to_platdata(struct device *dev)
+static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
@@ -225,7 +225,7 @@ static int sandbox_gpio_ofdata_to_platdata(struct device *dev)
return 0;
}
-static int gpio_sandbox_probe(struct device *dev)
+static int gpio_sandbox_probe(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
@@ -239,7 +239,7 @@ static int gpio_sandbox_probe(struct device *dev)
return 0;
}
-static const struct device_id sandbox_gpio_ids[] = {
+static const struct udevice_id sandbox_gpio_ids[] = {
{ .compatible = "sandbox,gpio" },
{ }
};
diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c
index 0b1715abf0..5eab338cfc 100644
--- a/drivers/i2c/kona_i2c.c
+++ b/drivers/i2c/kona_i2c.c
@@ -663,7 +663,7 @@ static int kona_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
static int kona_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
- struct i2c_msg msg[0];
+ struct i2c_msg msg[1];
unsigned char msgbuf0[64];
unsigned int i;
struct bcm_kona_i2c_dev *dev = kona_get_dev(adap);
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 4bb1d60e5a..8a04af557d 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -13,7 +13,7 @@
#include <hash.h>
#include <malloc.h>
#include <os.h>
-#include <sha256.h>
+#include <u-boot/sha256.h>
#include <spi.h>
#include <asm/state.h>
#include <asm/sdl.h>
diff --git a/drivers/mmc/kona_sdhci.c b/drivers/mmc/kona_sdhci.c
index 77e42c8afe..f804f4c0db 100644
--- a/drivers/mmc/kona_sdhci.c
+++ b/drivers/mmc/kona_sdhci.c
@@ -113,16 +113,20 @@ int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
__func__, dev_index);
ret = -EINVAL;
}
- if (ret)
+ if (ret) {
+ free(host);
return ret;
+ }
host->name = "kona-sdhci";
host->ioaddr = reg_base;
host->quirks = quirks;
host->host_caps = MMC_MODE_HC;
- if (init_kona_mmc_core(host))
+ if (init_kona_mmc_core(host)) {
+ free(host);
return -EINVAL;
+ }
if (quirks & SDHCI_QUIRK_REG32_RW)
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 55c2c68cdb..b5477b1271 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -10,6 +10,7 @@
#include <config.h>
#include <common.h>
#include <command.h>
+#include <errno.h>
#include <mmc.h>
#include <part.h>
#include <malloc.h>
@@ -564,19 +565,19 @@ int mmc_select_hwpart(int dev_num, int hwpart)
int ret;
if (!mmc)
- return -1;
+ return -ENODEV;
if (mmc->part_num == hwpart)
return 0;
if (mmc->part_config == MMCPART_NOAVAILABLE) {
printf("Card doesn't support part_switch\n");
- return -1;
+ return -EMEDIUMTYPE;
}
ret = mmc_switch_part(dev_num, hwpart);
if (ret)
- return -1;
+ return ret;
mmc->part_num = hwpart;
diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c
index 05936f5d1f..9d0b8bc0c8 100644
--- a/drivers/mmc/rpmb.c
+++ b/drivers/mmc/rpmb.c
@@ -11,7 +11,7 @@
#include <config.h>
#include <common.h>
#include <mmc.h>
-#include <sha256.h>
+#include <u-boot/sha256.h>
#include "mmc_private.h"
/* Request codes */
diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
index eb372b7575..ac886fd071 100644
--- a/drivers/mtd/spi/sf_params.c
+++ b/drivers/mtd/spi/sf_params.c
@@ -60,6 +60,7 @@ const struct spi_flash_params spi_flash_params_table[] = {
{"S25FL256S_64K", 0x010219, 0x4d01, 64 * 1024, 512, RD_FULL, WR_QPP},
{"S25FL512S_256K", 0x010220, 0x4d00, 256 * 1024, 256, RD_FULL, WR_QPP},
{"S25FL512S_64K", 0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL, WR_QPP},
+ {"S25FL512S_512K", 0x010220, 0x4f00, 256 * 1024, 256, RD_FULL, WR_QPP},
#endif
#ifdef CONFIG_SPI_FLASH_STMICRO /* STMICRO */
{"M25P10", 0x202011, 0x0, 32 * 1024, 4, 0, 0},
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 0a46fe38da..36ae5e0a77 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -197,16 +197,6 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
/* Go for default supported write cmd */
flash->write_cmd = CMD_PAGE_PROGRAM;
- /* Set the quad enable bit - only for quad commands */
- if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) ||
- (flash->read_cmd == CMD_READ_QUAD_IO_FAST) ||
- (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) {
- if (spi_flash_set_qeb(flash, idcode[0])) {
- debug("SF: Fail to set QEB for %02x\n", idcode[0]);
- return NULL;
- }
- }
-
/* Read dummy_byte: dummy byte is determined based on the
* dummy cycles of a particular command.
* Fast commands - dummy_byte = dummy_cycles/8
@@ -327,6 +317,16 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
if (!flash)
goto err_read_id;
+ /* Set the quad enable bit - only for quad commands */
+ if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) ||
+ (flash->read_cmd == CMD_READ_QUAD_IO_FAST) ||
+ (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) {
+ if (spi_flash_set_qeb(flash, idcode[0])) {
+ debug("SF: Fail to set QEB for %02x\n", idcode[0]);
+ return NULL;
+ }
+ }
+
#ifdef CONFIG_OF_CONTROL
if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
debug("SF: FDT decode error\n");
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 230ed97dd1..aac85c4d09 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -609,10 +609,8 @@ static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
while (phy_mask) {
int addr = ffs(phy_mask) - 1;
int r = get_phy_id(bus, addr, devad, &phy_id);
- if (r < 0)
- return ERR_PTR(r);
/* If the PHY ID is mostly f's, we didn't find anything */
- if ((phy_id & 0x1fffffff) != 0x1fffffff)
+ if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff)
return phy_device_create(bus, addr, phy_id, interface);
phy_mask &= ~(1 << addr);
}
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 5e132f2b53..81e8ddbbc7 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -67,7 +67,8 @@ int sh_eth_send(struct eth_device *dev, void *packet, int len)
/* packet must be a 4 byte boundary */
if ((int)packet & 3) {
- printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__);
+ printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n"
+ , __func__);
ret = -EFAULT;
goto err;
}
@@ -148,7 +149,7 @@ int sh_eth_recv(struct eth_device *dev)
static int sh_eth_reset(struct sh_eth_dev *eth)
{
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
int ret = 0, i;
/* Start e-dmac transmitter and receiver */
@@ -156,7 +157,7 @@ static int sh_eth_reset(struct sh_eth_dev *eth)
/* Perform a software reset and wait for it to complete */
sh_eth_write(eth, EDMR_SRST, EDMR);
- for (i = 0; i < TIMEOUT_CNT ; i++) {
+ for (i = 0; i < TIMEOUT_CNT; i++) {
if (!(sh_eth_read(eth, EDMR) & EDMR_SRST))
break;
udelay(1000);
@@ -218,7 +219,7 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
/* Point the controller to the tx descriptor list. Must use physical
addresses */
sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR);
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR);
sh_eth_write(eth, ADDR_TO_PHY(cur_tx_desc), TDFXR);
sh_eth_write(eth, 0x01, TDFFR);/* Last discriptor bit */
@@ -288,7 +289,7 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
/* Point the controller to the rx descriptor list */
sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR);
sh_eth_write(eth, ADDR_TO_PHY(cur_rx_desc), RDFXR);
sh_eth_write(eth, RDFFR_RDLF, RDFFR);
@@ -384,7 +385,7 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
sh_eth_write(eth, 0, TFTR);
sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR);
sh_eth_write(eth, RMCR_RST, RMCR);
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
sh_eth_write(eth, 0, RPADIR);
#endif
sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR);
@@ -403,6 +404,8 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
sh_eth_write(eth, RFLR_RFL_MIN, RFLR);
#if defined(SH_ETH_TYPE_GETHER)
sh_eth_write(eth, 0, PIPR);
+#endif
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
sh_eth_write(eth, APR_AP, APR);
sh_eth_write(eth, MPR_MP, MPR);
sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER);
@@ -521,41 +524,41 @@ void sh_eth_halt(struct eth_device *dev)
int sh_eth_initialize(bd_t *bd)
{
- int ret = 0;
+ int ret = 0;
struct sh_eth_dev *eth = NULL;
- struct eth_device *dev = NULL;
+ struct eth_device *dev = NULL;
- eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev));
+ eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev));
if (!eth) {
printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
ret = -ENOMEM;
goto err;
}
- dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+ dev = (struct eth_device *)malloc(sizeof(struct eth_device));
if (!dev) {
printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
ret = -ENOMEM;
goto err;
}
- memset(dev, 0, sizeof(struct eth_device));
- memset(eth, 0, sizeof(struct sh_eth_dev));
+ memset(dev, 0, sizeof(struct eth_device));
+ memset(eth, 0, sizeof(struct sh_eth_dev));
eth->port = CONFIG_SH_ETHER_USE_PORT;
eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
- dev->priv = (void *)eth;
- dev->iobase = 0;
- dev->init = sh_eth_init;
- dev->halt = sh_eth_halt;
- dev->send = sh_eth_send;
- dev->recv = sh_eth_recv;
- eth->port_info[eth->port].dev = dev;
+ dev->priv = (void *)eth;
+ dev->iobase = 0;
+ dev->init = sh_eth_init;
+ dev->halt = sh_eth_halt;
+ dev->send = sh_eth_send;
+ dev->recv = sh_eth_recv;
+ eth->port_info[eth->port].dev = dev;
sprintf(dev->name, SHETHER_NAME);
- /* Register Device to EtherNet subsystem */
- eth_register(dev);
+ /* Register Device to EtherNet subsystem */
+ eth_register(dev);
bb_miiphy_buses[0].priv = eth;
miiphy_register(dev->name, bb_miiphy_read, bb_miiphy_write);
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 331c07cb59..d0d9aaa703 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -230,6 +230,61 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
[RMII_MII] = 0x0790,
};
+#if defined(SH_ETH_TYPE_RZ)
+static const u16 sh_eth_offset_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
+ [EDSR] = 0x0000,
+ [EDMR] = 0x0400,
+ [EDTRR] = 0x0408,
+ [EDRRR] = 0x0410,
+ [EESR] = 0x0428,
+ [EESIPR] = 0x0430,
+ [TDLAR] = 0x0010,
+ [TDFAR] = 0x0014,
+ [TDFXR] = 0x0018,
+ [TDFFR] = 0x001c,
+ [RDLAR] = 0x0030,
+ [RDFAR] = 0x0034,
+ [RDFXR] = 0x0038,
+ [RDFFR] = 0x003c,
+ [TRSCER] = 0x0438,
+ [RMFCR] = 0x0440,
+ [TFTR] = 0x0448,
+ [FDR] = 0x0450,
+ [RMCR] = 0x0458,
+ [RPADIR] = 0x0460,
+ [FCFTR] = 0x0468,
+ [CSMR] = 0x04E4,
+
+ [ECMR] = 0x0500,
+ [ECSR] = 0x0510,
+ [ECSIPR] = 0x0518,
+ [PSR] = 0x0528,
+ [PIPR] = 0x052c,
+ [RFLR] = 0x0508,
+ [APR] = 0x0554,
+ [MPR] = 0x0558,
+ [PFTCR] = 0x055c,
+ [PFRCR] = 0x0560,
+ [TPAUSER] = 0x0564,
+ [GECMR] = 0x05b0,
+ [BCULR] = 0x05b4,
+ [MAHR] = 0x05c0,
+ [MALR] = 0x05c8,
+ [TROCR] = 0x0700,
+ [CDCR] = 0x0708,
+ [LCCR] = 0x0710,
+ [CEFCR] = 0x0740,
+ [FRECR] = 0x0748,
+ [TSFRCR] = 0x0750,
+ [TLFRCR] = 0x0758,
+ [RFCR] = 0x0760,
+ [CERCR] = 0x0768,
+ [CEECR] = 0x0770,
+ [MAFCR] = 0x0778,
+ [RMII_MII] = 0x0790,
+};
+#endif
+
static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
[ECMR] = 0x0100,
[RFLR] = 0x0108,
@@ -306,13 +361,16 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
#define SH_ETH_TYPE_ETHER
#define BASE_IO_ADDR 0xEE700200
+#elif defined(CONFIG_R7S72100)
+#define SH_ETH_TYPE_RZ
+#define BASE_IO_ADDR 0xE8203000
#endif
/*
* Register's bits
* Copy from Linux driver source code
*/
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
/* EDSR */
enum EDSR_BIT {
EDSR_ENT = 0x01, EDSR_ENR = 0x02,
@@ -323,7 +381,7 @@ enum EDSR_BIT {
/* EDMR */
enum DMAC_M_BIT {
EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
EDMR_SRST = 0x03, /* Receive/Send reset */
EMDR_DESC_R = 0x30, /* Descriptor reserve size */
EDMR_EL = 0x40, /* Litte endian */
@@ -349,7 +407,7 @@ enum DMAC_M_BIT {
/* EDTRR */
enum DMAC_T_BIT {
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
EDTRR_TRNS = 0x03,
#else
EDTRR_TRNS = 0x01,
@@ -394,7 +452,6 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
/* EESR */
enum EESR_BIT {
-
#if defined(SH_ETH_TYPE_ETHER)
EESR_TWB = 0x40000000,
#else
@@ -419,12 +476,12 @@ enum EESR_BIT {
EESR_CD = 0x00000200, EESR_RTO = 0x00000100,
EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040,
EESR_CELF = 0x00000020, EESR_RRF = 0x00000010,
- rESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
+ EESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
EESR_PRE = 0x00000002, EESR_CERF = 0x00000001,
};
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
# define TX_CHECK (EESR_TC1 | EESR_FTC)
# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
| EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
@@ -484,7 +541,8 @@ enum FCFTR_BIT {
/* Transfer descriptor bit */
enum TD_STS_BIT {
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_ETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_ETHER) || \
+ defined(SH_ETH_TYPE_RZ)
TD_TACT = 0x80000000,
#else
TD_TACT = 0x7fffffff,
@@ -500,9 +558,9 @@ enum TD_STS_BIT {
enum RECV_RST_BIT { RMCR_RST = 0x01, };
/* ECMR */
enum FELIC_MODE_BIT {
-#if defined(SH_ETH_TYPE_GETHER)
- ECMR_TRCCM=0x04000000, ECMR_RCSC= 0x00800000, ECMR_DPAD= 0x00200000,
- ECMR_RZPF = 0x00100000,
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+ ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
+ ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
#endif
ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
@@ -517,9 +575,9 @@ enum FELIC_MODE_BIT {
};
-#if defined(SH_ETH_TYPE_GETHER)
-#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF | ECMR_PFR | ECMR_RXF | \
- ECMR_TXF | ECMR_MCT)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF | ECMR_PFR | \
+ ECMR_RXF | ECMR_TXF | ECMR_MCT)
#elif defined(SH_ETH_TYPE_ETHER)
#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
#else
@@ -535,7 +593,7 @@ enum ECSR_STATUS_BIT {
ECSR_MPD = 0x02, ECSR_ICD = 0x01,
};
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
#else
# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
@@ -556,7 +614,7 @@ enum ECSIPR_STATUS_MASK_BIT {
ECSIPR_ICDIP = 0x01,
};
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
#else
# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
@@ -587,7 +645,7 @@ enum RPADIR_BIT {
RPADIR_PADR = 0x0003f,
};
-#if defined(SH_ETH_TYPE_GETHER)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
# define RPADIR_INIT (0x00)
#else
# define RPADIR_INIT (RPADIR_PADS1)
@@ -605,6 +663,8 @@ static inline unsigned long sh_eth_reg_addr(struct sh_eth_dev *eth,
const u16 *reg_offset = sh_eth_offset_gigabit;
#elif defined(SH_ETH_TYPE_ETHER)
const u16 *reg_offset = sh_eth_offset_fast_sh4;
+#elif defined(SH_ETH_TYPE_RZ)
+ const u16 *reg_offset = sh_eth_offset_rz;
#else
#error
#endif
diff --git a/drivers/power/pmic/pmic_tps65090.c b/drivers/power/pmic/pmic_tps65090.c
index c5b396610a..337903acec 100644
--- a/drivers/power/pmic/pmic_tps65090.c
+++ b/drivers/power/pmic/pmic_tps65090.c
@@ -285,7 +285,7 @@ int tps65090_init(void)
}
bus = i2c_get_bus_num_fdt(parent);
- if (p->bus < 0) {
+ if (bus < 0) {
debug("%s: Cannot find I2C bus\n", __func__);
return -ENOENT;
}
diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c
index 7c84582762..ae0fe58f2c 100644
--- a/drivers/spi/fsl_espi.c
+++ b/drivers/spi/fsl_espi.c
@@ -15,8 +15,10 @@
struct fsl_spi_slave {
struct spi_slave slave;
+ ccsr_espi_t *espi;
unsigned int div16;
unsigned int pm;
+ int tx_timeout;
unsigned int mode;
size_t cmd_len;
u8 cmd_buf[16];
@@ -25,11 +27,17 @@ struct fsl_spi_slave {
};
#define to_fsl_spi_slave(s) container_of(s, struct fsl_spi_slave, slave)
+#define US_PER_SECOND 1000000UL
#define ESPI_MAX_CS_NUM 4
+#define ESPI_FIFO_WIDTH_BIT 32
#define ESPI_EV_RNE (1 << 9)
#define ESPI_EV_TNF (1 << 8)
+#define ESPI_EV_DON (1 << 14)
+#define ESPI_EV_TXE (1 << 15)
+#define ESPI_EV_RFCNT_SHIFT 24
+#define ESPI_EV_RFCNT_MASK (0x3f << ESPI_EV_RFCNT_SHIFT)
#define ESPI_MODE_EN (1 << 31) /* Enable interface */
#define ESPI_MODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold */
@@ -61,6 +69,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
struct fsl_spi_slave *fsl;
sys_info_t sysinfo;
unsigned long spibrg = 0;
+ unsigned long spi_freq = 0;
unsigned char pm = 0;
if (!spi_cs_is_valid(bus, cs))
@@ -70,6 +79,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!fsl)
return NULL;
+ fsl->espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
fsl->mode = mode;
fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN;
@@ -91,6 +101,15 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
pm--;
fsl->pm = pm;
+ if (fsl->div16)
+ spi_freq = spibrg / ((pm + 1) * 2 * 16);
+ else
+ spi_freq = spibrg / ((pm + 1) * 2);
+
+ /* set tx_timeout to 10 times of one espi FIFO entry go out */
+ fsl->tx_timeout = DIV_ROUND_UP((US_PER_SECOND * ESPI_FIFO_WIDTH_BIT
+ * 10), spi_freq);
+
return &fsl->slave;
}
@@ -108,7 +127,7 @@ void spi_init(void)
int spi_claim_bus(struct spi_slave *slave)
{
struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave);
- ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
+ ccsr_espi_t *espi = fsl->espi;
unsigned char pm = fsl->pm;
unsigned int cs = slave->cs;
unsigned int mode = fsl->mode;
@@ -161,24 +180,86 @@ void spi_release_bus(struct spi_slave *slave)
}
+static void fsl_espi_tx(struct fsl_spi_slave *fsl, const void *dout)
+{
+ ccsr_espi_t *espi = fsl->espi;
+ unsigned int tmpdout, event;
+ int tmp_tx_timeout;
+
+ if (dout)
+ tmpdout = *(u32 *)dout;
+ else
+ tmpdout = 0;
+
+ out_be32(&espi->tx, tmpdout);
+ out_be32(&espi->event, ESPI_EV_TNF);
+ debug("***spi_xfer:...%08x written\n", tmpdout);
+
+ tmp_tx_timeout = fsl->tx_timeout;
+ /* Wait for eSPI transmit to go out */
+ while (tmp_tx_timeout--) {
+ event = in_be32(&espi->event);
+ if (event & ESPI_EV_DON || event & ESPI_EV_TXE) {
+ out_be32(&espi->event, ESPI_EV_TXE);
+ break;
+ }
+ udelay(1);
+ }
+
+ if (tmp_tx_timeout < 0)
+ debug("***spi_xfer:...Tx timeout! event = %08x\n", event);
+}
+
+static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, unsigned int bytes)
+{
+ ccsr_espi_t *espi = fsl->espi;
+ unsigned int tmpdin, rx_times;
+ unsigned char *buf, *p_cursor;
+
+ if (bytes <= 0)
+ return 0;
+
+ rx_times = DIV_ROUND_UP(bytes, 4);
+ buf = (unsigned char *)malloc(4 * rx_times);
+ if (!buf) {
+ debug("SF: Failed to malloc memory.\n");
+ return -1;
+ }
+ p_cursor = buf;
+ while (rx_times--) {
+ tmpdin = in_be32(&espi->rx);
+ debug("***spi_xfer:...%08x readed\n", tmpdin);
+ *(u32 *)p_cursor = tmpdin;
+ p_cursor += 4;
+ }
+
+ if (din)
+ memcpy(din, buf, bytes);
+
+ free(buf);
+ out_be32(&espi->event, ESPI_EV_RNE);
+
+ return bytes;
+}
+
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
void *data_in, unsigned long flags)
{
struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave);
- ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
- unsigned int tmpdout, tmpdin, event;
+ ccsr_espi_t *espi = fsl->espi;
+ unsigned int event, rx_bytes;
const void *dout = NULL;
void *din = NULL;
int len = 0;
int num_blks, num_chunks, max_tran_len, tran_len;
int num_bytes;
- unsigned char *ch;
unsigned char *buffer = NULL;
size_t buf_len;
u8 *cmd_buf = fsl->cmd_buf;
size_t cmd_len = fsl->cmd_len;
size_t data_len = bitlen / 8;
size_t rx_offset = 0;
+ int rf_cnt;
max_tran_len = fsl->max_transfer_length;
switch (flags) {
@@ -217,9 +298,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
break;
}
- debug("spi_xfer: slave %u:%u dout %08X(%p) din %08X(%p) len %u\n",
- slave->bus, slave->cs, *(uint *) dout,
- dout, *(uint *) din, din, len);
+ debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) len %u\n",
+ *(uint *)data_out, data_out, *(uint *)data_in, data_in, len);
num_chunks = DIV_ROUND_UP(data_len, max_tran_len);
while (num_chunks--) {
@@ -235,41 +315,34 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
/* Clear all eSPI events */
out_be32(&espi->event , 0xffffffff);
/* handle data in 32-bit chunks */
- while (num_blks--) {
-
+ while (num_blks) {
event = in_be32(&espi->event);
if (event & ESPI_EV_TNF) {
- tmpdout = *(u32 *)dout;
-
+ fsl_espi_tx(fsl, dout);
/* Set up the next iteration */
if (len > 4) {
len -= 4;
dout += 4;
}
-
- out_be32(&espi->tx, tmpdout);
- out_be32(&espi->event, ESPI_EV_TNF);
- debug("***spi_xfer:...%08x written\n", tmpdout);
}
- /* Wait for eSPI transmit to get out */
- udelay(80);
-
event = in_be32(&espi->event);
if (event & ESPI_EV_RNE) {
- tmpdin = in_be32(&espi->rx);
- if (num_blks == 0 && num_bytes != 0) {
- ch = (unsigned char *)&tmpdin;
- while (num_bytes--)
- *(unsigned char *)din++ = *ch++;
- } else {
- *(u32 *) din = tmpdin;
- din += 4;
+ rf_cnt = ((event & ESPI_EV_RFCNT_MASK)
+ >> ESPI_EV_RFCNT_SHIFT);
+ if (rf_cnt >= 4)
+ rx_bytes = 4;
+ else if (num_blks == 1 && rf_cnt == num_bytes)
+ rx_bytes = num_bytes;
+ else
+ continue;
+ if (fsl_espi_rx(fsl, din, rx_bytes)
+ == rx_bytes) {
+ num_blks--;
+ if (din)
+ din = (unsigned char *)din
+ + rx_bytes;
}
-
- out_be32(&espi->event, in_be32(&espi->event)
- | ESPI_EV_RNE);
- debug("***spi_xfer:...%08x readed\n", tmpdin);
}
}
if (data_in) {
@@ -295,7 +368,7 @@ int spi_cs_is_valid(unsigned int bus, unsigned int cs)
void spi_cs_activate(struct spi_slave *slave)
{
struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave);
- ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
+ ccsr_espi_t *espi = fsl->espi;
unsigned int com = 0;
size_t data_len = fsl->data_len;
@@ -307,7 +380,8 @@ void spi_cs_activate(struct spi_slave *slave)
void spi_cs_deactivate(struct spi_slave *slave)
{
- ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
+ struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave);
+ ccsr_espi_t *espi = fsl->espi;
/* clear the RXCNT and TXCNT */
out_be32(&espi->mode, in_be32(&espi->mode) & (~ESPI_MODE_EN));
diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index 5d22351290..c969be31eb 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -136,10 +136,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
/*
* Check if it is time to work on a new byte.
*/
- if((j % 8) == 0) {
- tmpdout = *txd++;
+ if ((j % 8) == 0) {
+ if (txd)
+ tmpdout = *txd++;
+ else
+ tmpdout = 0;
if(j != 0) {
- *rxd++ = tmpdin;
+ if (rxd)
+ *rxd++ = tmpdin;
}
tmpdin = 0;
}
@@ -164,9 +168,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
* bits over to left-justify them. Then store the last byte
* read in.
*/
- if((bitlen % 8) != 0)
- tmpdin <<= 8 - (bitlen % 8);
- *rxd++ = tmpdin;
+ if (rxd) {
+ if ((bitlen % 8) != 0)
+ tmpdin <<= 8 - (bitlen % 8);
+ *rxd++ = tmpdin;
+ }
if (flags & SPI_XFER_END)
spi_cs_deactivate(slave);
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 9cd003636a..b18bee43ad 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -56,14 +56,7 @@ static const char *reqname(unsigned r)
}
#endif
-static struct usb_endpoint_descriptor ep0_out_desc = {
- .bLength = sizeof(struct usb_endpoint_descriptor),
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0,
- .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
-};
-
-static struct usb_endpoint_descriptor ep0_in_desc = {
+static struct usb_endpoint_descriptor ep0_desc = {
.bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
@@ -205,8 +198,14 @@ static void ci_invalidate_qtd(int ep_num)
static struct usb_request *
ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
{
+ struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep);
+ int num;
struct ci_req *ci_req;
+ num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ if (num == 0 && controller.ep0_req)
+ return &controller.ep0_req->req;
+
ci_req = memalign(ARCH_DMA_MINALIGN, sizeof(*ci_req));
if (!ci_req)
return NULL;
@@ -214,14 +213,22 @@ ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
INIT_LIST_HEAD(&ci_req->queue);
ci_req->b_buf = 0;
+ if (num == 0)
+ controller.ep0_req = ci_req;
+
return &ci_req->req;
}
static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *req)
{
- struct ci_req *ci_req;
+ struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep);
+ struct ci_req *ci_req = container_of(req, struct ci_req, req);
+ int num;
+
+ num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ if (num == 0)
+ controller.ep0_req = 0;
- ci_req = container_of(req, struct ci_req, req);
if (ci_req->b_buf)
free(ci_req->b_buf);
free(ci_req);
@@ -362,18 +369,50 @@ static void ci_ep_submit_next_request(struct ci_ep *ci_ep)
ci_req = list_first_entry(&ci_ep->queue, struct ci_req, queue);
len = ci_req->req.length;
- item->next = TERMINATE;
- item->info = INFO_BYTES(len) | INFO_IOC | INFO_ACTIVE;
+ item->info = INFO_BYTES(len) | INFO_ACTIVE;
item->page0 = (uint32_t)ci_req->hw_buf;
item->page1 = ((uint32_t)ci_req->hw_buf & 0xfffff000) + 0x1000;
item->page2 = ((uint32_t)ci_req->hw_buf & 0xfffff000) + 0x2000;
item->page3 = ((uint32_t)ci_req->hw_buf & 0xfffff000) + 0x3000;
item->page4 = ((uint32_t)ci_req->hw_buf & 0xfffff000) + 0x4000;
- ci_flush_qtd(num);
head->next = (unsigned) item;
head->info = 0;
+ /*
+ * When sending the data for an IN transaction, the attached host
+ * knows that all data for the IN is sent when one of the following
+ * occurs:
+ * a) A zero-length packet is transmitted.
+ * b) A packet with length that isn't an exact multiple of the ep's
+ * maxpacket is transmitted.
+ * c) Enough data is sent to exactly fill the host's maximum expected
+ * IN transaction size.
+ *
+ * One of these conditions MUST apply at the end of an IN transaction,
+ * or the transaction will not be considered complete by the host. If
+ * none of (a)..(c) already applies, then we must force (a) to apply
+ * by explicitly sending an extra zero-length packet.
+ */
+ /* IN !a !b !c */
+ if (in && len && !(len % ci_ep->ep.maxpacket) && ci_req->req.zero) {
+ /*
+ * Each endpoint has 2 items allocated, even though typically
+ * only 1 is used at a time since either an IN or an OUT but
+ * not both is queued. For an IN transaction, item currently
+ * points at the second of these items, so we know that we
+ * can use (item - 1) to transmit the extra zero-length packet
+ */
+ item->next = (unsigned)(item - 1);
+ item--;
+ item->info = INFO_ACTIVE;
+ }
+
+ item->next = TERMINATE;
+ item->info |= INFO_IOC;
+
+ ci_flush_qtd(num);
+
DBG("ept%d %s queue len %x, req %p, buffer %p\n",
num, in ? "in" : "out", len, ci_req, ci_req->hw_buf);
ci_flush_qh(num);
@@ -397,6 +436,21 @@ static int ci_ep_queue(struct usb_ep *ep,
num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
in = (ci_ep->desc->bEndpointAddress & USB_DIR_IN) != 0;
+ if (!num && ci_ep->req_primed) {
+ /*
+ * The flipping of ep0 between IN and OUT relies on
+ * ci_ep_queue consuming the current IN/OUT setting
+ * immediately. If this is deferred to a later point when the
+ * req is pulled out of ci_req->queue, then the IN/OUT setting
+ * may have been changed since the req was queued, and state
+ * will get out of sync. This condition doesn't occur today,
+ * but could if bugs were introduced later, and this error
+ * check will save a lot of debugging time.
+ */
+ printf("%s: ep0 transaction already in progress\n", __func__);
+ return -EPROTO;
+ }
+
ret = ci_bounce(ci_req, in);
if (ret)
return ret;
@@ -411,6 +465,17 @@ static int ci_ep_queue(struct usb_ep *ep,
return 0;
}
+static void flip_ep0_direction(void)
+{
+ if (ep0_desc.bEndpointAddress == USB_DIR_IN) {
+ DBG("%s: Flipping ep0 ot OUT\n", __func__);
+ ep0_desc.bEndpointAddress = 0;
+ } else {
+ DBG("%s: Flipping ep0 ot IN\n", __func__);
+ ep0_desc.bEndpointAddress = USB_DIR_IN;
+ }
+}
+
static void handle_ep_complete(struct ci_ep *ep)
{
struct ept_queue_item *item;
@@ -419,8 +484,6 @@ static void handle_ep_complete(struct ci_ep *ep)
num = ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
in = (ep->desc->bEndpointAddress & USB_DIR_IN) != 0;
- if (num == 0)
- ep->desc = &ep0_out_desc;
item = ci_get_qtd(num, in);
ci_invalidate_qtd(num);
@@ -441,11 +504,18 @@ static void handle_ep_complete(struct ci_ep *ep)
DBG("ept%d %s req %p, complete %x\n",
num, in ? "in" : "out", ci_req, len);
- ci_req->req.complete(&ep->ep, &ci_req->req);
- if (num == 0) {
+ if (num != 0 || controller.ep0_data_phase)
+ ci_req->req.complete(&ep->ep, &ci_req->req);
+ if (num == 0 && controller.ep0_data_phase) {
+ /*
+ * Data Stage is complete, so flip ep0 dir for Status Stage,
+ * which always transfers a packet in the opposite direction.
+ */
+ DBG("%s: flip ep0 dir for Status Stage\n", __func__);
+ flip_ep0_direction();
+ controller.ep0_data_phase = false;
ci_req->req.length = 0;
usb_ep_queue(&ep->ep, &ci_req->req, 0);
- ep->desc = &ep0_in_desc;
}
}
@@ -463,7 +533,7 @@ static void handle_setup(void)
int num, in, _num, _in, i;
char *buf;
- ci_req = list_first_entry(&ci_ep->queue, struct ci_req, queue);
+ ci_req = controller.ep0_req;
req = &ci_req->req;
head = ci_get_qh(0, 0); /* EP0 OUT */
@@ -474,8 +544,26 @@ static void handle_setup(void)
#else
writel(EPT_RX(0), &udc->epstat);
#endif
- DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest),
- r.bRequestType, r.bRequest, r.wIndex, r.wValue);
+ DBG("handle setup %s, %x, %x index %x value %x length %x\n",
+ reqname(r.bRequest), r.bRequestType, r.bRequest, r.wIndex,
+ r.wValue, r.wLength);
+
+ /* Set EP0 dir for Data Stage based on Setup Stage data */
+ if (r.bRequestType & USB_DIR_IN) {
+ DBG("%s: Set ep0 to IN for Data Stage\n", __func__);
+ ep0_desc.bEndpointAddress = USB_DIR_IN;
+ } else {
+ DBG("%s: Set ep0 to OUT for Data Stage\n", __func__);
+ ep0_desc.bEndpointAddress = 0;
+ }
+ if (r.wLength) {
+ controller.ep0_data_phase = true;
+ } else {
+ /* 0 length -> no Data Stage. Flip dir for Status Stage */
+ DBG("%s: 0 length: flip ep0 dir for Status Stage\n", __func__);
+ flip_ep0_direction();
+ controller.ep0_data_phase = false;
+ }
list_del_init(&ci_req->queue);
ci_ep->req_primed = false;
@@ -646,6 +734,17 @@ int usb_gadget_handle_interrupts(void)
return value;
}
+void udc_disconnect(void)
+{
+ struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+ /* disable pullup */
+ stop_activity();
+ writel(USBCMD_FS2, &udc->usbcmd);
+ udelay(800);
+ if (controller.driver)
+ controller.driver->disconnect(&controller.gadget);
+}
+
static int ci_pullup(struct usb_gadget *gadget, int is_on)
{
struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
@@ -664,27 +763,12 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on)
/* Turn on the USB connection by enabling the pullup resistor */
writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RUN, &udc->usbcmd);
} else {
- stop_activity();
- writel(USBCMD_FS2, &udc->usbcmd);
- udelay(800);
- if (controller.driver)
- controller.driver->disconnect(gadget);
+ udc_disconnect();
}
return 0;
}
-void udc_disconnect(void)
-{
- struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
- /* disable pullup */
- stop_activity();
- writel(USBCMD_FS2, &udc->usbcmd);
- udelay(800);
- if (controller.driver)
- controller.driver->disconnect(&controller.gadget);
-}
-
static int ci_udc_probe(void)
{
struct ept_queue_head *head;
@@ -756,7 +840,7 @@ static int ci_udc_probe(void)
/* Init EP 0 */
memcpy(&controller.ep[0].ep, &ci_ep_init[0], sizeof(*ci_ep_init));
- controller.ep[0].desc = &ep0_in_desc;
+ controller.ep[0].desc = &ep0_desc;
INIT_LIST_HEAD(&controller.ep[0].queue);
controller.ep[0].req_primed = false;
controller.gadget.ep0 = &controller.ep[0].ep;
@@ -772,6 +856,13 @@ static int ci_udc_probe(void)
&controller.gadget.ep_list);
}
+ ci_ep_alloc_request(&controller.ep[0].ep, 0);
+ if (!controller.ep0_req) {
+ free(controller.items_mem);
+ free(controller.epts);
+ return -ENOMEM;
+ }
+
return 0;
}
@@ -816,5 +907,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
+ udc_disconnect();
+
+ ci_ep_free_request(&controller.ep[0].ep, &controller.ep0_req->req);
+ free(controller.items_mem);
+ free(controller.epts);
+
return 0;
}
diff --git a/drivers/usb/gadget/ci_udc.h b/drivers/usb/gadget/ci_udc.h
index 23cff56d7e..c2144021e6 100644
--- a/drivers/usb/gadget/ci_udc.h
+++ b/drivers/usb/gadget/ci_udc.h
@@ -97,6 +97,8 @@ struct ci_ep {
struct ci_drv {
struct usb_gadget gadget;
+ struct ci_req *ep0_req;
+ bool ep0_data_phase;
struct usb_gadget_driver *driver;
struct ehci_ctrl *ctrl;
struct ept_queue_head *epts;
OpenPOWER on IntegriCloud