From: Thomas Tanner Date: Mon, 7 Jun 2010 21:55:11 +0000 (+0200) Subject: really apply patches; updated refresh script X-Git-Url: http://git.maemo.org/git/?p=kernel-power;a=commitdiff_plain;h=7746741de96d6b2df623bb57cc5d3278a7633945 really apply patches; updated refresh script --- diff --git a/kernel-power-2.6.28/debian/patches/series b/kernel-power-2.6.28/debian/patches/series index ebde99d..cd4eb85 100644 --- a/kernel-power-2.6.28/debian/patches/series +++ b/kernel-power-2.6.28/debian/patches/series @@ -21,12 +21,13 @@ twl-scrollock.diff led_dbrightness.diff wl1251-monitor-mode.diff mmcnames-fanoush.diff -gethercharge.diff +#gethercharge.diff #ondemand-avoid.diff #overclock.diff -usbwhitelist.diff -usbignpower.diff +#usbwhitelist.diff +#usbignpower.diff #nootg.diff #bq24150-sniff.diff #usbhost4.diff -usbhostmode.diff +#usbhostmode.diff +usbhost.diff diff --git a/kernel-power-2.6.28/debian/patches/usbhostmode.diff b/kernel-power-2.6.28/debian/patches/usbhostmode.diff deleted file mode 100644 index 511e0e4..0000000 --- a/kernel-power-2.6.28/debian/patches/usbhostmode.diff +++ /dev/null @@ -1,841 +0,0 @@ ---- kernel-power-2.6.28.orig/arch/arm/mach-omap2/board-rx51.c -+++ kernel-power-2.6.28/arch/arm/mach-omap2/board-rx51.c -@@ -108,6 +108,7 @@ - - static int rx51_xceiv_reset(void) - { -+ printk(KERN_ERR "rx51_xceiv_reset\n"); - /* make sure the transceiver is awake */ - msleep(15); - /* only reset powered transceivers */ -@@ -125,6 +126,7 @@ - { - unsigned long timeout; - -+ printk(KERN_ERR "rx51_xceiv_power %d\n",power); - if (!power) { - /* Let musb go stdby before powering down the transceiver */ - timeout = jiffies + msecs_to_jiffies(100); ---- kernel-power-2.6.28.orig/drivers/usb/musb/isp1704.h -+++ kernel-power-2.6.28/drivers/usb/musb/isp1704.h -@@ -41,6 +41,7 @@ - #define ISP1704_OTG_CTRL 0x0a - #define ISP1704_USB_INTRISE 0x0d - #define ISP1704_USB_INTFALL 0x10 -+#define ISP1704_USB_INTSTAT 0x13 - #define ISP1704_DEBUG 0x15 - #define ISP1704_SCRATCH 0x16 - #define ISP1704_PWR_CTRL 0x3d ---- kernel-power-2.6.28.orig/drivers/usb/musb/musb_core.c -+++ kernel-power-2.6.28/drivers/usb/musb/musb_core.c -@@ -142,6 +142,59 @@ - MODULE_LICENSE("GPL"); - MODULE_ALIAS("platform:" MUSB_DRIVER_NAME); - -+ -+ -+inline void mbusywait(int ms) -+{ -+ unsigned long end_time = jiffies + msecs_to_jiffies(ms); -+ while(time_before(jiffies,end_time)) -+ cpu_relax(); -+ -+} -+ -+void musb_force_term(void __iomem *addr, enum musb_term term) -+{ -+ u8 r; -+ -+ -+ r = musb_ulpi_readb(addr, ISP1704_OTG_CTRL); -+ r |= ISP1704_OTG_CTRL_DP_PULLDOWN | ISP1704_OTG_CTRL_DM_PULLDOWN; -+ musb_ulpi_writeb(addr, ISP1704_OTG_CTRL, r); -+ -+ r = musb_ulpi_readb(addr, ISP1704_FUNC_CTRL); -+ -+ switch(term) { -+ -+ case MUSB_TERM_HOST_HIGHSPEED: -+ r &= ~ISP1704_FUNC_CTRL_XCVRSELECT; -+ r &= ~ISP1704_FUNC_CTRL_TERMSELECT; -+ r &= ~ISP1704_FUNC_CTRL_OPMODE; -+ break; -+ -+ case MUSB_TERM_HOST_FULLSPEED: -+ r |= 1 << ISP1704_FUNC_CTRL_XCVRSELECT_SHIFT; -+ r |= ISP1704_FUNC_CTRL_TERMSELECT; -+ r &= ~ISP1704_FUNC_CTRL_OPMODE; -+ break; -+ -+ case MUSB_TERM_HOST_LOWSPEED: -+ r |= 2 << ISP1704_FUNC_CTRL_XCVRSELECT_SHIFT; -+ r |= ISP1704_FUNC_CTRL_TERMSELECT; -+ r &= ~ISP1704_FUNC_CTRL_OPMODE; -+ break; -+ -+ default: -+ ERR("Unknown musb termination\n"); -+ return; -+ } -+ -+ r |= ISP1704_OTG_CTRL_IDPULLUP; -+ musb_ulpi_writeb(addr, ISP1704_FUNC_CTRL, r); -+ -+} -+ -+ -+ - static inline int musb_verify_charger(void __iomem *addr) - { - u8 r, ret = 0; -@@ -220,6 +273,8 @@ - - u8 vdat = 0; - u8 r; -+ u8 testmode; -+ testmode = musb_readb(musb->mregs,MUSB_TESTMODE); - - msleep(5); - -@@ -297,7 +352,7 @@ - break; - } - -- if (vdat) { -+ if (vdat && !(testmode & MUSB_TEST_FORCE_HOST)) { - /* REVISIT: This code works only with dedicated chargers! - * When support for HOST/HUB chargers is added, don't - * forget this. -@@ -349,7 +404,7 @@ - - prefetch((u8 *)src); - -- DBG(4, "%cX ep%d fifo %p count %d buf %p\n", -+ DBG(6, "%cX ep%d fifo %p count %d buf %p\n", - 'T', hw_ep->epnum, fifo, len, src); - - /* we can't assume unaligned reads work */ -@@ -387,7 +442,7 @@ - { - void __iomem *fifo = hw_ep->fifo; - -- DBG(4, "%cX ep%d fifo %p count %d buf %p\n", -+ DBG(6, "%cX ep%d fifo %p count %d buf %p\n", - 'R', hw_ep->epnum, fifo, len, dst); - - /* we can't assume unaligned writes work */ -@@ -490,7 +545,6 @@ - { - struct musb *musb = (struct musb *)data; - unsigned long flags; -- - spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { - case OTG_STATE_B_WAIT_ACON: -@@ -572,10 +626,19 @@ - static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - u8 devctl, u8 power) - { -+ u8 testmode; - irqreturn_t handled = IRQ_NONE; - void __iomem *mbase = musb->mregs; - u8 r; - -+ testmode = musb_readb(mbase,MUSB_TESTMODE); -+ if(testmode & MUSB_TEST_FORCE_HOST) { -+ if(int_usb & MUSB_INTR_SESSREQ) { -+ DBG(1,"Piggybacking CONNECT on SESS REQ\n"); -+ musb->int_usb |= MUSB_INTR_CONNECT; -+ } -+ } -+ - DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, - int_usb); - -@@ -630,6 +693,8 @@ - } else { - switch (musb->xceiv->state) { - #ifdef CONFIG_USB_MUSB_HDRC_HCD -+ case OTG_STATE_A_WAIT_BCON: -+ case OTG_STATE_A_HOST: - case OTG_STATE_A_SUSPEND: - /* possibly DISCONNECT is upcoming */ - musb->xceiv->state = OTG_STATE_A_HOST; -@@ -678,7 +743,7 @@ - * be discarded silently. - */ - if ((devctl & MUSB_DEVCTL_VBUS) -- && !(devctl & MUSB_DEVCTL_BDEVICE)) { -+ && host_mode(musb->mregs)) { - musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); - musb->ep0_stage = MUSB_EP0_START; - musb->xceiv->state = OTG_STATE_A_IDLE; -@@ -796,9 +861,15 @@ - + msecs_to_jiffies(musb->a_wait_bcon)); - break; - case OTG_STATE_A_HOST: -+ if(testmode & MUSB_TEST_FORCE_HOST) { -+ // musb->int_usb |= MUSB_INTR_RESUME; -+ break; -+ } -+ - musb->xceiv->state = OTG_STATE_A_SUSPEND; - musb->is_active = is_otg_enabled(musb) - && musb->xceiv->host->b_hnp_enable; -+ - break; - case OTG_STATE_B_HOST: - /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ -@@ -818,6 +889,7 @@ - musb->is_active = 1; - set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - -+ - musb->ep0_stage = MUSB_EP0_START; - - #ifdef CONFIG_USB_MUSB_OTG -@@ -836,9 +908,65 @@ - musb->port1_status |= USB_PORT_STAT_CONNECTION - |(USB_PORT_STAT_C_CONNECTION << 16); - -- /* high vs full speed is just a guess until after reset */ -- if (devctl & MUSB_DEVCTL_LSDEV) -- musb->port1_status |= USB_PORT_STAT_LOW_SPEED; -+ if (testmode & MUSB_TEST_FORCE_HOST) { -+ u8 r,reg; -+ void __iomem *mbase = musb->mregs; -+ -+ musb_force_term(musb->mregs,MUSB_TERM_HOST_HIGHSPEED); -+ -+ r = musb_ulpi_readb(mbase, ISP1704_DEBUG); -+ DBG(1,"Linestate %x\n",r); -+ switch(r) { -+ case 2: -+ musb->port1_status |= USB_PORT_STAT_LOW_SPEED; -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg &= ~MUSB_TEST_FORCE_FS; -+ reg &= ~MUSB_TEST_FORCE_HS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg &= ~MUSB_POWER_HSENAB; -+ musb_writeb(mbase, MUSB_POWER, reg); -+ -+ musb_force_term(musb->mregs,MUSB_TERM_HOST_LOWSPEED); -+ break; -+ case 1: -+ /*High or full speed*/ -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ if(reg & MUSB_TEST_FORCE_HS) { -+ /*High speed*/ -+ reg &= ~MUSB_TEST_FORCE_FS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg |= MUSB_POWER_HSENAB; -+ musb_writeb(mbase, MUSB_POWER, reg); -+ } else { -+ /*Full speed*/ -+ reg |= MUSB_TEST_FORCE_FS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg &= ~MUSB_POWER_HSENAB; -+ musb_writeb(mbase, MUSB_POWER, reg); -+ } -+ -+ musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED); -+ -+ break; -+ case 0: -+ case 3: -+ /*invalid*/ -+ WARNING("Invalid line state of %d\n",r); -+ break; -+ -+ } -+ } else { -+ -+ /* high vs full speed is just a guess until after reset */ -+ if (devctl & MUSB_DEVCTL_LSDEV) -+ musb->port1_status |= USB_PORT_STAT_LOW_SPEED; -+ } - - if (hcd->status_urb) - usb_hcd_poll_rh_status(hcd); -@@ -974,6 +1102,8 @@ - musb->ignore_disconnect = 1; - musb_g_reset(musb); - /* FALLTHROUGH */ -+ case OTG_STATE_A_HOST: -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ - DBG(1, "HNP: Setting timer as %s\n", - otg_state_string(musb)); -@@ -2421,8 +2551,7 @@ - DBG(1, "%s mode, status %d, devctl %02x %c\n", - "HOST", status, - musb_readb(musb->mregs, MUSB_DEVCTL), -- (musb_readb(musb->mregs, MUSB_DEVCTL) -- & MUSB_DEVCTL_BDEVICE -+ (!host_mode(musb->mregs) - ? 'B' : 'A')); - - } else /* peripheral is enabled */ { ---- kernel-power-2.6.28.orig/drivers/usb/musb/musb_core.h -+++ kernel-power-2.6.28/drivers/usb/musb/musb_core.h -@@ -85,6 +85,16 @@ - #define is_host_active(musb) is_host_capable() - #endif - -+static inline int host_mode(void __iomem *addr) -+{ -+ u8 devctl,testmode; -+ devctl = musb_readb(addr, MUSB_DEVCTL); -+ testmode = musb_readb(addr,MUSB_TESTMODE); -+ -+ return (testmode & MUSB_TEST_FORCE_HOST) || !(devctl & MUSB_DEVCTL_BDEVICE); -+} -+ -+ - #if defined(CONFIG_USB_MUSB_OTG) || defined(CONFIG_USB_MUSB_PERIPHERAL) - /* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't always - * override that choice selection (often USB_GADGET_DUMMY_HCD). -@@ -593,6 +603,14 @@ - - extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); - -+enum musb_term { -+ MUSB_TERM_HOST_HIGHSPEED, -+ MUSB_TERM_HOST_FULLSPEED, -+ MUSB_TERM_HOST_LOWSPEED, -+}; -+ -+extern void musb_force_term(void __iomem *addr, enum musb_term term); -+ - #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ - defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) - extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); ---- kernel-power-2.6.28.orig/drivers/usb/musb/musb_gadget.c -+++ kernel-power-2.6.28/drivers/usb/musb/musb_gadget.c -@@ -1957,7 +1957,7 @@ - u8 power; - - DBG(3, "<== %s addr=%x driver '%s'\n", -- (devctl & MUSB_DEVCTL_BDEVICE) -+ !host_mode(musb->mregs) - ? "B-Device" : "A-Device", - musb_readb(mbase, MUSB_FADDR), - musb->gadget_driver -@@ -1994,7 +1994,7 @@ - /* Normal reset, as B-Device; - * or else after HNP, as A-Device - */ -- if (devctl & MUSB_DEVCTL_BDEVICE) { -+ if (!host_mode(musb->mregs)) { - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - musb->g.is_a_peripheral = 0; - } else if (is_otg_enabled(musb)) { ---- kernel-power-2.6.28.orig/drivers/usb/musb/musb_host.c -+++ kernel-power-2.6.28/drivers/usb/musb/musb_host.c -@@ -1863,8 +1863,10 @@ - unsigned interval; - - /* host role must be active */ -- if (!is_host_active(musb) || !musb->is_active) -+ if (!is_host_active(musb) || !musb->is_active) { -+ printk(KERN_ERR "musb is_host_active %d is_active %d\n",is_host_active(musb),musb->is_active); - return -ENODEV; -+ } - - spin_lock_irqsave(&musb->lock, flags); - ret = usb_hcd_link_urb_to_ep(hcd, urb); -@@ -2275,6 +2277,7 @@ - return 0; - } - -+ - const struct hc_driver musb_hc_driver = { - .description = "musb-hcd", - .product_desc = "MUSB HDRC host driver", -@@ -2298,6 +2301,5 @@ - .hub_control = musb_hub_control, - .bus_suspend = musb_bus_suspend, - .bus_resume = musb_bus_resume, -- /* .start_port_reset = NULL, */ - /* .hub_irq_enable = NULL, */ - }; ---- kernel-power-2.6.28.orig/drivers/usb/musb/musb_procfs.c -+++ kernel-power-2.6.28/drivers/usb/musb/musb_procfs.c -@@ -37,6 +37,7 @@ - #include - #include /* FIXME remove procfs writes */ - #include -+#include - - #include "musb_core.h" - -@@ -450,8 +451,8 @@ - return 0; - buffer += count; - -- code = sprintf(buffer, "OTG state: %s; %sactive\n", -- otg_state_string(musb), -+ code = sprintf(buffer, "OTG state: %s:%d; %sactive\n", -+ otg_state_string(musb),musb->xceiv->state, - musb->is_active ? "" : "in"); - if (code <= 0) - goto done; -@@ -591,16 +592,34 @@ - * - * C soft-connect - * c soft-disconnect -- * I enable HS -- * i disable HS -- * s stop session -- * F force session (OTG-unfriendly) -+ * D set/query the debug level - * E rElinquish bus (OTG) -+ * e enumerate -+ * F force session (OTG-unfriendly) - * H request host mode - * h cancel host request -+ * I enable HS -+ * i disable HS -+ * J set HS test mode -+ * j clear HS test mode -+ * K set FS test mode -+ * k clear FS test mode -+ * M set host test mode -+ * m clear host test mode -+ * R reset peripheral -+ * r resume root hub -+ * s stop session - * T start sending TEST_PACKET -- * D set/query the debug level -+ * X term highspeed -+ * Y term fullspeed -+ * Z term lowspeed -+ * - */ -+ -+extern inline void mbusywait(int ms); -+extern void musb_port_reset(struct musb *musb, bool do_reset); -+extern void musb_port_suspend(struct musb *musb, bool do_suspend); -+ - static int musb_proc_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) - { -@@ -608,49 +627,63 @@ - u8 reg; - struct musb *musb = (struct musb *)data; - void __iomem *mbase = musb->mregs; -+ unsigned long flags; -+ struct usb_hcd *hcd = musb_to_hcd(musb); -+ struct usb_bus *bus = hcd_to_bus(hcd); - - /* MOD_INC_USE_COUNT; */ - - if (unlikely(copy_from_user(&cmd, buffer, 1))) - return -EFAULT; - -+ - switch (cmd) { - case 'C': - if (mbase) { -- reg = musb_readb(mbase, MUSB_POWER) -- | MUSB_POWER_SOFTCONN; -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg |= MUSB_POWER_SOFTCONN; - musb_writeb(mbase, MUSB_POWER, reg); - } - break; - - case 'c': - if (mbase) { -- reg = musb_readb(mbase, MUSB_POWER) -- & ~MUSB_POWER_SOFTCONN; -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg &= ~MUSB_POWER_SOFTCONN; - musb_writeb(mbase, MUSB_POWER, reg); - } - break; - - case 'I': - if (mbase) { -- reg = musb_readb(mbase, MUSB_POWER) -- | MUSB_POWER_HSENAB; -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg |= MUSB_POWER_HSENAB; - musb_writeb(mbase, MUSB_POWER, reg); - } - break; - - case 'i': - if (mbase) { -- reg = musb_readb(mbase, MUSB_POWER) -- & ~MUSB_POWER_HSENAB; -+ reg = musb_readb(mbase, MUSB_POWER); -+ reg &= ~MUSB_POWER_HSENAB; - musb_writeb(mbase, MUSB_POWER, reg); - } - break; - - case 'F': -- reg = musb_readb(mbase, MUSB_DEVCTL); -- reg |= MUSB_DEVCTL_SESSION; -- musb_writeb(mbase, MUSB_DEVCTL, reg); -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_DEVCTL); -+ reg |= MUSB_DEVCTL_SESSION; -+ musb_writeb(mbase, MUSB_DEVCTL, reg); -+ } -+ break; -+ -+ case 's': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_DEVCTL); -+ reg &= ~MUSB_DEVCTL_SESSION; -+ musb_writeb(mbase, MUSB_DEVCTL, reg); -+ } - break; - - case 'H': -@@ -679,6 +712,114 @@ - } - break; - -+ case 'M': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg |= MUSB_TEST_FORCE_HOST; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ } -+ break; -+ -+ case 'm': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg &= ~MUSB_TEST_FORCE_HOST; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ MUSB_DEV_MODE(musb); -+ musb->xceiv->state = OTG_STATE_B_IDLE; -+ } -+ break; -+ -+ case 'L': -+ musb->xceiv->state = OTG_STATE_A_HOST; -+ MUSB_HST_MODE(musb); -+ break; -+ -+ case 'l': -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; -+ MUSB_HST_MODE(musb); -+ break; -+ -+ case 'J': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg |= MUSB_TEST_FORCE_HS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ } -+ break; -+ -+ case 'j': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg &= ~MUSB_TEST_FORCE_HS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ } -+ break; -+ -+ case 'K': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg |= MUSB_TEST_FORCE_FS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ } -+ break; -+ -+ case 'k': -+ if (mbase) { -+ reg = musb_readb(mbase, MUSB_TESTMODE); -+ reg &= ~MUSB_TEST_FORCE_FS; -+ musb_writeb(mbase, MUSB_TESTMODE, reg); -+ } -+ break; -+ -+ case 'X': -+ if (mbase) -+ musb_force_term(mbase,MUSB_TERM_HOST_HIGHSPEED); -+ break; -+ -+ case 'Y': -+ if (mbase) -+ musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED); -+ break; -+ -+ case 'Z': -+ if (mbase) -+ musb_force_term(mbase,MUSB_TERM_HOST_LOWSPEED); -+ break; -+ -+ case 'R': -+ musb_port_reset(musb, true); -+ while (time_before(jiffies, musb->rh_timer)) -+ msleep(1); -+ musb_port_reset(musb, false); -+ -+ break; -+ -+ case 'r': -+ usb_hcd_resume_root_hub(hcd); -+ break; -+ -+ case 'e': -+ if(bus) -+ usb_bus_start_enum(bus,bus->otg_port); -+ break; -+ -+ case 'U': -+ /*Suspend*/ -+ musb_port_suspend(musb, true); -+ break; -+ -+ case 'u': -+ /*Resume*/ -+ musb_port_suspend(musb, false); -+ /*How to end sanely? */ -+ musb_port_reset(musb, true); -+ while (time_before(jiffies, musb->rh_timer)) -+ msleep(1); -+ musb_port_reset(musb, false); -+ -+ break; -+ - case '?': - INFO("?: you are seeing it\n"); - INFO("C/c: soft connect enable/disable\n"); -@@ -695,6 +836,7 @@ - - musb_platform_try_idle(musb, 0); - -+ - return count; - } - -@@ -709,6 +851,8 @@ - - count -= off; - count -= 1; /* for NUL at end */ -+ count -= 20; /* Padding */ -+ - if (count <= 0) - return -EINVAL; - -@@ -720,6 +864,9 @@ - count -= code; - } - -+ if (count < 0) -+ goto done; -+ - /* generate the report for the end points */ - /* REVISIT ... not unless something's connected! */ - for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints; -@@ -728,14 +875,22 @@ - if (code > 0) { - buffer += code; - count -= code; -+ if (count < 0) -+ goto done; - } - } - -+ -+ done: -+ - musb_platform_try_idle(musb, 0); - - spin_unlock_irqrestore(&musb->lock, flags); - *eof = 1; - -+ if(count < 0) -+ return -EINVAL; -+ - return buffer - page; - } - ---- kernel-power-2.6.28.orig/drivers/usb/musb/musb_virthub.c -+++ kernel-power-2.6.28/drivers/usb/musb/musb_virthub.c -@@ -46,7 +46,7 @@ - #include "musb_core.h" - - --static void musb_port_suspend(struct musb *musb, bool do_suspend) -+void musb_port_suspend(struct musb *musb, bool do_suspend) - { - u8 power; - void __iomem *mbase = musb->mregs; -@@ -106,11 +106,13 @@ - - /* later, GetPortStatus will stop RESUME signaling */ - musb->port1_status |= MUSB_PORT_STAT_RESUME; -- musb->rh_timer = jiffies + msecs_to_jiffies(20); -+ /*OMAP documentation states range of 10-15 ms */ -+ musb->rh_timer = jiffies + msecs_to_jiffies(13); -+ // musb->rh_timer = jiffies + msecs_to_jiffies(20); - } - } - --static void musb_port_reset(struct musb *musb, bool do_reset) -+void musb_port_reset(struct musb *musb, bool do_reset) - { - u8 power; - void __iomem *mbase = musb->mregs; -@@ -131,7 +133,7 @@ - */ - power = musb_readb(mbase, MUSB_POWER); - if (do_reset) { -- -+ DBG(4, "root port reset started\n"); - /* - * If RESUME is set, we must make sure it stays minimum 20 ms. - * Then we must clear RESUME and wait a bit to let musb start ---- kernel-power-2.6.28.orig/drivers/usb/musb/omap2430.c -+++ kernel-power-2.6.28/drivers/usb/musb/omap2430.c -@@ -77,11 +77,14 @@ - - switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_BCON: -+ if(host_mode(musb->mregs)) -+ break; /*Don't time out*/ -+ - devctl &= ~MUSB_DEVCTL_SESSION; - musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); -- if (devctl & MUSB_DEVCTL_BDEVICE) { -+ if (!host_mode(musb->mregs)) { - musb->xceiv->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); - } else { -@@ -109,11 +112,14 @@ - #endif - #ifdef CONFIG_USB_MUSB_HDRC_HCD - case OTG_STATE_A_HOST: -+ -+ - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); -- if (devctl & MUSB_DEVCTL_BDEVICE) -+ if (!host_mode(musb->mregs)) - musb->xceiv->state = OTG_STATE_B_IDLE; -- else -- musb->xceiv->state = OTG_STATE_A_WAIT_BCON; -+ /*Don't time out if host*/ -+ // else -+ // musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - #endif - default: - break; -@@ -133,7 +139,7 @@ - /* Never idle if active, or when VBUS timeout is not set as host */ - if (musb->is_active || ((musb->a_wait_bcon == 0) - && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { -- DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); -+ DBG(6, "%s active, deleting timer\n", otg_state_string(musb)); - del_timer(&musb_idle_timer); - last_timer = jiffies; - return; -@@ -143,13 +149,13 @@ - if (!timer_pending(&musb_idle_timer)) - last_timer = timeout; - else { -- DBG(4, "Longer idle timer already pending, ignoring\n"); -+ DBG(6, "Longer idle timer already pending, ignoring\n"); - return; - } - } - last_timer = timeout; - -- DBG(4, "%s inactive, for idle timer for %lu ms\n", -+ DBG(6, "%s inactive, for idle timer for %lu ms\n", - otg_state_string(musb), - (unsigned long)jiffies_to_msecs(timeout - jiffies)); - mod_timer(&musb_idle_timer, timeout); -@@ -182,8 +188,14 @@ - musb->xceiv->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; - devctl |= MUSB_DEVCTL_SESSION; -- - MUSB_HST_MODE(musb); -+ -+ if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { -+ /*Power is already applied. Skip VRISE and go directly to BCON.*/ -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; -+ } -+ -+ - } else { - musb->is_active = 0; - -@@ -420,7 +432,7 @@ - u8 r; - unsigned long flags; - -- DBG(3, "restoring register context\n"); -+ DBG(3, "restoring register context for %s\n","musb_restore_ctx_and_resume"); - - if (musb->board && musb->board->xceiv_power) - musb->board->xceiv_power(1); -@@ -431,13 +443,17 @@ - else - clk_enable(musb->clock); - -- /* Recover OTG control */ -- r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL); -- r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN; -- musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r); -- -+ if(host_mode(musb->mregs)) { -+ musb_force_term(musb->mregs,MUSB_TERM_HOST_FULLSPEED); -+ r = musb_ulpi_readb(musb->mregs,ISP1704_FUNC_CTRL); -+ } else { -+ /* Recover OTG control */ -+ r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL); -+ r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN; -+ musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r); -+ r = ISP1704_FUNC_CTRL_FULL_SPEED; -+ } - /* Recover FUNC control */ -- r = ISP1704_FUNC_CTRL_FULL_SPEED; - r |= ISP1704_FUNC_CTRL_SUSPENDM | ISP1704_FUNC_CTRL_RESET; - musb_ulpi_writeb(musb->mregs, ISP1704_FUNC_CTRL, r); - ---- kernel-power-2.6.28.orig/drivers/usb/otg/otg.c -+++ kernel-power-2.6.28/drivers/usb/otg/otg.c -@@ -160,7 +160,8 @@ - - /* add other match criteria here ... */ - -- -+ return 1; -+ - /* OTG MESSAGE: report errors here, customize to match your product */ - dev_err(&dev->dev, "device v%04x p%04x is not supported\n", - le16_to_cpu(dev->descriptor.idVendor), ---- kernel-power-2.6.28.orig/drivers/usb/otg/twl4030-usb.c -+++ kernel-power-2.6.28/drivers/usb/otg/twl4030-usb.c -@@ -239,9 +239,9 @@ - - enum linkstat { - USB_LINK_UNKNOWN = 0, -- USB_LINK_NONE, -- USB_LINK_VBUS, -- USB_LINK_ID, -+ USB_LINK_NONE = 1, -+ USB_LINK_VBUS = 2, -+ USB_LINK_ID = 3, - }; - - struct twl4030_usb { diff --git a/usbhost/drivers/usb/core/generic.c b/usbhost/drivers/usb/core/generic.c index 7e912f2..b51e5ea 100644 --- a/usbhost/drivers/usb/core/generic.c +++ b/usbhost/drivers/usb/core/generic.c @@ -97,10 +97,10 @@ int usb_choose_configuration(struct usb_device *udev) */ /* Rule out configs that draw too much bus current */ - if (c->desc.bMaxPower * 2 > udev->bus_mA) { + /*if (c->desc.bMaxPower * 2 > udev->bus_mA) { insufficient_power++; continue; - } + }*/ /* When the first config's first interface is one of Microsoft's * pet nonstandard Ethernet-over-USB protocols, ignore it unless @@ -132,10 +132,10 @@ int usb_choose_configuration(struct usb_device *udev) best = c; } - if (insufficient_power > 0) + /*if (insufficient_power > 0) dev_info(&udev->dev, "rejected %d configuration%s " "due to insufficient available bus power\n", - insufficient_power, plural(insufficient_power)); + insufficient_power, plural(insufficient_power));*/ if (best) { i = best->desc.bConfigurationValue; diff --git a/usbhost/drivers/usb/core/otg_whitelist.h b/usbhost/drivers/usb/core/otg_whitelist.h index d6b352e..31709bb 100644 --- a/usbhost/drivers/usb/core/otg_whitelist.h +++ b/usbhost/drivers/usb/core/otg_whitelist.h @@ -14,7 +14,7 @@ extern int is_targeted(struct usb_device *); #else static inline int is_targeted(struct usb_device *d) { - return 0; + return 1; } #endif diff --git a/usbhost/drivers/usb/gadget/ether.c b/usbhost/drivers/usb/gadget/ether.c index 37252d0..03797e1 100644 --- a/usbhost/drivers/usb/gadget/ether.c +++ b/usbhost/drivers/usb/gadget/ether.c @@ -241,7 +241,8 @@ static struct usb_configuration rndis_config_driver = { .bind = rndis_do_config, .bConfigurationValue = 2, /* .iConfiguration = DYNAMIC */ - .bmAttributes = USB_CONFIG_ATT_SELFPOWER, + .bmAttributes = USB_CONFIG_ATT_ONE, + .bMaxPower = 250, /* 500mA */ }; /*-------------------------------------------------------------------------*/ @@ -269,7 +270,8 @@ static struct usb_configuration eth_config_driver = { .bind = eth_do_config, .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ - .bmAttributes = USB_CONFIG_ATT_SELFPOWER, + .bmAttributes = USB_CONFIG_ATT_ONE, + .bMaxPower = 250, /* 500mA */ }; /*-------------------------------------------------------------------------*/ diff --git a/usbhost/drivers/usb/musb/isp1704.h b/usbhost/drivers/usb/musb/isp1704.h index c52406e..7a2220a 100644 --- a/usbhost/drivers/usb/musb/isp1704.h +++ b/usbhost/drivers/usb/musb/isp1704.h @@ -41,6 +41,7 @@ #define ISP1704_OTG_CTRL 0x0a #define ISP1704_USB_INTRISE 0x0d #define ISP1704_USB_INTFALL 0x10 +#define ISP1704_USB_INTSTAT 0x13 #define ISP1704_DEBUG 0x15 #define ISP1704_SCRATCH 0x16 #define ISP1704_PWR_CTRL 0x3d diff --git a/usbhost/drivers/usb/musb/musb_core.c b/usbhost/drivers/usb/musb/musb_core.c index 6adab83..27c7948 100644 --- a/usbhost/drivers/usb/musb/musb_core.c +++ b/usbhost/drivers/usb/musb/musb_core.c @@ -142,6 +142,59 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" MUSB_DRIVER_NAME); + + +inline void mbusywait(int ms) +{ + unsigned long end_time = jiffies + msecs_to_jiffies(ms); + while(time_before(jiffies,end_time)) + cpu_relax(); + +} + +void musb_force_term(void __iomem *addr, enum musb_term term) +{ + u8 r; + + + r = musb_ulpi_readb(addr, ISP1704_OTG_CTRL); + r |= ISP1704_OTG_CTRL_DP_PULLDOWN | ISP1704_OTG_CTRL_DM_PULLDOWN; + musb_ulpi_writeb(addr, ISP1704_OTG_CTRL, r); + + r = musb_ulpi_readb(addr, ISP1704_FUNC_CTRL); + + switch(term) { + + case MUSB_TERM_HOST_HIGHSPEED: + r &= ~ISP1704_FUNC_CTRL_XCVRSELECT; + r &= ~ISP1704_FUNC_CTRL_TERMSELECT; + r &= ~ISP1704_FUNC_CTRL_OPMODE; + break; + + case MUSB_TERM_HOST_FULLSPEED: + r |= 1 << ISP1704_FUNC_CTRL_XCVRSELECT_SHIFT; + r |= ISP1704_FUNC_CTRL_TERMSELECT; + r &= ~ISP1704_FUNC_CTRL_OPMODE; + break; + + case MUSB_TERM_HOST_LOWSPEED: + r |= 2 << ISP1704_FUNC_CTRL_XCVRSELECT_SHIFT; + r |= ISP1704_FUNC_CTRL_TERMSELECT; + r &= ~ISP1704_FUNC_CTRL_OPMODE; + break; + + default: + ERR("Unknown musb termination\n"); + return; + } + + r |= ISP1704_OTG_CTRL_IDPULLUP; + musb_ulpi_writeb(addr, ISP1704_FUNC_CTRL, r); + +} + + + static inline int musb_verify_charger(void __iomem *addr) { u8 r, ret = 0; @@ -220,6 +273,8 @@ static int musb_charger_detect(struct musb *musb) u8 vdat = 0; u8 r; + u8 testmode; + testmode = musb_readb(musb->mregs,MUSB_TESTMODE); msleep(5); @@ -297,7 +352,7 @@ static int musb_charger_detect(struct musb *musb) break; } - if (vdat) { + if (vdat && !(testmode & MUSB_TEST_FORCE_HOST)) { /* REVISIT: This code works only with dedicated chargers! * When support for HOST/HUB chargers is added, don't * forget this. @@ -349,7 +404,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) prefetch((u8 *)src); - DBG(4, "%cX ep%d fifo %p count %d buf %p\n", + DBG(6, "%cX ep%d fifo %p count %d buf %p\n", 'T', hw_ep->epnum, fifo, len, src); /* we can't assume unaligned reads work */ @@ -387,7 +442,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) { void __iomem *fifo = hw_ep->fifo; - DBG(4, "%cX ep%d fifo %p count %d buf %p\n", + DBG(6, "%cX ep%d fifo %p count %d buf %p\n", 'R', hw_ep->epnum, fifo, len, dst); /* we can't assume unaligned writes work */ @@ -490,7 +545,6 @@ void musb_otg_timer_func(unsigned long data) { struct musb *musb = (struct musb *)data; unsigned long flags; - spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { case OTG_STATE_B_WAIT_ACON: @@ -572,10 +626,19 @@ void musb_hnp_stop(struct musb *musb) static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl, u8 power) { + u8 testmode; irqreturn_t handled = IRQ_NONE; void __iomem *mbase = musb->mregs; u8 r; + testmode = musb_readb(mbase,MUSB_TESTMODE); + if(testmode & MUSB_TEST_FORCE_HOST) { + if(int_usb & MUSB_INTR_SESSREQ) { + DBG(1,"Piggybacking CONNECT on SESS REQ\n"); + musb->int_usb |= MUSB_INTR_CONNECT; + } + } + DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, int_usb); @@ -630,6 +693,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } else { switch (musb->xceiv->state) { #ifdef CONFIG_USB_MUSB_HDRC_HCD + case OTG_STATE_A_WAIT_BCON: + case OTG_STATE_A_HOST: case OTG_STATE_A_SUSPEND: /* possibly DISCONNECT is upcoming */ musb->xceiv->state = OTG_STATE_A_HOST; @@ -678,7 +743,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, * be discarded silently. */ if ((devctl & MUSB_DEVCTL_VBUS) - && !(devctl & MUSB_DEVCTL_BDEVICE)) { + && host_mode(musb->mregs)) { musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); musb->ep0_stage = MUSB_EP0_START; musb->xceiv->state = OTG_STATE_A_IDLE; @@ -796,9 +861,15 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, + msecs_to_jiffies(musb->a_wait_bcon)); break; case OTG_STATE_A_HOST: + if(testmode & MUSB_TEST_FORCE_HOST) { + // musb->int_usb |= MUSB_INTR_RESUME; + break; + } + musb->xceiv->state = OTG_STATE_A_SUSPEND; musb->is_active = is_otg_enabled(musb) && musb->xceiv->host->b_hnp_enable; + break; case OTG_STATE_B_HOST: /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ @@ -818,6 +889,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb->is_active = 1; set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + musb->ep0_stage = MUSB_EP0_START; #ifdef CONFIG_USB_MUSB_OTG @@ -836,9 +908,65 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb->port1_status |= USB_PORT_STAT_CONNECTION |(USB_PORT_STAT_C_CONNECTION << 16); - /* high vs full speed is just a guess until after reset */ - if (devctl & MUSB_DEVCTL_LSDEV) - musb->port1_status |= USB_PORT_STAT_LOW_SPEED; + if (testmode & MUSB_TEST_FORCE_HOST) { + u8 r,reg; + void __iomem *mbase = musb->mregs; + + musb_force_term(musb->mregs,MUSB_TERM_HOST_HIGHSPEED); + + r = musb_ulpi_readb(mbase, ISP1704_DEBUG); + DBG(1,"Linestate %x\n",r); + switch(r) { + case 2: + musb->port1_status |= USB_PORT_STAT_LOW_SPEED; + reg = musb_readb(mbase, MUSB_TESTMODE); + reg &= ~MUSB_TEST_FORCE_FS; + reg &= ~MUSB_TEST_FORCE_HS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + + reg = musb_readb(mbase, MUSB_POWER); + reg &= ~MUSB_POWER_HSENAB; + musb_writeb(mbase, MUSB_POWER, reg); + + musb_force_term(musb->mregs,MUSB_TERM_HOST_LOWSPEED); + break; + case 1: + /*High or full speed*/ + reg = musb_readb(mbase, MUSB_TESTMODE); + if(reg & MUSB_TEST_FORCE_HS) { + /*High speed*/ + reg &= ~MUSB_TEST_FORCE_FS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + + reg = musb_readb(mbase, MUSB_POWER); + reg |= MUSB_POWER_HSENAB; + musb_writeb(mbase, MUSB_POWER, reg); + } else { + /*Full speed*/ + reg |= MUSB_TEST_FORCE_FS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + + reg = musb_readb(mbase, MUSB_POWER); + reg &= ~MUSB_POWER_HSENAB; + musb_writeb(mbase, MUSB_POWER, reg); + } + + musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED); + + break; + case 0: + case 3: + /*invalid*/ + WARNING("Invalid line state of %d\n",r); + break; + + } + } else { + + /* high vs full speed is just a guess until after reset */ + if (devctl & MUSB_DEVCTL_LSDEV) + musb->port1_status |= USB_PORT_STAT_LOW_SPEED; + } if (hcd->status_urb) usb_hcd_poll_rh_status(hcd); @@ -974,6 +1102,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb->ignore_disconnect = 1; musb_g_reset(musb); /* FALLTHROUGH */ + case OTG_STATE_A_HOST: + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ DBG(1, "HNP: Setting timer as %s\n", otg_state_string(musb)); @@ -2421,8 +2551,7 @@ bad_config: DBG(1, "%s mode, status %d, devctl %02x %c\n", "HOST", status, musb_readb(musb->mregs, MUSB_DEVCTL), - (musb_readb(musb->mregs, MUSB_DEVCTL) - & MUSB_DEVCTL_BDEVICE + (!host_mode(musb->mregs) ? 'B' : 'A')); } else /* peripheral is enabled */ { diff --git a/usbhost/drivers/usb/musb/musb_core.h b/usbhost/drivers/usb/musb/musb_core.h index dd9de46..36a7dc4 100644 --- a/usbhost/drivers/usb/musb/musb_core.h +++ b/usbhost/drivers/usb/musb/musb_core.h @@ -85,6 +85,16 @@ struct musb_ep; #define is_host_active(musb) is_host_capable() #endif +static inline int host_mode(void __iomem *addr) +{ + u8 devctl,testmode; + devctl = musb_readb(addr, MUSB_DEVCTL); + testmode = musb_readb(addr,MUSB_TESTMODE); + + return (testmode & MUSB_TEST_FORCE_HOST) || !(devctl & MUSB_DEVCTL_BDEVICE); +} + + #if defined(CONFIG_USB_MUSB_OTG) || defined(CONFIG_USB_MUSB_PERIPHERAL) /* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't always * override that choice selection (often USB_GADGET_DUMMY_HCD). @@ -593,6 +603,14 @@ extern void musb_hnp_stop(struct musb *musb); extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); +enum musb_term { + MUSB_TERM_HOST_HIGHSPEED, + MUSB_TERM_HOST_FULLSPEED, + MUSB_TERM_HOST_LOWSPEED, +}; + +extern void musb_force_term(void __iomem *addr, enum musb_term term); + #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); diff --git a/usbhost/drivers/usb/musb/musb_gadget.c b/usbhost/drivers/usb/musb/musb_gadget.c index 70d6f91..01bd839 100644 --- a/usbhost/drivers/usb/musb/musb_gadget.c +++ b/usbhost/drivers/usb/musb/musb_gadget.c @@ -1957,7 +1957,7 @@ __acquires(musb->lock) u8 power; DBG(3, "<== %s addr=%x driver '%s'\n", - (devctl & MUSB_DEVCTL_BDEVICE) + !host_mode(musb->mregs) ? "B-Device" : "A-Device", musb_readb(mbase, MUSB_FADDR), musb->gadget_driver @@ -1994,7 +1994,7 @@ __acquires(musb->lock) /* Normal reset, as B-Device; * or else after HNP, as A-Device */ - if (devctl & MUSB_DEVCTL_BDEVICE) { + if (!host_mode(musb->mregs)) { musb->xceiv->state = OTG_STATE_B_PERIPHERAL; musb->g.is_a_peripheral = 0; } else if (is_otg_enabled(musb)) { diff --git a/usbhost/drivers/usb/musb/musb_host.c b/usbhost/drivers/usb/musb/musb_host.c index 7958251..eb21b7a 100644 --- a/usbhost/drivers/usb/musb/musb_host.c +++ b/usbhost/drivers/usb/musb/musb_host.c @@ -1863,8 +1863,10 @@ static int musb_urb_enqueue( unsigned interval; /* host role must be active */ - if (!is_host_active(musb) || !musb->is_active) + if (!is_host_active(musb) || !musb->is_active) { + printk(KERN_ERR "musb is_host_active %d is_active %d\n",is_host_active(musb),musb->is_active); return -ENODEV; + } spin_lock_irqsave(&musb->lock, flags); ret = usb_hcd_link_urb_to_ep(hcd, urb); @@ -2275,6 +2277,7 @@ static int musb_bus_resume(struct usb_hcd *hcd) return 0; } + const struct hc_driver musb_hc_driver = { .description = "musb-hcd", .product_desc = "MUSB HDRC host driver", @@ -2298,6 +2301,5 @@ const struct hc_driver musb_hc_driver = { .hub_control = musb_hub_control, .bus_suspend = musb_bus_suspend, .bus_resume = musb_bus_resume, - /* .start_port_reset = NULL, */ /* .hub_irq_enable = NULL, */ }; diff --git a/usbhost/drivers/usb/musb/musb_procfs.c b/usbhost/drivers/usb/musb/musb_procfs.c index 8915b62..6846f31 100644 --- a/usbhost/drivers/usb/musb/musb_procfs.c +++ b/usbhost/drivers/usb/musb/musb_procfs.c @@ -37,6 +37,7 @@ #include #include /* FIXME remove procfs writes */ #include +#include #include "musb_core.h" @@ -450,8 +451,8 @@ static int dump_header_stats(struct musb *musb, char *buffer) return 0; buffer += count; - code = sprintf(buffer, "OTG state: %s; %sactive\n", - otg_state_string(musb), + code = sprintf(buffer, "OTG state: %s:%d; %sactive\n", + otg_state_string(musb),musb->xceiv->state, musb->is_active ? "" : "in"); if (code <= 0) goto done; @@ -591,16 +592,34 @@ done: * * C soft-connect * c soft-disconnect - * I enable HS - * i disable HS - * s stop session - * F force session (OTG-unfriendly) + * D set/query the debug level * E rElinquish bus (OTG) + * e enumerate + * F force session (OTG-unfriendly) * H request host mode * h cancel host request + * I enable HS + * i disable HS + * J set HS test mode + * j clear HS test mode + * K set FS test mode + * k clear FS test mode + * M set host test mode + * m clear host test mode + * R reset peripheral + * r resume root hub + * s stop session * T start sending TEST_PACKET - * D set/query the debug level + * X term highspeed + * Y term fullspeed + * Z term lowspeed + * */ + +extern inline void mbusywait(int ms); +extern void musb_port_reset(struct musb *musb, bool do_reset); +extern void musb_port_suspend(struct musb *musb, bool do_suspend); + static int musb_proc_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { @@ -608,49 +627,63 @@ static int musb_proc_write(struct file *file, const char __user *buffer, u8 reg; struct musb *musb = (struct musb *)data; void __iomem *mbase = musb->mregs; + unsigned long flags; + struct usb_hcd *hcd = musb_to_hcd(musb); + struct usb_bus *bus = hcd_to_bus(hcd); /* MOD_INC_USE_COUNT; */ if (unlikely(copy_from_user(&cmd, buffer, 1))) return -EFAULT; + switch (cmd) { case 'C': if (mbase) { - reg = musb_readb(mbase, MUSB_POWER) - | MUSB_POWER_SOFTCONN; + reg = musb_readb(mbase, MUSB_POWER); + reg |= MUSB_POWER_SOFTCONN; musb_writeb(mbase, MUSB_POWER, reg); } break; case 'c': if (mbase) { - reg = musb_readb(mbase, MUSB_POWER) - & ~MUSB_POWER_SOFTCONN; + reg = musb_readb(mbase, MUSB_POWER); + reg &= ~MUSB_POWER_SOFTCONN; musb_writeb(mbase, MUSB_POWER, reg); } break; case 'I': if (mbase) { - reg = musb_readb(mbase, MUSB_POWER) - | MUSB_POWER_HSENAB; + reg = musb_readb(mbase, MUSB_POWER); + reg |= MUSB_POWER_HSENAB; musb_writeb(mbase, MUSB_POWER, reg); } break; case 'i': if (mbase) { - reg = musb_readb(mbase, MUSB_POWER) - & ~MUSB_POWER_HSENAB; + reg = musb_readb(mbase, MUSB_POWER); + reg &= ~MUSB_POWER_HSENAB; musb_writeb(mbase, MUSB_POWER, reg); } break; case 'F': - reg = musb_readb(mbase, MUSB_DEVCTL); - reg |= MUSB_DEVCTL_SESSION; - musb_writeb(mbase, MUSB_DEVCTL, reg); + if (mbase) { + reg = musb_readb(mbase, MUSB_DEVCTL); + reg |= MUSB_DEVCTL_SESSION; + musb_writeb(mbase, MUSB_DEVCTL, reg); + } + break; + + case 's': + if (mbase) { + reg = musb_readb(mbase, MUSB_DEVCTL); + reg &= ~MUSB_DEVCTL_SESSION; + musb_writeb(mbase, MUSB_DEVCTL, reg); + } break; case 'H': @@ -679,6 +712,114 @@ static int musb_proc_write(struct file *file, const char __user *buffer, } break; + case 'M': + if (mbase) { + reg = musb_readb(mbase, MUSB_TESTMODE); + reg |= MUSB_TEST_FORCE_HOST; + musb_writeb(mbase, MUSB_TESTMODE, reg); + } + break; + + case 'm': + if (mbase) { + reg = musb_readb(mbase, MUSB_TESTMODE); + reg &= ~MUSB_TEST_FORCE_HOST; + musb_writeb(mbase, MUSB_TESTMODE, reg); + MUSB_DEV_MODE(musb); + musb->xceiv->state = OTG_STATE_B_IDLE; + } + break; + + case 'L': + musb->xceiv->state = OTG_STATE_A_HOST; + MUSB_HST_MODE(musb); + break; + + case 'l': + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + MUSB_HST_MODE(musb); + break; + + case 'J': + if (mbase) { + reg = musb_readb(mbase, MUSB_TESTMODE); + reg |= MUSB_TEST_FORCE_HS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + } + break; + + case 'j': + if (mbase) { + reg = musb_readb(mbase, MUSB_TESTMODE); + reg &= ~MUSB_TEST_FORCE_HS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + } + break; + + case 'K': + if (mbase) { + reg = musb_readb(mbase, MUSB_TESTMODE); + reg |= MUSB_TEST_FORCE_FS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + } + break; + + case 'k': + if (mbase) { + reg = musb_readb(mbase, MUSB_TESTMODE); + reg &= ~MUSB_TEST_FORCE_FS; + musb_writeb(mbase, MUSB_TESTMODE, reg); + } + break; + + case 'X': + if (mbase) + musb_force_term(mbase,MUSB_TERM_HOST_HIGHSPEED); + break; + + case 'Y': + if (mbase) + musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED); + break; + + case 'Z': + if (mbase) + musb_force_term(mbase,MUSB_TERM_HOST_LOWSPEED); + break; + + case 'R': + musb_port_reset(musb, true); + while (time_before(jiffies, musb->rh_timer)) + msleep(1); + musb_port_reset(musb, false); + + break; + + case 'r': + usb_hcd_resume_root_hub(hcd); + break; + + case 'e': + if(bus) + usb_bus_start_enum(bus,bus->otg_port); + break; + + case 'U': + /*Suspend*/ + musb_port_suspend(musb, true); + break; + + case 'u': + /*Resume*/ + musb_port_suspend(musb, false); + /*How to end sanely? */ + musb_port_reset(musb, true); + while (time_before(jiffies, musb->rh_timer)) + msleep(1); + musb_port_reset(musb, false); + + break; + case '?': INFO("?: you are seeing it\n"); INFO("C/c: soft connect enable/disable\n"); @@ -695,6 +836,7 @@ static int musb_proc_write(struct file *file, const char __user *buffer, musb_platform_try_idle(musb, 0); + return count; } @@ -709,6 +851,8 @@ static int musb_proc_read(char *page, char **start, count -= off; count -= 1; /* for NUL at end */ + count -= 20; /* Padding */ + if (count <= 0) return -EINVAL; @@ -720,6 +864,9 @@ static int musb_proc_read(char *page, char **start, count -= code; } + if (count < 0) + goto done; + /* generate the report for the end points */ /* REVISIT ... not unless something's connected! */ for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints; @@ -728,14 +875,22 @@ static int musb_proc_read(char *page, char **start, if (code > 0) { buffer += code; count -= code; + if (count < 0) + goto done; } } + + done: + musb_platform_try_idle(musb, 0); spin_unlock_irqrestore(&musb->lock, flags); *eof = 1; + if(count < 0) + return -EINVAL; + return buffer - page; } diff --git a/usbhost/drivers/usb/musb/musb_virthub.c b/usbhost/drivers/usb/musb/musb_virthub.c index 7e7900f..770937f 100644 --- a/usbhost/drivers/usb/musb/musb_virthub.c +++ b/usbhost/drivers/usb/musb/musb_virthub.c @@ -46,7 +46,7 @@ #include "musb_core.h" -static void musb_port_suspend(struct musb *musb, bool do_suspend) +void musb_port_suspend(struct musb *musb, bool do_suspend) { u8 power; void __iomem *mbase = musb->mregs; @@ -106,11 +106,13 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) /* later, GetPortStatus will stop RESUME signaling */ musb->port1_status |= MUSB_PORT_STAT_RESUME; - musb->rh_timer = jiffies + msecs_to_jiffies(20); + /*OMAP documentation states range of 10-15 ms */ + musb->rh_timer = jiffies + msecs_to_jiffies(13); + // musb->rh_timer = jiffies + msecs_to_jiffies(20); } } -static void musb_port_reset(struct musb *musb, bool do_reset) +void musb_port_reset(struct musb *musb, bool do_reset) { u8 power; void __iomem *mbase = musb->mregs; @@ -131,7 +133,7 @@ static void musb_port_reset(struct musb *musb, bool do_reset) */ power = musb_readb(mbase, MUSB_POWER); if (do_reset) { - + DBG(4, "root port reset started\n"); /* * If RESUME is set, we must make sure it stays minimum 20 ms. * Then we must clear RESUME and wait a bit to let musb start diff --git a/usbhost/drivers/usb/musb/omap2430.c b/usbhost/drivers/usb/musb/omap2430.c index a712bc9..276ee85 100644 --- a/usbhost/drivers/usb/musb/omap2430.c +++ b/usbhost/drivers/usb/musb/omap2430.c @@ -77,11 +77,14 @@ static void musb_do_idle(unsigned long _musb) switch (musb->xceiv->state) { case OTG_STATE_A_WAIT_BCON: + if(host_mode(musb->mregs)) + break; /*Don't time out*/ + devctl &= ~MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) { + if (!host_mode(musb->mregs)) { musb->xceiv->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); } else { @@ -109,11 +112,14 @@ static void musb_do_idle(unsigned long _musb) #endif #ifdef CONFIG_USB_MUSB_HDRC_HCD case OTG_STATE_A_HOST: + + devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) + if (!host_mode(musb->mregs)) musb->xceiv->state = OTG_STATE_B_IDLE; - else - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + /*Don't time out if host*/ + // else + // musb->xceiv->state = OTG_STATE_A_WAIT_BCON; #endif default: break; @@ -133,7 +139,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || ((musb->a_wait_bcon == 0) && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); + DBG(6, "%s active, deleting timer\n", otg_state_string(musb)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -143,13 +149,13 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) if (!timer_pending(&musb_idle_timer)) last_timer = timeout; else { - DBG(4, "Longer idle timer already pending, ignoring\n"); + DBG(6, "Longer idle timer already pending, ignoring\n"); return; } } last_timer = timeout; - DBG(4, "%s inactive, for idle timer for %lu ms\n", + DBG(6, "%s inactive, for idle timer for %lu ms\n", otg_state_string(musb), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); @@ -182,8 +188,14 @@ static void omap_set_vbus(struct musb *musb, int is_on) musb->xceiv->default_a = 1; musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; devctl |= MUSB_DEVCTL_SESSION; - MUSB_HST_MODE(musb); + + if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { + /*Power is already applied. Skip VRISE and go directly to BCON.*/ + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + } + + } else { musb->is_active = 0; @@ -420,7 +432,7 @@ void musb_restore_ctx_and_resume(struct usb_gadget *gadget) u8 r; unsigned long flags; - DBG(3, "restoring register context\n"); + DBG(3, "restoring register context for %s\n","musb_restore_ctx_and_resume"); if (musb->board && musb->board->xceiv_power) musb->board->xceiv_power(1); @@ -431,13 +443,17 @@ void musb_restore_ctx_and_resume(struct usb_gadget *gadget) else clk_enable(musb->clock); - /* Recover OTG control */ - r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL); - r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN; - musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r); - + if(host_mode(musb->mregs)) { + musb_force_term(musb->mregs,MUSB_TERM_HOST_FULLSPEED); + r = musb_ulpi_readb(musb->mregs,ISP1704_FUNC_CTRL); + } else { + /* Recover OTG control */ + r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL); + r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN; + musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r); + r = ISP1704_FUNC_CTRL_FULL_SPEED; + } /* Recover FUNC control */ - r = ISP1704_FUNC_CTRL_FULL_SPEED; r |= ISP1704_FUNC_CTRL_SUSPENDM | ISP1704_FUNC_CTRL_RESET; musb_ulpi_writeb(musb->mregs, ISP1704_FUNC_CTRL, r); diff --git a/usbhost/drivers/usb/otg/otg.c b/usbhost/drivers/usb/otg/otg.c index f928b0b..cc890ab 100644 --- a/usbhost/drivers/usb/otg/otg.c +++ b/usbhost/drivers/usb/otg/otg.c @@ -160,7 +160,8 @@ int is_targeted(struct usb_device *dev) /* add other match criteria here ... */ - + return 1; + /* OTG MESSAGE: report errors here, customize to match your product */ dev_err(&dev->dev, "device v%04x p%04x is not supported\n", le16_to_cpu(dev->descriptor.idVendor), diff --git a/usbhost/drivers/usb/otg/twl4030-usb.c b/usbhost/drivers/usb/otg/twl4030-usb.c index ecffb2a..7c1672f 100644 --- a/usbhost/drivers/usb/otg/twl4030-usb.c +++ b/usbhost/drivers/usb/otg/twl4030-usb.c @@ -239,9 +239,9 @@ enum linkstat { USB_LINK_UNKNOWN = 0, - USB_LINK_NONE, - USB_LINK_VBUS, - USB_LINK_ID, + USB_LINK_NONE = 1, + USB_LINK_VBUS = 2, + USB_LINK_ID = 3, }; struct twl4030_usb { diff --git a/usbhost/refresh b/usbhost/refresh index feafe0a..0cb46f6 100755 --- a/usbhost/refresh +++ b/usbhost/refresh @@ -1,9 +1,11 @@ #!/bin/sh here=`pwd` -kdir="$here/../kernel-power-2.6.28" cd ../kernel-power-2.6.28 +echo top: +export QUILT_PATCHES=debian/patches quilt top +quilt push -a -q quilt delete -r usbhost.diff quilt new usbhost.diff git diff -r hostorig "$here/drivers/usb/" | quilt fold -p2