diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bootcount/bootcount.c | 2 | ||||
-rw-r--r-- | drivers/core/device.c | 169 | ||||
-rw-r--r-- | drivers/core/lists.c | 22 | ||||
-rw-r--r-- | drivers/core/root.c | 78 | ||||
-rw-r--r-- | drivers/core/uclass.c | 135 | ||||
-rw-r--r-- | drivers/ddr/fsl/ctrl_regs.c | 3 | ||||
-rw-r--r-- | drivers/ddr/fsl/fsl_ddr_gen4.c | 7 | ||||
-rw-r--r-- | drivers/demo/demo-uclass.c | 1 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 2 | ||||
-rw-r--r-- | drivers/input/cros_ec_keyb.c | 6 | ||||
-rw-r--r-- | drivers/input/i8042.c | 4 | ||||
-rw-r--r-- | drivers/input/keyboard.c | 6 | ||||
-rw-r--r-- | drivers/input/tegra-kbc.c | 6 | ||||
-rw-r--r-- | drivers/misc/cbmem_console.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 45 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_spl.c | 6 | ||||
-rw-r--r-- | drivers/net/fm/fm.h | 3 | ||||
-rw-r--r-- | drivers/net/fm/init.c | 6 | ||||
-rw-r--r-- | drivers/net/netconsole.c | 10 | ||||
-rw-r--r-- | drivers/pci/fsl_pci_init.c | 10 | ||||
-rw-r--r-- | drivers/qe/qe.c | 2 | ||||
-rw-r--r-- | drivers/qe/uccf.c | 2 | ||||
-rw-r--r-- | drivers/qe/uccf.h | 2 | ||||
-rw-r--r-- | drivers/qe/uec.c | 2 | ||||
-rw-r--r-- | drivers/qe/uec_phy.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial.c | 55 | ||||
-rw-r--r-- | drivers/serial/usbtty.c | 8 | ||||
-rw-r--r-- | drivers/video/cfb_console.c | 8 |
28 files changed, 530 insertions, 78 deletions
diff --git a/drivers/bootcount/bootcount.c b/drivers/bootcount/bootcount.c index 3ad441393e..e0343f71d7 100644 --- a/drivers/bootcount/bootcount.c +++ b/drivers/bootcount/bootcount.c @@ -36,7 +36,7 @@ #endif /* defined(CONFIG_MPC8260) */ #if defined(CONFIG_QE) -#include <asm/immap_qe.h> +#include <linux/immap_qe.h> #define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + 0x110000 + \ QE_MURAM_SIZE - 2 * sizeof(u32)) diff --git a/drivers/core/device.c b/drivers/core/device.c index c73c339d18..166b0732ab 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -10,6 +10,7 @@ */ #include <common.h> +#include <fdtdec.h> #include <malloc.h> #include <dm/device.h> #include <dm/device-internal.h> @@ -21,6 +22,8 @@ #include <linux/err.h> #include <linux/list.h> +DECLARE_GLOBAL_DATA_PTR; + /** * device_chld_unbind() - Unbind all device's children from the device * @@ -95,6 +98,21 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, dev->parent = parent; dev->driver = drv; dev->uclass = uc; + + /* + * For some devices, such as a SPI or I2C bus, the 'reg' property + * is a reasonable indicator of the sequence number. But if there is + * an alias, we use that in preference. In any case, this is just + * a 'requested' sequence, and will be resolved (and ->seq updated) + * when the device is probed. + */ + dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1); + dev->seq = -1; + if (uc->uc_drv->name && of_offset != -1) { + fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset, + &dev->req_seq); + } + if (!dev->platdata && drv->platdata_auto_alloc_size) dev->flags |= DM_FLAG_ALLOC_PDATA; @@ -129,14 +147,16 @@ fail_bind: return ret; } -int device_bind_by_name(struct udevice *parent, const struct driver_info *info, - struct udevice **devp) +int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, + const struct driver_info *info, struct udevice **devp) { struct driver *drv; drv = lists_driver_lookup_name(info->name); if (!drv) return -ENOENT; + if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC)) + return -EPERM; return device_bind(parent, drv, info->name, (void *)info->platdata, -1, devp); @@ -198,6 +218,13 @@ static void device_free(struct udevice *dev) free(dev->uclass_priv); dev->uclass_priv = NULL; } + if (dev->parent) { + size = dev->parent->driver->per_child_auto_alloc_size; + if (size) { + free(dev->parent_priv); + dev->parent_priv = NULL; + } + } } int device_probe(struct udevice *dev) @@ -205,6 +232,7 @@ int device_probe(struct udevice *dev) struct driver *drv; int size = 0; int ret; + int seq; if (!dev) return -EINVAL; @@ -242,11 +270,33 @@ int device_probe(struct udevice *dev) /* Ensure all parents are probed */ if (dev->parent) { + size = dev->parent->driver->per_child_auto_alloc_size; + if (size) { + dev->parent_priv = calloc(1, size); + if (!dev->parent_priv) { + ret = -ENOMEM; + goto fail; + } + } + ret = device_probe(dev->parent); if (ret) goto fail; } + seq = uclass_resolve_seq(dev); + if (seq < 0) { + ret = seq; + goto fail; + } + dev->seq = seq; + + if (dev->parent && dev->parent->driver->child_pre_probe) { + ret = dev->parent->driver->child_pre_probe(dev); + if (ret) + goto fail; + } + if (drv->ofdata_to_platdata && dev->of_offset >= 0) { ret = drv->ofdata_to_platdata(dev); if (ret) @@ -274,6 +324,7 @@ fail_uclass: __func__, dev->name); } fail: + dev->seq = -1; device_free(dev); return ret; @@ -307,11 +358,20 @@ int device_remove(struct udevice *dev) goto err_remove; } + if (dev->parent && dev->parent->driver->child_post_remove) { + ret = dev->parent->driver->child_post_remove(dev); + if (ret) { + dm_warn("%s: Device '%s' failed child_post_remove()", + __func__, dev->name); + } + } + device_free(dev); + dev->seq = -1; dev->flags &= ~DM_FLAG_ACTIVATED; - return 0; + return ret; err_remove: /* We can't put the children back */ @@ -346,3 +406,106 @@ void *dev_get_priv(struct udevice *dev) return dev->priv; } + +void *dev_get_parentdata(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device", __func__); + return NULL; + } + + return dev->parent_priv; +} + +static int device_get_device_tail(struct udevice *dev, int ret, + struct udevice **devp) +{ + if (ret) + return ret; + + ret = device_probe(dev); + if (ret) + return ret; + + *devp = dev; + + return 0; +} + +int device_get_child(struct udevice *parent, int index, struct udevice **devp) +{ + struct udevice *dev; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (!index--) + return device_get_device_tail(dev, 0, devp); + } + + return -ENODEV; +} + +int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq, + bool find_req_seq, struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + if (seq_or_req_seq == -1) + return -ENODEV; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if ((find_req_seq ? dev->req_seq : dev->seq) == + seq_or_req_seq) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +int device_get_child_by_seq(struct udevice *parent, int seq, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = device_find_child_by_seq(parent, seq, false, &dev); + if (ret == -ENODEV) { + /* + * We didn't find it in probed devices. See if there is one + * that will request this seq if probed. + */ + ret = device_find_child_by_seq(parent, seq, true, &dev); + } + return device_get_device_tail(dev, ret, devp); +} + +int device_find_child_by_of_offset(struct udevice *parent, int of_offset, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (dev->of_offset == of_offset) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +int device_get_child_by_of_offset(struct udevice *parent, int seq, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = device_find_child_by_of_offset(parent, seq, &dev); + return device_get_device_tail(dev, ret, devp); +} diff --git a/drivers/core/lists.c b/drivers/core/lists.c index 87164a5cf9..0f08bfd6ff 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -62,7 +62,7 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id) return NULL; } -int lists_bind_drivers(struct udevice *parent) +int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) { struct driver_info *info = ll_entry_start(struct driver_info, driver_info); @@ -73,8 +73,8 @@ int lists_bind_drivers(struct udevice *parent) int ret; for (entry = info; entry != info + n_ents; entry++) { - ret = device_bind_by_name(parent, entry, &dev); - if (ret) { + ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev); + if (ret && ret != -EPERM) { dm_warn("No match for driver '%s'\n", entry->name); if (!result || ret != -ENOENT) result = ret; @@ -124,16 +124,19 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset) const int n_ents = ll_entry_count(struct driver, driver); struct driver *entry; struct udevice *dev; + bool found = false; const char *name; int result = 0; - int ret; + int ret = 0; dm_dbg("bind node %s\n", fdt_get_name(blob, offset, NULL)); for (entry = driver; entry != driver + n_ents; entry++) { ret = driver_check_compatible(blob, offset, entry->of_match); + name = fdt_get_name(blob, offset, NULL); if (ret == -ENOENT) { continue; } else if (ret == -ENODEV) { + dm_dbg("Device '%s' has no compatible string\n", name); break; } else if (ret) { dm_warn("Device tree error at offset %d\n", offset); @@ -142,14 +145,21 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset) break; } - name = fdt_get_name(blob, offset, NULL); dm_dbg(" - found match at '%s'\n", entry->name); ret = device_bind(parent, entry, name, NULL, offset, &dev); if (ret) { - dm_warn("No match for driver '%s'\n", entry->name); + dm_warn("Error binding driver '%s'\n", entry->name); if (!result || ret != -ENOENT) result = ret; + } else { + found = true; } + break; + } + + if (!found && !result && ret != -ENODEV) { + dm_dbg("No match for node '%s'\n", + fdt_get_name(blob, offset, NULL)); } return result; diff --git a/drivers/core/root.c b/drivers/core/root.c index 11e08796b2..393dd98b9d 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -46,18 +46,29 @@ int dm_init(void) } INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); - ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST); + ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST); if (ret) return ret; + ret = device_probe(DM_ROOT_NON_CONST); + if (ret) + return ret; + + return 0; +} + +int dm_uninit(void) +{ + device_remove(dm_root()); + device_unbind(dm_root()); return 0; } -int dm_scan_platdata(void) +int dm_scan_platdata(bool pre_reloc_only) { int ret; - ret = lists_bind_drivers(DM_ROOT_NON_CONST); + ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only); if (ret == -ENOENT) { dm_warn("Some drivers were not found\n"); ret = 0; @@ -69,27 +80,66 @@ int dm_scan_platdata(void) } #ifdef CONFIG_OF_CONTROL -int dm_scan_fdt(const void *blob) +int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, + bool pre_reloc_only) { - int offset = 0; int ret = 0, err; - int depth = 0; - do { - offset = fdt_next_node(blob, offset, &depth); - if (offset > 0 && depth == 1) { - err = lists_bind_fdt(gd->dm_root, blob, offset); - if (err && !ret) - ret = err; - } - } while (offset > 0); + for (offset = fdt_first_subnode(blob, offset); + offset > 0; + offset = fdt_next_subnode(blob, offset)) { + if (pre_reloc_only && + !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) + continue; + err = lists_bind_fdt(parent, blob, offset); + if (err && !ret) + ret = err; + } if (ret) dm_warn("Some drivers failed to bind\n"); return ret; } + +int dm_scan_fdt(const void *blob, bool pre_reloc_only) +{ + return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); +} +#endif + +__weak int dm_scan_other(bool pre_reloc_only) +{ + return 0; +} + +int dm_init_and_scan(bool pre_reloc_only) +{ + int ret; + + ret = dm_init(); + if (ret) { + debug("dm_init() failed: %d\n", ret); + return ret; + } + ret = dm_scan_platdata(pre_reloc_only); + if (ret) { + debug("dm_scan_platdata() failed: %d\n", ret); + return ret; + } +#ifdef CONFIG_OF_CONTROL + ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); + if (ret) { + debug("dm_scan_fdt() failed: %d\n", ret); + return ret; + } #endif + ret = dm_scan_other(pre_reloc_only); + if (ret) + return ret; + + return 0; +} /* This is the root driver - all drivers are children of this */ U_BOOT_DRIVER(root_driver) = { diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 34723ec42a..61ca17e564 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -23,6 +23,8 @@ struct uclass *uclass_find(enum uclass_id key) { struct uclass *uc; + if (!gd->dm_root) + return NULL; /* * TODO(sjg@chromium.org): Optimise this, perhaps moving the found * node to the start of the list, or creating a linear array mapping @@ -158,13 +160,72 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) return -ENODEV; } -int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) +int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, + bool find_req_seq, struct udevice **devp) { + struct uclass *uc; struct udevice *dev; int ret; *devp = NULL; - ret = uclass_find_device(id, index, &dev); + debug("%s: %d %d\n", __func__, find_req_seq, seq_or_req_seq); + if (seq_or_req_seq == -1) + return -ENODEV; + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + debug(" - %d %d\n", dev->req_seq, dev->seq); + if ((find_req_seq ? dev->req_seq : dev->seq) == + seq_or_req_seq) { + *devp = dev; + debug(" - found\n"); + return 0; + } + } + debug(" - not found\n"); + + return -ENODEV; +} + +static int uclass_find_device_by_of_offset(enum uclass_id id, int node, + struct udevice **devp) +{ + struct uclass *uc; + struct udevice *dev; + int ret; + + *devp = NULL; + if (node < 0) + return -ENODEV; + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + if (dev->of_offset == node) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +/** + * uclass_get_device_tail() - handle the end of a get_device call + * + * This handles returning an error or probing a device as needed. + * + * @dev: Device that needs to be probed + * @ret: Error to return. If non-zero then the device is not probed + * @devp: Returns the value of 'dev' if there is no error + * @return ret, if non-zero, else the result of the device_probe() call + */ +static int uclass_get_device_tail(struct udevice *dev, int ret, + struct udevice **devp) +{ if (ret) return ret; @@ -177,6 +238,44 @@ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) return 0; } +int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device(id, index, &dev); + return uclass_get_device_tail(dev, ret, devp); +} + +int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device_by_seq(id, seq, false, &dev); + if (ret == -ENODEV) { + /* + * We didn't find it in probed devices. See if there is one + * that will request this seq if probed. + */ + ret = uclass_find_device_by_seq(id, seq, true, &dev); + } + return uclass_get_device_tail(dev, ret, devp); +} + +int uclass_get_device_by_of_offset(enum uclass_id id, int node, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device_by_of_offset(id, node, &dev); + return uclass_get_device_tail(dev, ret, devp); +} + int uclass_first_device(enum uclass_id id, struct udevice **devp) { struct uclass *uc; @@ -254,6 +353,37 @@ int uclass_unbind_device(struct udevice *dev) return 0; } +int uclass_resolve_seq(struct udevice *dev) +{ + struct udevice *dup; + int seq; + int ret; + + assert(dev->seq == -1); + ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, dev->req_seq, + false, &dup); + if (!ret) { + dm_warn("Device '%s': seq %d is in use by '%s'\n", + dev->name, dev->req_seq, dup->name); + } else if (ret == -ENODEV) { + /* Our requested sequence number is available */ + if (dev->req_seq != -1) + return dev->req_seq; + } else { + return ret; + } + + for (seq = 0; seq < DM_MAX_SEQ; seq++) { + ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, seq, + false, &dup); + if (ret == -ENODEV) + break; + if (ret) + return ret; + } + return seq; +} + int uclass_post_probe_device(struct udevice *dev) { struct uclass_driver *uc_drv = dev->uclass->uc_drv; @@ -281,6 +411,7 @@ int uclass_pre_remove_device(struct udevice *dev) free(dev->uclass_priv); dev->uclass_priv = NULL; } + dev->seq = -1; return 0; } diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index dcf6287f66..04e4178b15 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -1857,6 +1857,9 @@ static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr, acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps); wrtord_bg = max(4, picos_to_mclk(7500)); + if (popts->otf_burst_chop_en) + wrtord_bg += 2; + pre_all_rec = 0; ddr->timing_cfg_8 = (0 diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 7cd878aeec..bfc76b3485 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -8,6 +8,7 @@ #include <asm/io.h> #include <fsl_ddr_sdram.h> #include <asm/processor.h> +#include <fsl_immap.h> #include <fsl_ddr.h> #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) @@ -183,12 +184,14 @@ step2: * we choose the max, that is 500 us for all of case. */ udelay(500); - asm volatile("sync;isync"); + mb(); + isb(); /* Let the controller go */ temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); - asm volatile("sync;isync"); + mb(); + isb(); total_gb_size_per_controller = 0; for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c index 636fd8831f..f6510d602c 100644 --- a/drivers/demo/demo-uclass.c +++ b/drivers/demo/demo-uclass.c @@ -19,6 +19,7 @@ DECLARE_GLOBAL_DATA_PTR; UCLASS_DRIVER(demo) = { + .name = "demo", .id = UCLASS_DEMO, }; diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4e001e12bd..fb8dcd916b 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -5,7 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifndef CONFIG_SPL_BUILD obj-$(CONFIG_DM_GPIO) += gpio-uclass.o +endif obj-$(CONFIG_AT91_GPIO) += at91_gpio.o obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c index a2501e0206..47502b1763 100644 --- a/drivers/input/cros_ec_keyb.c +++ b/drivers/input/cros_ec_keyb.c @@ -93,7 +93,7 @@ static int check_for_keys(struct keyb *config, * * @return 0 if no keys available, 1 if keys are available */ -static int kbd_tstc(void) +static int kbd_tstc(struct stdio_dev *dev) { /* Just get input to do this for us */ return config.inited ? input_tstc(&config.input) : 0; @@ -104,7 +104,7 @@ static int kbd_tstc(void) * * @return ASCII key code, or 0 if no key, or -1 if error */ -static int kbd_getc(void) +static int kbd_getc(struct stdio_dev *dev) { /* Just get input to do this for us */ return config.inited ? input_getc(&config.input) : 0; @@ -214,7 +214,7 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node, * * @return 0 if ok, -1 on error */ -static int cros_ec_init_keyboard(void) +static int cros_ec_init_keyboard(struct stdio_dev *dev) { const void *blob = gd->fdt_blob; int node; diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index 35fa0bb504..ca1604c540 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -398,7 +398,7 @@ int i8042_kbd_init(void) * i8042_tstc - test if keyboard input is available * option: cursor blinking if called in a loop */ -int i8042_tstc(void) +int i8042_tstc(struct stdio_dev *dev) { unsigned char scan_code = 0; @@ -432,7 +432,7 @@ int i8042_tstc(void) * i8042_getc - wait till keyboard input is available * option: turn on/off cursor while waiting */ -int i8042_getc(void) +int i8042_getc(struct stdio_dev *dev) { int ret_chr; unsigned char scan_code; diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c index 614592ef3c..be0f3330db 100644 --- a/drivers/input/keyboard.c +++ b/drivers/input/keyboard.c @@ -70,7 +70,7 @@ static void kbd_put_queue(char data) } /* test if a character is in the queue */ -static int kbd_testc(void) +static int kbd_testc(struct stdio_dev *dev) { #if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) /* no ISR is used, so received chars must be polled */ @@ -83,7 +83,7 @@ static int kbd_testc(void) } /* gets the character from the queue */ -static int kbd_getc(void) +static int kbd_getc(struct stdio_dev *dev) { char c; while(in_pointer==out_pointer) { @@ -275,8 +275,6 @@ int kbd_init (void) memset (&kbddev, 0, sizeof(kbddev)); strcpy(kbddev.name, DEVNAME); kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - kbddev.putc = NULL ; - kbddev.puts = NULL ; kbddev.getc = kbd_getc ; kbddev.tstc = kbd_testc ; diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c index f137f930a9..7e36db0a71 100644 --- a/drivers/input/tegra-kbc.c +++ b/drivers/input/tegra-kbc.c @@ -194,7 +194,7 @@ int tegra_kbc_check(struct input_config *input) * * @return 0 if no keys available, 1 if keys are available */ -static int kbd_tstc(void) +static int kbd_tstc(struct stdio_dev *dev) { /* Just get input to do this for us */ return input_tstc(&config.input); @@ -207,7 +207,7 @@ static int kbd_tstc(void) * * @return ASCII key code, or 0 if no key, or -1 if error */ -static int kbd_getc(void) +static int kbd_getc(struct stdio_dev *dev) { /* Just get input to do this for us */ return input_getc(&config.input); @@ -289,7 +289,7 @@ static void tegra_kbc_open(void) * * @return 0 if ok, -ve on error */ -static int init_tegra_keyboard(void) +static int init_tegra_keyboard(struct stdio_dev *dev) { /* check if already created */ if (config.created) diff --git a/drivers/misc/cbmem_console.c b/drivers/misc/cbmem_console.c index 80a84fdf8f..5f85ccf21e 100644 --- a/drivers/misc/cbmem_console.c +++ b/drivers/misc/cbmem_console.c @@ -31,7 +31,7 @@ struct cbmem_console { static struct cbmem_console *cbmem_console_p; -void cbmemc_putc(char data) +void cbmemc_putc(struct stdio_dev *dev, char data) { int cursor; @@ -40,12 +40,12 @@ void cbmemc_putc(char data) cbmem_console_p->buffer_body[cursor] = data; } -void cbmemc_puts(const char *str) +void cbmemc_puts(struct stdio_dev *dev, const char *str) { char c; while ((c = *str++) != 0) - cbmemc_putc(c); + cbmemc_putc(dev, c); } int cbmemc_init(void) diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index be5a16a1ba..8b453cb383 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -19,8 +19,11 @@ #include <asm/errno.h> #include <fsl_ifc.h> -#define FSL_IFC_V1_1_0 0x01010000 -#define MAX_BANKS 4 +#ifndef CONFIG_SYS_FSL_IFC_BANK_COUNT +#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4 +#endif + +#define MAX_BANKS CONFIG_SYS_FSL_IFC_BANK_COUNT #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ #define IFC_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for IFC @@ -802,12 +805,30 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) { } -static void fsl_ifc_sram_init(void) +static int fsl_ifc_sram_init(uint32_t ver) { struct fsl_ifc *ifc = ifc_ctrl->regs; uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0; + uint32_t ncfgr = 0; long long end_tick; + if (ver > FSL_IFC_V1_1_0) { + ncfgr = ifc_in32(&ifc->ifc_nand.ncfgr); + ifc_out32(&ifc->ifc_nand.ncfgr, ncfgr | IFC_NAND_SRAM_INIT_EN); + + /* wait for SRAM_INIT bit to be clear or timeout */ + end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks(); + while (end_tick > get_ticks()) { + ifc_ctrl->status = + ifc_in32(&ifc->ifc_nand.nand_evter_stat); + + if (!(ifc_ctrl->status & IFC_NAND_SRAM_INIT_EN)) + return 0; + } + printf("fsl-ifc: Failed to Initialise SRAM\n"); + return 1; + } + cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT; /* Save CSOR and CSOR_ext */ @@ -850,11 +871,18 @@ static void fsl_ifc_sram_init(void) break; } + if (ifc_ctrl->status != IFC_NAND_EVTER_STAT_OPC) { + printf("fsl-ifc: Failed to Initialise SRAM\n"); + return 1; + } + ifc_out32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status); /* Restore CSOR and CSOR_ext */ ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor); ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext); + + return 0; } static int fsl_ifc_chip_init(int devnum, u8 *addr) @@ -864,7 +892,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr) struct fsl_ifc_mtd *priv; struct nand_ecclayout *layout; uint32_t cspr = 0, csor = 0, ver = 0; - int ret; + int ret = 0; if (!ifc_ctrl) { fsl_ifc_ctrl_init(); @@ -1006,8 +1034,13 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr) } ver = ifc_in32(&ifc_ctrl->regs->ifc_rev); - if (ver == FSL_IFC_V1_1_0) - fsl_ifc_sram_init(); + if (ver >= FSL_IFC_V1_1_0) + ret = fsl_ifc_sram_init(ver); + if (ret) + return ret; + + if (ver >= FSL_IFC_V2_0_0) + priv->bufnum_mask = (priv->bufnum_mask * 2) + 1; ret = nand_scan_ident(mtd, 1, NULL); if (ret) diff --git a/drivers/mtd/nand/fsl_ifc_spl.c b/drivers/mtd/nand/fsl_ifc_spl.c index 510077282c..e336cb1c94 100644 --- a/drivers/mtd/nand/fsl_ifc_spl.c +++ b/drivers/mtd/nand/fsl_ifc_spl.c @@ -97,7 +97,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) int pages_per_blk; int blk_size; int bad_marker = 0; - int bufnum_mask, bufnum; + int bufnum_mask, bufnum, ver = 0; int csor, cspr; int pos = 0; @@ -130,6 +130,10 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) bad_marker = 5; } + ver = ifc_in32(&ifc->ifc_rev); + if (ver >= FSL_IFC_V2_0_0) + bufnum_mask = (bufnum_mask * 2) + 1; + pages_per_blk = 32 << ((csor & CSOR_NAND_PB_MASK) >> CSOR_NAND_PB_SHIFT); diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 43de114b52..316e06e17e 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -143,6 +143,7 @@ struct fm_eth { #define MAX_RXBUF_LOG2 11 #define MAX_RXBUF_LEN (1 << MAX_RXBUF_LOG2) -#define PORT_IS_ENABLED(port) fm_info[fm_port_to_index(port)].enabled +#define PORT_IS_ENABLED(port) (fm_port_to_index(port) == -1 ? \ + 0 : fm_info[fm_port_to_index(port)].enabled) #endif /* __FM_H__ */ diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index cd787f4eed..ff04695c32 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -147,6 +147,9 @@ void fm_disable_port(enum fm_port port) { int i = fm_port_to_index(port); + if (i == -1) + return; + fm_info[i].enabled = 0; fman_disable_port(port); } @@ -155,6 +158,9 @@ void fm_enable_port(enum fm_port port) { int i = fm_port_to_index(port); + if (i == -1) + return; + fm_info[i].enabled = 1; fman_enable_port(port); } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 65c747e14b..623f7492c7 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -215,7 +215,7 @@ static void nc_send_packet(const char *buf, int len) } } -static int nc_start(void) +static int nc_start(struct stdio_dev *dev) { int retval; @@ -235,7 +235,7 @@ static int nc_start(void) return 0; } -static void nc_putc(char c) +static void nc_putc(struct stdio_dev *dev, char c) { if (output_recursion) return; @@ -246,7 +246,7 @@ static void nc_putc(char c) output_recursion = 0; } -static void nc_puts(const char *s) +static void nc_puts(struct stdio_dev *dev, const char *s) { int len; @@ -265,7 +265,7 @@ static void nc_puts(const char *s) output_recursion = 0; } -static int nc_getc(void) +static int nc_getc(struct stdio_dev *dev) { uchar c; @@ -286,7 +286,7 @@ static int nc_getc(void) return c; } -static int nc_tstc(void) +static int nc_tstc(struct stdio_dev *dev) { struct eth_device *eth; diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 3a41b0ec17..231b07573f 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -504,8 +504,14 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) } #endif if (!enabled) { - /* Let the user know there's no PCIe link */ - printf("no link, regs @ 0x%lx\n", pci_info->regs); + /* Let the user know there's no PCIe link for root + * complex. for endpoint, the link may not setup, so + * print undetermined. + */ + if (fsl_is_pci_agent(hose)) + printf("undetermined, regs @ 0x%lx\n", pci_info->regs); + else + printf("no link, regs @ 0x%lx\n", pci_info->regs); hose->last_busno = hose->first_busno; return; } diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 9c5fbd1d69..be09a17297 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -11,7 +11,7 @@ #include <command.h> #include "asm/errno.h" #include "asm/io.h" -#include "asm/immap_qe.h" +#include "linux/immap_qe.h" #include "qe.h" #define MPC85xx_DEVDISR_QE_DISABLE 0x1 diff --git a/drivers/qe/uccf.c b/drivers/qe/uccf.c index 593d96d1a2..85386bfc70 100644 --- a/drivers/qe/uccf.c +++ b/drivers/qe/uccf.c @@ -11,7 +11,7 @@ #include "malloc.h" #include "asm/errno.h" #include "asm/io.h" -#include "asm/immap_qe.h" +#include "linux/immap_qe.h" #include "qe.h" #include "uccf.h" diff --git a/drivers/qe/uccf.h b/drivers/qe/uccf.h index 0b57e2f422..55941e4601 100644 --- a/drivers/qe/uccf.h +++ b/drivers/qe/uccf.h @@ -12,7 +12,7 @@ #include "common.h" #include "qe.h" -#include "asm/immap_qe.h" +#include "linux/immap_qe.h" /* Fast or Giga ethernet */ diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index 68045733b8..c91f084a7c 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -11,7 +11,7 @@ #include "malloc.h" #include "asm/errno.h" #include "asm/io.h" -#include "asm/immap_qe.h" +#include "linux/immap_qe.h" #include "qe.h" #include "uccf.h" #include "uec.h" diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index 5dc4641bf6..e701787c41 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -14,7 +14,7 @@ #include "net.h" #include "malloc.h" #include "asm/errno.h" -#include "asm/immap_qe.h" +#include "linux/immap_qe.h" #include "asm/io.h" #include "qe.h" #include "uccf.h" diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index fd61a5e545..d2eb7520d0 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -254,6 +254,48 @@ void serial_initialize(void) serial_assign(default_serial_console()->name); } +int serial_stub_start(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->start(); +} + +int serial_stub_stop(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->stop(); +} + +void serial_stub_putc(struct stdio_dev *sdev, const char ch) +{ + struct serial_device *dev = sdev->priv; + + dev->putc(ch); +} + +void serial_stub_puts(struct stdio_dev *sdev, const char *str) +{ + struct serial_device *dev = sdev->priv; + + dev->puts(str); +} + +int serial_stub_getc(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->getc(); +} + +int serial_stub_tstc(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->tstc(); +} + /** * serial_stdio_init() - Register serial ports with STDIO core * @@ -272,12 +314,12 @@ void serial_stdio_init(void) strcpy(dev.name, s->name); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; - dev.start = s->start; - dev.stop = s->stop; - dev.putc = s->putc; - dev.puts = s->puts; - dev.getc = s->getc; - dev.tstc = s->tstc; + dev.start = serial_stub_start; + dev.stop = serial_stub_stop; + dev.putc = serial_stub_putc; + dev.puts = serial_stub_puts; + dev.getc = serial_stub_getc; + dev.tstc = serial_stub_tstc; stdio_register(&dev); @@ -376,6 +418,7 @@ static struct serial_device *get_current(void) */ int serial_init(void) { + gd->flags |= GD_FLG_SERIAL_READY; return get_current()->start(); } diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index 6b912efafd..b030526b6a 100644 --- a/drivers/serial/usbtty.c +++ b/drivers/serial/usbtty.c @@ -389,7 +389,7 @@ static void str2wide (char *str, u16 * wide) * Test whether a character is in the RX buffer */ -int usbtty_tstc (void) +int usbtty_tstc(struct stdio_dev *dev) { struct usb_endpoint_instance *endpoint = &endpoint_instance[rx_endpoint]; @@ -409,7 +409,7 @@ int usbtty_tstc (void) * written into its argument c. */ -int usbtty_getc (void) +int usbtty_getc(struct stdio_dev *dev) { char c; struct usb_endpoint_instance *endpoint = @@ -429,7 +429,7 @@ int usbtty_getc (void) /* * Output a single byte to the usb client port. */ -void usbtty_putc (const char c) +void usbtty_putc(struct stdio_dev *dev, const char c) { if (!usbtty_configured ()) return; @@ -484,7 +484,7 @@ static void __usbtty_puts (const char *str, int len) } } -void usbtty_puts (const char *str) +void usbtty_puts(struct stdio_dev *dev, const char *str) { int n; int len; diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index b52e9edd25..9231927879 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -944,7 +944,7 @@ static void parse_putc(const char c) CURSOR_SET; } -void video_putc(const char c) +void video_putc(struct stdio_dev *dev, const char c) { #ifdef CONFIG_CFB_CONSOLE_ANSI int i; @@ -1158,12 +1158,12 @@ void video_putc(const char c) flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); } -void video_puts(const char *s) +void video_puts(struct stdio_dev *dev, const char *s) { int count = strlen(s); while (count--) - video_putc(*s++); + video_putc(dev, *s++); } /* @@ -2279,8 +2279,6 @@ int drv_video_init(void) console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; console_dev.putc = video_putc; /* 'putc' function */ console_dev.puts = video_puts; /* 'puts' function */ - console_dev.tstc = NULL; /* 'tstc' function */ - console_dev.getc = NULL; /* 'getc' function */ #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE) /* Also init console device */ |