Commit 0d79ef71 authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

MUSB: Miscellaneous updates

Lots of miscellaneous updates:

  - bugfixes
     * flag hcd-framework "got irq" state earlier
     * reject urb submission if port is suspended
     * linkage fix: unbind became optional
     * initialize vbus error retry count earlier
     * tusb init removes diagnostic-only settings
  - procfs updates
     * always show otg state info in procfs
     * show some TUSB-specific registers in procfs
  - cleanups
     * remove pointless MUSB_ERR stuff (handled better now)
     * tusb init removes dead code
     * more informative vbus error debug message
     * comment fixes
     * etc
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent f71d321d
......@@ -1708,7 +1708,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver
|| driver->speed != USB_SPEED_HIGH
|| !driver->bind
|| !driver->unbind
|| !driver->setup)
return -EINVAL;
......@@ -1847,7 +1846,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
int retval = 0;
struct musb *musb = the_gadget;
if (!driver || !musb)
if (!driver || !driver->unbind || !musb)
return -EINVAL;
/* REVISIT always use otg_set_peripheral() here too;
......
......@@ -1176,7 +1176,6 @@ irqreturn_t musb_h_ep0_irq(struct musb *pThis)
if (bComplete)
musb_advance_schedule(pThis, pUrb, pEnd, 1);
done:
set_bit(HCD_FLAG_SAW_IRQ, &musb_to_hcd(pThis)->flags);
return retval;
}
......@@ -1812,7 +1811,7 @@ static int musb_urb_enqueue(
unsigned interval;
/* host role must be active */
if (!is_host_active(musb))
if (!is_host_active(musb) || !musb->is_active)
return -ENODEV;
/* DMA mapping was already done, if needed, and this urb is on
......@@ -2154,6 +2153,9 @@ static int musb_h_get_frame_number(struct usb_hcd *hcd)
static int musb_h_start(struct usb_hcd *hcd)
{
/* NOTE: musb_start() is called when the hub driver turns
* on port power, or when (OTG) peripheral starts.
*/
hcd->state = HC_STATE_RUNNING;
return 0;
}
......
......@@ -48,8 +48,6 @@
#include "davinci.h"
#ifdef CONFIG_USB_MUSB_OTG
static const char *state_string(enum usb_otg_state state)
{
switch (state) {
......@@ -70,8 +68,6 @@ static const char *state_string(enum usb_otg_state state)
}
}
#endif
#ifdef CONFIG_USB_MUSB_HDRC_HCD
static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
......@@ -489,15 +485,12 @@ static int dump_header_stats(struct musb *pThis, char *buffer)
return count;
buffer += count;
#ifdef CONFIG_USB_MUSB_OTG
code = sprintf(buffer, "OTG state: %s (%s)\n",
state_string(pThis->OtgMachine.bState),
state_string(pThis->xceiv.state));
code = sprintf(buffer, "OTG state: %s\n",
state_string(pThis->xceiv.state));
if (code < 0)
return code;
buffer += code;
count += code;
#endif
code = sprintf(buffer,
"Options: "
......@@ -548,6 +541,26 @@ static int dump_header_stats(struct musb *pThis, char *buffer)
buffer += code;
#endif /* DAVINCI */
#ifdef CONFIG_USB_TUSB6010
code = sprintf(buffer,
"TUSB6010: devconf %08x, phy enable %08x drive %08x"
"\n\totg %08x timer %08x"
"\n\tprcm conf %08x mgmt %08x; intmask %08x"
"\n",
musb_readl(pThis->ctrl_base, TUSB_DEV_CONF),
musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL),
musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_STAT),
musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_TIMER),
musb_readl(pThis->ctrl_base, TUSB_PRCM_CONF),
musb_readl(pThis->ctrl_base, TUSB_PRCM_MNGMT),
musb_readl(pThis->ctrl_base, TUSB_INT_MASK));
if (code < 0)
return count;
count += code;
buffer += code;
#endif /* DAVINCI */
#ifdef CONFIG_USB_TI_CPPI_DMA
if (pThis->pDmaController) {
code = sprintf(buffer,
......
......@@ -101,6 +101,7 @@ struct musb_ep;
#define is_host_active(musb) is_host_capable()
#endif
#ifdef CONFIG_PROC_FS
#include <linux/fs.h>
#define MUSB_CONFIG_PROC_FS
......@@ -197,15 +198,10 @@ enum musb_g_ep0_state {
MGC_END0_STAGE_ACKWAIT, /* after zlp, before statusin */
} __attribute__ ((packed));
/* failure codes */
#define MUSB_ERR_WAITING 1
#define MUSB_ERR_VBUS -1
#define MUSB_ERR_BABBLE -2
#define MUSB_ERR_CORRUPTED -3
#define MUSB_ERR_IRQ -4
#define MUSB_ERR_SHUTDOWN -5
#define MUSB_ERR_RESTART -6
/* OTG protocol constants */
#define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */
#define OTG_TIME_A_WAIT_BCON 0 /* 0=infinite; min 1000 msec */
#define OTG_TIME_A_IDLE_BDIS 200 /* msec (min) */
/*************************** REGISTER ACCESS ********************************/
......@@ -265,25 +261,15 @@ enum musb_g_ep0_state {
/****************************** FUNCTIONS ********************************/
#define MUSB_HST_MODE(_pthis)\
{ (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
(_pthis)->bFailCode=0; }
{ (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; }
#define MUSB_DEV_MODE(_pthis) \
{ (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
(_pthis)->bFailCode=0; }
{ (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; }
#define MUSB_OTG_MODE(_pthis) \
{ (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
(_pthis)->bFailCode=MUSB_ERR_WAITING; }
#define MUSB_ERR_MODE(_pthis, _cause) \
{ (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
(_pthis)->bFailCode=_cause; }
#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
#define MUSB_IS_HST(_x) (!MUSB_IS_ERR(_x) \
&& (_x)->bIsHost && !(_x)->bIsDevice )
#define MUSB_IS_DEV(_x) (!MUSB_IS_ERR(_x) \
&& !(_x)->bIsHost && (_x)->bIsDevice )
#define MUSB_IS_OTG(_x) (!MUSB_IS_ERR(_x) \
&& !(_x)->bIsHost && !(_x)->bIsDevice )
{ (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; }
#define MUSB_IS_HST(_x) ((_x)->bIsHost && !(_x)->bIsDevice)
#define MUSB_IS_DEV(_x) (!(_x)->bIsHost && (_x)->bIsDevice)
#define MUSB_IS_OTG(_x) (!(_x)->bIsHost && !(_x)->bIsDevice)
#define test_devctl_hst_mode(_x) \
(musb_readb((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM)
......@@ -447,8 +433,6 @@ struct musb {
u8 board_mode; /* enum musb_mode */
int (*board_set_power)(int state);
s8 bFailCode; /* one of MUSB_ERR_* failure code */
u8 min_power; /* vbus for periph, in mA/2 */
/* active means connected and not suspended */
......
......@@ -42,6 +42,9 @@
*
* - needs updating along the lines of <linux/usb_otg.h>
*
* - TUSB has a hardware OTG timer, unclear how much of this would
* ever be needed for it ...
*
* - doesn't yet use all the linux 2.6.10 usbcore hooks for OTG, but
* some of the conversion (and consequent shrinkage) has begun.
*
......
......@@ -89,14 +89,6 @@
* (And if it were to understand, there would still be limitations
* because of the lack of periodic endpoint scheduling.)
*
* - Host-side doesn't use the HCD framework, even the older version in
* the 2.6.10 kernel, which doesn't provide per-endpoint URB queues.
*
* +++ PARTIALLY RESOLVED +++
*
* RESULT: code bloat, because it provides its own root hub;
* correctness issues.
*
* - Provides its own OTG bits. These are untested, and many of them
* seem to be superfluous code bloat given what usbcore does. (They
* have now been partially removed.)
......@@ -444,9 +436,23 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if (bIntrUSB & MGC_M_INTR_VBUSERROR) {
// MGC_OtgMachineInputsChanged(otgm, &Inputs);
// otg_input_changed_X(pThis, TRUE, TRUE);
// ... may need to abort otg timer ...
DBG(1, "VBUS_ERROR (%02x)\n", devctl);
DBG(1, "VBUS_ERROR (%02x, %s), retry #%d\n", devctl,
({ char *s;
switch (devctl & MGC_M_DEVCTL_VBUS) {
case 0 << MGC_S_DEVCTL_VBUS:
s = "<SessEnd"; break;
case 1 << MGC_S_DEVCTL_VBUS:
s = "<AValid"; break;
case 2 << MGC_S_DEVCTL_VBUS:
s = "<VBusValid"; break;
//case 3 << MGC_S_DEVCTL_VBUS:
default:
s = "VALID"; break;
}; s; }),
pThis->vbuserr_retry);
/* after hw goes to A_IDLE, try connecting again */
pThis->xceiv.state = OTG_STATE_A_IDLE;
......@@ -460,6 +466,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if (bIntrUSB & MGC_M_INTR_CONNECT) {
handled = IRQ_HANDLED;
pThis->is_active = 1;
set_bit(HCD_FLAG_SAW_IRQ, &musb_to_hcd(pThis)->flags);
pThis->bEnd0Stage = MGC_END0_START;
......@@ -514,9 +521,12 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
/* REVISIT it's unclear how to handle this. Mentor's
* code stopped the whole USB host, which is clearly
* very wrong. For now, just expect the hardware is
* sane, so babbling devices also trigger a normal
* endpoint i/o fault (with automatic recovery).
* very wrong. Docs say (15.1) that babble ends the
* current sesssion, so shutdown _with restart_ would
* be appropriate ... except that seems to be wrong,
* at least some lowspeed enumerations trigger the
* babbles without aborting the session!
*
* (A "babble" IRQ seems quite pointless...)
*/
......@@ -658,10 +668,10 @@ void musb_start(struct musb * pThis)
musb_writew(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
musb_writeb(pBase, MGC_O_HDRC_INTRUSBE, 0xf7);
musb_platform_enable(pThis);
musb_writeb(pBase, MGC_O_HDRC_TESTMODE, 0);
musb_platform_enable(pThis);
/* enable high-speed/low-power and start session */
musb_writeb(pBase, MGC_O_HDRC_POWER,
MGC_M_POWER_SOFTCONN | MGC_M_POWER_HSENAB);
......@@ -744,8 +754,9 @@ static void musb_shutdown(struct platform_device *pdev)
spin_lock_irqsave(&musb->Lock, flags);
musb_platform_disable(musb);
musb_generic_disable(musb);
MUSB_ERR_MODE(musb, MUSB_ERR_SHUTDOWN);
spin_unlock_irqrestore(&musb->Lock, flags);
/* FIXME power down */
}
......@@ -1312,13 +1323,6 @@ irqreturn_t musb_interrupt(struct musb *musb)
(devctl & MGC_M_DEVCTL_HM) ? "host" : "peripheral",
musb->int_usb, musb->int_tx, musb->int_rx);
/* ignore requests when in error */
if (MUSB_IS_ERR(musb)) {
WARN("irq in error\n");
musb_platform_disable(musb);
return IRQ_NONE;
}
/* the core can interrupt us for multiple reasons; docs have
* a generic interrupt flowchart to follow
*/
......@@ -1534,6 +1538,7 @@ allocate_instance(struct device *dev, void __iomem *mbase)
hcd->uses_new_polling = 1;
musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
#else
musb = kzalloc(sizeof *musb, GFP_KERNEL);
if (!musb)
......
......@@ -463,7 +463,6 @@ static int dma_off;
* Enables TUSB6010. Caller must take care of locking.
* REVISIT:
* - Check what is unnecessary in MGC_HdrcStart()
* - Interrupt should really be IRQT_FALLING level sensitive
*/
void musb_platform_enable(struct musb * musb)
{
......@@ -612,25 +611,9 @@ static int tusb_start(struct musb *musb)
musb_writel(base, TUSB_PRCM_MNGMT,
TUSB_PRCM_MNGMT_VBUS_VALID_TIMER(0xa) |
TUSB_PRCM_MNGMT_VBUS_VALID_FLT_EN |
TUSB_PRCM_MNGMT_DFT_CLK_DIS |
TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS |
TUSB_PRCM_MNGMT_OTG_SESS_END_EN |
TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN |
TUSB_PRCM_MNGMT_OTG_ID_PULLUP);
#if 0
musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE,
musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE) |
TUSB_PHY_OTG_CTRL_WRPROTECT |
TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP |
TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN |
TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN);
musb_writel(base, TUSB_PHY_OTG_CTRL,
musb_readl(base, TUSB_PHY_OTG_CTRL) |
TUSB_PHY_OTG_CTRL_WRPROTECT |
TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP |
TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN |
TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN);
#endif
tusb_setup_cpu_interface(musb);
spin_unlock_irqrestore(&musb->Lock, flags);
......
......@@ -80,6 +80,8 @@
#define TUSB_DEV_OTG_STAT_DM_ENABLE (1 << 0)
#define TUSB_DEV_OTG_TIMER (TUSB_SYS_REG_BASE + 0x010)
# define TUSB_DEV_OTG_TIMER_ENABLE (1 << 31)
# define TUSB_DEV_OTG_TIMER_VAL(v) ((v) & 0x07ffffff)
#define TUSB_PRCM_REV (TUSB_SYS_REG_BASE + 0x014)
/* PRCM configuration register */
......@@ -198,8 +200,6 @@
#define TUSB_PROD_TEST_RESET (TUSB_SYS_REG_BASE + 0x1d8)
/* Device System & Control register bitfields */
#define TUSB_DEV_OTG_TIMER_ENABLE (1 << 31)
#define TUSB_DEV_OTG_TIMER_VAL(v) ((v) & 0x07ffffff)
#define TUSB_INT_CTRL_CONF_INT_RELCYC(v) (((v) & 0x7) << 18)
#define TUSB_INT_CTRL_CONF_INT_POLARITY (1 << 17)
#define TUSB_INT_CTRL_CONF_INT_MODE (1 << 16)
......
......@@ -277,7 +277,6 @@ int musb_hub_control(
* logic relating to VBUS power-up.
*/
musb_start(musb);
musb->port1_status |= USB_PORT_STAT_POWER;
break;
case USB_PORT_FEAT_RESET:
musb_port_reset(musb, TRUE);
......@@ -316,12 +315,12 @@ int musb_hub_control(
goto error;
}
musb_writeb(musb->pRegs, MGC_O_HDRC_TESTMODE, temp);
musb->port1_status |= USB_PORT_STAT_TEST;
break;
default:
goto error;
}
DBG(5, "set feature %d\n", wValue);
musb->port1_status |= 1 << wValue;
break;
default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment