--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -659,6 +659,7 @@ #define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) #define AR933X_BOOTSTRAP_EEPBUSY BIT(4) +#define AR933X_BOOTSTRAP_USB_MODE_HOST BIT(3) #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) #define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) @@ -688,6 +689,8 @@ #define QCA956X_BOOTSTRAP_REF_CLK_40 BIT(2) +#define AR933X_USB_CONFIG_HOST_ONLY BIT(8) + #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include @@ -170,6 +173,44 @@ static void __init ar913x_usb_setup(void &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); } +static void __init ar9xxx_ci_usb_setup(int bus_id, int irq) +{ + struct ci_hdrc_platform_data ci_pdata; + bool host_mode = true; + + if (soc_is_ar933x()) + host_mode = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP) & + AR933X_BOOTSTRAP_USB_MODE_HOST; + else + host_mode = !(ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP) & + AR934X_BOOTSTRAP_USB_MODE_DEVICE); + + if (host_mode) { + ath79_usb_register("ehci-platform", bus_id, + AR934X_EHCI_BASE, AR934X_EHCI_SIZE, + irq, &ath79_ehci_pdata_v2, + sizeof(ath79_ehci_pdata_v2)); + + return; + } + + memset(&ci_pdata, 0, sizeof(ci_pdata)); + ci_pdata.name = "ci_hdrc_ar9xxx"; + ci_pdata.capoffset = DEF_CAPOFFSET; + ci_pdata.dr_mode = USB_DR_MODE_PERIPHERAL; + ci_pdata.flags = CI_HDRC_DUAL_ROLE_NOT_OTG | CI_HDRC_DP_ALWAYS_PULLUP; + ci_pdata.vbus_extcon.edev = ERR_PTR(-ENODEV); + ci_pdata.id_extcon.edev = ERR_PTR(-ENODEV); + ci_pdata.itc_setting = 1; + + platform_device_register_simple("usb_phy_generic", + PLATFORM_DEVID_AUTO, NULL, 0); + + ath79_usb_register("ci_hdrc", -1, + AR934X_EHCI_BASE, AR934X_EHCI_SIZE, + irq, &ci_pdata, sizeof(ci_pdata)); +} + static void __init ar933x_usb_setup(void) { ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE); @@ -181,10 +222,7 @@ static void __init ar933x_usb_setup(void ath79_device_reset_clear(AR933X_RESET_USB_PHY); mdelay(10); - ath79_usb_register("ehci-platform", -1, - AR933X_EHCI_BASE, AR933X_EHCI_SIZE, - ATH79_CPU_IRQ(3), - &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); + ar9xxx_ci_usb_setup(-1, ATH79_CPU_IRQ(3)); } static void enable_tx_tx_idp_violation_fix(unsigned base) @@ -230,10 +268,7 @@ static void __init ar934x_usb_setup(void if (ath79_soc_rev >= 3) ath79_ehci_pdata_v2.reset_notifier = ar934x_usb_reset_notifier; - ath79_usb_register("ehci-platform", -1, - AR934X_EHCI_BASE, AR934X_EHCI_SIZE, - ATH79_CPU_IRQ(3), - &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); + ar9xxx_ci_usb_setup(-1, ATH79_CPU_IRQ(3)); } static void __init qca953x_usb_setup(void) @@ -254,10 +289,7 @@ static void __init qca953x_usb_setup(voi ath79_device_reset_clear(QCA953X_RESET_USB_HOST); udelay(1000); - ath79_usb_register("ehci-platform", -1, - QCA953X_EHCI_BASE, QCA953X_EHCI_SIZE, - ATH79_CPU_IRQ(3), - &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); + ar9xxx_ci_usb_setup(-1, ATH79_CPU_IRQ(3)); } static void qca955x_usb_reset_notifier(struct platform_device *pdev) @@ -285,10 +317,7 @@ static void __init qca955x_usb_setup(voi { ath79_ehci_pdata_v2.reset_notifier = qca955x_usb_reset_notifier; - ath79_usb_register("ehci-platform", 0, - QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, - ATH79_IP3_IRQ(0), - &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); + ar9xxx_ci_usb_setup(0, ATH79_IP3_IRQ(0)); ath79_usb_register("ehci-platform", 1, QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE,