$(eval $(call KernelPackage,usbip-server))
+define KernelPackage/usb-chipidea
+ TITLE:=Host and device support for Chipidea controllers
+ DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget
+ KCONFIG:= \
+ CONFIG_NOP_USB_XCEIV=y \
+ CONFIG_EXTCON \
+ CONFIG_USB_CHIPIDEA \
+ CONFIG_USB_CHIPIDEA_HOST=y \
+ CONFIG_USB_CHIPIDEA_UDC=y \
+ CONFIG_USB_CHIPIDEA_DEBUG=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/extcon/extcon.ko \
+ $(LINUX_DIR)/drivers/usb/chipidea/ci_hdrc.ko
+ AUTOLOAD:=$(call AutoLoad,51,ci_hdrc,0)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-chipidea/description
+ Kernel support for USB Chipidea controllers
+endef
+
+$(eval $(call KernelPackage,usb-chipidea))
+
define KernelPackage/usbmon
TITLE:=USB traffic monitor
KCONFIG:=CONFIG_USB_MON
ARCH:=mips
BOARD:=ar71xx
BOARDNAME:=Atheros AR7xxx/AR9xxx
-FEATURES:=mips16
+FEATURES:=mips16 usbgadget
CPU_TYPE:=24kc
SUBTARGETS:=generic nand mikrotik
--- /dev/null
+Index: linux-4.4.4/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+===================================================================
+--- linux-4.4.4.orig/arch/mips/include/asm/mach-ath79/ar71xx_regs.h 2016-03-31 21:43:10.595132564 +0300
++++ linux-4.4.4/arch/mips/include/asm/mach-ath79/ar71xx_regs.h 2016-03-31 21:56:21.463152017 +0300
+@@ -641,6 +641,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)
+@@ -670,6 +671,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)
+Index: linux-4.4.4/arch/mips/ath79/dev-usb.c
+===================================================================
+--- linux-4.4.4.orig/arch/mips/ath79/dev-usb.c 2016-03-31 21:43:10.407132560 +0300
++++ linux-4.4.4/arch/mips/ath79/dev-usb.c 2016-03-31 21:43:10.707132567 +0300
+@@ -19,6 +19,9 @@
+ #include <linux/platform_device.h>
+ #include <linux/usb/ehci_pdriver.h>
+ #include <linux/usb/ohci_pdriver.h>
++#include <linux/usb/otg.h>
++#include <linux/usb/chipidea.h>
++#include <linux/usb/usb_phy_generic.h>
+
+ #include <asm/mach-ath79/ath79.h>
+ #include <asm/mach-ath79/ar71xx_regs.h>
+@@ -170,6 +173,54 @@
+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+ }
+
++static void __init ar933x_usb_setup_ctrl_config(void)
++{
++ void __iomem *usb_ctrl_base, *usb_config_reg;
++ u32 usb_config;
++
++ usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE);
++ usb_config_reg = usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG;
++ usb_config = __raw_readl(usb_config_reg);
++ usb_config &= ~AR933X_USB_CONFIG_HOST_ONLY;
++ __raw_writel(usb_config, usb_config_reg);
++ iounmap(usb_ctrl_base);
++}
++
++static void __init ar933x_ci_usb_setup(void)
++{
++ u32 bootstrap;
++ enum usb_dr_mode dr_mode;
++ struct ci_hdrc_platform_data ci_pdata;
++ struct platform_device *phy;
++
++ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
++ if (bootstrap & AR933X_BOOTSTRAP_USB_MODE_HOST) {
++ dr_mode = USB_DR_MODE_HOST;
++ } else {
++ dr_mode = USB_DR_MODE_PERIPHERAL;
++ ar933x_usb_setup_ctrl_config();
++ }
++
++ memset(&ci_pdata, 0, sizeof(ci_pdata));
++ ci_pdata.name = "ci_hdrc_ar933x";
++ ci_pdata.capoffset = DEF_CAPOFFSET;
++ ci_pdata.dr_mode = dr_mode;
++ 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;
++
++ /* register a nop PHY */
++ phy = usb_phy_generic_register();
++ if (IS_ERR(phy))
++ return;
++
++ ath79_usb_register("ci_hdrc", -1,
++ AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
++ ATH79_CPU_IRQ(3),
++ &ci_pdata, sizeof(ci_pdata));
++}
++
+ static void __init ar933x_usb_setup(void)
+ {
+ ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
+@@ -185,6 +236,8 @@
+ AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
+ ATH79_CPU_IRQ(3),
+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
++
++ ar933x_ci_usb_setup();
+ }
+
+ static void enable_tx_tx_idp_violation_fix(unsigned base)
--- /dev/null
+Index: linux-4.4.4/drivers/usb/chipidea/ci.h
+===================================================================
+--- linux-4.4.4.orig/drivers/usb/chipidea/ci.h 2016-03-31 21:39:23.571126980 +0300
++++ linux-4.4.4/drivers/usb/chipidea/ci.h 2016-03-31 21:39:23.567126980 +0300
+@@ -199,6 +199,7 @@
+ * @in_lpm: if the core in low power mode
+ * @wakeup_int: if wakeup interrupt occur
+ * @rev: The revision number for controller
++ * @dp_always_pullup: keep dp always pullup at device mode
+ */
+ struct ci_hdrc {
+ struct device *dev;
+@@ -248,6 +249,7 @@
+ bool in_lpm;
+ bool wakeup_int;
+ enum ci_revision rev;
++ bool dp_always_pullup;
+ };
+
+ static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
+Index: linux-4.4.4/drivers/usb/chipidea/core.c
+===================================================================
+--- linux-4.4.4.orig/drivers/usb/chipidea/core.c 2016-03-31 21:39:23.571126980 +0300
++++ linux-4.4.4/drivers/usb/chipidea/core.c 2016-03-31 21:41:33.159130168 +0300
+@@ -883,7 +883,7 @@
+ {
+ ci_hdrc_gadget_destroy(ci);
+ ci_hdrc_host_destroy(ci);
+- if (ci->is_otg)
++ if (!ci->dp_always_pullup && ci->roles[CI_ROLE_GADGET])
+ ci_hdrc_otg_destroy(ci);
+ }
+
+@@ -933,6 +933,9 @@
+ ci->supports_runtime_pm = !!(ci->platdata->flags &
+ CI_HDRC_SUPPORTS_RUNTIME_PM);
+
++ ci->dp_always_pullup = !!(ci->platdata->flags &
++ CI_HDRC_DP_ALWAYS_PULLUP);
++
+ ret = hw_device_init(ci, base);
+ if (ret < 0) {
+ dev_err(dev, "can't initialize hardware\n");
+@@ -998,7 +1001,7 @@
+ goto deinit_phy;
+ }
+
+- if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
++ if (!ci->dp_always_pullup && ci->roles[CI_ROLE_GADGET]) {
+ ret = ci_hdrc_otg_init(ci);
+ if (ret) {
+ dev_err(dev, "init otg fails, ret = %d\n", ret);
+Index: linux-4.4.4/drivers/usb/chipidea/otg.c
+===================================================================
+--- linux-4.4.4.orig/drivers/usb/chipidea/otg.c 2016-03-31 21:39:23.571126980 +0300
++++ linux-4.4.4/drivers/usb/chipidea/otg.c 2016-03-31 21:39:23.567126980 +0300
+@@ -95,8 +95,10 @@
+
+ void ci_handle_vbus_change(struct ci_hdrc *ci)
+ {
+- if (!ci->is_otg)
++ if (ci->dp_always_pullup) {
++ usb_gadget_vbus_connect(&ci->gadget);
+ return;
++ }
+
+ if (hw_read_otgsc(ci, OTGSC_BSV))
+ usb_gadget_vbus_connect(&ci->gadget);
+Index: linux-4.4.4/include/linux/usb/chipidea.h
+===================================================================
+--- linux-4.4.4.orig/include/linux/usb/chipidea.h 2016-03-31 21:39:23.571126980 +0300
++++ linux-4.4.4/include/linux/usb/chipidea.h 2016-03-31 21:39:23.567126980 +0300
+@@ -55,6 +55,7 @@
+ #define CI_HDRC_OVERRIDE_AHB_BURST BIT(9)
+ #define CI_HDRC_OVERRIDE_TX_BURST BIT(10)
+ #define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
++#define CI_HDRC_DP_ALWAYS_PULLUP BIT(12)
+ enum usb_dr_mode dr_mode;
+ #define CI_HDRC_CONTROLLER_RESET_EVENT 0
+ #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1