diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/ti-st/st_kim.c | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 43ef8d162f2d..bc8a5718c0d7 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c | |||
@@ -469,37 +469,21 @@ long st_kim_start(void *kim_data) | |||
469 | /* wait for ldisc to be installed */ | 469 | /* wait for ldisc to be installed */ |
470 | err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, | 470 | err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, |
471 | msecs_to_jiffies(LDISC_TIME)); | 471 | msecs_to_jiffies(LDISC_TIME)); |
472 | if (!err) { /* timeout */ | 472 | if (!err) { |
473 | pr_err("line disc installation timed out "); | 473 | /* ldisc installation timeout, |
474 | kim_gdata->ldisc_install = 0; | 474 | * flush uart, power cycle BT_EN */ |
475 | pr_info("ldisc_install = 0"); | 475 | pr_err("ldisc installation timeout"); |
476 | sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, | 476 | err = st_kim_stop(kim_gdata); |
477 | NULL, "install"); | ||
478 | /* the following wait is never going to be completed, | ||
479 | * since the ldisc was never installed, hence serving | ||
480 | * as a mdelay of LDISC_TIME msecs */ | ||
481 | err = wait_for_completion_timeout | ||
482 | (&kim_gdata->ldisc_installed, | ||
483 | msecs_to_jiffies(LDISC_TIME)); | ||
484 | err = -ETIMEDOUT; | ||
485 | continue; | 477 | continue; |
486 | } else { | 478 | } else { |
487 | /* ldisc installed now */ | 479 | /* ldisc installed now */ |
488 | pr_info(" line discipline installed "); | 480 | pr_info("line discipline installed"); |
489 | err = download_firmware(kim_gdata); | 481 | err = download_firmware(kim_gdata); |
490 | if (err != 0) { | 482 | if (err != 0) { |
483 | /* ldisc installed but fw download failed, | ||
484 | * flush uart & power cycle BT_EN */ | ||
491 | pr_err("download firmware failed"); | 485 | pr_err("download firmware failed"); |
492 | kim_gdata->ldisc_install = 0; | 486 | err = st_kim_stop(kim_gdata); |
493 | pr_info("ldisc_install = 0"); | ||
494 | sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, | ||
495 | NULL, "install"); | ||
496 | /* this wait might be completed, though in the | ||
497 | * tty_close() since the ldisc is already | ||
498 | * installed */ | ||
499 | err = wait_for_completion_timeout | ||
500 | (&kim_gdata->ldisc_installed, | ||
501 | msecs_to_jiffies(LDISC_TIME)); | ||
502 | err = -EINVAL; | ||
503 | continue; | 487 | continue; |
504 | } else { /* on success don't retry */ | 488 | } else { /* on success don't retry */ |
505 | break; | 489 | break; |
@@ -510,8 +494,14 @@ long st_kim_start(void *kim_data) | |||
510 | } | 494 | } |
511 | 495 | ||
512 | /** | 496 | /** |
513 | * st_kim_stop - called from ST Core, on the last un-registration | 497 | * st_kim_stop - stop communication with chip. |
514 | * toggle low the chip enable gpio | 498 | * This can be called from ST Core/KIM, on the- |
499 | * (a) last un-register when chip need not be powered there-after, | ||
500 | * (b) upon failure to either install ldisc or download firmware. | ||
501 | * The function is responsible to (a) notify UIM about un-installation, | ||
502 | * (b) flush UART if the ldisc was installed. | ||
503 | * (c) reset BT_EN - pull down nshutdown at the end. | ||
504 | * (d) invoke platform's chip disabling routine. | ||
515 | */ | 505 | */ |
516 | long st_kim_stop(void *kim_data) | 506 | long st_kim_stop(void *kim_data) |
517 | { | 507 | { |
@@ -519,12 +509,16 @@ long st_kim_stop(void *kim_data) | |||
519 | struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; | 509 | struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; |
520 | struct ti_st_plat_data *pdata = | 510 | struct ti_st_plat_data *pdata = |
521 | kim_gdata->kim_pdev->dev.platform_data; | 511 | kim_gdata->kim_pdev->dev.platform_data; |
512 | struct tty_struct *tty = kim_gdata->core_data->tty; | ||
522 | 513 | ||
523 | INIT_COMPLETION(kim_gdata->ldisc_installed); | 514 | INIT_COMPLETION(kim_gdata->ldisc_installed); |
524 | 515 | ||
525 | /* Flush any pending characters in the driver and discipline. */ | 516 | if (tty) { /* can be called before ldisc is installed */ |
526 | tty_ldisc_flush(kim_gdata->core_data->tty); | 517 | /* Flush any pending characters in the driver and discipline. */ |
527 | tty_driver_flush_buffer(kim_gdata->core_data->tty); | 518 | tty_ldisc_flush(tty); |
519 | tty_driver_flush_buffer(tty); | ||
520 | tty->ops->flush_buffer(tty); | ||
521 | } | ||
528 | 522 | ||
529 | /* send uninstall notification to UIM */ | 523 | /* send uninstall notification to UIM */ |
530 | pr_info("ldisc_install = 0"); | 524 | pr_info("ldisc_install = 0"); |