diff options
author | Masahiro Yamada <yamada.m@jp.panasonic.com> | 2014-11-26 18:34:01 +0900 |
---|---|---|
committer | Masahiro Yamada <yamada.m@jp.panasonic.com> | 2014-11-28 02:21:01 +0900 |
commit | 149c751dc7958f3db99203e49208198aa40811b3 (patch) | |
tree | 81dd4430f3367fcc52a82d495f11a931d44231ee /drivers/usb | |
parent | 625177d27ed9e91cb96c0221b8020f7e4d24bfb6 (diff) |
usb: UniPhier: support OF configuration
If CONFIG_OF_CONTROL is defined, search device tree nodes that are
compatible with "panasonic,uniphier-ehci" and take the base address
from their "reg" property.
Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
Cc: Marek Vasut <marex@denx.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ehci-uniphier.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-uniphier.c b/drivers/usb/host/ehci-uniphier.c index 77f6c9d9d1..32a4375279 100644 --- a/drivers/usb/host/ehci-uniphier.c +++ b/drivers/usb/host/ehci-uniphier.c @@ -6,10 +6,43 @@ */ #include <common.h> +#include <linux/err.h> #include <usb.h> #include <asm/arch/ehci-uniphier.h> #include "ehci.h" +#ifdef CONFIG_OF_CONTROL +#include <fdtdec.h> +DECLARE_GLOBAL_DATA_PTR; + +#define FDT gd->fdt_blob +#define COMPAT "panasonic,uniphier-ehci" + +static int get_uniphier_ehci_base(int index, struct ehci_hccr **base) +{ + int offset; + + for (offset = fdt_node_offset_by_compatible(FDT, 0, COMPAT); + offset >= 0; + offset = fdt_node_offset_by_compatible(FDT, offset, COMPAT)) { + if (index == 0) { + *base = (struct ehci_hccr *) + fdtdec_get_addr(FDT, offset, "reg"); + return 0; + } + index--; + } + + return -ENODEV; /* not found */ +} +#else +static int get_uniphier_ehci_base(int index, struct ehci_hccr **base) +{ + *base = (struct ehci_hccr *)uniphier_ehci_platdata[index].base; + return 0; +} +#endif + /* * Create the appropriate control structures to manage * a new EHCI host controller. @@ -17,12 +50,15 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { + int ret; struct ehci_hccr *cr; struct ehci_hcor *or; uniphier_ehci_reset(index, 0); - cr = (struct ehci_hccr *)(uniphier_ehci_platdata[index].base); + ret = get_uniphier_ehci_base(index, &cr); + if (ret < 0) + return ret; or = (void *)cr + HC_LENGTH(ehci_readl(&cr->cr_capbase)); *hccr = cr; |