input: touchscreen: focaltech: toggle reset gpio during error

Toggle reset gpio of touch controller during an error scenario
on Secondary Virtual Machine(SVM).

Change-Id: Id5fdbb8e0106e636676060edfb05b6219f7400c8
Signed-off-by: Ritesh Kumar <riteshk@codeaurora.org>
This commit is contained in:
Ritesh Kumar 2020-10-27 14:41:38 +05:30 • committed by Gerrit - the friendly Code Review server
commit 88af9a72fe
3 changed files with 111 additions and 4 deletions

View file

@ -247,6 +247,49 @@ static void fts_ts_trusted_touch_tvm_vm_mode_disable(struct fts_ts_data *fts_dat
static void fts_ts_trusted_touch_abort_tvm(struct fts_ts_data *fts_data);
static void fts_ts_trusted_touch_event_notify(struct fts_ts_data *fts_data, int event);
void fts_ts_trusted_touch_tvm_i2c_failure_report(struct fts_ts_data *fts_data)
{
pr_err("initiating trusted touch abort due to i2c failure\n");
fts_ts_trusted_touch_abort_handler(fts_data,
TRUSTED_TOUCH_EVENT_I2C_FAILURE);
}
static void fts_ts_trusted_touch_reset_gpio_toggle(struct fts_ts_data *fts_data)
{
void __iomem *base;
base = ioremap(TOUCH_RESET_GPIO_BASE, TOUCH_RESET_GPIO_SIZE);
writel_relaxed(0x1, base + TOUCH_RESET_GPIO_OFFSET);
/* wait until toggle to finish*/
wmb();
writel_relaxed(0x0, base + TOUCH_RESET_GPIO_OFFSET);
/* wait until toggle to finish*/
wmb();
iounmap(base);
}
static void fts_trusted_touch_intr_gpio_toggle(struct fts_ts_data *fts_data,
bool enable)
{
void __iomem *base;
u32 val;
base = ioremap(TOUCH_INTR_GPIO_BASE, TOUCH_INTR_GPIO_SIZE);
val = readl_relaxed(base + TOUCH_RESET_GPIO_OFFSET);
if (enable) {
val |= BIT(0);
writel_relaxed(val, base + TOUCH_INTR_GPIO_OFFSET);
/* wait until toggle to finish*/
wmb();
} else {
val &= ~BIT(0);
writel_relaxed(val, base + TOUCH_INTR_GPIO_OFFSET);
/* wait until toggle to finish*/
wmb();
}
iounmap(base);
}
static int fts_ts_trusted_touch_get_tvm_driver_state(struct fts_ts_data *fts_data)
{
int state;
@ -376,6 +419,7 @@ static void fts_ts_trusted_touch_tvm_vm_mode_enable(struct fts_ts_data *fts_data
kfree(acl_desc);
irq = hh_irq_accept(fts_data->vm_info->irq_label, -1, IRQ_TYPE_EDGE_RISING);
fts_trusted_touch_intr_gpio_toggle(fts_data, false);
if (irq < 0) {
pr_err("failed to accept irq\n");
goto accept_fail;
@ -1040,6 +1084,14 @@ static void fts_ts_trusted_touch_abort_handler(struct fts_ts_data *fts_data, int
atomic_set(&fts_data->trusted_touch_abort_status, error);
pr_err("TUI session aborted with failure:%d\n", error);
fts_ts_trusted_touch_event_notify(fts_data, error);
#ifdef CONFIG_ARCH_QTI_VM
pr_err("Resetting touch controller\n");
if (fts_ts_trusted_touch_get_tvm_driver_state(fts_data) >= TVM_IOMEM_ACCEPTED
&& error == TRUSTED_TOUCH_EVENT_I2C_FAILURE) {
pr_err("Resetting touch controller\n");
fts_ts_trusted_touch_reset_gpio_toggle(fts_data);
}
#endif
}
static int fts_ts_vm_init(struct fts_ts_data *fts_data)

View file

@ -178,17 +178,25 @@ enum trusted_touch_tvm_states {
TRUSTED_TOUCH_TVM_STATE_MAX
};
#ifdef CONFIG_FTS_TRUSTED_TOUCH
#define TRUSTED_TOUCH_MEM_LABEL 0x7
#define TOUCH_RESET_GPIO_BASE 0xF116000
#define TOUCH_RESET_GPIO_SIZE 0x1000
#define TOUCH_RESET_GPIO_OFFSET 0x4
#define TOUCH_INTR_GPIO_BASE 0xF117000
#define TOUCH_INTR_GPIO_SIZE 0x1000
#define TOUCH_INTR_GPIO_OFFSET 0x8
#define TRUSTED_TOUCH_EVENT_LEND_FAILURE -1
#define TRUSTED_TOUCH_EVENT_LEND_NOTIFICATION_FAILURE -2
#define TRUSTED_TOUCH_EVENT_ACCEPT_FAILURE -3
#define TRUSTED_TOUCH_EVENT_FUNCTIONAL_FAILURE -4
#define TRUSTED_TOUCH_EVENT_RELEASE_FAILURE -5
#define TRUSTED_TOUCH_EVENT_RECLAIM_FAILURE -6
#define TRUSTED_TOUCH_EVENT_I2C_FAILURE -7
#define TRUSTED_TOUCH_EVENT_NOTIFICATIONS_PENDING 5
#ifdef CONFIG_FTS_TRUSTED_TOUCH
#define TRUSTED_TOUCH_MEM_LABEL 0x7
struct trusted_touch_vm_info {
enum hh_irq_label irq_label;
enum hh_vm_names vm_name;
@ -346,4 +354,9 @@ void fts_irq_disable(void);
void fts_irq_enable(void);
int fts_ts_handle_trusted_touch_pvm(struct fts_ts_data *ts_data, int value);
int fts_ts_handle_trusted_touch_tvm(struct fts_ts_data *ts_data, int value);
#ifdef CONFIG_FTS_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
void fts_ts_trusted_touch_tvm_i2c_failure_report(struct fts_ts_data *fts_data);
#endif
#endif
#endif /* __LINUX_FOCALTECH_CORE_H__ */

View file

@ -35,7 +35,7 @@
* Included header files
*****************************************************************************/
#include "focaltech_core.h"
#include <linux/pm_runtime.h>
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
@ -101,6 +101,18 @@ int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen)
for (i = 0; i < I2C_RETRY_NUMBER; i++) {
ret = i2c_transfer(ts_data->client->adapter, msg, msg_num);
if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
if (atomic_read(&ts_data->trusted_touch_enabled) &&
ret == -ECONNRESET) {
pr_err("failed i2c read reacquiring session\n");
pm_runtime_put_sync(
ts_data->client->adapter->dev.parent);
pm_runtime_get_sync(
ts_data->client->adapter->dev.parent);
}
#endif
#endif
FTS_ERROR("i2c_transfer(read) fail,ret:%d", ret);
} else {
memcpy(data, ts_data->bus_rx_buf, datalen);
@ -108,6 +120,15 @@ int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen)
}
}
if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
pr_err("initiating abort due to i2c xfer failure\n");
fts_ts_trusted_touch_tvm_i2c_failure_report(ts_data);
#endif
#endif
}
mutex_unlock(&ts_data->bus_lock);
return ret;
}
@ -135,11 +156,32 @@ int fts_write(u8 *writebuf, u32 writelen)
for (i = 0; i < I2C_RETRY_NUMBER; i++) {
ret = i2c_transfer(ts_data->client->adapter, &msgs, 1);
if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
if (atomic_read(&ts_data->trusted_touch_enabled) &&
ret == -ECONNRESET){
pr_err("failed i2c write reacquiring session\n");
pm_runtime_put_sync(
ts_data->client->adapter->dev.parent);
pm_runtime_get_sync(
ts_data->client->adapter->dev.parent);
}
#endif
#endif
FTS_ERROR("i2c_transfer(write) fail,ret:%d", ret);
} else {
break;
}
}
if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
pr_err("initiating abort due to i2c xfer failure\n");
fts_ts_trusted_touch_tvm_i2c_failure_report(ts_data);
#endif
#endif
}
mutex_unlock(&ts_data->bus_lock);
return ret;
}