Skip to content

Commit

Permalink
drivers:misc: ti-st: flush UART upon fw failure
Browse files Browse the repository at this point in the history
Upon failure to read firmware version from chip or upon failure in responses
to firmware download the UART needs to be flushed of its existing buffers so
that the UIM can restart UART properly.

Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Pavan Savoy authored and Greg Kroah-Hartman committed Jan 4, 2012
1 parent bfb88d6 commit 18ccecf
Showing 1 changed file with 24 additions and 30 deletions.
54 changes: 24 additions & 30 deletions drivers/misc/ti-st/st_kim.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,37 +469,21 @@ long st_kim_start(void *kim_data)
/* wait for ldisc to be installed */
err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
msecs_to_jiffies(LDISC_TIME));
if (!err) { /* timeout */
pr_err("line disc installation timed out ");
kim_gdata->ldisc_install = 0;
pr_info("ldisc_install = 0");
sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
NULL, "install");
/* the following wait is never going to be completed,
* since the ldisc was never installed, hence serving
* as a mdelay of LDISC_TIME msecs */
err = wait_for_completion_timeout
(&kim_gdata->ldisc_installed,
msecs_to_jiffies(LDISC_TIME));
err = -ETIMEDOUT;
if (!err) {
/* ldisc installation timeout,
* flush uart, power cycle BT_EN */
pr_err("ldisc installation timeout");
err = st_kim_stop(kim_gdata);
continue;
} else {
/* ldisc installed now */
pr_info(" line discipline installed ");
pr_info("line discipline installed");
err = download_firmware(kim_gdata);
if (err != 0) {
/* ldisc installed but fw download failed,
* flush uart & power cycle BT_EN */
pr_err("download firmware failed");
kim_gdata->ldisc_install = 0;
pr_info("ldisc_install = 0");
sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
NULL, "install");
/* this wait might be completed, though in the
* tty_close() since the ldisc is already
* installed */
err = wait_for_completion_timeout
(&kim_gdata->ldisc_installed,
msecs_to_jiffies(LDISC_TIME));
err = -EINVAL;
err = st_kim_stop(kim_gdata);
continue;
} else { /* on success don't retry */
break;
Expand All @@ -510,21 +494,31 @@ long st_kim_start(void *kim_data)
}

/**
* st_kim_stop - called from ST Core, on the last un-registration
* toggle low the chip enable gpio
* st_kim_stop - stop communication with chip.
* This can be called from ST Core/KIM, on the-
* (a) last un-register when chip need not be powered there-after,
* (b) upon failure to either install ldisc or download firmware.
* The function is responsible to (a) notify UIM about un-installation,
* (b) flush UART if the ldisc was installed.
* (c) reset BT_EN - pull down nshutdown at the end.
* (d) invoke platform's chip disabling routine.
*/
long st_kim_stop(void *kim_data)
{
long err = 0;
struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
struct ti_st_plat_data *pdata =
kim_gdata->kim_pdev->dev.platform_data;
struct tty_struct *tty = kim_gdata->core_data->tty;

INIT_COMPLETION(kim_gdata->ldisc_installed);

/* Flush any pending characters in the driver and discipline. */
tty_ldisc_flush(kim_gdata->core_data->tty);
tty_driver_flush_buffer(kim_gdata->core_data->tty);
if (tty) { /* can be called before ldisc is installed */
/* Flush any pending characters in the driver and discipline. */
tty_ldisc_flush(tty);
tty_driver_flush_buffer(tty);
tty->ops->flush_buffer(tty);
}

/* send uninstall notification to UIM */
pr_info("ldisc_install = 0");
Expand Down

0 comments on commit 18ccecf

Please sign in to comment.