* Re: [PATCH v1] Input: synaptics-rmi4 - convert irq distribution to irq_domain
From: Christopher Heiny @ 2018-01-24 21:37 UTC (permalink / raw)
To: Nick Dyer, Dmitry Torokhov
Cc: Benjamin Tissoires, Andrew Duggan, linux-input, Chris Healy,
Lucas Stach
In-Reply-To: <1516829193-27590-1-git-send-email-nick@shmanahar.org>
On Wed, 2018-01-24 at 21:26 +0000, Nick Dyer wrote:
> Convert the RMI driver to use the standard mechanism for
> distributing IRQs to the various functions.
>
> Tested on:
> * S7300 (F11, F34, F54)
> * S7817 (F12, F34, F54)
>
> Signed-off-by: Nick Dyer <nick@shmanahar.org>
Acked-by: Christopher Heiny <cheiny@synaptics.com>
Thanks for the fix - it replaces a bit of paleozoic cruft that I'd
forgotten all about. I'm not able to bench test this, but don't see
any gotchas on a read-through.
Cheers,
Chris
> ---
> drivers/input/rmi4/Kconfig | 1 +
> drivers/input/rmi4/rmi_bus.c | 13 ++++++++-
> drivers/input/rmi4/rmi_bus.h | 3 +-
> drivers/input/rmi4/rmi_driver.c | 65 ++++++++++++++++++++-----------
> ----------
> drivers/input/rmi4/rmi_f01.c | 10 +++----
> drivers/input/rmi4/rmi_f03.c | 9 +++---
> drivers/input/rmi4/rmi_f11.c | 25 +++++++---------
> drivers/input/rmi4/rmi_f12.c | 8 ++---
> drivers/input/rmi4/rmi_f30.c | 9 +++---
> drivers/input/rmi4/rmi_f34.c | 5 ++--
> drivers/input/rmi4/rmi_f54.c | 6 ----
> include/linux/rmi.h | 2 ++
> 12 files changed, 81 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> index 7172b88..fad2eae 100644
> --- a/drivers/input/rmi4/Kconfig
> +++ b/drivers/input/rmi4/Kconfig
> @@ -3,6 +3,7 @@
> #
> config RMI4_CORE
> tristate "Synaptics RMI4 bus support"
> + select IRQ_DOMAIN
> help
> Say Y here if you want to support the Synaptics RMI4
> bus. This is
> required for all RMI4 device support.
> diff --git a/drivers/input/rmi4/rmi_bus.c
> b/drivers/input/rmi4/rmi_bus.c
> index ae1bffe..ae288d6 100644
> --- a/drivers/input/rmi4/rmi_bus.c
> +++ b/drivers/input/rmi4/rmi_bus.c
> @@ -178,7 +178,18 @@ static int rmi_function_probe(struct device
> *dev)
>
> if (handler->probe) {
> error = handler->probe(fn);
> - return error;
> + if (error)
> + return error;
> + }
> +
> + if (fn->irq_base && handler->attention) {
> + error = devm_request_threaded_irq(&fn->dev, fn-
> >irq_base, NULL,
> + handler->attention,
> IRQF_ONESHOT,
> + dev_name(&fn->dev), fn);
> + if (error) {
> + dev_err(dev, "Failed registering IRQ %d\n",
> error);
> + return error;
> + }
> }
>
> return 0;
> diff --git a/drivers/input/rmi4/rmi_bus.h
> b/drivers/input/rmi4/rmi_bus.h
> index b7625a9..745a030 100644
> --- a/drivers/input/rmi4/rmi_bus.h
> +++ b/drivers/input/rmi4/rmi_bus.h
> @@ -35,6 +35,7 @@ struct rmi_function {
> struct device dev;
> struct list_head node;
>
> + unsigned int irq_base;
> unsigned int num_of_irqs;
> unsigned int irq_pos;
> unsigned long irq_mask[];
> @@ -76,7 +77,7 @@ struct rmi_function_handler {
> void (*remove)(struct rmi_function *fn);
> int (*config)(struct rmi_function *fn);
> int (*reset)(struct rmi_function *fn);
> - int (*attention)(struct rmi_function *fn, unsigned long
> *irq_bits);
> + irqreturn_t (*attention)(int irq, void *ctx);
> int (*suspend)(struct rmi_function *fn);
> int (*resume)(struct rmi_function *fn);
> };
> diff --git a/drivers/input/rmi4/rmi_driver.c
> b/drivers/input/rmi4/rmi_driver.c
> index 141ea22..b7ef1f5a 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -21,6 +21,7 @@
> #include <linux/pm.h>
> #include <linux/slab.h>
> #include <linux/of.h>
> +#include <linux/irqdomain.h>
> #include <uapi/linux/input.h>
> #include <linux/rmi.h>
> #include "rmi_bus.h"
> @@ -127,28 +128,11 @@ static int
> rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
> return 0;
> }
>
> -static void process_one_interrupt(struct rmi_driver_data *data,
> - struct rmi_function *fn)
> -{
> - struct rmi_function_handler *fh;
> -
> - if (!fn || !fn->dev.driver)
> - return;
> -
> - fh = to_rmi_function_handler(fn->dev.driver);
> - if (fh->attention) {
> - bitmap_and(data->fn_irq_bits, data->irq_status, fn-
> >irq_mask,
> - data->irq_count);
> - if (!bitmap_empty(data->fn_irq_bits, data-
> >irq_count))
> - fh->attention(fn, data->fn_irq_bits);
> - }
> -}
> -
> static int rmi_process_interrupt_requests(struct rmi_device
> *rmi_dev)
> {
> struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev-
> >dev);
> struct device *dev = &rmi_dev->dev;
> - struct rmi_function *entry;
> + int i;
> int error;
>
> if (!data)
> @@ -173,16 +157,8 @@ static int rmi_process_interrupt_requests(struct
> rmi_device *rmi_dev)
> */
> mutex_unlock(&data->irq_mutex);
>
> - /*
> - * It would be nice to be able to use irq_chip to handle
> these
> - * nested IRQs. Unfortunately, most of the current
> customers for
> - * this driver are using older kernels (3.0.x) that don't
> support
> - * the features required for that. Once they've shifted to
> more
> - * recent kernels (say, 3.3 and higher), this should be
> switched to
> - * use irq_chip.
> - */
> - list_for_each_entry(entry, &data->function_list, node)
> - process_one_interrupt(data, entry);
> + for_each_set_bit(i, data->irq_status, data->irq_count)
> + handle_nested_irq(irq_find_mapping(data->irqdomain,
> i));
>
> if (data->input)
> input_sync(data->input);
> @@ -847,6 +823,10 @@ int rmi_initial_reset(struct rmi_device
> *rmi_dev, void *ctx,
> return pdt->page_start == 0 ? RMI_SCAN_CONTINUE : -ENODEV;
> }
>
> +static struct irq_chip rmi_irq_chip = {
> + .name = "rmi4",
> +};
> +
> static int rmi_create_function(struct rmi_device *rmi_dev,
> void *ctx, const struct pdt_entry
> *pdt)
> {
> @@ -878,9 +858,18 @@ static int rmi_create_function(struct rmi_device
> *rmi_dev,
> fn->irq_pos = *current_irq_count;
> *current_irq_count += fn->num_of_irqs;
>
> - for (i = 0; i < fn->num_of_irqs; i++)
> + for (i = 0; i < fn->num_of_irqs; i++) {
> set_bit(fn->irq_pos + i, fn->irq_mask);
>
> + fn->irq_base = irq_create_mapping(data->irqdomain,
> + fn->irq_pos + i);
> +
> +
> + irq_set_chip_data(fn->irq_base, data);
> + irq_set_chip_and_handler(fn->irq_base,
> &rmi_irq_chip,
> + handle_simple_irq);
> + }
> +
> error = rmi_register_function(fn);
> if (error)
> goto err_put_fn;
> @@ -1000,9 +989,12 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume);
> static int rmi_driver_remove(struct device *dev)
> {
> struct rmi_device *rmi_dev = to_rmi_device(dev);
> + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev-
> >dev);
>
> rmi_disable_irq(rmi_dev, false);
>
> + irq_domain_remove(data->irqdomain);
> +
> rmi_f34_remove_sysfs(rmi_dev);
> rmi_free_function_list(rmi_dev);
>
> @@ -1034,7 +1026,8 @@ int rmi_probe_interrupts(struct rmi_driver_data
> *data)
> {
> struct rmi_device *rmi_dev = data->rmi_dev;
> struct device *dev = &rmi_dev->dev;
> - int irq_count;
> + struct device_node *rmi_of_node = rmi_dev->xport->dev-
> >of_node;
> + int irq_count = 0;
> size_t size;
> int retval;
>
> @@ -1045,7 +1038,6 @@ int rmi_probe_interrupts(struct rmi_driver_data
> *data)
> * being accessed.
> */
> rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n",
> __func__);
> - irq_count = 0;
> data->bootloader_mode = false;
>
> retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs);
> @@ -1057,6 +1049,14 @@ int rmi_probe_interrupts(struct
> rmi_driver_data *data)
> if (data->bootloader_mode)
> dev_warn(dev, "Device in bootloader mode.\n");
>
> + /* Allocate and register a linear revmap irq_domain */
> + data->irqdomain = irq_domain_add_linear(rmi_of_node,
> irq_count,
> + &irq_domain_simple_o
> ps, data);
> + if (!data->irqdomain) {
> + dev_err(&rmi_dev->dev, "Failed to create IRQ
> domain\n");
> + return PTR_ERR(data->irqdomain);
> + }
> +
> data->irq_count = irq_count;
> data->num_of_irq_regs = (data->irq_count + 7) / 8;
>
> @@ -1079,10 +1079,9 @@ int rmi_init_functions(struct rmi_driver_data
> *data)
> {
> struct rmi_device *rmi_dev = data->rmi_dev;
> struct device *dev = &rmi_dev->dev;
> - int irq_count;
> + int irq_count = 0;
> int retval;
>
> - irq_count = 0;
> rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n",
> __func__);
> retval = rmi_scan_pdt(rmi_dev, &irq_count,
> rmi_create_function);
> if (retval < 0) {
> diff --git a/drivers/input/rmi4/rmi_f01.c
> b/drivers/input/rmi4/rmi_f01.c
> index 8a07ae1..4edaa14 100644
> --- a/drivers/input/rmi4/rmi_f01.c
> +++ b/drivers/input/rmi4/rmi_f01.c
> @@ -681,9 +681,9 @@ static int rmi_f01_resume(struct rmi_function
> *fn)
> return 0;
> }
>
> -static int rmi_f01_attention(struct rmi_function *fn,
> - unsigned long *irq_bits)
> +static irqreturn_t rmi_f01_attention(int irq, void *ctx)
> {
> + struct rmi_function *fn = ctx;
> struct rmi_device *rmi_dev = fn->rmi_dev;
> int error;
> u8 device_status;
> @@ -692,7 +692,7 @@ static int rmi_f01_attention(struct rmi_function
> *fn,
> if (error) {
> dev_err(&fn->dev,
> "Failed to read device status: %d.\n",
> error);
> - return error;
> + return IRQ_RETVAL(error);
> }
>
> if (RMI_F01_STATUS_BOOTLOADER(device_status))
> @@ -704,11 +704,11 @@ static int rmi_f01_attention(struct
> rmi_function *fn,
> error = rmi_dev->driver->reset_handler(rmi_dev);
> if (error) {
> dev_err(&fn->dev, "Device reset failed:
> %d\n", error);
> - return error;
> + return IRQ_RETVAL(error);
> }
> }
>
> - return 0;
> + return IRQ_HANDLED;
> }
>
> struct rmi_function_handler rmi_f01_handler = {
> diff --git a/drivers/input/rmi4/rmi_f03.c
> b/drivers/input/rmi4/rmi_f03.c
> index ad71a5e..b9f07c9 100644
> --- a/drivers/input/rmi4/rmi_f03.c
> +++ b/drivers/input/rmi4/rmi_f03.c
> @@ -199,8 +199,9 @@ static int rmi_f03_config(struct rmi_function
> *fn)
> return 0;
> }
>
> -static int rmi_f03_attention(struct rmi_function *fn, unsigned long
> *irq_bits)
> +static irqreturn_t rmi_f03_attention(int irq, void *ctx)
> {
> + struct rmi_function *fn = ctx;
> struct rmi_device *rmi_dev = fn->rmi_dev;
> struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev-
> >dev);
> struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> @@ -217,7 +218,7 @@ static int rmi_f03_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> /* First grab the data passed by the transport
> device */
> if (drvdata->attn_data.size < ob_len) {
> dev_warn(&fn->dev, "F03 interrupted, but
> data is missing!\n");
> - return 0;
> + return IRQ_HANDLED;
> }
>
> memcpy(obs, drvdata->attn_data.data, ob_len);
> @@ -233,7 +234,7 @@ static int rmi_f03_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> "%s: Failed to read F03 output
> buffers: %d\n",
> __func__, error);
> serio_interrupt(f03->serio, 0,
> SERIO_TIMEOUT);
> - return error;
> + return IRQ_RETVAL(error);
> }
> }
>
> @@ -259,7 +260,7 @@ static int rmi_f03_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> serio_interrupt(f03->serio, ob_data, serio_flags);
> }
>
> - return 0;
> + return IRQ_HANDLED;
> }
>
> static void rmi_f03_remove(struct rmi_function *fn)
> diff --git a/drivers/input/rmi4/rmi_f11.c
> b/drivers/input/rmi4/rmi_f11.c
> index bc5e37f..e587c87 100644
> --- a/drivers/input/rmi4/rmi_f11.c
> +++ b/drivers/input/rmi4/rmi_f11.c
> @@ -571,8 +571,7 @@ static inline u8 rmi_f11_parse_finger_state(const
> u8 *f_state, u8 n_finger)
>
> static void rmi_f11_finger_handler(struct f11_data *f11,
> struct rmi_2d_sensor *sensor,
> - unsigned long *irq_bits, int
> num_irq_regs,
> - int size)
> + int num_irq_regs, int size)
> {
> const u8 *f_state = f11->data.f_state;
> u8 finger_state;
> @@ -581,12 +580,7 @@ static void rmi_f11_finger_handler(struct
> f11_data *f11,
> int rel_fingers;
> int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES;
>
> - int abs_bits = bitmap_and(f11->result_bits, irq_bits, f11-
> >abs_mask,
> - num_irq_regs * 8);
> - int rel_bits = bitmap_and(f11->result_bits, irq_bits, f11-
> >rel_mask,
> - num_irq_regs * 8);
> -
> - if (abs_bits) {
> + if (sensor->report_abs) {
> if (abs_size > size)
> abs_fingers = size / RMI_F11_ABS_BYTES;
> else
> @@ -606,7 +600,7 @@ static void rmi_f11_finger_handler(struct
> f11_data *f11,
> }
> }
>
> - if (rel_bits) {
> + if (sensor->report_rel) {
> if ((abs_size + sensor->nbr_fingers *
> RMI_F11_REL_BYTES) > size)
> rel_fingers = (size - abs_size) /
> RMI_F11_REL_BYTES;
> else
> @@ -616,7 +610,7 @@ static void rmi_f11_finger_handler(struct
> f11_data *f11,
> rmi_f11_rel_pos_report(f11, i);
> }
>
> - if (abs_bits) {
> + if (sensor->report_abs) {
> /*
> * the absolute part is made in 2 parts to allow the
> kernel
> * tracking to take place.
> @@ -1275,8 +1269,9 @@ static int rmi_f11_config(struct rmi_function
> *fn)
> return 0;
> }
>
> -static int rmi_f11_attention(struct rmi_function *fn, unsigned long
> *irq_bits)
> +static irqreturn_t rmi_f11_attention(int irq, void *ctx)
> {
> + struct rmi_function *fn = ctx;
> struct rmi_device *rmi_dev = fn->rmi_dev;
> struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev-
> >dev);
> struct f11_data *f11 = dev_get_drvdata(&fn->dev);
> @@ -1302,13 +1297,13 @@ static int rmi_f11_attention(struct
> rmi_function *fn, unsigned long *irq_bits)
> data_base_addr, f11-
> >sensor.data_pkt,
> f11->sensor.pkt_size);
> if (error < 0)
> - return error;
> + return IRQ_RETVAL(error);
> }
>
> - rmi_f11_finger_handler(f11, &f11->sensor, irq_bits,
> - drvdata->num_of_irq_regs,
> valid_bytes);
> + rmi_f11_finger_handler(f11, &f11->sensor,
> + drvdata->num_of_irq_regs,
> valid_bytes);
>
> - return 0;
> + return IRQ_HANDLED;
> }
>
> static int rmi_f11_resume(struct rmi_function *fn)
> diff --git a/drivers/input/rmi4/rmi_f12.c
> b/drivers/input/rmi4/rmi_f12.c
> index 8b0db08..e226def 100644
> --- a/drivers/input/rmi4/rmi_f12.c
> +++ b/drivers/input/rmi4/rmi_f12.c
> @@ -197,10 +197,10 @@ static void rmi_f12_process_objects(struct
> f12_data *f12, u8 *data1, int size)
> rmi_2d_sensor_abs_report(sensor, &sensor->objs[i],
> i);
> }
>
> -static int rmi_f12_attention(struct rmi_function *fn,
> - unsigned long *irq_nr_regs)
> +static irqreturn_t rmi_f12_attention(int irq, void *ctx)
> {
> int retval;
> + struct rmi_function *fn = ctx;
> struct rmi_device *rmi_dev = fn->rmi_dev;
> struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev-
> >dev);
> struct f12_data *f12 = dev_get_drvdata(&fn->dev);
> @@ -222,7 +222,7 @@ static int rmi_f12_attention(struct rmi_function
> *fn,
> if (retval < 0) {
> dev_err(&fn->dev, "Failed to read object
> data. Code: %d.\n",
> retval);
> - return retval;
> + return IRQ_RETVAL(retval);
> }
> }
>
> @@ -232,7 +232,7 @@ static int rmi_f12_attention(struct rmi_function
> *fn,
>
> input_mt_sync_frame(sensor->input);
>
> - return 0;
> + return IRQ_HANDLED;
> }
>
> static int rmi_f12_write_control_regs(struct rmi_function *fn)
> diff --git a/drivers/input/rmi4/rmi_f30.c
> b/drivers/input/rmi4/rmi_f30.c
> index 82e0f0d..5e3ed5a 100644
> --- a/drivers/input/rmi4/rmi_f30.c
> +++ b/drivers/input/rmi4/rmi_f30.c
> @@ -122,8 +122,9 @@ static void rmi_f30_report_button(struct
> rmi_function *fn,
> }
> }
>
> -static int rmi_f30_attention(struct rmi_function *fn, unsigned long
> *irq_bits)
> +static irqreturn_t rmi_f30_attention(int irq, void *ctx)
> {
> + struct rmi_function *fn = ctx;
> struct f30_data *f30 = dev_get_drvdata(&fn->dev);
> struct rmi_driver_data *drvdata = dev_get_drvdata(&fn-
> >rmi_dev->dev);
> int error;
> @@ -134,7 +135,7 @@ static int rmi_f30_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> if (drvdata->attn_data.size < f30->register_count) {
> dev_warn(&fn->dev,
> "F30 interrupted, but data is
> missing\n");
> - return 0;
> + return IRQ_HANDLED;
> }
> memcpy(f30->data_regs, drvdata->attn_data.data,
> f30->register_count);
> @@ -147,7 +148,7 @@ static int rmi_f30_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> dev_err(&fn->dev,
> "%s: Failed to read F30 data
> registers: %d\n",
> __func__, error);
> - return error;
> + return IRQ_RETVAL(error);
> }
> }
>
> @@ -159,7 +160,7 @@ static int rmi_f30_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> rmi_f03_commit_buttons(f30->f03);
> }
>
> - return 0;
> + return IRQ_HANDLED;
> }
>
> static int rmi_f30_config(struct rmi_function *fn)
> diff --git a/drivers/input/rmi4/rmi_f34.c
> b/drivers/input/rmi4/rmi_f34.c
> index 4cfe970..7268cf9 100644
> --- a/drivers/input/rmi4/rmi_f34.c
> +++ b/drivers/input/rmi4/rmi_f34.c
> @@ -101,8 +101,9 @@ static int rmi_f34_command(struct f34_data *f34,
> u8 command,
> return 0;
> }
>
> -static int rmi_f34_attention(struct rmi_function *fn, unsigned long
> *irq_bits)
> +static irqreturn_t rmi_f34_attention(int irq, void *ctx)
> {
> + struct rmi_function *fn = ctx;
> struct f34_data *f34 = dev_get_drvdata(&fn->dev);
> int ret;
> u8 status;
> @@ -127,7 +128,7 @@ static int rmi_f34_attention(struct rmi_function
> *fn, unsigned long *irq_bits)
> complete(&f34->v7.cmd_done);
> }
>
> - return 0;
> + return IRQ_HANDLED;
> }
>
> static int rmi_f34_write_blocks(struct f34_data *f34, const void
> *data,
> diff --git a/drivers/input/rmi4/rmi_f54.c
> b/drivers/input/rmi4/rmi_f54.c
> index 5343f2c..98a935e 100644
> --- a/drivers/input/rmi4/rmi_f54.c
> +++ b/drivers/input/rmi4/rmi_f54.c
> @@ -610,11 +610,6 @@ static void rmi_f54_work(struct work_struct
> *work)
> mutex_unlock(&f54->data_mutex);
> }
>
> -static int rmi_f54_attention(struct rmi_function *fn, unsigned long
> *irqbits)
> -{
> - return 0;
> -}
> -
> static int rmi_f54_config(struct rmi_function *fn)
> {
> struct rmi_driver *drv = fn->rmi_dev->driver;
> @@ -756,6 +751,5 @@ struct rmi_function_handler rmi_f54_handler = {
> .func = 0x54,
> .probe = rmi_f54_probe,
> .config = rmi_f54_config,
> - .attention = rmi_f54_attention,
> .remove = rmi_f54_remove,
> };
> diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> index 64125443..5ef5c7c 100644
> --- a/include/linux/rmi.h
> +++ b/include/linux/rmi.h
> @@ -354,6 +354,8 @@ struct rmi_driver_data {
> struct mutex irq_mutex;
> struct input_dev *input;
>
> + struct irq_domain *irqdomain;
> +
> u8 pdt_props;
>
> u8 num_rx_electrodes;
^ permalink raw reply
* Re: [PATCH v1] Revert "Input: synaptics_rmi4 - use devm_device_add_group() for attributes in F01"
From: Dmitry Torokhov @ 2018-01-24 21:47 UTC (permalink / raw)
To: Nick Dyer
Cc: Benjamin Tissoires, Andrew Duggan, Christopher Heiny, linux-input,
Chris Healy, Lucas Stach
In-Reply-To: <1516829163-27534-1-git-send-email-nick@shmanahar.org>
On Wed, Jan 24, 2018 at 09:26:03PM +0000, Nick Dyer wrote:
> Since the sysfs attribute hangs off the RMI bus, which doesn't go away during
> firmware flash, it needs to be explictly removed, otherwise we would try and
> register the same attribute twice.
>
> This reverts commit 36a44af5c176d619552d99697433261141dd1296.
>
> Signed-off-by: Nick Dyer <nick@shmanahar.org>
Applied, thank you.
> ---
> drivers/input/rmi4/rmi_f01.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
> index ae966e3..8a07ae1 100644
> --- a/drivers/input/rmi4/rmi_f01.c
> +++ b/drivers/input/rmi4/rmi_f01.c
> @@ -570,14 +570,19 @@ static int rmi_f01_probe(struct rmi_function *fn)
>
> dev_set_drvdata(&fn->dev, f01);
>
> - error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group);
> + error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
> if (error)
> - dev_warn(&fn->dev,
> - "Failed to create attribute group: %d\n", error);
> + dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error);
>
> return 0;
> }
>
> +static void rmi_f01_remove(struct rmi_function *fn)
> +{
> + /* Note that the bus device is used, not the F01 device */
> + sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
> +}
> +
> static int rmi_f01_config(struct rmi_function *fn)
> {
> struct f01_data *f01 = dev_get_drvdata(&fn->dev);
> @@ -717,6 +722,7 @@ struct rmi_function_handler rmi_f01_handler = {
> },
> .func = 0x01,
> .probe = rmi_f01_probe,
> + .remove = rmi_f01_remove,
> .config = rmi_f01_config,
> .attention = rmi_f01_attention,
> .suspend = rmi_f01_suspend,
> --
> 2.7.4
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH v1] Input: synaptics-rmi4 - convert irq distribution to irq_domain
From: Nick Dyer @ 2018-01-24 22:23 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benjamin Tissoires, Andrew Duggan, Christopher Heiny, linux-input,
Chris Healy, Lucas Stach
In-Reply-To: <20180124213750.3sfmie4upq3ugx7w@dtor-ws>
On Wed, Jan 24, 2018 at 01:37:50PM -0800, Dmitry Torokhov wrote:
> On Wed, Jan 24, 2018 at 09:26:33PM +0000, Nick Dyer wrote:
> > Convert the RMI driver to use the standard mechanism for
> > distributing IRQs to the various functions.
> >
> > Tested on:
> > * S7300 (F11, F34, F54)
> > * S7817 (F12, F34, F54)
>
> Awesome! Thank you!
>
> >
> > Signed-off-by: Nick Dyer <nick@shmanahar.org>
> > ---
> > drivers/input/rmi4/Kconfig | 1 +
> > drivers/input/rmi4/rmi_bus.c | 13 ++++++++-
> > drivers/input/rmi4/rmi_bus.h | 3 +-
> > drivers/input/rmi4/rmi_driver.c | 65 ++++++++++++++++++++---------------------
> > drivers/input/rmi4/rmi_f01.c | 10 +++----
> > drivers/input/rmi4/rmi_f03.c | 9 +++---
> > drivers/input/rmi4/rmi_f11.c | 25 +++++++---------
> > drivers/input/rmi4/rmi_f12.c | 8 ++---
> > drivers/input/rmi4/rmi_f30.c | 9 +++---
> > drivers/input/rmi4/rmi_f34.c | 5 ++--
> > drivers/input/rmi4/rmi_f54.c | 6 ----
> > include/linux/rmi.h | 2 ++
> > 12 files changed, 81 insertions(+), 75 deletions(-)
> >
> > diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> > index 7172b88..fad2eae 100644
> > --- a/drivers/input/rmi4/Kconfig
> > +++ b/drivers/input/rmi4/Kconfig
> > @@ -3,6 +3,7 @@
> > #
> > config RMI4_CORE
> > tristate "Synaptics RMI4 bus support"
> > + select IRQ_DOMAIN
> > help
> > Say Y here if you want to support the Synaptics RMI4 bus. This is
> > required for all RMI4 device support.
> > diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
> > index ae1bffe..ae288d6 100644
> > --- a/drivers/input/rmi4/rmi_bus.c
> > +++ b/drivers/input/rmi4/rmi_bus.c
> > @@ -178,7 +178,18 @@ static int rmi_function_probe(struct device *dev)
> >
> > if (handler->probe) {
> > error = handler->probe(fn);
> > - return error;
> > + if (error)
> > + return error;
> > + }
> > +
> > + if (fn->irq_base && handler->attention) {
> > + error = devm_request_threaded_irq(&fn->dev, fn->irq_base, NULL,
>
> Does this mean we have a thread for each function? The "parent" IRQ is
> already threaded, I wonder if we could piggy-back on it... Or irqchip
> code will not allow us to sleep in nested interrupt unless it is on a
> separate thread?
>
> Sorry, just dumping random thoughts, I have not looked at tghe IRQ ocre
> code closely.
Looking at the way regmap does it, I need to add a call to
irq_set_nested_thread() where the function irq is being set up, then it
appears to skip creating a separate thread. I'll repost a new version
when I've had a chance to test it more thoroughly.
> > + handler->attention, IRQF_ONESHOT,
> > + dev_name(&fn->dev), fn);
> > + if (error) {
> > + dev_err(dev, "Failed registering IRQ %d\n", error);
> > + return error;
> > + }
> > }
> >
> > return 0;
> > diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
> > index b7625a9..745a030 100644
> > --- a/drivers/input/rmi4/rmi_bus.h
> > +++ b/drivers/input/rmi4/rmi_bus.h
> > @@ -35,6 +35,7 @@ struct rmi_function {
> > struct device dev;
> > struct list_head node;
> >
> > + unsigned int irq_base;
> > unsigned int num_of_irqs;
> > unsigned int irq_pos;
> > unsigned long irq_mask[];
> > @@ -76,7 +77,7 @@ struct rmi_function_handler {
> > void (*remove)(struct rmi_function *fn);
> > int (*config)(struct rmi_function *fn);
> > int (*reset)(struct rmi_function *fn);
> > - int (*attention)(struct rmi_function *fn, unsigned long *irq_bits);
> > + irqreturn_t (*attention)(int irq, void *ctx);
> > int (*suspend)(struct rmi_function *fn);
> > int (*resume)(struct rmi_function *fn);
> > };
> > diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> > index 141ea22..b7ef1f5a 100644
> > --- a/drivers/input/rmi4/rmi_driver.c
> > +++ b/drivers/input/rmi4/rmi_driver.c
> > @@ -21,6 +21,7 @@
> > #include <linux/pm.h>
> > #include <linux/slab.h>
> > #include <linux/of.h>
> > +#include <linux/irqdomain.h>
> > #include <uapi/linux/input.h>
> > #include <linux/rmi.h>
> > #include "rmi_bus.h"
> > @@ -127,28 +128,11 @@ static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
> > return 0;
> > }
> >
> > -static void process_one_interrupt(struct rmi_driver_data *data,
> > - struct rmi_function *fn)
> > -{
> > - struct rmi_function_handler *fh;
> > -
> > - if (!fn || !fn->dev.driver)
> > - return;
> > -
> > - fh = to_rmi_function_handler(fn->dev.driver);
> > - if (fh->attention) {
> > - bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask,
> > - data->irq_count);
> > - if (!bitmap_empty(data->fn_irq_bits, data->irq_count))
> > - fh->attention(fn, data->fn_irq_bits);
> > - }
> > -}
> > -
> > static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
> > {
> > struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> > struct device *dev = &rmi_dev->dev;
> > - struct rmi_function *entry;
> > + int i;
> > int error;
> >
> > if (!data)
> > @@ -173,16 +157,8 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
> > */
> > mutex_unlock(&data->irq_mutex);
> >
> > - /*
> > - * It would be nice to be able to use irq_chip to handle these
> > - * nested IRQs. Unfortunately, most of the current customers for
> > - * this driver are using older kernels (3.0.x) that don't support
> > - * the features required for that. Once they've shifted to more
> > - * recent kernels (say, 3.3 and higher), this should be switched to
> > - * use irq_chip.
> > - */
> > - list_for_each_entry(entry, &data->function_list, node)
> > - process_one_interrupt(data, entry);
> > + for_each_set_bit(i, data->irq_status, data->irq_count)
> > + handle_nested_irq(irq_find_mapping(data->irqdomain, i));
> >
> > if (data->input)
> > input_sync(data->input);
> > @@ -847,6 +823,10 @@ int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx,
> > return pdt->page_start == 0 ? RMI_SCAN_CONTINUE : -ENODEV;
> > }
> >
> > +static struct irq_chip rmi_irq_chip = {
> > + .name = "rmi4",
> > +};
> > +
> > static int rmi_create_function(struct rmi_device *rmi_dev,
> > void *ctx, const struct pdt_entry *pdt)
> > {
> > @@ -878,9 +858,18 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
> > fn->irq_pos = *current_irq_count;
> > *current_irq_count += fn->num_of_irqs;
> >
> > - for (i = 0; i < fn->num_of_irqs; i++)
> > + for (i = 0; i < fn->num_of_irqs; i++) {
> > set_bit(fn->irq_pos + i, fn->irq_mask);
> >
> > + fn->irq_base = irq_create_mapping(data->irqdomain,
> > + fn->irq_pos + i);
> > +
> > +
> > + irq_set_chip_data(fn->irq_base, data);
> > + irq_set_chip_and_handler(fn->irq_base, &rmi_irq_chip,
> > + handle_simple_irq);
> > + }
> > +
> > error = rmi_register_function(fn);
> > if (error)
> > goto err_put_fn;
> > @@ -1000,9 +989,12 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume);
> > static int rmi_driver_remove(struct device *dev)
> > {
> > struct rmi_device *rmi_dev = to_rmi_device(dev);
> > + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> >
> > rmi_disable_irq(rmi_dev, false);
> >
> > + irq_domain_remove(data->irqdomain);
> > +
> > rmi_f34_remove_sysfs(rmi_dev);
> > rmi_free_function_list(rmi_dev);
> >
> > @@ -1034,7 +1026,8 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
> > {
> > struct rmi_device *rmi_dev = data->rmi_dev;
> > struct device *dev = &rmi_dev->dev;
> > - int irq_count;
> > + struct device_node *rmi_of_node = rmi_dev->xport->dev->of_node;
> > + int irq_count = 0;
> > size_t size;
> > int retval;
> >
> > @@ -1045,7 +1038,6 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
> > * being accessed.
> > */
> > rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__);
> > - irq_count = 0;
> > data->bootloader_mode = false;
> >
> > retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs);
> > @@ -1057,6 +1049,14 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
> > if (data->bootloader_mode)
> > dev_warn(dev, "Device in bootloader mode.\n");
> >
> > + /* Allocate and register a linear revmap irq_domain */
> > + data->irqdomain = irq_domain_add_linear(rmi_of_node, irq_count,
> > + &irq_domain_simple_ops, data);
> > + if (!data->irqdomain) {
> > + dev_err(&rmi_dev->dev, "Failed to create IRQ domain\n");
> > + return PTR_ERR(data->irqdomain);
> > + }
> > +
> > data->irq_count = irq_count;
> > data->num_of_irq_regs = (data->irq_count + 7) / 8;
> >
> > @@ -1079,10 +1079,9 @@ int rmi_init_functions(struct rmi_driver_data *data)
> > {
> > struct rmi_device *rmi_dev = data->rmi_dev;
> > struct device *dev = &rmi_dev->dev;
> > - int irq_count;
> > + int irq_count = 0;
> > int retval;
> >
> > - irq_count = 0;
> > rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__);
> > retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function);
> > if (retval < 0) {
> > diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
> > index 8a07ae1..4edaa14 100644
> > --- a/drivers/input/rmi4/rmi_f01.c
> > +++ b/drivers/input/rmi4/rmi_f01.c
> > @@ -681,9 +681,9 @@ static int rmi_f01_resume(struct rmi_function *fn)
> > return 0;
> > }
> >
> > -static int rmi_f01_attention(struct rmi_function *fn,
> > - unsigned long *irq_bits)
> > +static irqreturn_t rmi_f01_attention(int irq, void *ctx)
> > {
> > + struct rmi_function *fn = ctx;
> > struct rmi_device *rmi_dev = fn->rmi_dev;
> > int error;
> > u8 device_status;
> > @@ -692,7 +692,7 @@ static int rmi_f01_attention(struct rmi_function *fn,
> > if (error) {
> > dev_err(&fn->dev,
> > "Failed to read device status: %d.\n", error);
> > - return error;
> > + return IRQ_RETVAL(error);
> > }
> >
> > if (RMI_F01_STATUS_BOOTLOADER(device_status))
> > @@ -704,11 +704,11 @@ static int rmi_f01_attention(struct rmi_function *fn,
> > error = rmi_dev->driver->reset_handler(rmi_dev);
> > if (error) {
> > dev_err(&fn->dev, "Device reset failed: %d\n", error);
> > - return error;
> > + return IRQ_RETVAL(error);
> > }
> > }
> >
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > struct rmi_function_handler rmi_f01_handler = {
> > diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
> > index ad71a5e..b9f07c9 100644
> > --- a/drivers/input/rmi4/rmi_f03.c
> > +++ b/drivers/input/rmi4/rmi_f03.c
> > @@ -199,8 +199,9 @@ static int rmi_f03_config(struct rmi_function *fn)
> > return 0;
> > }
> >
> > -static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > +static irqreturn_t rmi_f03_attention(int irq, void *ctx)
> > {
> > + struct rmi_function *fn = ctx;
> > struct rmi_device *rmi_dev = fn->rmi_dev;
> > struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> > struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> > @@ -217,7 +218,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > /* First grab the data passed by the transport device */
> > if (drvdata->attn_data.size < ob_len) {
> > dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > memcpy(obs, drvdata->attn_data.data, ob_len);
> > @@ -233,7 +234,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > "%s: Failed to read F03 output buffers: %d\n",
> > __func__, error);
> > serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
> > - return error;
> > + return IRQ_RETVAL(error);
> > }
> > }
> >
> > @@ -259,7 +260,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > serio_interrupt(f03->serio, ob_data, serio_flags);
> > }
> >
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > static void rmi_f03_remove(struct rmi_function *fn)
> > diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
> > index bc5e37f..e587c87 100644
> > --- a/drivers/input/rmi4/rmi_f11.c
> > +++ b/drivers/input/rmi4/rmi_f11.c
> > @@ -571,8 +571,7 @@ static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
> >
> > static void rmi_f11_finger_handler(struct f11_data *f11,
> > struct rmi_2d_sensor *sensor,
> > - unsigned long *irq_bits, int num_irq_regs,
> > - int size)
> > + int num_irq_regs, int size)
> > {
> > const u8 *f_state = f11->data.f_state;
> > u8 finger_state;
> > @@ -581,12 +580,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
> > int rel_fingers;
> > int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES;
> >
> > - int abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask,
> > - num_irq_regs * 8);
> > - int rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask,
> > - num_irq_regs * 8);
> > -
> > - if (abs_bits) {
> > + if (sensor->report_abs) {
> > if (abs_size > size)
> > abs_fingers = size / RMI_F11_ABS_BYTES;
> > else
> > @@ -606,7 +600,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
> > }
> > }
> >
> > - if (rel_bits) {
> > + if (sensor->report_rel) {
> > if ((abs_size + sensor->nbr_fingers * RMI_F11_REL_BYTES) > size)
> > rel_fingers = (size - abs_size) / RMI_F11_REL_BYTES;
> > else
> > @@ -616,7 +610,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
> > rmi_f11_rel_pos_report(f11, i);
> > }
> >
> > - if (abs_bits) {
> > + if (sensor->report_abs) {
> > /*
> > * the absolute part is made in 2 parts to allow the kernel
> > * tracking to take place.
> > @@ -1275,8 +1269,9 @@ static int rmi_f11_config(struct rmi_function *fn)
> > return 0;
> > }
> >
> > -static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > +static irqreturn_t rmi_f11_attention(int irq, void *ctx)
> > {
> > + struct rmi_function *fn = ctx;
> > struct rmi_device *rmi_dev = fn->rmi_dev;
> > struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> > struct f11_data *f11 = dev_get_drvdata(&fn->dev);
> > @@ -1302,13 +1297,13 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > data_base_addr, f11->sensor.data_pkt,
> > f11->sensor.pkt_size);
> > if (error < 0)
> > - return error;
> > + return IRQ_RETVAL(error);
> > }
> >
> > - rmi_f11_finger_handler(f11, &f11->sensor, irq_bits,
> > - drvdata->num_of_irq_regs, valid_bytes);
> > + rmi_f11_finger_handler(f11, &f11->sensor,
> > + drvdata->num_of_irq_regs, valid_bytes);
> >
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > static int rmi_f11_resume(struct rmi_function *fn)
> > diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
> > index 8b0db08..e226def 100644
> > --- a/drivers/input/rmi4/rmi_f12.c
> > +++ b/drivers/input/rmi4/rmi_f12.c
> > @@ -197,10 +197,10 @@ static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size)
> > rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
> > }
> >
> > -static int rmi_f12_attention(struct rmi_function *fn,
> > - unsigned long *irq_nr_regs)
> > +static irqreturn_t rmi_f12_attention(int irq, void *ctx)
> > {
> > int retval;
> > + struct rmi_function *fn = ctx;
> > struct rmi_device *rmi_dev = fn->rmi_dev;
> > struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> > struct f12_data *f12 = dev_get_drvdata(&fn->dev);
> > @@ -222,7 +222,7 @@ static int rmi_f12_attention(struct rmi_function *fn,
> > if (retval < 0) {
> > dev_err(&fn->dev, "Failed to read object data. Code: %d.\n",
> > retval);
> > - return retval;
> > + return IRQ_RETVAL(retval);
> > }
> > }
> >
> > @@ -232,7 +232,7 @@ static int rmi_f12_attention(struct rmi_function *fn,
> >
> > input_mt_sync_frame(sensor->input);
> >
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > static int rmi_f12_write_control_regs(struct rmi_function *fn)
> > diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
> > index 82e0f0d..5e3ed5a 100644
> > --- a/drivers/input/rmi4/rmi_f30.c
> > +++ b/drivers/input/rmi4/rmi_f30.c
> > @@ -122,8 +122,9 @@ static void rmi_f30_report_button(struct rmi_function *fn,
> > }
> > }
> >
> > -static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > +static irqreturn_t rmi_f30_attention(int irq, void *ctx)
> > {
> > + struct rmi_function *fn = ctx;
> > struct f30_data *f30 = dev_get_drvdata(&fn->dev);
> > struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
> > int error;
> > @@ -134,7 +135,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > if (drvdata->attn_data.size < f30->register_count) {
> > dev_warn(&fn->dev,
> > "F30 interrupted, but data is missing\n");
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> > memcpy(f30->data_regs, drvdata->attn_data.data,
> > f30->register_count);
> > @@ -147,7 +148,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > dev_err(&fn->dev,
> > "%s: Failed to read F30 data registers: %d\n",
> > __func__, error);
> > - return error;
> > + return IRQ_RETVAL(error);
> > }
> > }
> >
> > @@ -159,7 +160,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > rmi_f03_commit_buttons(f30->f03);
> > }
> >
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > static int rmi_f30_config(struct rmi_function *fn)
> > diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
> > index 4cfe970..7268cf9 100644
> > --- a/drivers/input/rmi4/rmi_f34.c
> > +++ b/drivers/input/rmi4/rmi_f34.c
> > @@ -101,8 +101,9 @@ static int rmi_f34_command(struct f34_data *f34, u8 command,
> > return 0;
> > }
> >
> > -static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > +static irqreturn_t rmi_f34_attention(int irq, void *ctx)
> > {
> > + struct rmi_function *fn = ctx;
> > struct f34_data *f34 = dev_get_drvdata(&fn->dev);
> > int ret;
> > u8 status;
> > @@ -127,7 +128,7 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
> > complete(&f34->v7.cmd_done);
> > }
> >
> > - return 0;
> > + return IRQ_HANDLED;
> > }
> >
> > static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
> > diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
> > index 5343f2c..98a935e 100644
> > --- a/drivers/input/rmi4/rmi_f54.c
> > +++ b/drivers/input/rmi4/rmi_f54.c
> > @@ -610,11 +610,6 @@ static void rmi_f54_work(struct work_struct *work)
> > mutex_unlock(&f54->data_mutex);
> > }
> >
> > -static int rmi_f54_attention(struct rmi_function *fn, unsigned long *irqbits)
> > -{
> > - return 0;
> > -}
> > -
> > static int rmi_f54_config(struct rmi_function *fn)
> > {
> > struct rmi_driver *drv = fn->rmi_dev->driver;
> > @@ -756,6 +751,5 @@ struct rmi_function_handler rmi_f54_handler = {
> > .func = 0x54,
> > .probe = rmi_f54_probe,
> > .config = rmi_f54_config,
> > - .attention = rmi_f54_attention,
> > .remove = rmi_f54_remove,
> > };
> > diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> > index 64125443..5ef5c7c 100644
> > --- a/include/linux/rmi.h
> > +++ b/include/linux/rmi.h
> > @@ -354,6 +354,8 @@ struct rmi_driver_data {
> > struct mutex irq_mutex;
> > struct input_dev *input;
> >
> > + struct irq_domain *irqdomain;
> > +
> > u8 pdt_props;
> >
> > u8 num_rx_electrodes;
> > --
> > 2.7.4
> >
>
> Thanks.
>
> --
> Dmitry
^ permalink raw reply
* Re: [PATCH 1/2] Input: wm831x-on: Delete an error message for a failed memory allocation in wm831x_on_probe()
From: Charles Keepax @ 2018-01-25 9:49 UTC (permalink / raw)
To: SF Markus Elfring
Cc: linux-input, patches, Dmitry Torokhov, LKML, kernel-janitors
In-Reply-To: <d393999d-0c39-c9ea-3a0c-eb534e61b665@users.sourceforge.net>
On Wed, Jan 24, 2018 at 10:21:39PM +0100, SF Markus Elfring wrote:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Wed, 24 Jan 2018 21:55:49 +0100
>
> Omit an extra message for a memory allocation failure in this function.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> ---
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Thanks,
Charles
^ permalink raw reply
* Re: [PATCH 2/2] Input: wm831x-on: Improve a size determination in wm831x_on_probe()
From: Charles Keepax @ 2018-01-25 9:49 UTC (permalink / raw)
To: SF Markus Elfring
Cc: linux-input, patches, Dmitry Torokhov, LKML, kernel-janitors
In-Reply-To: <43f052c7-c98d-7ca2-08ca-e5428b5ad575@users.sourceforge.net>
On Wed, Jan 24, 2018 at 10:22:35PM +0100, SF Markus Elfring wrote:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Wed, 24 Jan 2018 21:58:42 +0100
>
> Replace the specification of a data structure by a pointer dereference
> as the parameter for the operator "sizeof" to make the corresponding size
> determination a bit safer according to the Linux coding style convention.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> ---
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Thanks,
Charles
^ permalink raw reply
* Re: [PATCH 0/4] MMS114 touchscreen patches
From: Simon Shields @ 2018-01-25 13:01 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Andi Shyti, Rob Herring, linux-input, linux-kernel
In-Reply-To: <20180124193804.155654-1-dmitry.torokhov@gmail.com>
Hi Dmitry,
Thanks for the extra fixes!
On Wed, Jan 24, 2018 at 11:38:00AM -0800, Dmitry Torokhov wrote:
> Hi,
>
> This is a combination of couple of my patches + Simons patches dropping
> support for platform data and adding support for mms152, slightly reworked.
>
> Andi, because patches changed a bit I did not add your reviewed-by or
> tested-by, please take another look.
>
> Thanks!
>
> Dmitry Torokhov (2):
> Input: mms114 - do not clobber interrupt trigger
> Input: mms114 - mark as direct input device
>
> Simon Shields (2):
> Input: mms114 - drop platform data and use generic APIs
> Input: mms114 - add support for mms152
>
> .../bindings/input/touchscreen/mms114.txt | 35 ++--
> drivers/input/touchscreen/mms114.c | 229 ++++++++++++---------
> include/linux/platform_data/mms114.h | 24 ---
> 3 files changed, 151 insertions(+), 137 deletions(-)
> delete mode 100644 include/linux/platform_data/mms114.h
>
> --
> Dmitry
>
All looks good to me. Tested on MMS114 and MMS152.
Reviewed-by: Simon Shields <simon@lineageos.org>
Tested-by: Simon Shields <simon@lineageos.org>
Cheers,
Simon
^ permalink raw reply
* [PATCH] Input: twl6040-vibra: Delete an error message for a failed memory allocation in twl6040_vibra_probe()
From: SF Markus Elfring @ 2018-01-25 15:08 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 16:01:32 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/twl6040-vibra.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
index 5690eb7ff954..1bdca0eeed3f 100644
--- a/drivers/input/misc/twl6040-vibra.c
+++ b/drivers/input/misc/twl6040-vibra.c
@@ -259,7 +259,6 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info) {
of_node_put(twl6040_core_node);
- dev_err(&pdev->dev, "couldn't allocate memory\n");
return -ENOMEM;
}
--
2.16.1
^ permalink raw reply related
* [PATCH 0/2] Input: sirfsoc-onkey: Adjustments for sirfsoc_pwrc_probe()
From: SF Markus Elfring @ 2018-01-25 15:45 UTC (permalink / raw)
To: linux-input, linux-arm-kernel, Barry Song, Dmitry Torokhov
Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 16:42:24 +0100
Two update suggestions were taken into account
from static source code analysis.
Markus Elfring (2):
Delete an error message for a failed memory allocation
Improve a size determination
drivers/input/misc/sirfsoc-onkey.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
--
2.16.1
^ permalink raw reply
* [PATCH 1/2] Input: sirfsoc-onkey: Delete an error message for a failed memory allocation in sirfsoc_pwrc_probe()
From: SF Markus Elfring @ 2018-01-25 15:46 UTC (permalink / raw)
To: linux-input, linux-arm-kernel, Barry Song, Dmitry Torokhov
Cc: kernel-janitors, LKML
In-Reply-To: <b66f4105-57f2-adc2-ecde-cd4dacac408c@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 16:32:09 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/sirfsoc-onkey.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
index 4fd038d476a3..9d8b4e2d7063 100644
--- a/drivers/input/misc/sirfsoc-onkey.c
+++ b/drivers/input/misc/sirfsoc-onkey.c
@@ -113,10 +113,8 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata),
GFP_KERNEL);
- if (!pwrcdrv) {
- dev_info(&pdev->dev, "Not enough memory for the device data\n");
+ if (!pwrcdrv)
return -ENOMEM;
- }
/*
* We can't use of_iomap because pwrc is not mapped in memory,
--
2.16.1
^ permalink raw reply related
* [PATCH 2/2] Input: sirfsoc-onkey: Improve a size determination in sirfsoc_pwrc_probe()
From: SF Markus Elfring @ 2018-01-25 15:48 UTC (permalink / raw)
To: linux-input, linux-arm-kernel, Barry Song, Dmitry Torokhov
Cc: kernel-janitors, LKML
In-Reply-To: <b66f4105-57f2-adc2-ecde-cd4dacac408c@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 16:35:13 +0100
Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/sirfsoc-onkey.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
index 9d8b4e2d7063..cdad20811d35 100644
--- a/drivers/input/misc/sirfsoc-onkey.c
+++ b/drivers/input/misc/sirfsoc-onkey.c
@@ -111,8 +111,7 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
int irq;
int error;
- pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata),
- GFP_KERNEL);
+ pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(*pwrcdrv), GFP_KERNEL);
if (!pwrcdrv)
return -ENOMEM;
--
2.16.1
^ permalink raw reply related
* Re: [PATCH v2 3/5] Input: add KEY_ROTATE_LOCK_TOGGLE
From: Jason Gerecke @ 2018-01-25 16:23 UTC (permalink / raw)
To: Brüns, Stefan, Alex Hung, Dmitry Torokhov
Cc: Bastien Nocera, platform-driver-x86@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CANRwn3SzMUvNoBjp2X1jtN9XaQ98RxCCZ86Hu4sPQygTORqjKg@mail.gmail.com>
Any movement on this? Are we just waiting on an ACK/NAK from Dmitry?
Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one /
(That is to say, eight) to the two, /
But you can’t take seven from three, /
So you look at the sixty-fours....
On Tue, Dec 5, 2017 at 10:50 AM, Jason Gerecke <killertofu@gmail.com> wrote:
> Looks like this might also be needed for the MobileStudio Pro...
>
> https://bugzilla.kernel.org/show_bug.cgi?id=197991
>
> Jason
> ---
> Now instead of four in the eights place /
> you’ve got three, ‘Cause you added one /
> (That is to say, eight) to the two, /
> But you can’t take seven from three, /
> So you look at the sixty-fours....
>
>
>
> On Thu, Nov 30, 2017 at 9:51 AM, Brüns, Stefan
> <Stefan.Bruens@rwth-aachen.de> wrote:
>> On Freitag, 10. November 2017 00:34:53 CET Bastien Nocera wrote:
>>> On Thu, 2017-11-09 at 23:44 +0100, Stefan Brüns wrote:
>>> > The key has the same use as the SW_ROTATE_LOCK, but is used on
>>> > devices
>>> > where the state is not tracked by the hardware but has to be handled
>>> > in software.
>>>
>>> I'll let the input and hid subsystem maintainers have the final say
>>> here, though I think that sending out Win+O would be easier, as this is
>>> already something that desktops need to support for those devices that
>>> send the actual Win+O key combination when those buttons are pressed
>>> there.
>>>
>>> If we're going with the separate keycode, could you also file bugs
>>> against xkbd-common and xkeyboard-config to get the key added to the
>>> list of XF86 keysyms and to the default evdev keymap? Otherwise Wayland
>>> and X11 based desktops won't be able to use it.
>>
>> Filed for xkeyboard-config:
>> https://bugs.freedesktop.org/show_bug.cgi?id=103998
>>
>> and xkb-common:
>> https://github.com/xkbcommon/libxkbcommon/issues/55
>>
>> Regards,
>>
>> Stefan
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-input" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] Input: kxtj9: Delete an error message for a failed memory allocation in kxtj9_probe()
From: SF Markus Elfring @ 2018-01-25 17:18 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 18:13:57 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/kxtj9.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c
index efaffcc57e36..ddd5ca6812cb 100644
--- a/drivers/input/misc/kxtj9.c
+++ b/drivers/input/misc/kxtj9.c
@@ -526,11 +526,8 @@ static int kxtj9_probe(struct i2c_client *client,
}
tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL);
- if (!tj9) {
- dev_err(&client->dev,
- "failed to allocate memory for module data\n");
+ if (!tj9)
return -ENOMEM;
- }
tj9->client = client;
tj9->pdata = *pdata;
--
2.16.1
^ permalink raw reply related
* [PATCH 0/3] Input: ims-pcu: Adjustments for three function implementations
From: SF Markus Elfring @ 2018-01-25 18:51 UTC (permalink / raw)
To: linux-input, Arvind Yadav, Dmitry Torokhov, Joe Perches,
Johan Hovold, Zhen Lei
Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 19:46:56 +0100
Three update suggestions were taken into account
from static source code analysis.
Markus Elfring (3):
Delete an error message for a failed memory allocation
in ims_pcu_buffers_alloc()
Improve a size determination in two functions
Delete an unnecessary variable assignment in ims_pcu_setup_gamepad()
drivers/input/misc/ims-pcu.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
--
2.16.1
^ permalink raw reply
* [PATCH 1/3] Input: ims-pcu: Delete an error message for a failed memory allocation in ims_pcu_buffers_alloc()
From: SF Markus Elfring @ 2018-01-25 18:52 UTC (permalink / raw)
To: linux-input, Arvind Yadav, Dmitry Torokhov, Joe Perches,
Johan Hovold, Zhen Lei
Cc: LKML, kernel-janitors
In-Reply-To: <ff77a871-d30a-e873-ab73-2d80198bfbe7@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 19:06:07 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/ims-pcu.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 3d51175c4d72..4aca2a02ff6d 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1556,7 +1556,6 @@ static int ims_pcu_buffers_alloc(struct ims_pcu *pcu)
*/
pcu->urb_out_buf = kmalloc(pcu->max_out_size, GFP_KERNEL);
if (!pcu->urb_out_buf) {
- dev_err(pcu->dev, "Failed to allocate memory for write buffer\n");
error = -ENOMEM;
goto err_free_in_urb;
}
--
2.16.1
^ permalink raw reply related
* [PATCH 2/3] Input: ims-pcu: Improve a size determination in two functions
From: SF Markus Elfring @ 2018-01-25 18:53 UTC (permalink / raw)
To: linux-input, Arvind Yadav, Dmitry Torokhov, Joe Perches,
Johan Hovold, Zhen Lei
Cc: LKML, kernel-janitors
In-Reply-To: <ff77a871-d30a-e873-ab73-2d80198bfbe7@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 19:20:38 +0100
Replace the specification of data structures by pointer dereferences
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/ims-pcu.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 4aca2a02ff6d..d7778b273151 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -288,12 +288,10 @@ static void ims_pcu_gamepad_report(struct ims_pcu *pcu, u32 data)
static int ims_pcu_setup_gamepad(struct ims_pcu *pcu)
{
- struct ims_pcu_gamepad *gamepad;
- struct input_dev *input;
int error;
+ struct ims_pcu_gamepad *gamepad = kzalloc(sizeof(*gamepad), GFP_KERNEL);
+ struct input_dev *input = input_allocate_device();
- gamepad = kzalloc(sizeof(struct ims_pcu_gamepad), GFP_KERNEL);
- input = input_allocate_device();
if (!gamepad || !input) {
dev_err(pcu->dev,
"Not enough memory for gamepad device\n");
@@ -2003,10 +2001,9 @@ static int ims_pcu_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
- struct ims_pcu *pcu;
int error;
+ struct ims_pcu *pcu = kzalloc(sizeof(*pcu), GFP_KERNEL);
- pcu = kzalloc(sizeof(struct ims_pcu), GFP_KERNEL);
if (!pcu)
return -ENOMEM;
--
2.16.1
^ permalink raw reply related
* [PATCH 3/3] Input: ims-pcu: Delete an unnecessary variable assignment in ims_pcu_setup_gamepad()
From: SF Markus Elfring @ 2018-01-25 18:54 UTC (permalink / raw)
To: linux-input, Arvind Yadav, Dmitry Torokhov, Joe Perches,
Johan Hovold, Zhen Lei
Cc: LKML, kernel-janitors
In-Reply-To: <ff77a871-d30a-e873-ab73-2d80198bfbe7@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 19:37:34 +0100
An error code was assigned to a local variable in an if branch.
This value was not read again before it was used by a return statement
as a constant value at the end of this function.
Thus remove such an unneeded assignment.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/ims-pcu.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index d7778b273151..aa1bb284c714 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -295,7 +295,6 @@ static int ims_pcu_setup_gamepad(struct ims_pcu *pcu)
if (!gamepad || !input) {
dev_err(pcu->dev,
"Not enough memory for gamepad device\n");
- error = -ENOMEM;
goto err_free_mem;
}
--
2.16.1
^ permalink raw reply related
* [PATCH v3 3/3] Input: goodix - use generic touchscreen_properties
From: Marcin Niestroj @ 2018-01-25 19:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Bastien Nocera, Antonio Ospite, linux-input, Marcin Niestroj
In-Reply-To: <20180125190829.8968-1-m.niestroj@grinn-global.com>
Use touchscreen_properties structure instead of implementing all
properties by our own. It allows us to reuse generic code for parsing
device-tree properties (which was implemented manually in the driver
for now). Additionally, it allows us to report events using generic
touchscreen_report_pos(), which automatically handles inverted and
swapped axes.
Developed and tested on custom DT-based device with gt1151 touch
panel.
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
---
Changes v2 -> v3 (suggested by Bastien):
- fix commit description
Changes v1 -> v2:
- rebased on patches 1 and 2 in series
- added description of test board in changelog (suggested by Bastien)
drivers/input/touchscreen/goodix.c | 93 ++++++++++++++------------------------
1 file changed, 33 insertions(+), 60 deletions(-)
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index dc832890f6d3..f82101cd9c04 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/irq.h>
@@ -43,11 +44,7 @@ struct goodix_ts_data {
struct i2c_client *client;
struct input_dev *input_dev;
const struct goodix_chip_data *chip;
- int abs_x_max;
- int abs_y_max;
- bool swapped_x_y;
- bool inverted_x;
- bool inverted_y;
+ struct touchscreen_properties prop;
unsigned int max_touch_num;
unsigned int int_trigger_type;
struct gpio_desc *gpiod_int;
@@ -295,24 +292,10 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
int input_y = get_unaligned_le16(&coor_data[3]);
int input_w = get_unaligned_le16(&coor_data[5]);
- /* Inversions have to happen before axis swapping */
- if (!ts->swapped_x_y) {
- if (ts->inverted_x)
- input_x = ts->abs_x_max - input_x;
- if (ts->inverted_y)
- input_y = ts->abs_y_max - input_y;
- } else {
- if (ts->inverted_x)
- input_x = ts->abs_y_max - input_x;
- if (ts->inverted_y)
- input_y = ts->abs_x_max - input_y;
- swap(input_x, input_y);
- }
-
input_mt_slot(ts->input_dev, id);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
+ touchscreen_report_pos(ts->input_dev, &ts->prop, input_x, input_y,
+ true);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
}
@@ -585,6 +568,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
static void goodix_read_config(struct goodix_ts_data *ts)
{
u8 config[GOODIX_CONFIG_MAX_LENGTH];
+ int x_max, y_max;
int error;
error = goodix_i2c_read(ts->client, ts->chip->config_addr,
@@ -593,37 +577,34 @@ static void goodix_read_config(struct goodix_ts_data *ts)
dev_warn(&ts->client->dev,
"Error reading config (%d), using defaults\n",
error);
- ts->abs_x_max = GOODIX_MAX_WIDTH - 1;
- ts->abs_y_max = GOODIX_MAX_HEIGHT - 1;
- if (ts->swapped_x_y)
- swap(ts->abs_x_max, ts->abs_y_max);
+ x_max = GOODIX_MAX_WIDTH;
+ y_max = GOODIX_MAX_HEIGHT;
ts->int_trigger_type = GOODIX_INT_TRIGGER;
ts->max_touch_num = GOODIX_MAX_CONTACTS;
- return;
+ goto input_set_params;
}
- ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]) - 1;
- ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]) - 1;
- if (ts->swapped_x_y)
- swap(ts->abs_x_max, ts->abs_y_max);
+ x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
+ y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f;
- if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) {
+ if (!x_max || !y_max || !ts->max_touch_num) {
dev_err(&ts->client->dev,
"Invalid config, using defaults\n");
- ts->abs_x_max = GOODIX_MAX_WIDTH - 1;
- ts->abs_y_max = GOODIX_MAX_HEIGHT - 1;
- if (ts->swapped_x_y)
- swap(ts->abs_x_max, ts->abs_y_max);
+ x_max = GOODIX_MAX_WIDTH;
+ y_max = GOODIX_MAX_HEIGHT;
ts->max_touch_num = GOODIX_MAX_CONTACTS;
}
- if (dmi_check_system(rotated_screen)) {
- ts->inverted_x = true;
- ts->inverted_y = true;
- dev_dbg(&ts->client->dev,
- "Applying '180 degrees rotated screen' quirk\n");
- }
+input_set_params:
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
+ 0, x_max - 1, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+ 0, y_max - 1, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ input_mt_init_slots(ts->input_dev, ts->max_touch_num,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
}
/**
@@ -698,16 +679,6 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts)
return -ENOMEM;
}
- input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
- 0, ts->abs_x_max, 0, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
- 0, ts->abs_y_max, 0, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
-
- input_mt_init_slots(ts->input_dev, ts->max_touch_num,
- INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
-
ts->input_dev->name = "Goodix Capacitive TouchScreen";
ts->input_dev->phys = "input/ts";
ts->input_dev->id.bustype = BUS_I2C;
@@ -742,19 +713,21 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
{
int error;
- ts->swapped_x_y = device_property_read_bool(&ts->client->dev,
- "touchscreen-swapped-x-y");
- ts->inverted_x = device_property_read_bool(&ts->client->dev,
- "touchscreen-inverted-x");
- ts->inverted_y = device_property_read_bool(&ts->client->dev,
- "touchscreen-inverted-y");
-
- goodix_read_config(ts);
-
error = goodix_request_input_dev(ts);
if (error)
return error;
+ goodix_read_config(ts);
+
+ touchscreen_parse_properties(ts->input_dev, true, &ts->prop);
+
+ if (dmi_check_system(rotated_screen)) {
+ ts->prop.invert_x = true;
+ ts->prop.invert_y = true;
+ dev_dbg(&ts->client->dev,
+ "Applying '180 degrees rotated screen' quirk\n");
+ }
+
ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
error = goodix_request_irq(ts);
if (error) {
--
2.16.1
^ permalink raw reply related
* [PATCH v3 0/3] Input: goodix - fixes and conversion to touchscreen_properties
From: Marcin Niestroj @ 2018-01-25 19:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Bastien Nocera, Antonio Ospite, linux-input, Marcin Niestroj
Hi,
In this patch series I have only improved / fixed commit descriptions.
In comments of v2 patch series [1] there was a question if we should
left these 3 patches separate or meld them together. However there was
no decision made, so I've kept them separate for now. That way patches
1 and 2 can be easily backported to stable releases.
Patches were rebased and tested on v4.15-rc9.
[1] https://www.spinics.net/lists/linux-input/msg53976.html
Marcin Niestroj (3):
Input: goodix - fix reported range
Input: goodix - fix simultaneous axes inversion and swap
Input: goodix - use generic touchscreen_properties
drivers/input/touchscreen/goodix.c | 87 +++++++++++++++-----------------------
1 file changed, 33 insertions(+), 54 deletions(-)
--
2.16.1
^ permalink raw reply
* [PATCH 0/2] Input-da9063_onkey: Adjustments for da9063_onkey_probe()
From: SF Markus Elfring @ 2018-01-25 19:34 UTC (permalink / raw)
To: linux-input, support.opensource, Dmitry Torokhov, Steve Twiss
Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 20:30:40 +0100
Two update suggestions were taken into account
from static source code analysis.
Markus Elfring (2):
Delete an error message for a failed memory allocation
Improve a size determination
drivers/input/misc/da9063_onkey.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
--
2.16.1
^ permalink raw reply
* [PATCH 1/2] Input: da9063_onkey: Delete an error message for a failed memory allocation in da9063_onkey_probe()
From: SF Markus Elfring @ 2018-01-25 19:35 UTC (permalink / raw)
To: linux-input, support.opensource, Dmitry Torokhov, Steve Twiss
Cc: LKML, kernel-janitors
In-Reply-To: <9b0e8f6a-6386-d307-34fc-7936c52bd0c6@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 20:22:57 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/da9063_onkey.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/misc/da9063_onkey.c b/drivers/input/misc/da9063_onkey.c
index 3e9c353d82ef..acf592975bef 100644
--- a/drivers/input/misc/da9063_onkey.c
+++ b/drivers/input/misc/da9063_onkey.c
@@ -215,10 +215,8 @@ static int da9063_onkey_probe(struct platform_device *pdev)
onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
GFP_KERNEL);
- if (!onkey) {
- dev_err(&pdev->dev, "Failed to allocate memory.\n");
+ if (!onkey)
return -ENOMEM;
- }
onkey->config = match->data;
onkey->dev = &pdev->dev;
--
2.16.1
^ permalink raw reply related
* [PATCH v3 2/3] Input: goodix - fix simultaneous axes inversion and swap
From: Marcin Niestroj @ 2018-01-25 19:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Bastien Nocera, Antonio Ospite, linux-input, Marcin Niestroj
In-Reply-To: <20180125190829.8968-1-m.niestroj@grinn-global.com>
goodix_ts_data structure contains abs_x_max and abs_y_max members,
which contain already swapped maximum ranges. That causes reporting
touch events with invalid position (out of range values).
Problem occurs for example when ts->inverted_x and ts->swapped_x_y are
true, but ts->inverted_y is false. Assuming we have 720x1280 touch
panel, ts->abs_x_max == 1279 and ts->abs_y_max == 719 (because we
inverted that in goodix_read_config()). Now let's assume that we
received event from (0:0) position (in touch panel original
coordinates). In function goodix_ts_report_touch() we calculate
input_x as 1279, but after swapping input_y takes that value (which is
more that maximum 719 value reported during initialization).
Take into account that abs_x_max and abs_y_max are already swapped
in goodix_ts_report_touch(), so position for inverted axes will be
calculated correctly.
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
Fixes: ad48cf5e9597 ("Input: goodix - add axis swapping and axis inversion support")
---
Changes v2 -> v3 (suggested by Bastien):
- add explanation about when the problem occurs
Changes v1 -> v2 (suggested by Bastien):
- patch splitted off from patch 3
drivers/input/touchscreen/goodix.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index 7896097ca69b..dc832890f6d3 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -296,12 +296,18 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
int input_w = get_unaligned_le16(&coor_data[5]);
/* Inversions have to happen before axis swapping */
- if (ts->inverted_x)
- input_x = ts->abs_x_max - input_x;
- if (ts->inverted_y)
- input_y = ts->abs_y_max - input_y;
- if (ts->swapped_x_y)
+ if (!ts->swapped_x_y) {
+ if (ts->inverted_x)
+ input_x = ts->abs_x_max - input_x;
+ if (ts->inverted_y)
+ input_y = ts->abs_y_max - input_y;
+ } else {
+ if (ts->inverted_x)
+ input_x = ts->abs_y_max - input_x;
+ if (ts->inverted_y)
+ input_y = ts->abs_x_max - input_y;
swap(input_x, input_y);
+ }
input_mt_slot(ts->input_dev, id);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
--
2.16.1
^ permalink raw reply related
* [PATCH v3 1/3] Input: goodix - fix reported range
From: Marcin Niestroj @ 2018-01-25 19:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Bastien Nocera, Antonio Ospite, linux-input, Marcin Niestroj
In-Reply-To: <20180125190829.8968-1-m.niestroj@grinn-global.com>
Touchscreen coordinates are 0-indexed, so report touchscreen range
as (0:size-1).
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
Fixes: ca96ea86eed4 ("Input: add driver for the Goodix touchpanel")
---
Changes v2 -> v3: fix commit description (suggested by Bastien)
Changes v1 -> v2: patch splitted off from patch 3 (suggested by Bastien)
drivers/input/touchscreen/goodix.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index 69d0b8cbc71f..7896097ca69b 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -587,8 +587,8 @@ static void goodix_read_config(struct goodix_ts_data *ts)
dev_warn(&ts->client->dev,
"Error reading config (%d), using defaults\n",
error);
- ts->abs_x_max = GOODIX_MAX_WIDTH;
- ts->abs_y_max = GOODIX_MAX_HEIGHT;
+ ts->abs_x_max = GOODIX_MAX_WIDTH - 1;
+ ts->abs_y_max = GOODIX_MAX_HEIGHT - 1;
if (ts->swapped_x_y)
swap(ts->abs_x_max, ts->abs_y_max);
ts->int_trigger_type = GOODIX_INT_TRIGGER;
@@ -596,8 +596,8 @@ static void goodix_read_config(struct goodix_ts_data *ts)
return;
}
- ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
- ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
+ ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]) - 1;
+ ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]) - 1;
if (ts->swapped_x_y)
swap(ts->abs_x_max, ts->abs_y_max);
ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
@@ -605,8 +605,8 @@ static void goodix_read_config(struct goodix_ts_data *ts)
if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) {
dev_err(&ts->client->dev,
"Invalid config, using defaults\n");
- ts->abs_x_max = GOODIX_MAX_WIDTH;
- ts->abs_y_max = GOODIX_MAX_HEIGHT;
+ ts->abs_x_max = GOODIX_MAX_WIDTH - 1;
+ ts->abs_y_max = GOODIX_MAX_HEIGHT - 1;
if (ts->swapped_x_y)
swap(ts->abs_x_max, ts->abs_y_max);
ts->max_touch_num = GOODIX_MAX_CONTACTS;
--
2.16.1
^ permalink raw reply related
* [PATCH 2/2] Input: da9063_onkey: Improve a size determination in da9063_onkey_probe()
From: SF Markus Elfring @ 2018-01-25 19:36 UTC (permalink / raw)
To: linux-input, support.opensource, Dmitry Torokhov, Steve Twiss
Cc: LKML, kernel-janitors
In-Reply-To: <9b0e8f6a-6386-d307-34fc-7936c52bd0c6@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 20:24:47 +0100
Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/da9063_onkey.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/misc/da9063_onkey.c b/drivers/input/misc/da9063_onkey.c
index acf592975bef..310f9c408636 100644
--- a/drivers/input/misc/da9063_onkey.c
+++ b/drivers/input/misc/da9063_onkey.c
@@ -213,8 +213,7 @@ static int da9063_onkey_probe(struct platform_device *pdev)
if (!match)
return -ENXIO;
- onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
- GFP_KERNEL);
+ onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
if (!onkey)
return -ENOMEM;
--
2.16.1
^ permalink raw reply related
* [PATCH] Input: da9055_onkey: Delete an error message for a failed memory allocation in da9055_onkey_probe()
From: SF Markus Elfring @ 2018-01-25 19:51 UTC (permalink / raw)
To: linux-input, support.opensource, Dmitry Torokhov; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 20:47:03 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/misc/da9055_onkey.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c
index 3251a9693f45..eabddb226998 100644
--- a/drivers/input/misc/da9055_onkey.c
+++ b/drivers/input/misc/da9055_onkey.c
@@ -87,10 +87,8 @@ static int da9055_onkey_probe(struct platform_device *pdev)
}
onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
- if (!onkey) {
- dev_err(&pdev->dev, "Failed to allocate memory\n");
+ if (!onkey)
return -ENOMEM;
- }
input_dev = input_allocate_device();
if (!input_dev) {
--
2.16.1
^ permalink raw reply related
* [PATCH] Input: matrix-keymap: Delete an error message for a failed memory allocation in matrix_keypad_build_keymap()
From: SF Markus Elfring @ 2018-01-25 20:12 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 25 Jan 2018 21:07:00 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/matrix-keymap.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c
index 8ccefc15c7a4..298bd56b02bd 100644
--- a/drivers/input/matrix-keymap.c
+++ b/drivers/input/matrix-keymap.c
@@ -173,11 +173,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
keymap = devm_kzalloc(input_dev->dev.parent,
max_keys * sizeof(*keymap),
GFP_KERNEL);
- if (!keymap) {
- dev_err(input_dev->dev.parent,
- "Unable to allocate memory for keymap");
+ if (!keymap)
return -ENOMEM;
- }
}
input_dev->keycode = keymap;
--
2.16.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox