musb_dsps.c (768330756d9bbfee6eca573b96c828adb1ba9058) | musb_dsps.c (e47d92545c2972bcf3711e7db80f481e402163c7) |
---|---|
1/* 2 * Texas Instruments DSPS platforms "glue layer" 3 * 4 * Copyright (C) 2012, by Texas Instruments 5 * 6 * Based on the am35x "glue layer" code. 7 * 8 * This file is part of the Inventra Controller Driver for Linux. --- 165 unchanged lines hidden (view full) --- 174 struct device *dev = musb->controller; 175 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 176 177 if (timeout == 0) 178 timeout = jiffies + msecs_to_jiffies(3); 179 180 /* Never idle if active, or when VBUS timeout is not set as host */ 181 if (musb->is_active || (musb->a_wait_bcon == 0 && | 1/* 2 * Texas Instruments DSPS platforms "glue layer" 3 * 4 * Copyright (C) 2012, by Texas Instruments 5 * 6 * Based on the am35x "glue layer" code. 7 * 8 * This file is part of the Inventra Controller Driver for Linux. --- 165 unchanged lines hidden (view full) --- 174 struct device *dev = musb->controller; 175 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 176 177 if (timeout == 0) 178 timeout = jiffies + msecs_to_jiffies(3); 179 180 /* Never idle if active, or when VBUS timeout is not set as host */ 181 if (musb->is_active || (musb->a_wait_bcon == 0 && |
182 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { | 182 musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) { |
183 dev_dbg(musb->controller, "%s active, deleting timer\n", | 183 dev_dbg(musb->controller, "%s active, deleting timer\n", |
184 usb_otg_state_string(musb->xceiv->state)); | 184 usb_otg_state_string(musb->xceiv->otg->state)); |
185 del_timer(&glue->timer); 186 glue->last_timer = jiffies; 187 return; 188 } 189 if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE) 190 return; 191 192 if (!musb->g.dev.driver) 193 return; 194 195 if (time_after(glue->last_timer, timeout) && 196 timer_pending(&glue->timer)) { 197 dev_dbg(musb->controller, 198 "Longer idle timer already pending, ignoring...\n"); 199 return; 200 } 201 glue->last_timer = timeout; 202 203 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", | 185 del_timer(&glue->timer); 186 glue->last_timer = jiffies; 187 return; 188 } 189 if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE) 190 return; 191 192 if (!musb->g.dev.driver) 193 return; 194 195 if (time_after(glue->last_timer, timeout) && 196 timer_pending(&glue->timer)) { 197 dev_dbg(musb->controller, 198 "Longer idle timer already pending, ignoring...\n"); 199 return; 200 } 201 glue->last_timer = timeout; 202 203 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", |
204 usb_otg_state_string(musb->xceiv->state), | 204 usb_otg_state_string(musb->xceiv->otg->state), |
205 jiffies_to_msecs(timeout - jiffies)); 206 mod_timer(&glue->timer, timeout); 207} 208 209/** 210 * dsps_musb_enable - enable interrupts 211 */ 212static void dsps_musb_enable(struct musb *musb) --- 47 unchanged lines hidden (view full) --- 260 int skip_session = 0; 261 262 /* 263 * We poll because DSPS IP's won't expose several OTG-critical 264 * status change events (from the transceiver) otherwise. 265 */ 266 devctl = dsps_readb(mregs, MUSB_DEVCTL); 267 dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, | 205 jiffies_to_msecs(timeout - jiffies)); 206 mod_timer(&glue->timer, timeout); 207} 208 209/** 210 * dsps_musb_enable - enable interrupts 211 */ 212static void dsps_musb_enable(struct musb *musb) --- 47 unchanged lines hidden (view full) --- 260 int skip_session = 0; 261 262 /* 263 * We poll because DSPS IP's won't expose several OTG-critical 264 * status change events (from the transceiver) otherwise. 265 */ 266 devctl = dsps_readb(mregs, MUSB_DEVCTL); 267 dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, |
268 usb_otg_state_string(musb->xceiv->state)); | 268 usb_otg_state_string(musb->xceiv->otg->state)); |
269 270 spin_lock_irqsave(&musb->lock, flags); | 269 270 spin_lock_irqsave(&musb->lock, flags); |
271 switch (musb->xceiv->state) { | 271 switch (musb->xceiv->otg->state) { |
272 case OTG_STATE_A_WAIT_BCON: 273 dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); 274 skip_session = 1; 275 /* fall */ 276 277 case OTG_STATE_A_IDLE: 278 case OTG_STATE_B_IDLE: 279 if (devctl & MUSB_DEVCTL_BDEVICE) { | 272 case OTG_STATE_A_WAIT_BCON: 273 dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); 274 skip_session = 1; 275 /* fall */ 276 277 case OTG_STATE_A_IDLE: 278 case OTG_STATE_B_IDLE: 279 if (devctl & MUSB_DEVCTL_BDEVICE) { |
280 musb->xceiv->state = OTG_STATE_B_IDLE; | 280 musb->xceiv->otg->state = OTG_STATE_B_IDLE; |
281 MUSB_DEV_MODE(musb); 282 } else { | 281 MUSB_DEV_MODE(musb); 282 } else { |
283 musb->xceiv->state = OTG_STATE_A_IDLE; | 283 musb->xceiv->otg->state = OTG_STATE_A_IDLE; |
284 MUSB_HST_MODE(musb); 285 } 286 if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) 287 dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); 288 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 289 break; 290 case OTG_STATE_A_WAIT_VFALL: | 284 MUSB_HST_MODE(musb); 285 } 286 if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) 287 dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); 288 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 289 break; 290 case OTG_STATE_A_WAIT_VFALL: |
291 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 291 musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
292 dsps_writel(musb->ctrl_base, wrp->coreintr_set, 293 MUSB_INTR_VBUSERROR << wrp->usb_shift); 294 break; 295 default: 296 break; 297 } 298 spin_unlock_irqrestore(&musb->lock, flags); 299} --- 68 unchanged lines hidden (view full) --- 368 * to get VBUS errors during enumeration. 369 * 370 * This is a workaround, but newer RTL from Mentor 371 * seems to allow a better one: "re"-starting sessions 372 * without waiting for VBUS to stop registering in 373 * devctl. 374 */ 375 musb->int_usb &= ~MUSB_INTR_VBUSERROR; | 292 dsps_writel(musb->ctrl_base, wrp->coreintr_set, 293 MUSB_INTR_VBUSERROR << wrp->usb_shift); 294 break; 295 default: 296 break; 297 } 298 spin_unlock_irqrestore(&musb->lock, flags); 299} --- 68 unchanged lines hidden (view full) --- 368 * to get VBUS errors during enumeration. 369 * 370 * This is a workaround, but newer RTL from Mentor 371 * seems to allow a better one: "re"-starting sessions 372 * without waiting for VBUS to stop registering in 373 * devctl. 374 */ 375 musb->int_usb &= ~MUSB_INTR_VBUSERROR; |
376 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | 376 musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; |
377 mod_timer(&glue->timer, 378 jiffies + wrp->poll_seconds * HZ); 379 WARNING("VBUS error workaround (delay coming)\n"); 380 } else if (drvvbus) { 381 MUSB_HST_MODE(musb); 382 musb->xceiv->otg->default_a = 1; | 377 mod_timer(&glue->timer, 378 jiffies + wrp->poll_seconds * HZ); 379 WARNING("VBUS error workaround (delay coming)\n"); 380 } else if (drvvbus) { 381 MUSB_HST_MODE(musb); 382 musb->xceiv->otg->default_a = 1; |
383 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 383 musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
384 del_timer(&glue->timer); 385 } else { 386 musb->is_active = 0; 387 MUSB_DEV_MODE(musb); 388 musb->xceiv->otg->default_a = 0; | 384 del_timer(&glue->timer); 385 } else { 386 musb->is_active = 0; 387 MUSB_DEV_MODE(musb); 388 musb->xceiv->otg->default_a = 0; |
389 musb->xceiv->state = OTG_STATE_B_IDLE; | 389 musb->xceiv->otg->state = OTG_STATE_B_IDLE; |
390 } 391 392 /* NOTE: this must complete power-on within 100 ms. */ 393 dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", 394 drvvbus ? "on" : "off", | 390 } 391 392 /* NOTE: this must complete power-on within 100 ms. */ 393 dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", 394 drvvbus ? "on" : "off", |
395 usb_otg_state_string(musb->xceiv->state), | 395 usb_otg_state_string(musb->xceiv->otg->state), |
396 err ? " ERROR" : "", 397 devctl); 398 ret = IRQ_HANDLED; 399 } 400 401 if (musb->int_tx || musb->int_rx || musb->int_usb) 402 ret |= musb_interrupt(musb); 403 404 /* Poll for ID change in OTG port mode */ | 396 err ? " ERROR" : "", 397 devctl); 398 ret = IRQ_HANDLED; 399 } 400 401 if (musb->int_tx || musb->int_rx || musb->int_usb) 402 ret |= musb_interrupt(musb); 403 404 /* Poll for ID change in OTG port mode */ |
405 if (musb->xceiv->state == OTG_STATE_B_IDLE && | 405 if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && |
406 musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) 407 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 408out: 409 spin_unlock_irqrestore(&musb->lock, flags); 410 411 return ret; 412} 413 --- 481 unchanged lines hidden (view full) --- 895 mbase = musb->ctrl_base; 896 dsps_writel(mbase, wrp->control, glue->context.control); 897 dsps_writel(mbase, wrp->epintr_set, glue->context.epintr); 898 dsps_writel(mbase, wrp->coreintr_set, glue->context.coreintr); 899 dsps_writel(mbase, wrp->phy_utmi, glue->context.phy_utmi); 900 dsps_writel(mbase, wrp->mode, glue->context.mode); 901 dsps_writel(mbase, wrp->tx_mode, glue->context.tx_mode); 902 dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); | 406 musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) 407 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 408out: 409 spin_unlock_irqrestore(&musb->lock, flags); 410 411 return ret; 412} 413 --- 481 unchanged lines hidden (view full) --- 895 mbase = musb->ctrl_base; 896 dsps_writel(mbase, wrp->control, glue->context.control); 897 dsps_writel(mbase, wrp->epintr_set, glue->context.epintr); 898 dsps_writel(mbase, wrp->coreintr_set, glue->context.coreintr); 899 dsps_writel(mbase, wrp->phy_utmi, glue->context.phy_utmi); 900 dsps_writel(mbase, wrp->mode, glue->context.mode); 901 dsps_writel(mbase, wrp->tx_mode, glue->context.tx_mode); 902 dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); |
903 if (musb->xceiv->state == OTG_STATE_B_IDLE && | 903 if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && |
904 musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) 905 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 906 907 return 0; 908} 909#endif 910 911static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); --- 17 unchanged lines hidden --- | 904 musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) 905 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 906 907 return 0; 908} 909#endif 910 911static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); --- 17 unchanged lines hidden --- |