diff options
-rw-r--r-- | target/linux/adm8668/files/arch/mips/adm8668/platform.c | 45 | ||||
-rw-r--r-- | target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h | 1 |
2 files changed, 46 insertions, 0 deletions
diff --git a/target/linux/adm8668/files/arch/mips/adm8668/platform.c b/target/linux/adm8668/files/arch/mips/adm8668/platform.c index dc0fd91a33..71f3eca142 100644 --- a/target/linux/adm8668/files/arch/mips/adm8668/platform.c +++ b/target/linux/adm8668/files/arch/mips/adm8668/platform.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/platform_data/tulip.h> +#include <linux/usb/ehci_pdriver.h> #include <linux/mtd/physmap.h> #include <linux/mtd/partitions.h> #include <linux/pci.h> @@ -130,10 +131,38 @@ static struct platform_device adm8668_nor_device = { .dev.platform_data = &nor_flash_data, }; +static struct resource usb_resources[] = { + { + .start = ADM8668_USB_BASE, + .end = ADM8668_USB_BASE + 0x1FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_LVL_USB, + .end = INT_LVL_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct usb_ehci_pdata usb_pdata = { + .caps_offset = 0x100, + .has_tt = 1, + .port_power_off = 1, +}; + +static struct platform_device adm8668_usb_device = { + .name = "ehci-platform", + .id = -1, + .resource = usb_resources, + .num_resources = ARRAY_SIZE(usb_resources), + .dev.platform_data = &usb_pdata, +}; + static struct platform_device *adm8668_devs[] = { &adm8668_eth0_device, &adm8668_eth1_device, &adm8668_nor_device, + &adm8668_usb_device, }; static void adm8668_fetch_mac(int unit) @@ -162,6 +191,21 @@ static void adm8668_fetch_mac(int unit) memcpy(pdata->mac, mac, sizeof(pdata->mac)); } +static void adm8668_ehci_workaround(void) +{ + u32 chipid; + + chipid = ADM8668_CONFIG_REG(ADM8668_CR0); + ADM8668_CONFIG_REG(ADM8668_CR66) = 0x0C1600D9; + + if (chipid == 0x86880001) + return; + + ADM8668_CONFIG_REG(ADM8668_CR66) &= ~(3 << 20); + ADM8668_CONFIG_REG(ADM8668_CR66) |= (1 << 20); + pr_info("ADM8668: applied USB workaround\n"); +} + int __devinit adm8668_devs_register(void) { @@ -173,6 +217,7 @@ int __devinit adm8668_devs_register(void) adm8668_fetch_mac(0); adm8668_fetch_mac(1); + adm8668_ehci_workaround(); return platform_add_devices(adm8668_devs, ARRAY_SIZE(adm8668_devs)); } diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h index f7b2c5e632..65ed0b5d3e 100644 --- a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h @@ -64,6 +64,7 @@ #define ADM8668_CR0 0x00 #define ADM8668_CR1 0x04 #define ADM8668_CR3 0x0C +#define ADM8668_CR66 0x108 /** For GPIO control **/ #define GPIO_REG 0x5C /* on WLAN */ |