* [PATCH 0/3] robustness fixes for ti-st @ 2011-12-13 17:56 pavan_savoy 2011-12-13 17:56 ` [PATCH 1/3] drivers:misc: ti-st: protect registrations pavan_savoy 0 siblings, 1 reply; 4+ messages in thread From: pavan_savoy @ 2011-12-13 17:56 UTC (permalink / raw) To: gregkh, linux-kernel; +Cc: pavan_savoy, Pavan Savoy From: Pavan Savoy <pavan_savoy@ti.com> The following patches are fixes for some of the issues found during some robustness tests carried out on ti-st. With all 3 technologies (BT, FM and GPS) working over this transport along with WLAN's SDIO driver - there were certain issues where the chip didn't respond over UART as expected. The patch also includes 1 debug related change - which allows anyone who is porting ti-st to new platforms with doubt-able UARTs to debug various UART devices and baud-rates. Pavan Savoy (3): drivers:misc: ti-st: protect registrations drivers:misc: ti-st: flush UART upon fw failure drivers:misc: ti-st: DEBUG uart, baud rate mods drivers/misc/ti-st/st_core.c | 18 +++++++-- drivers/misc/ti-st/st_kim.c | 84 +++++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 34 deletions(-) -- 1.7.4.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] drivers:misc: ti-st: protect registrations 2011-12-13 17:56 [PATCH 0/3] robustness fixes for ti-st pavan_savoy @ 2011-12-13 17:56 ` pavan_savoy 2011-12-13 17:56 ` [PATCH 2/3] drivers:misc: ti-st: flush UART upon fw failure pavan_savoy 0 siblings, 1 reply; 4+ messages in thread From: pavan_savoy @ 2011-12-13 17:56 UTC (permalink / raw) To: gregkh, linux-kernel; +Cc: pavan_savoy, Pavan Savoy From: Pavan Savoy <pavan_savoy@ti.com> Concurrent access to UART2/combo-interface by multiple protocol drivers such as BT, FM and GPS caused issues during firmware download failure cases or cases when the firmware download took longer than usual. This was because of un-safe access to protos_registered & st_states. Protecting this will also make the registration complete callback un-safe for sleep. Signed-off-by: Pavan Savoy <pavan_savoy@ti.com> --- drivers/misc/ti-st/st_core.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index ba168a7..2b62232 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -137,6 +137,8 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) * st_reg_complete - * to call registration complete callbacks * of all protocol stack drivers + * This function is being called with spin lock held, protocol drivers are + * only expected to complete their waits and do nothing more than that. */ void st_reg_complete(struct st_data_s *st_gdata, char err) { @@ -538,11 +540,12 @@ long st_register(struct st_proto_s *new_proto) set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_kim_recv; + /* enable the ST LL - to set default chip state */ + st_ll_enable(st_gdata); + /* release lock previously held - re-locked below */ spin_unlock_irqrestore(&st_gdata->lock, flags); - /* enable the ST LL - to set default chip state */ - st_ll_enable(st_gdata); /* this may take a while to complete * since it involves BT fw download */ @@ -553,10 +556,13 @@ long st_register(struct st_proto_s *new_proto) (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { pr_err(" KIM failure complete callback "); st_reg_complete(st_gdata, err); + clear_bit(ST_REG_PENDING, &st_gdata->st_state); } return -EINVAL; } + spin_lock_irqsave(&st_gdata->lock, flags); + clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_int_recv; @@ -576,10 +582,10 @@ long st_register(struct st_proto_s *new_proto) if (st_gdata->is_registered[new_proto->chnl_id] == true) { pr_err(" proto %d already registered ", new_proto->chnl_id); + spin_unlock_irqrestore(&st_gdata->lock, flags); return -EALREADY; } - spin_lock_irqsave(&st_gdata->lock, flags); add_channel_to_table(st_gdata, new_proto); st_gdata->protos_registered++; new_proto->write = st_write; @@ -619,7 +625,7 @@ long st_unregister(struct st_proto_s *proto) spin_lock_irqsave(&st_gdata->lock, flags); - if (st_gdata->list[proto->chnl_id] == NULL) { + if (st_gdata->is_registered[proto->chnl_id] == false) { pr_err(" chnl_id %d not registered", proto->chnl_id); spin_unlock_irqrestore(&st_gdata->lock, flags); return -EPROTONOSUPPORT; @@ -629,6 +635,10 @@ long st_unregister(struct st_proto_s *proto) remove_channel_from_table(st_gdata, proto); spin_unlock_irqrestore(&st_gdata->lock, flags); + /* paranoid check */ + if (st_gdata->protos_registered < ST_EMPTY) + st_gdata->protos_registered = ST_EMPTY; + if ((st_gdata->protos_registered == ST_EMPTY) && (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { pr_info(" all chnl_ids unregistered "); -- 1.7.4.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/3] drivers:misc: ti-st: flush UART upon fw failure 2011-12-13 17:56 ` [PATCH 1/3] drivers:misc: ti-st: protect registrations pavan_savoy @ 2011-12-13 17:56 ` pavan_savoy 2011-12-13 17:56 ` [PATCH 3/3] drivers:misc: ti-st: DEBUG uart, baud rate mods pavan_savoy 0 siblings, 1 reply; 4+ messages in thread From: pavan_savoy @ 2011-12-13 17:56 UTC (permalink / raw) To: gregkh, linux-kernel; +Cc: pavan_savoy, Pavan Savoy From: Pavan Savoy <pavan_savoy@ti.com> 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> --- 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 43ef8d1..bc8a571 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) /* 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; @@ -510,8 +494,14 @@ 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) { @@ -519,12 +509,16 @@ long st_kim_stop(void *kim_data) 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"); -- 1.7.4.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 3/3] drivers:misc: ti-st: DEBUG uart, baud rate mods 2011-12-13 17:56 ` [PATCH 2/3] drivers:misc: ti-st: flush UART upon fw failure pavan_savoy @ 2011-12-13 17:56 ` pavan_savoy 0 siblings, 0 replies; 4+ messages in thread From: pavan_savoy @ 2011-12-13 17:56 UTC (permalink / raw) To: gregkh, linux-kernel; +Cc: pavan_savoy, Pavan Savoy From: Pavan Savoy <pavan_savoy@ti.com> To debug different UARTs at different baud-rates connected to the WiLink connectivity combo-chipset, this patch enables the debugging code so that upon boot different UARTs at different baud-rates can be tried out to verify the interface with WiLink. Signed-off-by: Pavan Savoy <pavan_savoy@ti.com> --- drivers/misc/ti-st/st_kim.c | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index bc8a571..55ab031 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -573,6 +573,28 @@ static ssize_t show_install(struct device *dev, return sprintf(buf, "%d\n", kim_data->ldisc_install); } +#ifdef DEBUG +static ssize_t store_dev_name(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + pr_debug("storing dev name >%s<", buf); + strncpy(kim_data->dev_name, buf, count); + pr_debug("stored dev name >%s<", kim_data->dev_name); + return count; +} + +static ssize_t store_baud_rate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + pr_debug("storing baud rate >%s<", buf); + sscanf(buf, "%ld", &kim_data->baud_rate); + pr_debug("stored baud rate >%ld<", kim_data->baud_rate); + return count; +} +#endif /* if DEBUG */ + static ssize_t show_dev_name(struct device *dev, struct device_attribute *attr, char *buf) { @@ -598,11 +620,19 @@ static ssize_t show_flow_cntrl(struct device *dev, static struct kobj_attribute ldisc_install = __ATTR(install, 0444, (void *)show_install, NULL); +#ifdef DEBUG /* TODO: move this to debug-fs if possible */ +__ATTR(dev_name, 0644, (void *)show_dev_name, (void *)store_dev_name); +#else static struct kobj_attribute uart_dev_name = __ATTR(dev_name, 0444, (void *)show_dev_name, NULL); +#endif static struct kobj_attribute uart_baud_rate = +#ifdef DEBUG /* TODO: move to debugfs */ +__ATTR(baud_rate, 0644, (void *)show_baud_rate, (void *)store_baud_rate); +#else __ATTR(baud_rate, 0444, (void *)show_baud_rate, NULL); +#endif static struct kobj_attribute uart_flow_cntrl = __ATTR(flow_cntrl, 0444, (void *)show_flow_cntrl, NULL); -- 1.7.4.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-12-13 17:56 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-12-13 17:56 [PATCH 0/3] robustness fixes for ti-st pavan_savoy 2011-12-13 17:56 ` [PATCH 1/3] drivers:misc: ti-st: protect registrations pavan_savoy 2011-12-13 17:56 ` [PATCH 2/3] drivers:misc: ti-st: flush UART upon fw failure pavan_savoy 2011-12-13 17:56 ` [PATCH 3/3] drivers:misc: ti-st: DEBUG uart, baud rate mods pavan_savoy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®