Loading drivers/input/touchscreen/Kconfig +3 −3 Original line number Diff line number Diff line Loading @@ -992,10 +992,10 @@ config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE config SECURE_TOUCH bool "Secure Touch" depends on TOUCHSCREEN_ATMEL_MXT depends on (TOUCHSCREEN_ATMEL_MXT || TOUCHSCREEN_SYNAPTICS_I2C_RMI4 || \ TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21) help Say Y here to enable Secure Touch support in the Atmel MXT driver. Say Y here to enable Secure Touch in supported drivers. If unsure, say N. Loading drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c +220 −7 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ * * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -31,6 +32,10 @@ #ifdef KERNEL_ABOVE_2_6_38 #include <linux/input/mt.h> #endif #if defined(CONFIG_SECURE_TOUCH) #include <linux/errno.h> #include <asm/system.h> #endif #define INPUT_PHYS_NAME "synaptics_dsx/input0" #define DEBUGFS_DIR_NAME "ts_debug" Loading Loading @@ -134,6 +139,19 @@ static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, static ssize_t synaptics_rmi4_suspend_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static irqreturn_t synaptics_rmi4_irq(int irq, void *data); #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf); #endif struct synaptics_rmi4_f01_device_status { union { struct { Loading Loading @@ -362,6 +380,14 @@ static struct device_attribute attrs[] = { __ATTR(suspend, S_IWUGO, synaptics_rmi4_show_error, synaptics_rmi4_suspend_store), #if defined(CONFIG_SECURE_TOUCH) __ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO), synaptics_secure_touch_enable_show, synaptics_secure_touch_enable_store), __ATTR(secure_touch, S_IRUGO , synaptics_secure_touch_show, NULL), #endif }; static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val) Loading @@ -388,6 +414,174 @@ static int synaptics_rmi4_debug_suspend_get(void *_data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, synaptics_rmi4_debug_suspend_get, synaptics_rmi4_debug_suspend_set, "%lld\n"); #if defined(CONFIG_SECURE_TOUCH) static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { init_completion(&data->st_powerdown); init_completion(&data->st_irq_processed); } static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *rmi4_data) { sysfs_notify(&rmi4_data->input_dev->dev.kobj, NULL, "secure_touch"); } static irqreturn_t synaptics_filter_interrupt( struct synaptics_rmi4_data *rmi4_data) { if (atomic_read(&rmi4_data->st_enabled)) { if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 0, 1) == 0) { synaptics_secure_touch_notify(rmi4_data); wait_for_completion_interruptible( &rmi4_data->st_irq_processed); } return IRQ_HANDLED; } return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *rmi4_data, int blocking) { if (atomic_read(&rmi4_data->st_enabled)) { atomic_set(&rmi4_data->st_pending_irqs, -1); synaptics_secure_touch_notify(rmi4_data); if (blocking) wait_for_completion_interruptible( &rmi4_data->st_powerdown); } } #else static void synaptics_secure_touch_init(struct synaptics_rmi4_data *rmi4_data) { } static irqreturn_t synaptics_filter_interrupt( struct synaptics_rmi4_data *rmi4_data) { return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *rmi4_data, int blocking) { } #endif #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); return scnprintf( buf, PAGE_SIZE, "%d", atomic_read(&rmi4_data->st_enabled)); } /* * Accept only "0" and "1" valid values. * "0" will reset the st_enabled flag, then wake up the reading process and * the interrupt handler. * The bus driver is notified via pm_runtime that it is not required to stay * awake anymore. * It will also make sure the queue of events is emptied in the controller, * in case a touch happened in between the secure touch being disabled and * the local ISR being ungated. * "1" will set the st_enabled flag and clear the st_pending_irqs flag. * The bus driver is requested via pm_runtime to stay awake. */ static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); unsigned long value; int err = 0; if (count > 2) return -EINVAL; err = kstrtoul(buf, 10, &value); if (err != 0) return err; err = count; switch (value) { case 0: if (atomic_read(&rmi4_data->st_enabled) == 0) break; synaptics_rmi4_bus_put(rmi4_data); atomic_set(&rmi4_data->st_enabled, 0); synaptics_secure_touch_notify(rmi4_data); complete(&rmi4_data->st_irq_processed); synaptics_rmi4_irq(rmi4_data->irq, rmi4_data); complete(&rmi4_data->st_powerdown); break; case 1: if (atomic_read(&rmi4_data->st_enabled)) { err = -EBUSY; break; } synchronize_irq(rmi4_data->irq); if (synaptics_rmi4_bus_get(rmi4_data) < 0) { dev_err( rmi4_data->pdev->dev.parent, "synaptics_rmi4_bus_get failed\n"); err = -EIO; break; } INIT_COMPLETION(rmi4_data->st_powerdown); INIT_COMPLETION(rmi4_data->st_irq_processed); atomic_set(&rmi4_data->st_enabled, 1); atomic_set(&rmi4_data->st_pending_irqs, 0); break; default: dev_err( rmi4_data->pdev->dev.parent, "unsupported value: %lu\n", value); err = -EINVAL; break; } return err; } /* * This function returns whether there are pending interrupts, or * other error conditions that need to be signaled to the userspace library, * according tot he following logic: * - st_enabled is 0 if secure touch is not enabled, returning -EBADF * - st_pending_irqs is -1 to signal that secure touch is in being stopped, * returning -EINVAL * - st_pending_irqs is 1 to signal that there is a pending irq, returning * the value "1" to the sysfs read operation * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt * has been processed, so the interrupt handler can be allowed to continue. */ static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); int val = 0; if (atomic_read(&rmi4_data->st_enabled) == 0) return -EBADF; if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, -1, 0) == -1) return -EINVAL; if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 1, 0) == 1) val = 1; else complete(&rmi4_data->st_irq_processed); return scnprintf(buf, PAGE_SIZE, "%u", val); } #endif static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, struct device_attribute *attr, char *buf) { Loading Loading @@ -1122,6 +1316,9 @@ static irqreturn_t synaptics_rmi4_irq(int irq, void *data) { struct synaptics_rmi4_data *rmi4_data = data; if (IRQ_HANDLED == synaptics_filter_interrupt(data)) return IRQ_HANDLED; if (!rmi4_data->touch_stopped) synaptics_rmi4_sensor_report(rmi4_data); Loading Loading @@ -2963,6 +3160,9 @@ static int synaptics_rmi4_probe(struct platform_device *pdev) } } synaptics_secure_touch_init(rmi4_data); synaptics_secure_touch_stop(rmi4_data, 1); return retval; err_sysfs: Loading Loading @@ -3202,13 +3402,18 @@ static int fb_notifier_callback(struct notifier_block *self, struct synaptics_rmi4_data *rmi4_data = container_of(self, struct synaptics_rmi4_data, fb_notif); if (evdata && evdata->data && event == FB_EVENT_BLANK && rmi4_data) { if (evdata && evdata->data && rmi4_data) { if (event == FB_EARLY_EVENT_BLANK) synaptics_secure_touch_stop(rmi4_data, 0); else if (event == FB_EVENT_BLANK) { blank = evdata->data; if (*blank == FB_BLANK_UNBLANK) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); synaptics_rmi4_resume( &(rmi4_data->input_dev->dev)); else if (*blank == FB_BLANK_POWERDOWN) synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); synaptics_rmi4_suspend( &(rmi4_data->input_dev->dev)); } } return 0; Loading Loading @@ -3237,6 +3442,8 @@ static void synaptics_rmi4_early_suspend(struct early_suspend *h) rmi4_data->staying_awake = false; } synaptics_secure_touch_stop(rmi4_data, 0); rmi4_data->touch_stopped = true; synaptics_rmi4_irq_enable(rmi4_data, false); synaptics_rmi4_sensor_sleep(rmi4_data); Loading Loading @@ -3276,6 +3483,8 @@ static void synaptics_rmi4_late_resume(struct early_suspend *h) if (rmi4_data->staying_awake) return; synaptics_secure_touch_stop(rmi4_data, 0); if (rmi4_data->full_pm_cycle) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); Loading Loading @@ -3328,6 +3537,8 @@ static int synaptics_rmi4_suspend(struct device *dev) if (rmi4_data->suspended) return 0; synaptics_secure_touch_stop(rmi4_data, 1); if (!rmi4_data->sensor_sleep) { rmi4_data->touch_stopped = true; synaptics_rmi4_irq_enable(rmi4_data, false); Loading Loading @@ -3387,6 +3598,8 @@ static int synaptics_rmi4_resume(struct device *dev) if (!rmi4_data->suspended) return 0; synaptics_secure_touch_stop(rmi4_data, 1); synaptics_dsx_regulator_enable(rmi4_data, true); if (bdata->disable_gpios) { Loading drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h +26 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ * * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading Loading @@ -33,6 +34,10 @@ #elif defined(CONFIG_HAS_EARLYSUSPEND) #include <linux/earlysuspend.h> #endif #if defined(CONFIG_SECURE_TOUCH) #include <linux/completion.h> #include <linux/atomic.h> #endif #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) #define KERNEL_ABOVE_2_6_38 Loading Loading @@ -273,6 +278,12 @@ struct synaptics_rmi4_data { struct pinctrl_state *gpio_state_suspend; char fw_name[SYNA_FW_NAME_MAX_LEN]; bool suspended; #if defined(CONFIG_SECURE_TOUCH) atomic_t st_enabled; atomic_t st_pending_irqs; struct completion st_powerdown; struct completion st_irq_processed; #endif }; struct synaptics_dsx_bus_access { Loading @@ -281,6 +292,10 @@ struct synaptics_dsx_bus_access { unsigned char *data, unsigned short length); int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, unsigned char *data, unsigned short length); #if defined(CONFIG_SECURE_TOUCH) int (*get)(struct synaptics_rmi4_data *rmi4_data); void (*put)(struct synaptics_rmi4_data *rmi4_data); #endif }; struct synaptics_rmi4_exp_fn { Loading Loading @@ -324,6 +339,17 @@ static inline int synaptics_rmi4_reg_write( return rmi4_data->hw_if->bus_access->write(rmi4_data, addr, data, len); } #if defined(CONFIG_SECURE_TOUCH) static inline int synaptics_rmi4_bus_get(struct synaptics_rmi4_data *rmi4_data) { return rmi4_data->hw_if->bus_access->get(rmi4_data); } static inline void synaptics_rmi4_bus_put(struct synaptics_rmi4_data *rmi4_data) { rmi4_data->hw_if->bus_access->put(rmi4_data); } #endif static inline ssize_t synaptics_rmi4_show_error(struct device *dev, struct device_attribute *attr, char *buf) { Loading drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c +30 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ #include "synaptics_dsx_core.h" #include <linux/of_gpio.h> #include <linux/of_irq.h> #if defined(CONFIG_SECURE_TOUCH) #include <linux/pm_runtime.h> #endif #define SYN_I2C_RETRY_TIMES 10 #define RESET_DELAY 100 Loading Loading @@ -177,10 +180,37 @@ exit: return retval; } #if defined(CONFIG_SECURE_TOUCH) static int synaptics_rmi4_i2c_get(struct synaptics_rmi4_data *rmi4_data) { int retval; struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); retval = pm_runtime_get_sync(i2c->adapter->dev.parent); mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); return retval; } static void synaptics_rmi4_i2c_put(struct synaptics_rmi4_data *rmi4_data) { struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); pm_runtime_put_sync(i2c->adapter->dev.parent); mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); } #endif static struct synaptics_dsx_bus_access bus_access = { .type = BUS_I2C, .read = synaptics_rmi4_i2c_read, .write = synaptics_rmi4_i2c_write, #if defined(CONFIG_SECURE_TOUCH) .get = synaptics_rmi4_i2c_get, .put = synaptics_rmi4_i2c_put, #endif }; static struct synaptics_dsx_hw_interface hw_if; Loading drivers/input/touchscreen/synaptics_i2c_rmi4.c +212 −7 Original line number Diff line number Diff line Loading @@ -30,6 +30,13 @@ #include <linux/pinctrl/consumer.h> #include <linux/input/synaptics_dsx.h> #include <linux/of_gpio.h> #if defined(CONFIG_SECURE_TOUCH) #include <linux/pm_runtime.h> #include <linux/errno.h> #include <asm/system.h> #endif #include "synaptics_i2c_rmi4.h" #include <linux/input/mt.h> Loading Loading @@ -185,6 +192,19 @@ static int synaptics_rmi4_capacitance_button_map( struct synaptics_rmi4_data *rmi4_data, struct synaptics_rmi4_fn *fhandler); static irqreturn_t synaptics_rmi4_irq(int irq, void *data); #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf); #endif struct synaptics_rmi4_f01_device_status { union { struct { Loading Loading @@ -433,12 +453,178 @@ static struct device_attribute attrs[] = { __ATTR(flipy, (S_IRUGO | S_IWUSR | S_IWGRP), synaptics_rmi4_flipy_show, synaptics_rmi4_flipy_store), #if defined(CONFIG_SECURE_TOUCH) __ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO), synaptics_secure_touch_enable_show, synaptics_secure_touch_enable_store), __ATTR(secure_touch, S_IRUGO , synaptics_secure_touch_show, NULL), #endif }; static bool exp_fn_inited; static struct mutex exp_fn_list_mutex; static struct list_head exp_fn_list; #if defined(CONFIG_SECURE_TOUCH) static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { init_completion(&data->st_powerdown); init_completion(&data->st_irq_processed); } static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *data) { sysfs_notify(&data->i2c_client->dev.kobj, NULL, "secure_touch"); } static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data) { if (atomic_read(&data->st_enabled)) { if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0) { synaptics_secure_touch_notify(data); wait_for_completion_interruptible( &data->st_irq_processed); } return IRQ_HANDLED; } return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *data, int blocking) { if (atomic_read(&data->st_enabled)) { atomic_set(&data->st_pending_irqs, -1); synaptics_secure_touch_notify(data); if (blocking) wait_for_completion_interruptible(&data->st_powerdown); } } #else static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { } static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data) { return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *data, int blocking) { } #endif #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *data = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&data->st_enabled)); } /* * Accept only "0" and "1" valid values. * "0" will reset the st_enabled flag, then wake up the reading process and * the interrupt handler. * The bus driver is notified via pm_runtime that it is not required to stay * awake anymore. * It will also make sure the queue of events is emptied in the controller, * in case a touch happened in between the secure touch being disabled and * the local ISR being ungated. * "1" will set the st_enabled flag and clear the st_pending_irqs flag. * The bus driver is requested via pm_runtime to stay awake. */ static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct synaptics_rmi4_data *data = dev_get_drvdata(dev); unsigned long value; int err = 0; if (count > 2) return -EINVAL; err = kstrtoul(buf, 10, &value); if (err != 0) return err; err = count; switch (value) { case 0: if (atomic_read(&data->st_enabled) == 0) break; pm_runtime_put_sync(data->i2c_client->adapter->dev.parent); atomic_set(&data->st_enabled, 0); synaptics_secure_touch_notify(data); complete(&data->st_irq_processed); synaptics_rmi4_irq(data->irq, data); complete(&data->st_powerdown); break; case 1: if (atomic_read(&data->st_enabled)) { err = -EBUSY; break; } synchronize_irq(data->irq); if (pm_runtime_get_sync( data->i2c_client->adapter->dev.parent) < 0) { dev_err(&data->i2c_client->dev, "pm_runtime_get failed\n"); err = -EIO; break; } INIT_COMPLETION(data->st_powerdown); INIT_COMPLETION(data->st_irq_processed); atomic_set(&data->st_enabled, 1); atomic_set(&data->st_pending_irqs, 0); break; default: dev_err(&data->i2c_client->dev, "unsupported value: %lu\n", value); err = -EINVAL; break; } return err; } /* * This function returns whether there are pending interrupts, or * other error conditions that need to be signaled to the userspace library, * according tot he following logic: * - st_enabled is 0 if secure touch is not enabled, returning -EBADF * - st_pending_irqs is -1 to signal that secure touch is in being stopped, * returning -EINVAL * - st_pending_irqs is 1 to signal that there is a pending irq, returning * the value "1" to the sysfs read operation * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt * has been processed, so the interrupt handler can be allowed to continue. */ static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *data = dev_get_drvdata(dev); int val = 0; if (atomic_read(&data->st_enabled) == 0) return -EBADF; if (atomic_cmpxchg(&data->st_pending_irqs, -1, 0) == -1) return -EINVAL; if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) == 1) val = 1; else complete(&data->st_irq_processed); return scnprintf(buf, PAGE_SIZE, "%u", val); } #endif static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val) { struct synaptics_rmi4_data *rmi4_data = _data; Loading Loading @@ -1370,6 +1556,9 @@ static irqreturn_t synaptics_rmi4_irq(int irq, void *data) { struct synaptics_rmi4_data *rmi4_data = data; if (IRQ_HANDLED == synaptics_filter_interrupt(data)) return IRQ_HANDLED; synaptics_rmi4_sensor_report(rmi4_data); return IRQ_HANDLED; Loading Loading @@ -3426,6 +3615,9 @@ static int synaptics_rmi4_probe(struct i2c_client *client, goto err_sysfs; } synaptics_secure_touch_init(rmi4_data); synaptics_secure_touch_stop(rmi4_data, 1); retval = synaptics_rmi4_check_configuration(rmi4_data); if (retval < 0) { dev_err(&client->dev, "Failed to check configuration\n"); Loading Loading @@ -3663,13 +3855,18 @@ static int fb_notifier_callback(struct notifier_block *self, struct synaptics_rmi4_data *rmi4_data = container_of(self, struct synaptics_rmi4_data, fb_notif); if (evdata && evdata->data && event == FB_EVENT_BLANK && rmi4_data && rmi4_data->i2c_client) { if (evdata && evdata->data && rmi4_data && rmi4_data->i2c_client) { if (event == FB_EARLY_EVENT_BLANK) synaptics_secure_touch_stop(rmi4_data, 0); else if (event == FB_EVENT_BLANK) { blank = evdata->data; if (*blank == FB_BLANK_UNBLANK) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); synaptics_rmi4_resume( &(rmi4_data->input_dev->dev)); else if (*blank == FB_BLANK_POWERDOWN) synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); synaptics_rmi4_suspend( &(rmi4_data->input_dev->dev)); } } return 0; Loading @@ -3695,6 +3892,8 @@ static void synaptics_rmi4_early_suspend(struct early_suspend *h) else rmi4_data->staying_awake = false; synaptics_secure_touch_stop(rmi4_data, 0); rmi4_data->touch_stopped = true; wake_up(&rmi4_data->wait); synaptics_rmi4_irq_enable(rmi4_data, false); Loading Loading @@ -3724,6 +3923,8 @@ static void synaptics_rmi4_late_resume(struct early_suspend *h) if (rmi4_data->staying_awake) return; synaptics_secure_touch_stop(rmi4_data, 0); if (rmi4_data->full_pm_cycle) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); Loading Loading @@ -3925,6 +4126,8 @@ static int synaptics_rmi4_suspend(struct device *dev) return 0; } synaptics_secure_touch_stop(rmi4_data, 1); if (!rmi4_data->fw_updating) { if (!rmi4_data->sensor_sleep) { rmi4_data->touch_stopped = true; Loading Loading @@ -4005,6 +4208,8 @@ static int synaptics_rmi4_resume(struct device *dev) return 0; } synaptics_secure_touch_stop(rmi4_data, 1); retval = synaptics_rmi4_regulator_lpm(rmi4_data, false); if (retval < 0) { dev_err(dev, "Failed to enter active power mode\n"); Loading Loading
drivers/input/touchscreen/Kconfig +3 −3 Original line number Diff line number Diff line Loading @@ -992,10 +992,10 @@ config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE config SECURE_TOUCH bool "Secure Touch" depends on TOUCHSCREEN_ATMEL_MXT depends on (TOUCHSCREEN_ATMEL_MXT || TOUCHSCREEN_SYNAPTICS_I2C_RMI4 || \ TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21) help Say Y here to enable Secure Touch support in the Atmel MXT driver. Say Y here to enable Secure Touch in supported drivers. If unsure, say N. Loading
drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c +220 −7 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ * * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -31,6 +32,10 @@ #ifdef KERNEL_ABOVE_2_6_38 #include <linux/input/mt.h> #endif #if defined(CONFIG_SECURE_TOUCH) #include <linux/errno.h> #include <asm/system.h> #endif #define INPUT_PHYS_NAME "synaptics_dsx/input0" #define DEBUGFS_DIR_NAME "ts_debug" Loading Loading @@ -134,6 +139,19 @@ static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, static ssize_t synaptics_rmi4_suspend_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static irqreturn_t synaptics_rmi4_irq(int irq, void *data); #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf); #endif struct synaptics_rmi4_f01_device_status { union { struct { Loading Loading @@ -362,6 +380,14 @@ static struct device_attribute attrs[] = { __ATTR(suspend, S_IWUGO, synaptics_rmi4_show_error, synaptics_rmi4_suspend_store), #if defined(CONFIG_SECURE_TOUCH) __ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO), synaptics_secure_touch_enable_show, synaptics_secure_touch_enable_store), __ATTR(secure_touch, S_IRUGO , synaptics_secure_touch_show, NULL), #endif }; static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val) Loading @@ -388,6 +414,174 @@ static int synaptics_rmi4_debug_suspend_get(void *_data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, synaptics_rmi4_debug_suspend_get, synaptics_rmi4_debug_suspend_set, "%lld\n"); #if defined(CONFIG_SECURE_TOUCH) static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { init_completion(&data->st_powerdown); init_completion(&data->st_irq_processed); } static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *rmi4_data) { sysfs_notify(&rmi4_data->input_dev->dev.kobj, NULL, "secure_touch"); } static irqreturn_t synaptics_filter_interrupt( struct synaptics_rmi4_data *rmi4_data) { if (atomic_read(&rmi4_data->st_enabled)) { if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 0, 1) == 0) { synaptics_secure_touch_notify(rmi4_data); wait_for_completion_interruptible( &rmi4_data->st_irq_processed); } return IRQ_HANDLED; } return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *rmi4_data, int blocking) { if (atomic_read(&rmi4_data->st_enabled)) { atomic_set(&rmi4_data->st_pending_irqs, -1); synaptics_secure_touch_notify(rmi4_data); if (blocking) wait_for_completion_interruptible( &rmi4_data->st_powerdown); } } #else static void synaptics_secure_touch_init(struct synaptics_rmi4_data *rmi4_data) { } static irqreturn_t synaptics_filter_interrupt( struct synaptics_rmi4_data *rmi4_data) { return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *rmi4_data, int blocking) { } #endif #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); return scnprintf( buf, PAGE_SIZE, "%d", atomic_read(&rmi4_data->st_enabled)); } /* * Accept only "0" and "1" valid values. * "0" will reset the st_enabled flag, then wake up the reading process and * the interrupt handler. * The bus driver is notified via pm_runtime that it is not required to stay * awake anymore. * It will also make sure the queue of events is emptied in the controller, * in case a touch happened in between the secure touch being disabled and * the local ISR being ungated. * "1" will set the st_enabled flag and clear the st_pending_irqs flag. * The bus driver is requested via pm_runtime to stay awake. */ static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); unsigned long value; int err = 0; if (count > 2) return -EINVAL; err = kstrtoul(buf, 10, &value); if (err != 0) return err; err = count; switch (value) { case 0: if (atomic_read(&rmi4_data->st_enabled) == 0) break; synaptics_rmi4_bus_put(rmi4_data); atomic_set(&rmi4_data->st_enabled, 0); synaptics_secure_touch_notify(rmi4_data); complete(&rmi4_data->st_irq_processed); synaptics_rmi4_irq(rmi4_data->irq, rmi4_data); complete(&rmi4_data->st_powerdown); break; case 1: if (atomic_read(&rmi4_data->st_enabled)) { err = -EBUSY; break; } synchronize_irq(rmi4_data->irq); if (synaptics_rmi4_bus_get(rmi4_data) < 0) { dev_err( rmi4_data->pdev->dev.parent, "synaptics_rmi4_bus_get failed\n"); err = -EIO; break; } INIT_COMPLETION(rmi4_data->st_powerdown); INIT_COMPLETION(rmi4_data->st_irq_processed); atomic_set(&rmi4_data->st_enabled, 1); atomic_set(&rmi4_data->st_pending_irqs, 0); break; default: dev_err( rmi4_data->pdev->dev.parent, "unsupported value: %lu\n", value); err = -EINVAL; break; } return err; } /* * This function returns whether there are pending interrupts, or * other error conditions that need to be signaled to the userspace library, * according tot he following logic: * - st_enabled is 0 if secure touch is not enabled, returning -EBADF * - st_pending_irqs is -1 to signal that secure touch is in being stopped, * returning -EINVAL * - st_pending_irqs is 1 to signal that there is a pending irq, returning * the value "1" to the sysfs read operation * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt * has been processed, so the interrupt handler can be allowed to continue. */ static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); int val = 0; if (atomic_read(&rmi4_data->st_enabled) == 0) return -EBADF; if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, -1, 0) == -1) return -EINVAL; if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 1, 0) == 1) val = 1; else complete(&rmi4_data->st_irq_processed); return scnprintf(buf, PAGE_SIZE, "%u", val); } #endif static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, struct device_attribute *attr, char *buf) { Loading Loading @@ -1122,6 +1316,9 @@ static irqreturn_t synaptics_rmi4_irq(int irq, void *data) { struct synaptics_rmi4_data *rmi4_data = data; if (IRQ_HANDLED == synaptics_filter_interrupt(data)) return IRQ_HANDLED; if (!rmi4_data->touch_stopped) synaptics_rmi4_sensor_report(rmi4_data); Loading Loading @@ -2963,6 +3160,9 @@ static int synaptics_rmi4_probe(struct platform_device *pdev) } } synaptics_secure_touch_init(rmi4_data); synaptics_secure_touch_stop(rmi4_data, 1); return retval; err_sysfs: Loading Loading @@ -3202,13 +3402,18 @@ static int fb_notifier_callback(struct notifier_block *self, struct synaptics_rmi4_data *rmi4_data = container_of(self, struct synaptics_rmi4_data, fb_notif); if (evdata && evdata->data && event == FB_EVENT_BLANK && rmi4_data) { if (evdata && evdata->data && rmi4_data) { if (event == FB_EARLY_EVENT_BLANK) synaptics_secure_touch_stop(rmi4_data, 0); else if (event == FB_EVENT_BLANK) { blank = evdata->data; if (*blank == FB_BLANK_UNBLANK) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); synaptics_rmi4_resume( &(rmi4_data->input_dev->dev)); else if (*blank == FB_BLANK_POWERDOWN) synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); synaptics_rmi4_suspend( &(rmi4_data->input_dev->dev)); } } return 0; Loading Loading @@ -3237,6 +3442,8 @@ static void synaptics_rmi4_early_suspend(struct early_suspend *h) rmi4_data->staying_awake = false; } synaptics_secure_touch_stop(rmi4_data, 0); rmi4_data->touch_stopped = true; synaptics_rmi4_irq_enable(rmi4_data, false); synaptics_rmi4_sensor_sleep(rmi4_data); Loading Loading @@ -3276,6 +3483,8 @@ static void synaptics_rmi4_late_resume(struct early_suspend *h) if (rmi4_data->staying_awake) return; synaptics_secure_touch_stop(rmi4_data, 0); if (rmi4_data->full_pm_cycle) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); Loading Loading @@ -3328,6 +3537,8 @@ static int synaptics_rmi4_suspend(struct device *dev) if (rmi4_data->suspended) return 0; synaptics_secure_touch_stop(rmi4_data, 1); if (!rmi4_data->sensor_sleep) { rmi4_data->touch_stopped = true; synaptics_rmi4_irq_enable(rmi4_data, false); Loading Loading @@ -3387,6 +3598,8 @@ static int synaptics_rmi4_resume(struct device *dev) if (!rmi4_data->suspended) return 0; synaptics_secure_touch_stop(rmi4_data, 1); synaptics_dsx_regulator_enable(rmi4_data, true); if (bdata->disable_gpios) { Loading
drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h +26 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ * * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading Loading @@ -33,6 +34,10 @@ #elif defined(CONFIG_HAS_EARLYSUSPEND) #include <linux/earlysuspend.h> #endif #if defined(CONFIG_SECURE_TOUCH) #include <linux/completion.h> #include <linux/atomic.h> #endif #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) #define KERNEL_ABOVE_2_6_38 Loading Loading @@ -273,6 +278,12 @@ struct synaptics_rmi4_data { struct pinctrl_state *gpio_state_suspend; char fw_name[SYNA_FW_NAME_MAX_LEN]; bool suspended; #if defined(CONFIG_SECURE_TOUCH) atomic_t st_enabled; atomic_t st_pending_irqs; struct completion st_powerdown; struct completion st_irq_processed; #endif }; struct synaptics_dsx_bus_access { Loading @@ -281,6 +292,10 @@ struct synaptics_dsx_bus_access { unsigned char *data, unsigned short length); int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, unsigned char *data, unsigned short length); #if defined(CONFIG_SECURE_TOUCH) int (*get)(struct synaptics_rmi4_data *rmi4_data); void (*put)(struct synaptics_rmi4_data *rmi4_data); #endif }; struct synaptics_rmi4_exp_fn { Loading Loading @@ -324,6 +339,17 @@ static inline int synaptics_rmi4_reg_write( return rmi4_data->hw_if->bus_access->write(rmi4_data, addr, data, len); } #if defined(CONFIG_SECURE_TOUCH) static inline int synaptics_rmi4_bus_get(struct synaptics_rmi4_data *rmi4_data) { return rmi4_data->hw_if->bus_access->get(rmi4_data); } static inline void synaptics_rmi4_bus_put(struct synaptics_rmi4_data *rmi4_data) { rmi4_data->hw_if->bus_access->put(rmi4_data); } #endif static inline ssize_t synaptics_rmi4_show_error(struct device *dev, struct device_attribute *attr, char *buf) { Loading
drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c +30 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ #include "synaptics_dsx_core.h" #include <linux/of_gpio.h> #include <linux/of_irq.h> #if defined(CONFIG_SECURE_TOUCH) #include <linux/pm_runtime.h> #endif #define SYN_I2C_RETRY_TIMES 10 #define RESET_DELAY 100 Loading Loading @@ -177,10 +180,37 @@ exit: return retval; } #if defined(CONFIG_SECURE_TOUCH) static int synaptics_rmi4_i2c_get(struct synaptics_rmi4_data *rmi4_data) { int retval; struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); retval = pm_runtime_get_sync(i2c->adapter->dev.parent); mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); return retval; } static void synaptics_rmi4_i2c_put(struct synaptics_rmi4_data *rmi4_data) { struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); pm_runtime_put_sync(i2c->adapter->dev.parent); mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); } #endif static struct synaptics_dsx_bus_access bus_access = { .type = BUS_I2C, .read = synaptics_rmi4_i2c_read, .write = synaptics_rmi4_i2c_write, #if defined(CONFIG_SECURE_TOUCH) .get = synaptics_rmi4_i2c_get, .put = synaptics_rmi4_i2c_put, #endif }; static struct synaptics_dsx_hw_interface hw_if; Loading
drivers/input/touchscreen/synaptics_i2c_rmi4.c +212 −7 Original line number Diff line number Diff line Loading @@ -30,6 +30,13 @@ #include <linux/pinctrl/consumer.h> #include <linux/input/synaptics_dsx.h> #include <linux/of_gpio.h> #if defined(CONFIG_SECURE_TOUCH) #include <linux/pm_runtime.h> #include <linux/errno.h> #include <asm/system.h> #endif #include "synaptics_i2c_rmi4.h" #include <linux/input/mt.h> Loading Loading @@ -185,6 +192,19 @@ static int synaptics_rmi4_capacitance_button_map( struct synaptics_rmi4_data *rmi4_data, struct synaptics_rmi4_fn *fhandler); static irqreturn_t synaptics_rmi4_irq(int irq, void *data); #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf); #endif struct synaptics_rmi4_f01_device_status { union { struct { Loading Loading @@ -433,12 +453,178 @@ static struct device_attribute attrs[] = { __ATTR(flipy, (S_IRUGO | S_IWUSR | S_IWGRP), synaptics_rmi4_flipy_show, synaptics_rmi4_flipy_store), #if defined(CONFIG_SECURE_TOUCH) __ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO), synaptics_secure_touch_enable_show, synaptics_secure_touch_enable_store), __ATTR(secure_touch, S_IRUGO , synaptics_secure_touch_show, NULL), #endif }; static bool exp_fn_inited; static struct mutex exp_fn_list_mutex; static struct list_head exp_fn_list; #if defined(CONFIG_SECURE_TOUCH) static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { init_completion(&data->st_powerdown); init_completion(&data->st_irq_processed); } static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *data) { sysfs_notify(&data->i2c_client->dev.kobj, NULL, "secure_touch"); } static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data) { if (atomic_read(&data->st_enabled)) { if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0) { synaptics_secure_touch_notify(data); wait_for_completion_interruptible( &data->st_irq_processed); } return IRQ_HANDLED; } return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *data, int blocking) { if (atomic_read(&data->st_enabled)) { atomic_set(&data->st_pending_irqs, -1); synaptics_secure_touch_notify(data); if (blocking) wait_for_completion_interruptible(&data->st_powerdown); } } #else static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { } static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data) { return IRQ_NONE; } static void synaptics_secure_touch_stop( struct synaptics_rmi4_data *data, int blocking) { } #endif #if defined(CONFIG_SECURE_TOUCH) static ssize_t synaptics_secure_touch_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *data = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&data->st_enabled)); } /* * Accept only "0" and "1" valid values. * "0" will reset the st_enabled flag, then wake up the reading process and * the interrupt handler. * The bus driver is notified via pm_runtime that it is not required to stay * awake anymore. * It will also make sure the queue of events is emptied in the controller, * in case a touch happened in between the secure touch being disabled and * the local ISR being ungated. * "1" will set the st_enabled flag and clear the st_pending_irqs flag. * The bus driver is requested via pm_runtime to stay awake. */ static ssize_t synaptics_secure_touch_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct synaptics_rmi4_data *data = dev_get_drvdata(dev); unsigned long value; int err = 0; if (count > 2) return -EINVAL; err = kstrtoul(buf, 10, &value); if (err != 0) return err; err = count; switch (value) { case 0: if (atomic_read(&data->st_enabled) == 0) break; pm_runtime_put_sync(data->i2c_client->adapter->dev.parent); atomic_set(&data->st_enabled, 0); synaptics_secure_touch_notify(data); complete(&data->st_irq_processed); synaptics_rmi4_irq(data->irq, data); complete(&data->st_powerdown); break; case 1: if (atomic_read(&data->st_enabled)) { err = -EBUSY; break; } synchronize_irq(data->irq); if (pm_runtime_get_sync( data->i2c_client->adapter->dev.parent) < 0) { dev_err(&data->i2c_client->dev, "pm_runtime_get failed\n"); err = -EIO; break; } INIT_COMPLETION(data->st_powerdown); INIT_COMPLETION(data->st_irq_processed); atomic_set(&data->st_enabled, 1); atomic_set(&data->st_pending_irqs, 0); break; default: dev_err(&data->i2c_client->dev, "unsupported value: %lu\n", value); err = -EINVAL; break; } return err; } /* * This function returns whether there are pending interrupts, or * other error conditions that need to be signaled to the userspace library, * according tot he following logic: * - st_enabled is 0 if secure touch is not enabled, returning -EBADF * - st_pending_irqs is -1 to signal that secure touch is in being stopped, * returning -EINVAL * - st_pending_irqs is 1 to signal that there is a pending irq, returning * the value "1" to the sysfs read operation * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt * has been processed, so the interrupt handler can be allowed to continue. */ static ssize_t synaptics_secure_touch_show(struct device *dev, struct device_attribute *attr, char *buf) { struct synaptics_rmi4_data *data = dev_get_drvdata(dev); int val = 0; if (atomic_read(&data->st_enabled) == 0) return -EBADF; if (atomic_cmpxchg(&data->st_pending_irqs, -1, 0) == -1) return -EINVAL; if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) == 1) val = 1; else complete(&data->st_irq_processed); return scnprintf(buf, PAGE_SIZE, "%u", val); } #endif static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val) { struct synaptics_rmi4_data *rmi4_data = _data; Loading Loading @@ -1370,6 +1556,9 @@ static irqreturn_t synaptics_rmi4_irq(int irq, void *data) { struct synaptics_rmi4_data *rmi4_data = data; if (IRQ_HANDLED == synaptics_filter_interrupt(data)) return IRQ_HANDLED; synaptics_rmi4_sensor_report(rmi4_data); return IRQ_HANDLED; Loading Loading @@ -3426,6 +3615,9 @@ static int synaptics_rmi4_probe(struct i2c_client *client, goto err_sysfs; } synaptics_secure_touch_init(rmi4_data); synaptics_secure_touch_stop(rmi4_data, 1); retval = synaptics_rmi4_check_configuration(rmi4_data); if (retval < 0) { dev_err(&client->dev, "Failed to check configuration\n"); Loading Loading @@ -3663,13 +3855,18 @@ static int fb_notifier_callback(struct notifier_block *self, struct synaptics_rmi4_data *rmi4_data = container_of(self, struct synaptics_rmi4_data, fb_notif); if (evdata && evdata->data && event == FB_EVENT_BLANK && rmi4_data && rmi4_data->i2c_client) { if (evdata && evdata->data && rmi4_data && rmi4_data->i2c_client) { if (event == FB_EARLY_EVENT_BLANK) synaptics_secure_touch_stop(rmi4_data, 0); else if (event == FB_EVENT_BLANK) { blank = evdata->data; if (*blank == FB_BLANK_UNBLANK) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); synaptics_rmi4_resume( &(rmi4_data->input_dev->dev)); else if (*blank == FB_BLANK_POWERDOWN) synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); synaptics_rmi4_suspend( &(rmi4_data->input_dev->dev)); } } return 0; Loading @@ -3695,6 +3892,8 @@ static void synaptics_rmi4_early_suspend(struct early_suspend *h) else rmi4_data->staying_awake = false; synaptics_secure_touch_stop(rmi4_data, 0); rmi4_data->touch_stopped = true; wake_up(&rmi4_data->wait); synaptics_rmi4_irq_enable(rmi4_data, false); Loading Loading @@ -3724,6 +3923,8 @@ static void synaptics_rmi4_late_resume(struct early_suspend *h) if (rmi4_data->staying_awake) return; synaptics_secure_touch_stop(rmi4_data, 0); if (rmi4_data->full_pm_cycle) synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); Loading Loading @@ -3925,6 +4126,8 @@ static int synaptics_rmi4_suspend(struct device *dev) return 0; } synaptics_secure_touch_stop(rmi4_data, 1); if (!rmi4_data->fw_updating) { if (!rmi4_data->sensor_sleep) { rmi4_data->touch_stopped = true; Loading Loading @@ -4005,6 +4208,8 @@ static int synaptics_rmi4_resume(struct device *dev) return 0; } synaptics_secure_touch_stop(rmi4_data, 1); retval = synaptics_rmi4_regulator_lpm(rmi4_data, false); if (retval < 0) { dev_err(dev, "Failed to enter active power mode\n"); Loading