diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c index 896db3afa245..38fe6d413f68 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c @@ -38,13 +38,13 @@ static ssize_t name##_show(struct device *dev, \ { \ struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); \ int ret = 0; \ - if (!touch_cdev || !touch_cdev->mdata->get_##name) { \ + if (!touch_cdev) { \ dev_err(dev, "get_%s: invalid pointer\n", #name); \ return (ssize_t)0; \ } \ mutex_lock(&touch_cdev->extif_mutex); \ if (!chk_tp_status || is_touch_active) { \ - ret = touch_cdev->mdata->get_##name(DEV_TS, &touch_cdev->name); \ + TRY_TO_GET(name, &touch_cdev->name); \ if (ret < 0) { \ dev_err(dev, "get_%s: return error %d\n", #name, ret); \ ret = 0; \ @@ -63,27 +63,29 @@ static ssize_t name##_store(struct device *dev, \ { \ struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); \ unsigned long value = 0; \ - int err = 0; \ - err = kstrtoul(buf, 0, &value); \ - if (err < 0) { \ + int ret = 0; \ + ret = kstrtoul(buf, 0, &value); \ + if (ret < 0) { \ dev_err(dev, "%s: Failed to convert value\n", #name); \ return -EINVAL; \ } \ - if (!touch_cdev || !touch_cdev->mdata->name) { \ + if (!touch_cdev) { \ dev_err(dev, "%s: invalid pointer\n", #name); \ return -EINVAL; \ } \ mutex_lock(&touch_cdev->extif_mutex); \ + mutex_lock(&touch_cdev->method_mutex); \ touch_cdev->name = value; \ if (!chk_tp_status || is_touch_active) { \ - err = touch_cdev->mdata->name(DEV_TS, touch_cdev->name); \ - if (err < 0) { \ - dev_err(dev, "%s: return error %d\n", #name, err); \ + _TRY_TO_CALL(name, touch_cdev->name); \ + if (ret < 0) { \ + dev_err(dev, "%s: return error %d\n", #name, ret); \ goto TOUCH_MMI_STORE_OUT; \ } \ } else \ dev_dbg(dev, "%s: write to cache data.\n", #name); \ TOUCH_MMI_STORE_OUT: \ + mutex_unlock(&touch_cdev->method_mutex); \ mutex_unlock(&touch_cdev->extif_mutex); \ return size; \ } \ @@ -214,7 +216,7 @@ static ssize_t ts_mmi_doreflash_store(struct device *dev, struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); char fw_path[TS_MMI_MAX_FW_PATH]; char template[TS_MMI_MAX_FW_PATH]; - int err; + int ret = 0; if (size > TS_MMI_MAX_FW_PATH) { dev_err(dev, "%s: FW filename is too long\n", __func__); @@ -222,7 +224,7 @@ static ssize_t ts_mmi_doreflash_store(struct device *dev, } if (!touch_cdev->forcereflash) { - touch_cdev->mdata->get_vendor(DEV_TS, &touch_cdev->vendor); + TRY_TO_GET(vendor, &touch_cdev->vendor); if (strncmp(buf, touch_cdev->vendor, strnlen(touch_cdev->vendor, TS_MMI_MAX_VENDOR_LEN))) { dev_err(dev, @@ -231,7 +233,7 @@ static ssize_t ts_mmi_doreflash_store(struct device *dev, return -EINVAL; } - touch_cdev->mdata->get_productinfo(DEV_TS, &touch_cdev->productinfo); + TRY_TO_GET(productinfo, &touch_cdev->productinfo); snprintf(template, sizeof(template), "-%s-", touch_cdev->productinfo); if (!strnstr(buf + strnlen(touch_cdev->vendor, TS_MMI_MAX_VENDOR_LEN), template, size)) { @@ -243,19 +245,15 @@ static ssize_t ts_mmi_doreflash_store(struct device *dev, strlcpy(fw_path, buf, size); dev_dbg(dev, "%s: FW filename: %s\n", __func__, fw_path); - if (!touch_cdev->mdata->firmware_update) { - dev_err(dev, - "%s: firmware_update method not exist.\n", __func__); - return -EINVAL; - } - err = touch_cdev->mdata->firmware_update(DEV_TS, fw_path); - if (err < 0) { - dev_err(dev, "%s: firmware_update failed %d.\n", __func__, err); + + TRY_TO_CALL(firmware_update, fw_path); + if (ret < 0) { + dev_err(dev, "%s: firmware_update failed %d.\n", __func__, ret); return -EINVAL; } dev_info(dev, "%s: update fw from %s, return %d\n", - __func__, fw_path, err); + __func__, fw_path, ret); return size; } @@ -266,17 +264,17 @@ static ssize_t pwr_store(struct device *dev, { struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); unsigned long value = 0; - int err = 0; - err = kstrtoul(buf, 10, &value); - if (err < 0) { + int ret = 0; + ret = kstrtoul(buf, 10, &value); + if (ret < 0) { dev_err(dev, "%s: Failed to convert value\n", __func__); return -EINVAL; } - if (!touch_cdev || !touch_cdev->mdata->power) { + if (!touch_cdev) { dev_err(dev, "%s: invalid pointer\n", __func__); return -EINVAL; } - touch_cdev->mdata->power(DEV_TS, value); + TRY_TO_CALL(power, value); return size; } static DEVICE_ATTR(pwr, (S_IWUSR | S_IWGRP), NULL, pwr_store); @@ -319,13 +317,13 @@ static ssize_t pill_region_show(struct device *dev, struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); int ret = 0; - if (!touch_cdev || !touch_cdev->mdata->get_pill_region) { + if (!touch_cdev) { dev_err(dev, "get_pill_region: invalid pointer\n"); return (ssize_t)0; } mutex_lock(&touch_cdev->extif_mutex); if (is_touch_active) { - ret = touch_cdev->mdata->get_pill_region(DEV_TS, &touch_cdev->pill_region); + TRY_TO_GET(pill_region, &touch_cdev->pill_region); if (ret < 0) { dev_err(dev, "get_pill_region: return error %d\n", ret); ret = 0; @@ -346,26 +344,28 @@ static ssize_t pill_region_store(struct device *dev, { struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); unsigned int args[TS_MMI_PILL_REGION_REQ_ARGS_NUM] = {0}; - int err = 0; + int ret = 0; int i = TS_MMI_PILL_REGION_REQ_ARGS_NUM; - err = sscanf(buf, "0x%x 0x%x 0x%x", &args[0], &args[1], &args[2]); - if (err < TS_MMI_PILL_REGION_REQ_ARGS_NUM) { + ret = sscanf(buf, "0x%x 0x%x 0x%x", &args[0], &args[1], &args[2]); + if (ret < TS_MMI_PILL_REGION_REQ_ARGS_NUM) { dev_err(dev, "pill_region: Failed to convert value\n"); return -EINVAL; } - if (!touch_cdev || !touch_cdev->mdata->pill_region) { + if (!touch_cdev) { dev_err(dev, "pill_region: invalid pointer\n"); return -EINVAL; } mutex_lock(&touch_cdev->extif_mutex); + mutex_lock(&touch_cdev->method_mutex); \ while (i--) touch_cdev->pill_region[i] = args[i]; if (is_touch_active) - touch_cdev->mdata->pill_region(DEV_TS, touch_cdev->pill_region); + _TRY_TO_CALL(pill_region, touch_cdev->pill_region); else dev_dbg(dev, "pill_region: write to cache data.\n"); + mutex_unlock(&touch_cdev->method_mutex); \ mutex_unlock(&touch_cdev->extif_mutex); return size; } @@ -462,14 +462,12 @@ CREATE_SUPPRESSION_FAILED: static int ts_mmi_get_vendor_info( struct ts_mmi_dev *touch_cdev) { - struct ts_mmi_methods *mdata = touch_cdev->mdata; + int ret = 0; + + TRY_TO_GET(productinfo, &touch_cdev->productinfo); + TRY_TO_GET(vendor, &touch_cdev->vendor); + TRY_TO_GET(bus_type, &touch_cdev->bus_type); - if (mdata->get_productinfo) - mdata->get_productinfo(DEV_TS, &touch_cdev->productinfo); - if (mdata->get_vendor) - mdata->get_vendor(DEV_TS, &touch_cdev->vendor); - if (mdata->get_bus_type) - mdata->get_bus_type(DEV_TS, &touch_cdev->bus_type); return 0; } @@ -519,6 +517,7 @@ int ts_mmi_dev_register(struct device *parent, DEV_TS = parent; touch_cdev->mdata = mdata; mutex_init(&touch_cdev->extif_mutex); + mutex_init(&touch_cdev->method_mutex); ret = ts_mmi_parse_dt(touch_cdev, DEV_TS->of_node); if (ret < 0) { diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c index 68ed648cf8d8..ed801f076363 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c @@ -59,6 +59,8 @@ enum ts_mmi_work { #if defined(CONFIG_PANEL_NOTIFICATIONS) static int ts_mmi_panel_off(struct ts_mmi_dev *touch_cdev) { + int ret = 0; + if (atomic_cmpxchg(&touch_cdev->touch_stopped, 0, 1) == 1) return 0; @@ -103,6 +105,7 @@ static int ts_mmi_panel_cb(struct notifier_block *nb, int idx = evd ? *(int *)evd : -1; struct ts_mmi_dev *touch_cdev = container_of(nb, struct ts_mmi_dev, panel_nb); + int ret = 0; if (!touch_cdev) return 0; @@ -128,14 +131,14 @@ static int ts_mmi_panel_cb(struct notifier_block *nb, ts_mmi_panel_off(touch_cdev); if (NEED_TO_SET_PINCTRL) { dev_dbg(DEV_MMI, "%s: touch pinctrl off\n", __func__); - touch_cdev->mdata->pinctrl(DEV_TS, TS_MMI_PINCTL_OFF); + TRY_TO_CALL(pinctrl, TS_MMI_PINCTL_OFF); } break; case PANEL_EVENT_DISPLAY_OFF: if (NEED_TO_SET_POWER) { /* then proceed with de-powering */ - touch_cdev->mdata->power(DEV_TS, TS_MMI_POWER_OFF); + TRY_TO_CALL(power, TS_MMI_POWER_OFF); dev_dbg(DEV_MMI, "%s: touch powered off\n", __func__); } break; @@ -143,7 +146,7 @@ static int ts_mmi_panel_cb(struct notifier_block *nb, case PANEL_EVENT_PRE_DISPLAY_ON: if (NEED_TO_SET_POWER) { /* powering on early */ - touch_cdev->mdata->power(DEV_TS, TS_MMI_POWER_ON); + TRY_TO_CALL(power, TS_MMI_POWER_ON); dev_dbg(DEV_MMI, "%s: touch powered on\n", __func__); } else if (touch_cdev->pdata.reset && touch_cdev->mdata->reset) { @@ -151,14 +154,14 @@ static int ts_mmi_panel_cb(struct notifier_block *nb, * But need reset IC in resume. */ dev_dbg(DEV_MMI, "%s: resetting...\n", __func__); - touch_cdev->mdata->reset(DEV_TS, TS_MMI_RESET_HARD); + TRY_TO_CALL(reset, TS_MMI_RESET_HARD); } break; case PANEL_EVENT_DISPLAY_ON: /* out of reset to allow wait for boot complete */ if (NEED_TO_SET_PINCTRL) { - touch_cdev->mdata->pinctrl(DEV_TS, TS_MMI_PINCTL_ON); + TRY_TO_CALL(pinctrl, TS_MMI_PINCTL_ON); dev_dbg(DEV_MMI, "%s: touch pinctrl_on\n", __func__); } ts_mmi_panel_on(touch_cdev); @@ -174,6 +177,8 @@ static int ts_mmi_panel_cb(struct notifier_block *nb, static inline void ts_mmi_restore_settings(struct ts_mmi_dev *touch_cdev) { + int ret = 0; + if (touch_cdev->pdata.usb_detection) TRY_TO_CALL(charger_mode, (int)touch_cdev->ps_is_present); if (touch_cdev->pdata.update_refresh_rate) @@ -193,6 +198,7 @@ static inline void ts_mmi_restore_settings(struct ts_mmi_dev *touch_cdev) static void ts_mmi_queued_resume(struct ts_mmi_dev *touch_cdev) { bool wait4_boot_complete = true; + int ret = 0; if (atomic_cmpxchg(&touch_cdev->touch_stopped, 1, 0) == 0) return; @@ -243,13 +249,13 @@ static void ts_mmi_worker_func(struct work_struct *w) container_of(w, struct delayed_work, work); struct ts_mmi_dev *touch_cdev = container_of(dw, struct ts_mmi_dev, work); - int rc, cmd = 0; + int ret, cmd = 0; while (kfifo_get(&touch_cdev->cmd_pipe, &cmd)) { switch (cmd) { case TS_MMI_DO_RESUME: - rc = atomic_read(&touch_cdev->resume_should_stop); - if (rc) { + ret = atomic_read(&touch_cdev->resume_should_stop); + if (ret) { dev_info(DEV_MMI, "%s: resume cancelled\n", __func__); break; } diff --git a/include/linux/touchscreen_mmi.h b/include/linux/touchscreen_mmi.h index 592b410b838e..4c20b6db0529 100644 --- a/include/linux/touchscreen_mmi.h +++ b/include/linux/touchscreen_mmi.h @@ -176,6 +176,7 @@ struct ts_mmi_dev { struct ts_mmi_dev_pdata pdata; struct notifier_block panel_nb; struct mutex extif_mutex; + struct mutex method_mutex; atomic_t touch_stopped; enum ts_mmi_pm_mode pm_mode; @@ -190,7 +191,6 @@ struct ts_mmi_dev { struct work_struct ps_notify_work; struct notifier_block ps_notif; bool ps_is_present; - /* * sys entey variable */ @@ -224,17 +224,27 @@ struct ts_mmi_dev { #define DEV_MMI (touch_cdev->class_dev) #define DEV_TS (touch_cdev->dev) #define MMI_DEV_TO_TS_DEV(cdev) (((struct ts_mmi_dev *)dev_get_drvdata(dev))->dev) -#define TRY_TO_CALL(_method, ...) \ +/* call this after hold method mutex */ +#define _TRY_TO_CALL(_method, ...) \ do { \ if (touch_cdev->mdata->_method) { \ - touch_cdev->mdata->_method(DEV_TS, ##__VA_ARGS__); \ + ret = touch_cdev->mdata->_method(DEV_TS, ##__VA_ARGS__); \ } \ } while (0) +#define TRY_TO_CALL(_method, ...) \ +do { \ + ret = ret; \ + mutex_lock(&touch_cdev->method_mutex); \ + _TRY_TO_CALL(_method, ##__VA_ARGS__); \ + mutex_unlock(&touch_cdev->method_mutex); \ +} while (0) #define TRY_TO_GET(_method, ...) \ do { \ ret = ret; \ - if (touch_cdev->mdata->_method) { \ + if (touch_cdev->mdata->get_##_method) { \ + mutex_lock(&touch_cdev->method_mutex); \ ret = touch_cdev->mdata->get_##_method(DEV_TS, ##__VA_ARGS__); \ + mutex_unlock(&touch_cdev->method_mutex); \ } \ } while (0) #define is_touch_stopped (atomic_read(&touch_cdev->touch_stopped) == 1)