diff options
author | Nikhil Badola <nikhil.badola@freescale.com> | 2014-09-30 11:24:07 +0530 |
---|---|---|
committer | York Sun <yorksun@freescale.com> | 2014-12-11 09:41:03 -0800 |
commit | ecfc19f31f1fa25f739d11c81d4810f9b35b29aa (patch) | |
tree | 09c62f7728e41e0b708484485b4c112836262564 /drivers | |
parent | a1c04e2785fe9843abcaeaa5d46f819215550d90 (diff) |
drivers: usb: fsl: Add USB device-tree errata framework
Add a new framework for fsl usb erratum handling to standardize
erratum checking only inside Uboot. Information to kernel is passed
via a boolean property corresponding to erratum, hence eliminating
need for code duplication inside kernel
Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 54efe5ef00..61cd16840a 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -211,10 +211,57 @@ static int fdt_fixup_usb_mode_phy_type(void *blob, const char *mode, return node_offset; } +static const char *fdt_usb_get_node_type(void *blob, int start_offset, + int *node_offset) +{ + const char *compat_dr = "fsl-usb2-dr"; + const char *compat_mph = "fsl-usb2-mph"; + const char *node_type = NULL; + + *node_offset = fdt_node_offset_by_compatible(blob, start_offset, + compat_mph); + if (*node_offset < 0) { + *node_offset = fdt_node_offset_by_compatible(blob, + start_offset, + compat_dr); + if (*node_offset < 0) { + printf("ERROR: could not find compatible node: %s\n", + fdt_strerror(*node_offset)); + } else { + node_type = compat_dr; + } + } else { + node_type = compat_mph; + } + + return node_type; +} + +static int fdt_fixup_usb_erratum(void *blob, const char *prop_erratum, + int start_offset) +{ + int node_offset, err; + const char *node_type = NULL; + + node_type = fdt_usb_get_node_type(blob, start_offset, &node_offset); + if (!node_type) + return -1; + + err = fdt_setprop(blob, node_offset, prop_erratum, NULL, 0); + if (err < 0) { + printf("ERROR: could not set %s for %s: %s.\n", + prop_erratum, node_type, fdt_strerror(err)); + } + + return node_offset; +} + void fdt_fixup_dr_usb(void *blob, bd_t *bd) { static const char * const modes[] = { "host", "peripheral", "otg" }; static const char * const phys[] = { "ulpi", "utmi" }; + int usb_erratum_a006261_off = -1; + int usb_erratum_a007075_off = -1; int usb_mode_off = -1; int usb_phy_off = -1; char str[5]; @@ -268,6 +315,23 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd) if (usb_phy_off < 0) return; + + if (has_erratum_a006261()) { + usb_erratum_a006261_off = fdt_fixup_usb_erratum + (blob, + "fsl,usb-erratum-a006261", + usb_erratum_a006261_off); + if (usb_erratum_a006261_off < 0) + return; + } + if (has_erratum_a007075()) { + usb_erratum_a007075_off = fdt_fixup_usb_erratum + (blob, + "fsl,usb-erratum-a007075", + usb_erratum_a007075_off); + if (usb_erratum_a007075_off < 0) + return; + } } } #endif |