diff options
Diffstat (limited to 'drivers/input/mouse')
27 files changed, 425 insertions, 425 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index e2c11d9f3868..0bd7b09b0aa3 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1396,24 +1396,16 @@ static bool alps_is_valid_package_ss4_v2(struct psmouse *psmouse) static DEFINE_MUTEX(alps_mutex); -static void alps_register_bare_ps2_mouse(struct work_struct *work) +static int alps_do_register_bare_ps2_mouse(struct alps_data *priv) { - struct alps_data *priv = - container_of(work, struct alps_data, dev3_register_work.work); struct psmouse *psmouse = priv->psmouse; struct input_dev *dev3; - int error = 0; - - mutex_lock(&alps_mutex); - - if (priv->dev3) - goto out; + int error; dev3 = input_allocate_device(); if (!dev3) { psmouse_err(psmouse, "failed to allocate secondary device\n"); - error = -ENOMEM; - goto out; + return -ENOMEM; } snprintf(priv->phys3, sizeof(priv->phys3), "%s/%s", @@ -1446,21 +1438,35 @@ static void alps_register_bare_ps2_mouse(struct work_struct *work) psmouse_err(psmouse, "failed to register secondary device: %d\n", error); - input_free_device(dev3); - goto out; + goto err_free_input; } priv->dev3 = dev3; + return 0; -out: - /* - * Save the error code so that we can detect that we - * already tried to create the device. - */ - if (error) - priv->dev3 = ERR_PTR(error); +err_free_input: + input_free_device(dev3); + return error; +} - mutex_unlock(&alps_mutex); +static void alps_register_bare_ps2_mouse(struct work_struct *work) +{ + struct alps_data *priv = container_of(work, struct alps_data, + dev3_register_work.work); + int error; + + guard(mutex)(&alps_mutex); + + if (!priv->dev3) { + error = alps_do_register_bare_ps2_mouse(priv); + if (error) { + /* + * Save the error code so that we can detect that we + * already tried to create the device. + */ + priv->dev3 = ERR_PTR(error); + } + } } static void alps_report_bare_ps2_packet(struct psmouse *psmouse, @@ -1513,7 +1519,7 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) return PSMOUSE_GOOD_DATA; } - del_timer(&priv->timer); + timer_delete(&priv->timer); if (psmouse->packet[6] & 0x80) { @@ -1579,7 +1585,7 @@ static void alps_flush_packet(struct timer_list *t) struct alps_data *priv = from_timer(priv, t, timer); struct psmouse *psmouse = priv->psmouse; - serio_pause_rx(psmouse->ps2dev.serio); + guard(serio_pause_rx)(psmouse->ps2dev.serio); if (psmouse->pktcnt == psmouse->pktsize) { @@ -1599,8 +1605,6 @@ static void alps_flush_packet(struct timer_list *t) } psmouse->pktcnt = 0; } - - serio_continue_rx(psmouse->ps2dev.serio); } static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) @@ -3201,7 +3205,7 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) */ psmouse_reset(psmouse); - priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index cda0c3ff5a28..d203c2a6c438 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -132,8 +132,14 @@ static void __exit amimouse_remove(struct platform_device *pdev) input_unregister_device(dev); } -static struct platform_driver amimouse_driver = { - .remove_new = __exit_p(amimouse_remove), +/* + * amimouse_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this is ok because they cannot get unbound at + * runtime. So mark the driver struct with __refdata to prevent modpost + * triggering a section mismatch warning. + */ +static struct platform_driver amimouse_driver __refdata = { + .remove = __exit_p(amimouse_remove), .driver = { .name = "amiga-mouse", }, diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 627048bc6a12..e669f86f1882 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -855,7 +855,7 @@ static int atp_probe(struct usb_interface *iface, } /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(struct atp), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); input_dev = input_allocate_device(); if (!dev || !input_dev) { dev_err(&iface->dev, "Out of memory\n"); diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index ca150618d32f..dfdfb59cc8b5 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -834,13 +834,11 @@ static int bcm5974_open(struct input_dev *input) if (error) return error; - mutex_lock(&dev->pm_mutex); - - error = bcm5974_start_traffic(dev); - if (!error) - dev->opened = 1; - - mutex_unlock(&dev->pm_mutex); + scoped_guard(mutex, &dev->pm_mutex) { + error = bcm5974_start_traffic(dev); + if (!error) + dev->opened = 1; + } if (error) usb_autopm_put_interface(dev->intf); @@ -852,12 +850,10 @@ static void bcm5974_close(struct input_dev *input) { struct bcm5974 *dev = input_get_drvdata(input); - mutex_lock(&dev->pm_mutex); - - bcm5974_pause_traffic(dev); - dev->opened = 0; - - mutex_unlock(&dev->pm_mutex); + scoped_guard(mutex, &dev->pm_mutex) { + bcm5974_pause_traffic(dev); + dev->opened = 0; + } usb_autopm_put_interface(dev->intf); } @@ -866,29 +862,24 @@ static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message) { struct bcm5974 *dev = usb_get_intfdata(iface); - mutex_lock(&dev->pm_mutex); + guard(mutex)(&dev->pm_mutex); if (dev->opened) bcm5974_pause_traffic(dev); - mutex_unlock(&dev->pm_mutex); - return 0; } static int bcm5974_resume(struct usb_interface *iface) { struct bcm5974 *dev = usb_get_intfdata(iface); - int error = 0; - mutex_lock(&dev->pm_mutex); + guard(mutex)(&dev->pm_mutex); if (dev->opened) - error = bcm5974_start_traffic(dev); + return bcm5974_start_traffic(dev); - mutex_unlock(&dev->pm_mutex); - - return error; + return 0; } static int bcm5974_probe(struct usb_interface *iface, @@ -904,7 +895,7 @@ static int bcm5974_probe(struct usb_interface *iface, cfg = bcm5974_get_config(udev); /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); input_dev = input_allocate_device(); if (!dev || !input_dev) { dev_err(&iface->dev, "out of memory\n"); diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c index 221a553f45cd..4ee084e00a7c 100644 --- a/drivers/input/mouse/byd.c +++ b/drivers/input/mouse/byd.c @@ -254,13 +254,12 @@ static void byd_clear_touch(struct timer_list *t) struct byd_data *priv = from_timer(priv, t, timer); struct psmouse *psmouse = priv->psmouse; - serio_pause_rx(psmouse->ps2dev.serio); + guard(serio_pause_rx)(psmouse->ps2dev.serio); + priv->touch = false; byd_report_input(psmouse); - serio_continue_rx(psmouse->ps2dev.serio); - /* * Move cursor back to center of pad when we lose touch - this * specifically improves user experience when moving cursor with one @@ -426,7 +425,7 @@ static void byd_disconnect(struct psmouse *psmouse) struct byd_data *priv = psmouse->private; if (priv) { - del_timer(&priv->timer); + timer_delete(&priv->timer); kfree(psmouse->private); psmouse->private = NULL; } diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index 5979deabe23d..00c87c0532a6 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -1080,8 +1080,8 @@ static ssize_t cyapa_update_fw_store(struct device *dev, char fw_name[NAME_MAX]; int ret, error; - if (count >= NAME_MAX) { - dev_err(dev, "File name too long\n"); + if (!count || count >= NAME_MAX) { + dev_err(dev, "Bad file name size\n"); return -EINVAL; } @@ -1347,10 +1347,16 @@ static int cyapa_suspend(struct device *dev) u8 power_mode; int error; - error = mutex_lock_interruptible(&cyapa->state_sync_lock); + error = mutex_lock_interruptible(&cyapa->input->mutex); if (error) return error; + error = mutex_lock_interruptible(&cyapa->state_sync_lock); + if (error) { + mutex_unlock(&cyapa->input->mutex); + return error; + } + /* * Runtime PM is enable only when device is in operational mode and * users in use, so need check it before disable it to @@ -1385,6 +1391,8 @@ static int cyapa_suspend(struct device *dev) cyapa->irq_wake = (enable_irq_wake(client->irq) == 0); mutex_unlock(&cyapa->state_sync_lock); + mutex_unlock(&cyapa->input->mutex); + return 0; } @@ -1394,6 +1402,7 @@ static int cyapa_resume(struct device *dev) struct cyapa *cyapa = i2c_get_clientdata(client); int error; + mutex_lock(&cyapa->input->mutex); mutex_lock(&cyapa->state_sync_lock); if (device_may_wakeup(dev) && cyapa->irq_wake) { @@ -1412,6 +1421,7 @@ static int cyapa_resume(struct device *dev) enable_irq(client->irq); mutex_unlock(&cyapa->state_sync_lock); + mutex_unlock(&cyapa->input->mutex); return 0; } @@ -1449,8 +1459,8 @@ static const struct dev_pm_ops cyapa_pm_ops = { }; static const struct i2c_device_id cyapa_id_table[] = { - { "cyapa", 0 }, - { }, + { "cyapa" }, + { } }; MODULE_DEVICE_TABLE(i2c, cyapa_id_table); diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c index 60c83bc71d84..fc3fb954523b 100644 --- a/drivers/input/mouse/cyapa_gen3.c +++ b/drivers/input/mouse/cyapa_gen3.c @@ -20,7 +20,7 @@ #include <linux/input/mt.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cyapa.h" diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c index 2e6bcb07257e..3b4439f10635 100644 --- a/drivers/input/mouse/cyapa_gen5.c +++ b/drivers/input/mouse/cyapa_gen5.c @@ -17,7 +17,7 @@ #include <linux/mutex.h> #include <linux/completion.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-itu-t.h> #include <linux/pm_runtime.h> #include "cyapa.h" diff --git a/drivers/input/mouse/cyapa_gen6.c b/drivers/input/mouse/cyapa_gen6.c index 4ffe08fee10c..570c06dcef78 100644 --- a/drivers/input/mouse/cyapa_gen6.c +++ b/drivers/input/mouse/cyapa_gen6.c @@ -17,7 +17,7 @@ #include <linux/mutex.h> #include <linux/completion.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-itu-t.h> #include "cyapa.h" diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index d272f1ec27ba..9446657a5f35 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -32,33 +32,30 @@ static void cypress_set_packet_size(struct psmouse *psmouse, unsigned int n) cytp->pkt_size = n; } -static const unsigned char cytp_rate[] = {10, 20, 40, 60, 100, 200}; -static const unsigned char cytp_resolution[] = {0x00, 0x01, 0x02, 0x03}; +static const u8 cytp_rate[] = {10, 20, 40, 60, 100, 200}; +static const u8 cytp_resolution[] = {0x00, 0x01, 0x02, 0x03}; -static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value) +static int cypress_ps2_sendbyte(struct psmouse *psmouse, u8 cmd) { struct ps2dev *ps2dev = &psmouse->ps2dev; + int error; - if (ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT) < 0) { + error = ps2_sendbyte(ps2dev, cmd, CYTP_CMD_TIMEOUT); + if (error) { psmouse_dbg(psmouse, - "sending command 0x%02x failed, resp 0x%02x\n", - value & 0xff, ps2dev->nak); - if (ps2dev->nak == CYTP_PS2_RETRY) - return CYTP_PS2_RETRY; - else - return CYTP_PS2_ERROR; + "sending command 0x%02x failed, resp 0x%02x, error %d\n", + cmd, ps2dev->nak, error); + return error; } #ifdef CYTP_DEBUG_VERBOSE - psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n", - value & 0xff); + psmouse_dbg(psmouse, "sending command 0x%02x succeeded\n", cmd); #endif return 0; } -static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, - unsigned char data) +static int cypress_ps2_ext_cmd(struct psmouse *psmouse, u8 prefix, u8 nibble) { struct ps2dev *ps2dev = &psmouse->ps2dev; int tries = CYTP_PS2_CMD_TRIES; @@ -72,71 +69,29 @@ static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, * If sending the command fails, send recovery command * to make the device return to the ready state. */ - rc = cypress_ps2_sendbyte(psmouse, cmd & 0xff); - if (rc == CYTP_PS2_RETRY) { + rc = cypress_ps2_sendbyte(psmouse, prefix); + if (rc == -EAGAIN) { rc = cypress_ps2_sendbyte(psmouse, 0x00); - if (rc == CYTP_PS2_RETRY) + if (rc == -EAGAIN) rc = cypress_ps2_sendbyte(psmouse, 0x0a); } - if (rc == CYTP_PS2_ERROR) - continue; - - rc = cypress_ps2_sendbyte(psmouse, data); - if (rc == CYTP_PS2_RETRY) - rc = cypress_ps2_sendbyte(psmouse, data); - if (rc == CYTP_PS2_ERROR) - continue; - else - break; - } while (--tries > 0); - - ps2_end_command(ps2dev); - - return rc; -} - -static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, - unsigned char cmd, - unsigned char *param) -{ - int rc; - struct ps2dev *ps2dev = &psmouse->ps2dev; - enum psmouse_state old_state; - int pktsize; - - ps2_begin_command(ps2dev); - old_state = psmouse->state; - psmouse->state = PSMOUSE_CMD_MODE; - psmouse->pktcnt = 0; + if (!rc) { + rc = cypress_ps2_sendbyte(psmouse, nibble); + if (rc == -EAGAIN) + rc = cypress_ps2_sendbyte(psmouse, nibble); - pktsize = (cmd == CYTP_CMD_READ_TP_METRICS) ? 8 : 3; - memset(param, 0, pktsize); - - rc = cypress_ps2_sendbyte(psmouse, 0xe9); - if (rc < 0) - goto out; - - wait_event_timeout(ps2dev->wait, - (psmouse->pktcnt >= pktsize), - msecs_to_jiffies(CYTP_CMD_TIMEOUT)); - - memcpy(param, psmouse->packet, pktsize); - - psmouse_dbg(psmouse, "Command 0x%02x response data (0x): %*ph\n", - cmd, pktsize, param); - -out: - psmouse->state = old_state; - psmouse->pktcnt = 0; + if (!rc) + break; + } + } while (--tries > 0); ps2_end_command(ps2dev); return rc; } -static bool cypress_verify_cmd_state(struct psmouse *psmouse, - unsigned char cmd, unsigned char *param) +static bool cypress_verify_cmd_state(struct psmouse *psmouse, u8 cmd, u8* param) { bool rate_match = false; bool resolution_match = false; @@ -166,33 +121,36 @@ static bool cypress_verify_cmd_state(struct psmouse *psmouse, return false; } -static int cypress_send_ext_cmd(struct psmouse *psmouse, unsigned char cmd, - unsigned char *param) +static int cypress_send_ext_cmd(struct psmouse *psmouse, u8 cmd, u8 *param) { + u8 cmd_prefix = PSMOUSE_CMD_SETRES & 0xff; + unsigned int resp_size = cmd == CYTP_CMD_READ_TP_METRICS ? 8 : 3; + unsigned int ps2_cmd = (PSMOUSE_CMD_GETINFO & 0xff) | (resp_size << 8); int tries = CYTP_PS2_CMD_TRIES; - int rc; + int error; psmouse_dbg(psmouse, "send extension cmd 0x%02x, [%d %d %d %d]\n", cmd, DECODE_CMD_AA(cmd), DECODE_CMD_BB(cmd), DECODE_CMD_CC(cmd), DECODE_CMD_DD(cmd)); do { - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_DD(cmd)); - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_CC(cmd)); - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_BB(cmd)); - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_AA(cmd)); - - rc = cypress_ps2_read_cmd_status(psmouse, cmd, param); - if (rc) - continue; - - if (cypress_verify_cmd_state(psmouse, cmd, param)) - return 0; - + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_DD(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_CC(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_BB(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_AA(cmd)); + + error = ps2_command(&psmouse->ps2dev, param, ps2_cmd); + if (error) { + psmouse_dbg(psmouse, "Command 0x%02x failed: %d\n", + cmd, error); + } else { + psmouse_dbg(psmouse, + "Command 0x%02x response data (0x): %*ph\n", + cmd, resp_size, param); + + if (cypress_verify_cmd_state(psmouse, cmd, param)) + return 0; + } } while (--tries > 0); return -EIO; @@ -200,7 +158,7 @@ static int cypress_send_ext_cmd(struct psmouse *psmouse, unsigned char cmd, int cypress_detect(struct psmouse *psmouse, bool set_properties) { - unsigned char param[3]; + u8 param[3]; if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param)) return -ENODEV; @@ -220,7 +178,7 @@ int cypress_detect(struct psmouse *psmouse, bool set_properties) static int cypress_read_fw_version(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; - unsigned char param[3]; + u8 param[3]; if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param)) return -ENODEV; @@ -249,7 +207,7 @@ static int cypress_read_fw_version(struct psmouse *psmouse) static int cypress_read_tp_metrics(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; - unsigned char param[8]; + u8 param[8]; /* set default values for tp metrics. */ cytp->tp_width = CYTP_DEFAULT_WIDTH; @@ -321,15 +279,15 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse) static int cypress_query_hardware(struct psmouse *psmouse) { - int ret; + int error; - ret = cypress_read_fw_version(psmouse); - if (ret) - return ret; + error = cypress_read_fw_version(psmouse); + if (error) + return error; - ret = cypress_read_tp_metrics(psmouse); - if (ret) - return ret; + error = cypress_read_tp_metrics(psmouse); + if (error) + return error; return 0; } @@ -337,10 +295,13 @@ static int cypress_query_hardware(struct psmouse *psmouse) static int cypress_set_absolute_mode(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; - unsigned char param[3]; + u8 param[3]; + int error; - if (cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE, param) < 0) - return -1; + error = cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE, + param); + if (error) + return error; cytp->mode = (cytp->mode & ~CYTP_BIT_ABS_REL_MASK) | CYTP_BIT_ABS_PRESSURE; @@ -365,7 +326,7 @@ static void cypress_reset(struct psmouse *psmouse) static int cypress_set_input_params(struct input_dev *input, struct cytp_data *cytp) { - int ret; + int error; if (!cytp->tp_res_x || !cytp->tp_res_y) return -EINVAL; @@ -382,10 +343,10 @@ static int cypress_set_input_params(struct input_dev *input, input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cytp->tp_max_abs_y, 0, 0); input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0); - ret = input_mt_init_slots(input, CYTP_MAX_MT_SLOTS, - INPUT_MT_DROP_UNUSED|INPUT_MT_TRACK); - if (ret < 0) - return ret; + error = input_mt_init_slots(input, CYTP_MAX_MT_SLOTS, + INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); + if (error) + return error; __set_bit(INPUT_PROP_SEMI_MT, input->propbit); @@ -414,9 +375,9 @@ static int cypress_set_input_params(struct input_dev *input, return 0; } -static int cypress_get_finger_count(unsigned char header_byte) +static int cypress_get_finger_count(u8 header_byte) { - unsigned char bits6_7; + u8 bits6_7; int finger_count; bits6_7 = header_byte >> 6; @@ -441,10 +402,11 @@ static int cypress_get_finger_count(unsigned char header_byte) static int cypress_parse_packet(struct psmouse *psmouse, - struct cytp_data *cytp, struct cytp_report_data *report_data) + struct cytp_data *cytp, + struct cytp_report_data *report_data) { - unsigned char *packet = psmouse->packet; - unsigned char header_byte = packet[0]; + u8 *packet = psmouse->packet; + u8 header_byte = packet[0]; memset(report_data, 0, sizeof(struct cytp_report_data)); @@ -559,7 +521,7 @@ static psmouse_ret_t cypress_validate_byte(struct psmouse *psmouse) { int contact_cnt; int index = psmouse->pktcnt - 1; - unsigned char *packet = psmouse->packet; + u8 *packet = psmouse->packet; struct cytp_data *cytp = psmouse->private; if (index < 0 || index > cytp->pkt_size) @@ -612,6 +574,7 @@ static psmouse_ret_t cypress_protocol_handler(struct psmouse *psmouse) static void cypress_set_rate(struct psmouse *psmouse, unsigned int rate) { struct cytp_data *cytp = psmouse->private; + u8 rate_param; if (rate >= 80) { psmouse->rate = 80; @@ -621,8 +584,8 @@ static void cypress_set_rate(struct psmouse *psmouse, unsigned int rate) cytp->mode &= ~CYTP_BIT_HIGH_RATE; } - ps2_command(&psmouse->ps2dev, (unsigned char *)&psmouse->rate, - PSMOUSE_CMD_SETRATE); + rate_param = (u8)rate; + ps2_command(&psmouse->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE); } static void cypress_disconnect(struct psmouse *psmouse) @@ -635,21 +598,22 @@ static void cypress_disconnect(struct psmouse *psmouse) static int cypress_reconnect(struct psmouse *psmouse) { int tries = CYTP_PS2_CMD_TRIES; - int rc; + int error; do { cypress_reset(psmouse); - rc = cypress_detect(psmouse, false); - } while (rc && (--tries > 0)); + error = cypress_detect(psmouse, false); + } while (error && (--tries > 0)); - if (rc) { + if (error) { psmouse_err(psmouse, "Reconnect: unable to detect trackpad.\n"); - return -1; + return error; } - if (cypress_set_absolute_mode(psmouse)) { + error = cypress_set_absolute_mode(psmouse); + if (error) { psmouse_err(psmouse, "Reconnect: Unable to initialize Cypress absolute mode.\n"); - return -1; + return error; } return 0; @@ -658,8 +622,9 @@ static int cypress_reconnect(struct psmouse *psmouse) int cypress_init(struct psmouse *psmouse) { struct cytp_data *cytp; + int error; - cytp = kzalloc(sizeof(struct cytp_data), GFP_KERNEL); + cytp = kzalloc(sizeof(*cytp), GFP_KERNEL); if (!cytp) return -ENOMEM; @@ -668,17 +633,20 @@ int cypress_init(struct psmouse *psmouse) cypress_reset(psmouse); - if (cypress_query_hardware(psmouse)) { + error = cypress_query_hardware(psmouse); + if (error) { psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); goto err_exit; } - if (cypress_set_absolute_mode(psmouse)) { + error = cypress_set_absolute_mode(psmouse); + if (error) { psmouse_err(psmouse, "init: Unable to initialize Cypress absolute mode.\n"); goto err_exit; } - if (cypress_set_input_params(psmouse->dev, cytp) < 0) { + error = cypress_set_input_params(psmouse->dev, cytp); + if (error) { psmouse_err(psmouse, "init: Unable to set input params.\n"); goto err_exit; } @@ -703,5 +671,5 @@ err_exit: psmouse->private = NULL; kfree(cytp); - return -1; + return error; } diff --git a/drivers/input/mouse/cypress_ps2.h b/drivers/input/mouse/cypress_ps2.h index bb4979d06bf9..47d538a49089 100644 --- a/drivers/input/mouse/cypress_ps2.h +++ b/drivers/input/mouse/cypress_ps2.h @@ -72,12 +72,6 @@ #define CYTP_DATA_TIMEOUT 30 #define CYTP_EXT_CMD 0xe8 -#define CYTP_PS2_RETRY 0xfe -#define CYTP_PS2_ERROR 0xfc - -#define CYTP_RESP_RETRY 0x01 -#define CYTP_RESP_ERROR 0xfe - #define CYTP_105001_WIDTH 97 /* Dell XPS 13 */ #define CYTP_105001_HIGH 59 diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 8a72c200ccb5..fee1796da3d0 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -28,6 +28,7 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/string_choices.h> #include <linux/input.h> #include <linux/uaccess.h> #include <linux/jiffies.h> @@ -36,7 +37,7 @@ #include <linux/pm_wakeirq.h> #include <linux/property.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "elan_i2c.h" @@ -199,7 +200,7 @@ static int elan_set_power(struct elan_tp_data *data, bool on) } while (--repeat > 0); dev_err(&data->client->dev, "failed to set power %s: %d\n", - on ? "on" : "off", error); + str_on_off(on), error); return error; } @@ -541,7 +542,8 @@ static int elan_update_firmware(struct elan_tp_data *data, dev_dbg(&client->dev, "Starting firmware update....\n"); - disable_irq(client->irq); + guard(disable_irq)(&client->irq); + data->in_fw_update = true; retval = __elan_update_firmware(data, fw); @@ -555,7 +557,6 @@ static int elan_update_firmware(struct elan_tp_data *data, } data->in_fw_update = false; - enable_irq(client->irq); return retval; } @@ -621,8 +622,6 @@ static ssize_t elan_sysfs_update_fw(struct device *dev, const char *buf, size_t count) { struct elan_tp_data *data = dev_get_drvdata(dev); - const struct firmware *fw; - char *fw_name; int error; const u8 *fw_signature; static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF}; @@ -631,15 +630,16 @@ static ssize_t elan_sysfs_update_fw(struct device *dev, return -EINVAL; /* Look for a firmware with the product id appended. */ - fw_name = kasprintf(GFP_KERNEL, ETP_FW_NAME, data->product_id); + const char *fw_name __free(kfree) = + kasprintf(GFP_KERNEL, ETP_FW_NAME, data->product_id); if (!fw_name) { dev_err(dev, "failed to allocate memory for firmware name\n"); return -ENOMEM; } dev_info(dev, "requesting fw '%s'\n", fw_name); + const struct firmware *fw __free(firmware) = NULL; error = request_firmware(&fw, fw_name, dev); - kfree(fw_name); if (error) { dev_err(dev, "failed to request firmware: %d\n", error); return error; @@ -651,46 +651,36 @@ static ssize_t elan_sysfs_update_fw(struct device *dev, dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n", (int)sizeof(signature), signature, (int)sizeof(signature), fw_signature); - error = -EBADF; - goto out_release_fw; + return -EBADF; } - error = mutex_lock_interruptible(&data->sysfs_mutex); - if (error) - goto out_release_fw; - - error = elan_update_firmware(data, fw); - - mutex_unlock(&data->sysfs_mutex); + scoped_cond_guard(mutex_intr, return -EINTR, &data->sysfs_mutex) { + error = elan_update_firmware(data, fw); + if (error) + return error; + } -out_release_fw: - release_firmware(fw); - return error ?: count; + return count; } -static ssize_t calibrate_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static int elan_calibrate(struct elan_tp_data *data) { - struct i2c_client *client = to_i2c_client(dev); - struct elan_tp_data *data = i2c_get_clientdata(client); + struct i2c_client *client = data->client; + struct device *dev = &client->dev; int tries = 20; int retval; int error; u8 val[ETP_CALIBRATE_MAX_LEN]; - retval = mutex_lock_interruptible(&data->sysfs_mutex); - if (retval) - return retval; - - disable_irq(client->irq); + guard(disable_irq)(&client->irq); data->mode |= ETP_ENABLE_CALIBRATE; retval = data->ops->set_mode(client, data->mode); if (retval) { + data->mode &= ~ETP_ENABLE_CALIBRATE; dev_err(dev, "failed to enable calibration mode: %d\n", retval); - goto out; + return retval; } retval = data->ops->calibrate(client); @@ -728,10 +718,24 @@ out_disable_calibrate: if (!retval) retval = error; } -out: - enable_irq(client->irq); - mutex_unlock(&data->sysfs_mutex); - return retval ?: count; + return retval; +} + +static ssize_t calibrate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + + scoped_cond_guard(mutex_intr, return -EINTR, &data->sysfs_mutex) { + error = elan_calibrate(data); + if (error) + return error; + } + + return count; } static ssize_t elan_sysfs_read_mode(struct device *dev, @@ -743,16 +747,11 @@ static ssize_t elan_sysfs_read_mode(struct device *dev, int error; enum tp_mode mode; - error = mutex_lock_interruptible(&data->sysfs_mutex); - if (error) - return error; - - error = data->ops->iap_get_mode(data->client, &mode); - - mutex_unlock(&data->sysfs_mutex); - - if (error) - return error; + scoped_cond_guard(mutex_intr, return -EINTR, &data->sysfs_mutex) { + error = data->ops->iap_get_mode(data->client, &mode); + if (error) + return error; + } return sysfs_emit(buf, "%d\n", (int)mode); } @@ -783,44 +782,40 @@ static const struct attribute_group elan_sysfs_group = { .attrs = elan_sysfs_entries, }; -static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static int elan_acquire_baseline(struct elan_tp_data *data) { - struct i2c_client *client = to_i2c_client(dev); - struct elan_tp_data *data = i2c_get_clientdata(client); - int error; + struct i2c_client *client = data->client; + struct device *dev = &client->dev; int retval; + int error; - retval = mutex_lock_interruptible(&data->sysfs_mutex); - if (retval) - return retval; - - disable_irq(client->irq); + guard(disable_irq)(&client->irq); data->baseline_ready = false; data->mode |= ETP_ENABLE_CALIBRATE; - retval = data->ops->set_mode(data->client, data->mode); + retval = data->ops->set_mode(client, data->mode); if (retval) { + data->mode &= ~ETP_ENABLE_CALIBRATE; dev_err(dev, "Failed to enable calibration mode to get baseline: %d\n", retval); - goto out; + return retval; } msleep(250); - retval = data->ops->get_baseline_data(data->client, true, + retval = data->ops->get_baseline_data(client, true, &data->max_baseline); if (retval) { - dev_err(dev, "Failed to read max baseline form device: %d\n", + dev_err(dev, "Failed to read max baseline from device: %d\n", retval); goto out_disable_calibrate; } - retval = data->ops->get_baseline_data(data->client, false, + retval = data->ops->get_baseline_data(client, false, &data->min_baseline); if (retval) { - dev_err(dev, "Failed to read min baseline form device: %d\n", + dev_err(dev, "Failed to read min baseline from device: %d\n", retval); goto out_disable_calibrate; } @@ -829,17 +824,31 @@ static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, out_disable_calibrate: data->mode &= ~ETP_ENABLE_CALIBRATE; - error = data->ops->set_mode(data->client, data->mode); + error = data->ops->set_mode(client, data->mode); if (error) { dev_err(dev, "Failed to disable calibration mode after acquiring baseline: %d\n", error); if (!retval) retval = error; } -out: - enable_irq(client->irq); - mutex_unlock(&data->sysfs_mutex); - return retval ?: count; + + return retval; +} + +static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + + scoped_cond_guard(mutex_intr, return -EINTR, &data->sysfs_mutex) { + error = elan_acquire_baseline(data); + if (error) + return error; + } + + return count; } static ssize_t min_show(struct device *dev, @@ -847,22 +856,15 @@ static ssize_t min_show(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct elan_tp_data *data = i2c_get_clientdata(client); - int retval; - retval = mutex_lock_interruptible(&data->sysfs_mutex); - if (retval) - return retval; + scoped_guard(mutex_intr, &data->sysfs_mutex) { + if (!data->baseline_ready) + return -ENODATA; - if (!data->baseline_ready) { - retval = -ENODATA; - goto out; + return sysfs_emit(buf, "%d", data->min_baseline); } - retval = sysfs_emit(buf, "%d", data->min_baseline); - -out: - mutex_unlock(&data->sysfs_mutex); - return retval; + return -EINTR; } static ssize_t max_show(struct device *dev, @@ -870,25 +872,17 @@ static ssize_t max_show(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct elan_tp_data *data = i2c_get_clientdata(client); - int retval; - retval = mutex_lock_interruptible(&data->sysfs_mutex); - if (retval) - return retval; + scoped_guard(mutex_intr, &data->sysfs_mutex) { + if (!data->baseline_ready) + return -ENODATA; - if (!data->baseline_ready) { - retval = -ENODATA; - goto out; + return sysfs_emit(buf, "%d", data->max_baseline); } - retval = sysfs_emit(buf, "%d", data->max_baseline); - -out: - mutex_unlock(&data->sysfs_mutex); - return retval; + return -EINTR; } - static DEVICE_ATTR_WO(acquire); static DEVICE_ATTR_RO(min); static DEVICE_ATTR_RO(max); @@ -1323,41 +1317,54 @@ static int elan_probe(struct i2c_client *client) return 0; } +static int __elan_suspend(struct elan_tp_data *data) +{ + struct i2c_client *client = data->client; + int error; + + if (device_may_wakeup(&client->dev)) + return elan_sleep(data); + + /* Touchpad is not a wakeup source */ + error = elan_set_power(data, false); + if (error) + return error; + + error = regulator_disable(data->vcc); + if (error) { + dev_err(&client->dev, + "failed to disable regulator when suspending: %d\n", + error); + /* Attempt to power the chip back up */ + elan_set_power(data, true); + return error; + } + + return 0; +} + static int elan_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct elan_tp_data *data = i2c_get_clientdata(client); - int ret; + int error; /* * We are taking the mutex to make sure sysfs operations are * complete before we attempt to bring the device into low[er] * power mode. */ - ret = mutex_lock_interruptible(&data->sysfs_mutex); - if (ret) - return ret; - - disable_irq(client->irq); + scoped_cond_guard(mutex_intr, return -EINTR, &data->sysfs_mutex) { + disable_irq(client->irq); - if (device_may_wakeup(dev)) { - ret = elan_sleep(data); - } else { - ret = elan_set_power(data, false); - if (ret) - goto err; - - ret = regulator_disable(data->vcc); - if (ret) { - dev_err(dev, "error %d disabling regulator\n", ret); - /* Attempt to power the chip back up */ - elan_set_power(data, true); + error = __elan_suspend(data); + if (error) { + enable_irq(client->irq); + return error; } } -err: - mutex_unlock(&data->sysfs_mutex); - return ret; + return 0; } static int elan_resume(struct device *dev) @@ -1392,8 +1399,8 @@ err: static DEFINE_SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); static const struct i2c_device_id elan_id[] = { - { DRIVER_NAME, 0 }, - { }, + { DRIVER_NAME }, + { } }; MODULE_DEVICE_TABLE(i2c, elan_id); diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c index 13dc097eb6c6..a9057d124a88 100644 --- a/drivers/input/mouse/elan_i2c_i2c.c +++ b/drivers/input/mouse/elan_i2c_i2c.c @@ -21,7 +21,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/sched.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "elan_i2c.h" @@ -628,12 +628,11 @@ static int elan_i2c_write_fw_block(struct i2c_client *client, u16 fw_page_size, const u8 *page, u16 checksum, int idx) { struct device *dev = &client->dev; - u8 *page_store; u8 val[3]; u16 result; int ret, error; - page_store = kmalloc(fw_page_size + 4, GFP_KERNEL); + u8 *page_store __free(kfree) = kmalloc(fw_page_size + 4, GFP_KERNEL); if (!page_store) return -ENOMEM; @@ -647,7 +646,7 @@ static int elan_i2c_write_fw_block(struct i2c_client *client, u16 fw_page_size, if (ret != fw_page_size + 4) { error = ret < 0 ? ret : -EIO; dev_err(dev, "Failed to write page %d: %d\n", idx, error); - goto exit; + return error; } /* Wait for F/W to update one page ROM data. */ @@ -656,20 +655,17 @@ static int elan_i2c_write_fw_block(struct i2c_client *client, u16 fw_page_size, error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); if (error) { dev_err(dev, "Failed to read IAP write result: %d\n", error); - goto exit; + return error; } result = le16_to_cpup((__le16 *)val); if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { dev_err(dev, "IAP reports failed write: %04hx\n", result); - error = -EIO; - goto exit; + return -EIO; } -exit: - kfree(page_store); - return error; + return 0; } static int elan_i2c_finish_fw_update(struct i2c_client *client, diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 4e38229404b4..79ad98cc1e79 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -17,7 +17,7 @@ #include <linux/platform_device.h> #include <linux/serio.h> #include <linux/libps2.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "psmouse.h" #include "elantech.h" #include "elan_i2c.h" @@ -1477,15 +1477,46 @@ static void elantech_disconnect(struct psmouse *psmouse) } /* + * Some hw_version 4 models fail to properly activate absolute mode on + * resume without going through disable/enable cycle. + */ +static const struct dmi_system_id elantech_needs_reenable[] = { +#if defined(CONFIG_DMI) && defined(CONFIG_X86) + { + /* Lenovo N24 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "81AF"), + }, + }, +#endif + { } +}; + +/* * Put the touchpad back into absolute mode when reconnecting */ static int elantech_reconnect(struct psmouse *psmouse) { + int err; + psmouse_reset(psmouse); if (elantech_detect(psmouse, 0)) return -1; + if (dmi_check_system(elantech_needs_reenable)) { + err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE); + if (err) + psmouse_warn(psmouse, "failed to deactivate mouse on %s: %d\n", + psmouse->ps2dev.serio->phys, err); + + err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); + if (err) + psmouse_warn(psmouse, "failed to reactivate mouse on %s: %d\n", + psmouse->ps2dev.serio->phys, err); + } + if (elantech_set_absolute_mode(psmouse)) { psmouse_err(psmouse, "failed to put touchpad back into absolute mode.\n"); diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index c74b99077d16..356b99d48544 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -408,8 +408,7 @@ int focaltech_init(struct psmouse *psmouse) struct focaltech_data *priv; int error; - psmouse->private = priv = kzalloc(sizeof(struct focaltech_data), - GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 3c8310da0b05..6125652e5ad8 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -981,7 +981,7 @@ int hgpk_init(struct psmouse *psmouse) struct hgpk_data *priv; int err; - priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { err = -ENOMEM; goto alloc_fail; diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index bd9955730176..7147dacc404f 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -273,7 +273,7 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) struct lifebook_data *priv; int error = -ENOMEM; - priv = kzalloc(sizeof(struct lifebook_data), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); dev2 = input_allocate_device(); if (!priv || !dev2) goto err_out; diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index 2de64d6a04d1..baef4be14b54 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c @@ -73,7 +73,7 @@ static int probe_maple_mouse(struct device *dev) struct input_dev *input_dev; struct dc_mouse *mse; - mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL); + mse = kzalloc(sizeof(*mse), GFP_KERNEL); if (!mse) { error = -ENOMEM; goto fail; diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index a0aac76b1e41..a2c9f7144864 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1591,7 +1591,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_deactivate(parent); } - psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); + psmouse = kzalloc(sizeof(*psmouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!psmouse || !input_dev) goto err_free; diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c index 2a2459b1b4f2..93420f07b7d0 100644 --- a/drivers/input/mouse/psmouse-smbus.c +++ b/drivers/input/mouse/psmouse-smbus.c @@ -35,7 +35,7 @@ static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY)) return; - mutex_lock(&psmouse_smbus_mutex); + guard(mutex)(&psmouse_smbus_mutex); list_for_each_entry(smbdev, &psmouse_smbus_list, node) { if (smbdev->dead) @@ -55,15 +55,13 @@ static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter) "SMBus candidate adapter appeared, triggering rescan\n"); serio_rescan(smbdev->psmouse->ps2dev.serio); } - - mutex_unlock(&psmouse_smbus_mutex); } static void psmouse_smbus_detach_i2c_client(struct i2c_client *client) { struct psmouse_smbus_dev *smbdev, *tmp; - mutex_lock(&psmouse_smbus_mutex); + guard(mutex)(&psmouse_smbus_mutex); list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) { if (smbdev->client != client) @@ -85,8 +83,6 @@ static void psmouse_smbus_detach_i2c_client(struct i2c_client *client) kfree(smbdev); } } - - mutex_unlock(&psmouse_smbus_mutex); } static int psmouse_smbus_notifier_call(struct notifier_block *nb, @@ -171,7 +167,7 @@ static void psmouse_smbus_disconnect(struct psmouse *psmouse) { struct psmouse_smbus_dev *smbdev = psmouse->private; - mutex_lock(&psmouse_smbus_mutex); + guard(mutex)(&psmouse_smbus_mutex); if (smbdev->dead) { list_del(&smbdev->node); @@ -186,8 +182,6 @@ static void psmouse_smbus_disconnect(struct psmouse *psmouse) psmouse_smbus_schedule_remove(smbdev->client); } - mutex_unlock(&psmouse_smbus_mutex); - psmouse->private = NULL; } @@ -219,7 +213,7 @@ void psmouse_smbus_cleanup(struct psmouse *psmouse) { struct psmouse_smbus_dev *smbdev, *tmp; - mutex_lock(&psmouse_smbus_mutex); + guard(mutex)(&psmouse_smbus_mutex); list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) { if (psmouse == smbdev->psmouse) { @@ -227,8 +221,6 @@ void psmouse_smbus_cleanup(struct psmouse *psmouse) kfree(smbdev); } } - - mutex_unlock(&psmouse_smbus_mutex); } int psmouse_smbus_init(struct psmouse *psmouse, @@ -267,9 +259,9 @@ int psmouse_smbus_init(struct psmouse *psmouse, psmouse->disconnect = psmouse_smbus_disconnect; psmouse->resync_time = 0; - mutex_lock(&psmouse_smbus_mutex); - list_add_tail(&smbdev->node, &psmouse_smbus_list); - mutex_unlock(&psmouse_smbus_mutex); + scoped_guard(mutex, &psmouse_smbus_mutex) { + list_add_tail(&smbdev->node, &psmouse_smbus_list); + } /* Bind to already existing adapters right away */ error = i2c_for_each_dev(smbdev, psmouse_smbus_create_companion); @@ -293,9 +285,9 @@ int psmouse_smbus_init(struct psmouse *psmouse, smbdev->board.platform_data = NULL; if (error < 0 || !leave_breadcrumbs) { - mutex_lock(&psmouse_smbus_mutex); - list_del(&smbdev->node); - mutex_unlock(&psmouse_smbus_mutex); + scoped_guard(mutex, &psmouse_smbus_mutex) { + list_del(&smbdev->node); + } kfree(smbdev); } diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 2716d2ba386a..44b136fc29aa 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -1028,7 +1028,7 @@ int fsp_init(struct psmouse *psmouse) "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n", ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver); - psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 993f90333380..218c8432a13b 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -231,7 +231,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) unsigned char c = serio->id.extra; int err = -ENOMEM; - sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL); + sermouse = kzalloc(sizeof(*sermouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!sermouse || !input_dev) goto fail1; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 7a303a9d6bf7..c5c88a75a019 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -161,8 +161,10 @@ static const char * const topbuttonpad_pnp_ids[] = { NULL }; +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS static const char * const smbus_pnp_ids[] = { /* all of the topbuttonpad_pnp_ids are valid, we just add some extras */ + "DLL060d", /* Dell Precision M3800 */ "LEN0048", /* X1 Carbon 3 */ "LEN0046", /* X250 */ "LEN0049", /* Yoga 11e */ @@ -189,12 +191,18 @@ static const char * const smbus_pnp_ids[] = { "LEN2054", /* E480 */ "LEN2055", /* E580 */ "LEN2068", /* T14 Gen 1 */ + "SYN1221", /* TUXEDO InfinityBook Pro 14 v5 */ + "SYN3003", /* HP EliteBook 850 G1 */ + "SYN3015", /* HP EliteBook 840 G2 */ "SYN3052", /* HP EliteBook 840 G4 */ "SYN3221", /* HP 15-ay000 */ "SYN323d", /* HP Spectre X360 13-w013dx */ "SYN3257", /* HP Envy 13-ad105ng */ + "TOS01f6", /* Dynabook Portege X30L-G */ + "TOS0213", /* Dynabook Portege X30-D */ NULL }; +#endif static const char * const forcepad_pnp_ids[] = { "SYN300D", @@ -649,9 +657,8 @@ static int synaptics_pt_start(struct serio *serio) struct psmouse *parent = psmouse_from_serio(serio->parent); struct synaptics_data *priv = parent->private; - serio_pause_rx(parent->ps2dev.serio); + guard(serio_pause_rx)(parent->ps2dev.serio); priv->pt_port = serio; - serio_continue_rx(parent->ps2dev.serio); return 0; } @@ -661,9 +668,28 @@ static void synaptics_pt_stop(struct serio *serio) struct psmouse *parent = psmouse_from_serio(serio->parent); struct synaptics_data *priv = parent->private; - serio_pause_rx(parent->ps2dev.serio); + guard(serio_pause_rx)(parent->ps2dev.serio); priv->pt_port = NULL; - serio_continue_rx(parent->ps2dev.serio); +} + +static int synaptics_pt_open(struct serio *serio) +{ + struct psmouse *parent = psmouse_from_serio(serio->parent); + struct synaptics_data *priv = parent->private; + + guard(serio_pause_rx)(parent->ps2dev.serio); + priv->pt_port_open = true; + + return 0; +} + +static void synaptics_pt_close(struct serio *serio) +{ + struct psmouse *parent = psmouse_from_serio(serio->parent); + struct synaptics_data *priv = parent->private; + + guard(serio_pause_rx)(parent->ps2dev.serio); + priv->pt_port_open = false; } static int synaptics_is_pt_packet(u8 *buf) @@ -671,18 +697,25 @@ static int synaptics_is_pt_packet(u8 *buf) return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; } -static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet) +static void synaptics_pass_pt_packet(struct synaptics_data *priv, u8 *packet) { - struct psmouse *child = psmouse_from_serio(ptport); + struct serio *ptport; - if (child && child->state == PSMOUSE_ACTIVATED) { - serio_interrupt(ptport, packet[1], 0); - serio_interrupt(ptport, packet[4], 0); - serio_interrupt(ptport, packet[5], 0); - if (child->pktsize == 4) - serio_interrupt(ptport, packet[2], 0); - } else { - serio_interrupt(ptport, packet[1], 0); + ptport = priv->pt_port; + if (!ptport) + return; + + serio_interrupt(ptport, packet[1], 0); + + if (priv->pt_port_open) { + struct psmouse *child = psmouse_from_serio(ptport); + + if (child->state == PSMOUSE_ACTIVATED) { + serio_interrupt(ptport, packet[4], 0); + serio_interrupt(ptport, packet[5], 0); + if (child->pktsize == 4) + serio_interrupt(ptport, packet[2], 0); + } } } @@ -708,7 +741,7 @@ static void synaptics_pt_create(struct psmouse *psmouse) { struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) { psmouse_err(psmouse, "not enough memory for pass-through port\n"); @@ -721,6 +754,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) serio->write = synaptics_pt_write; serio->start = synaptics_pt_start; serio->stop = synaptics_pt_stop; + serio->open = synaptics_pt_open; + serio->close = synaptics_pt_close; serio->parent = psmouse->ps2dev.serio; psmouse->pt_activate = synaptics_pt_activate; @@ -1217,11 +1252,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) && synaptics_is_pt_packet(psmouse->packet)) { - if (priv->pt_port) - synaptics_pass_pt_packet(priv->pt_port, - psmouse->packet); - } else + synaptics_pass_pt_packet(priv, psmouse->packet); + } else { synaptics_process_packet(psmouse); + } return PSMOUSE_FULL_PACKET; } @@ -1563,7 +1597,7 @@ static int synaptics_init_ps2(struct psmouse *psmouse, synaptics_apply_quirks(psmouse, info); - psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 08533d1b1b16..3853165b6b3a 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -21,7 +21,7 @@ #define SYN_QUE_EXT_MIN_COORDS 0x0f #define SYN_QUE_MEXT_CAPAB_10 0x10 -/* synatics modes */ +/* synaptics modes */ #define SYN_BIT_ABSOLUTE_MODE BIT(7) #define SYN_BIT_HIGH_RATE BIT(6) #define SYN_BIT_SLEEP_MODE BIT(3) @@ -188,6 +188,7 @@ struct synaptics_data { bool disable_gesture; /* disable gestures */ struct serio *pt_port; /* Pass-through serio port */ + bool pt_port_open; /* * Last received Advanced Gesture Mode (AGM) packet. An AGM packet diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index af5cc64c622d..a0d707e47d93 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -508,7 +508,7 @@ static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *clien { struct synaptics_i2c *touch; - touch = kzalloc(sizeof(struct synaptics_i2c), GFP_KERNEL); + touch = kzalloc(sizeof(*touch), GFP_KERNEL); if (!touch) return NULL; @@ -630,8 +630,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend, synaptics_i2c_resume); static const struct i2c_device_id synaptics_i2c_id_table[] = { - { "synaptics_i2c", 0 }, - { }, + { "synaptics_i2c" }, + { } }; MODULE_DEVICE_TABLE(i2c, synaptics_i2c_id_table); diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c index ea9eff7c8099..fb1d986a6895 100644 --- a/drivers/input/mouse/vmmouse.c +++ b/drivers/input/mouse/vmmouse.c @@ -21,19 +21,16 @@ #include "psmouse.h" #include "vmmouse.h" -#define VMMOUSE_PROTO_MAGIC 0x564D5868U - /* * Main commands supported by the vmmouse hypervisor port. */ -#define VMMOUSE_PROTO_CMD_GETVERSION 10 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS 40 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT 86 +#define VMWARE_CMD_ABSPOINTER_DATA 39 +#define VMWARE_CMD_ABSPOINTER_STATUS 40 +#define VMWARE_CMD_ABSPOINTER_COMMAND 41 +#define VMWARE_CMD_ABSPOINTER_RESTRICT 86 /* - * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND + * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND */ #define VMMOUSE_CMD_ENABLE 0x45414552U #define VMMOUSE_CMD_DISABLE 0x000000f5U @@ -76,28 +73,6 @@ struct vmmouse_data { char dev_name[128]; }; -/* - * Hypervisor-specific bi-directional communication channel - * implementing the vmmouse protocol. Should never execute on - * bare metal hardware. - */ -#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ -({ \ - unsigned long __dummy1, __dummy2; \ - __asm__ __volatile__ (VMWARE_HYPERCALL : \ - "=a"(out1), \ - "=b"(out2), \ - "=c"(out3), \ - "=d"(out4), \ - "=S"(__dummy1), \ - "=D"(__dummy2) : \ - "a"(VMMOUSE_PROTO_MAGIC), \ - "b"(in1), \ - "c"(VMMOUSE_PROTO_CMD_##cmd), \ - "d"(0) : \ - "memory"); \ -}) - /** * vmmouse_report_button - report button state on the correct input device * @@ -145,14 +120,12 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse) struct input_dev *abs_dev = priv->abs_dev; struct input_dev *pref_dev; u32 status, x, y, z; - u32 dummy1, dummy2, dummy3; unsigned int queue_length; unsigned int count = 255; while (count--) { /* See if we have motion data. */ - VMMOUSE_CMD(ABSPOINTER_STATUS, 0, - status, dummy1, dummy2, dummy3); + status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0); if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) { psmouse_err(psmouse, "failed to fetch status data\n"); /* @@ -172,7 +145,8 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse) } /* Now get it */ - VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z); + status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4, + &x, &y, &z); /* * And report what we've got. Prefer to report button @@ -247,14 +221,10 @@ static psmouse_ret_t vmmouse_process_byte(struct psmouse *psmouse) static void vmmouse_disable(struct psmouse *psmouse) { u32 status; - u32 dummy1, dummy2, dummy3, dummy4; - - VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE, - dummy1, dummy2, dummy3, dummy4); - VMMOUSE_CMD(ABSPOINTER_STATUS, 0, - status, dummy1, dummy2, dummy3); + vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE); + status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0); if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR) psmouse_warn(psmouse, "failed to disable vmmouse device\n"); } @@ -271,26 +241,24 @@ static void vmmouse_disable(struct psmouse *psmouse) static int vmmouse_enable(struct psmouse *psmouse) { u32 status, version; - u32 dummy1, dummy2, dummy3, dummy4; /* * Try enabling the device. If successful, we should be able to * read valid version ID back from it. */ - VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE, - dummy1, dummy2, dummy3, dummy4); + vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE); /* * See if version ID can be retrieved. */ - VMMOUSE_CMD(ABSPOINTER_STATUS, 0, status, dummy1, dummy2, dummy3); + status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0); if ((status & 0x0000ffff) == 0) { psmouse_dbg(psmouse, "empty flags - assuming no device\n"); return -ENXIO; } - VMMOUSE_CMD(ABSPOINTER_DATA, 1 /* single item */, - version, dummy1, dummy2, dummy3); + version = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_DATA, + 1 /* single item */); if (version != VMMOUSE_VERSION_ID) { psmouse_dbg(psmouse, "Unexpected version value: %u vs %u\n", (unsigned) version, VMMOUSE_VERSION_ID); @@ -301,11 +269,11 @@ static int vmmouse_enable(struct psmouse *psmouse) /* * Restrict ioport access, if possible. */ - VMMOUSE_CMD(ABSPOINTER_RESTRICT, VMMOUSE_RESTRICT_CPL0, - dummy1, dummy2, dummy3, dummy4); + vmware_hypercall1(VMWARE_CMD_ABSPOINTER_RESTRICT, + VMMOUSE_RESTRICT_CPL0); - VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_REQUEST_ABSOLUTE, - dummy1, dummy2, dummy3, dummy4); + vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, + VMMOUSE_CMD_REQUEST_ABSOLUTE); return 0; } @@ -342,7 +310,7 @@ static bool vmmouse_check_hypervisor(void) */ int vmmouse_detect(struct psmouse *psmouse, bool set_properties) { - u32 response, version, dummy1, dummy2; + u32 response, version, type; if (!vmmouse_check_hypervisor()) { psmouse_dbg(psmouse, @@ -351,9 +319,9 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties) } /* Check if the device is present */ - response = ~VMMOUSE_PROTO_MAGIC; - VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2); - if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU) + response = ~VMWARE_HYPERVISOR_MAGIC; + version = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &response, &type); + if (response != VMWARE_HYPERVISOR_MAGIC || version == 0xffffffffU) return -ENXIO; if (set_properties) { diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 8af8e4a15f95..707cd28f4ba6 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -456,7 +456,7 @@ static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err = -ENOMEM; - mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL); + mouse = kzalloc(sizeof(*mouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!mouse || !input_dev) goto fail1; |