diff options
Diffstat (limited to 'drivers/usb/musb/blackfin.c')
-rw-r--r-- | drivers/usb/musb/blackfin.c | 80 |
1 files changed, 54 insertions, 26 deletions
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 611a9d274363..fcb5206a65bd 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -171,8 +171,9 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci) | |||
171 | } | 171 | } |
172 | 172 | ||
173 | /* Start sampling ID pin, when plug is removed from MUSB */ | 173 | /* Start sampling ID pin, when plug is removed from MUSB */ |
174 | if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE | 174 | if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE |
175 | || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { | 175 | || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) || |
176 | (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) { | ||
176 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 177 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
177 | musb->a_wait_bcon = TIMER_DELAY; | 178 | musb->a_wait_bcon = TIMER_DELAY; |
178 | } | 179 | } |
@@ -323,30 +324,8 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
323 | return -EIO; | 324 | return -EIO; |
324 | } | 325 | } |
325 | 326 | ||
326 | int __init musb_platform_init(struct musb *musb, void *board_data) | 327 | static void musb_platform_reg_init(struct musb *musb) |
327 | { | 328 | { |
328 | |||
329 | /* | ||
330 | * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE | ||
331 | * and OTG HOST modes, while rev 1.1 and greater require PE7 to | ||
332 | * be low for DEVICE mode and high for HOST mode. We set it high | ||
333 | * here because we are in host mode | ||
334 | */ | ||
335 | |||
336 | if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { | ||
337 | printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n", | ||
338 | musb->config->gpio_vrsel); | ||
339 | return -ENODEV; | ||
340 | } | ||
341 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
342 | |||
343 | usb_nop_xceiv_register(); | ||
344 | musb->xceiv = otg_get_transceiver(); | ||
345 | if (!musb->xceiv) { | ||
346 | gpio_free(musb->config->gpio_vrsel); | ||
347 | return -ENODEV; | ||
348 | } | ||
349 | |||
350 | if (ANOMALY_05000346) { | 329 | if (ANOMALY_05000346) { |
351 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); | 330 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); |
352 | SSYNC(); | 331 | SSYNC(); |
@@ -358,7 +337,8 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
358 | } | 337 | } |
359 | 338 | ||
360 | /* Configure PLL oscillator register */ | 339 | /* Configure PLL oscillator register */ |
361 | bfin_write_USB_PLLOSC_CTRL(0x30a8); | 340 | bfin_write_USB_PLLOSC_CTRL(0x3080 | |
341 | ((480/musb->config->clkin) << 1)); | ||
362 | SSYNC(); | 342 | SSYNC(); |
363 | 343 | ||
364 | bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); | 344 | bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); |
@@ -380,6 +360,33 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
380 | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | | 360 | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | |
381 | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); | 361 | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); |
382 | SSYNC(); | 362 | SSYNC(); |
363 | } | ||
364 | |||
365 | int __init musb_platform_init(struct musb *musb, void *board_data) | ||
366 | { | ||
367 | |||
368 | /* | ||
369 | * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE | ||
370 | * and OTG HOST modes, while rev 1.1 and greater require PE7 to | ||
371 | * be low for DEVICE mode and high for HOST mode. We set it high | ||
372 | * here because we are in host mode | ||
373 | */ | ||
374 | |||
375 | if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { | ||
376 | printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n", | ||
377 | musb->config->gpio_vrsel); | ||
378 | return -ENODEV; | ||
379 | } | ||
380 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
381 | |||
382 | usb_nop_xceiv_register(); | ||
383 | musb->xceiv = otg_get_transceiver(); | ||
384 | if (!musb->xceiv) { | ||
385 | gpio_free(musb->config->gpio_vrsel); | ||
386 | return -ENODEV; | ||
387 | } | ||
388 | |||
389 | musb_platform_reg_init(musb); | ||
383 | 390 | ||
384 | if (is_host_enabled(musb)) { | 391 | if (is_host_enabled(musb)) { |
385 | musb->board_set_vbus = bfin_set_vbus; | 392 | musb->board_set_vbus = bfin_set_vbus; |
@@ -394,6 +401,27 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
394 | return 0; | 401 | return 0; |
395 | } | 402 | } |
396 | 403 | ||
404 | #ifdef CONFIG_PM | ||
405 | void musb_platform_save_context(struct musb *musb, | ||
406 | struct musb_context_registers *musb_context) | ||
407 | { | ||
408 | if (is_host_active(musb)) | ||
409 | /* | ||
410 | * During hibernate gpio_vrsel will change from high to low | ||
411 | * low which will generate wakeup event resume the system | ||
412 | * immediately. Set it to 0 before hibernate to avoid this | ||
413 | * wakeup event. | ||
414 | */ | ||
415 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
416 | } | ||
417 | |||
418 | void musb_platform_restore_context(struct musb *musb, | ||
419 | struct musb_context_registers *musb_context) | ||
420 | { | ||
421 | musb_platform_reg_init(musb); | ||
422 | } | ||
423 | #endif | ||
424 | |||
397 | int musb_platform_exit(struct musb *musb) | 425 | int musb_platform_exit(struct musb *musb) |
398 | { | 426 | { |
399 | gpio_free(musb->config->gpio_vrsel); | 427 | gpio_free(musb->config->gpio_vrsel); |