All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Dudley Du <dudley.dulixin@gmail.com>
Cc: rydberg@euromail.se, Dudley Du <dudl@cypress.com>,
	bleung@google.com, linux-input@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v9 01/18] input: cyapa: add device resource management infrastructure support
Date: Sun, 9 Nov 2014 13:25:41 -0800	[thread overview]
Message-ID: <20141109212541.GC37384@dtor-ws> (raw)
In-Reply-To: <1415003590-30485-2-git-send-email-dudl@cypress.com>

Hi Dudley,

On Mon, Nov 03, 2014 at 04:32:53PM +0800, Dudley Du wrote:
> Modify cyapa driver to support device resource management infrastructure
> to reduce the mistakes of resource management.
> TEST=test on Chromebooks.
> 
> Signed-off-by: Dudley Du <dudl@cypress.com>
> ---
>  drivers/input/mouse/cyapa.c | 48 ++++++++++++++++++---------------------------
>  1 file changed, 19 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
> index b409c3d..b3d7a2a 100644
> --- a/drivers/input/mouse/cyapa.c
> +++ b/drivers/input/mouse/cyapa.c
> @@ -409,11 +409,11 @@ static ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values)
>  		cmd = cyapa_smbus_cmds[cmd_idx].cmd;
>  		len = cyapa_smbus_cmds[cmd_idx].len;
>  		return cyapa_smbus_read_block(cyapa, cmd, len, values);
> -	} else {
> -		cmd = cyapa_i2c_cmds[cmd_idx].cmd;
> -		len = cyapa_i2c_cmds[cmd_idx].len;
> -		return cyapa_i2c_reg_read_block(cyapa, cmd, len, values);
>  	}
> +
> +	cmd = cyapa_i2c_cmds[cmd_idx].cmd;
> +	len = cyapa_i2c_cmds[cmd_idx].len;
> +	return cyapa_i2c_reg_read_block(cyapa, cmd, len, values);

I am not sure why you are changing this code, it has nothing to do with
managed resources and the original was just fine.

>  }
>  
>  /*
> @@ -762,7 +762,7 @@ static int cyapa_create_input_dev(struct cyapa *cyapa)
>  	if (!cyapa->physical_size_x || !cyapa->physical_size_y)
>  		return -EINVAL;
>  
> -	input = cyapa->input = input_allocate_device();
> +	input = cyapa->input = devm_input_allocate_device(dev);

If you are using devm_* then you do not need to manually cal
input_free_device() (further down in this fucntion).

>  	if (!input) {
>  		dev_err(dev, "allocate memory for input device failed\n");
>  		return -ENOMEM;
> @@ -837,11 +837,9 @@ static int cyapa_probe(struct i2c_client *client,
>  		return -EIO;
>  	}
>  
> -	cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL);
> -	if (!cyapa) {
> -		dev_err(dev, "allocate memory for cyapa failed\n");
> +	cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL);
> +	if (!cyapa)
>  		return -ENOMEM;
> -	}
>  
>  	cyapa->gen = CYAPA_GEN3;
>  	cyapa->client = client;
> @@ -856,51 +854,43 @@ static int cyapa_probe(struct i2c_client *client,
>  	ret = cyapa_check_is_operational(cyapa);
>  	if (ret) {
>  		dev_err(dev, "device not operational, %d\n", ret);
> -		goto err_mem_free;
> +		return ret;
>  	}
>  
>  	ret = cyapa_create_input_dev(cyapa);
>  	if (ret) {
>  		dev_err(dev, "create input_dev instance failed, %d\n", ret);
> -		goto err_mem_free;
> +		return ret;
>  	}
>  
>  	ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
>  	if (ret) {
>  		dev_err(dev, "set active power failed, %d\n", ret);
> -		goto err_unregister_device;
> +		return ret;
>  	}
>  
>  	cyapa->irq = client->irq;
> -	ret = request_threaded_irq(cyapa->irq,
> -				   NULL,
> -				   cyapa_irq,
> -				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> -				   "cyapa",
> -				   cyapa);
> +	ret = devm_request_threaded_irq(dev,
> +					cyapa->irq,
> +					NULL,
> +					cyapa_irq,
> +					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> +					"cyapa",
> +					cyapa);
>  	if (ret) {
>  		dev_err(dev, "IRQ request failed: %d\n, ", ret);
> -		goto err_unregister_device;
> +		return ret;
>  	}
>  
>  	return 0;
> -
> -err_unregister_device:
> -	input_unregister_device(cyapa->input);
> -err_mem_free:
> -	kfree(cyapa);
> -
> -	return ret;
>  }
>  
>  static int cyapa_remove(struct i2c_client *client)
>  {
>  	struct cyapa *cyapa = i2c_get_clientdata(client);
>  
> -	free_irq(cyapa->irq, cyapa);
> -	input_unregister_device(cyapa->input);
> +	disable_irq(cyapa->irq);
>  	cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
> -	kfree(cyapa);

I refer devm* conversions to completely eradicate ->remove() methods.
I took the liberty to edit the patch a bit, does the version below work
for you?

Thanks!

-- 
Dmitry


Input: cyapa - switch to using managed resources

From: Dudley Du <dudley.dulixin@gmail.com>

Use of managed resources simplifies error handling and device removal code.

Signed-off-by: Dudley Du <dudl@cypress.com>
[Dmitry: added open/close methods so cyapa_remove is no longer needed.]
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/mouse/cyapa.c |  184 +++++++++++++++++++++++++------------------
 1 file changed, 105 insertions(+), 79 deletions(-)

diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 1d978c7..c84a9eb 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -577,10 +577,13 @@ static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode)
 	power = ret & ~PWR_MODE_MASK;
 	power |= power_mode & PWR_MODE_MASK;
 	ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power);
-	if (ret < 0)
+	if (ret < 0) {
 		dev_err(dev, "failed to set power_mode 0x%02x err = %d\n",
 			power_mode, ret);
-	return ret;
+		return ret;
+	}
+
+	return 0;
 }
 
 static int cyapa_get_query_data(struct cyapa *cyapa)
@@ -753,16 +756,40 @@ static u8 cyapa_check_adapter_functionality(struct i2c_client *client)
 	return ret;
 }
 
+static int cyapa_open(struct input_dev *input)
+{
+	struct cyapa *cyapa = input_get_drvdata(input);
+	struct i2c_client *client = cyapa->client;
+	int error;
+
+	error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
+	if (error) {
+		dev_err(&client->dev, "set active power failed: %d\n", error);
+		return error;
+	}
+
+	enable_irq(client->irq);
+	return 0;
+}
+
+static void cyapa_close(struct input_dev *input)
+{
+	struct cyapa *cyapa = input_get_drvdata(input);
+
+	disable_irq(cyapa->client->irq);
+	cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
+}
+
 static int cyapa_create_input_dev(struct cyapa *cyapa)
 {
 	struct device *dev = &cyapa->client->dev;
-	int ret;
 	struct input_dev *input;
+	int error;
 
 	if (!cyapa->physical_size_x || !cyapa->physical_size_y)
 		return -EINVAL;
 
-	input = cyapa->input = input_allocate_device();
+	input = devm_input_allocate_device(dev);
 	if (!input) {
 		dev_err(dev, "allocate memory for input device failed\n");
 		return -ENOMEM;
@@ -775,6 +802,9 @@ static int cyapa_create_input_dev(struct cyapa *cyapa)
 	input->id.product = 0;  /* means any product in eventcomm. */
 	input->dev.parent = &cyapa->client->dev;
 
+	input->open = cyapa_open;
+	input->close = cyapa_close;
+
 	input_set_drvdata(input, cyapa);
 
 	__set_bit(EV_ABS, input->evbit);
@@ -802,34 +832,24 @@ static int cyapa_create_input_dev(struct cyapa *cyapa)
 		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 
 	/* handle pointer emulation and unused slots in core */
-	ret = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS,
-				  INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED);
-	if (ret) {
-		dev_err(dev, "allocate memory for MT slots failed, %d\n", ret);
-		goto err_free_device;
+	error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS,
+				    INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED);
+	if (error) {
+		dev_err(dev, "failed to initialize MT slots: %d\n", error);
+		return error;
 	}
 
-	/* Register the device in input subsystem */
-	ret = input_register_device(input);
-	if (ret) {
-		dev_err(dev, "input device register failed, %d\n", ret);
-		goto err_free_device;
-	}
+	cyapa->input = input;
 	return 0;
-
-err_free_device:
-	input_free_device(input);
-	cyapa->input = NULL;
-	return ret;
 }
 
 static int cyapa_probe(struct i2c_client *client,
 		       const struct i2c_device_id *dev_id)
 {
-	int ret;
-	u8 adapter_func;
-	struct cyapa *cyapa;
 	struct device *dev = &client->dev;
+	struct cyapa *cyapa;
+	u8 adapter_func;
+	int error;
 
 	adapter_func = cyapa_check_adapter_functionality(client);
 	if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) {
@@ -837,11 +857,9 @@ static int cyapa_probe(struct i2c_client *client,
 		return -EIO;
 	}
 
-	cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL);
-	if (!cyapa) {
-		dev_err(dev, "allocate memory for cyapa failed\n");
+	cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL);
+	if (!cyapa)
 		return -ENOMEM;
-	}
 
 	cyapa->gen = CYAPA_GEN3;
 	cyapa->client = client;
@@ -852,66 +870,61 @@ static int cyapa_probe(struct i2c_client *client,
 	/* i2c isn't supported, use smbus */
 	if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS)
 		cyapa->smbus = true;
+
 	cyapa->state = CYAPA_STATE_NO_DEVICE;
-	ret = cyapa_check_is_operational(cyapa);
-	if (ret) {
-		dev_err(dev, "device not operational, %d\n", ret);
-		goto err_mem_free;
-	}
 
-	ret = cyapa_create_input_dev(cyapa);
-	if (ret) {
-		dev_err(dev, "create input_dev instance failed, %d\n", ret);
-		goto err_mem_free;
+	error = cyapa_check_is_operational(cyapa);
+	if (error) {
+		dev_err(dev, "device not operational, %d\n", error);
+		return error;
 	}
 
-	ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
-	if (ret) {
-		dev_err(dev, "set active power failed, %d\n", ret);
-		goto err_unregister_device;
+	/* Power down the device until we need it */
+	error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
+	if (error) {
+		dev_err(dev, "failed to quiesce the device: %d\n", error);
+		return error;
 	}
 
-	cyapa->irq = client->irq;
-	ret = request_threaded_irq(cyapa->irq,
-				   NULL,
-				   cyapa_irq,
-				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-				   "cyapa",
-				   cyapa);
-	if (ret) {
-		dev_err(dev, "IRQ request failed: %d\n, ", ret);
-		goto err_unregister_device;
+	error = cyapa_create_input_dev(cyapa);
+	if (error)
+		return error;
+
+	error = devm_request_threaded_irq(dev, client->irq,
+					  NULL, cyapa_irq,
+					  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					  "cyapa", cyapa);
+	if (error) {
+		dev_err(dev, "IRQ request failed: %d\n, ", error);
+		return error;
 	}
 
-	return 0;
-
-err_unregister_device:
-	input_unregister_device(cyapa->input);
-err_mem_free:
-	kfree(cyapa);
+	/* Disable IRQ until the device is opened */
+	disable_irq(client->irq);
 
-	return ret;
-}
-
-static int cyapa_remove(struct i2c_client *client)
-{
-	struct cyapa *cyapa = i2c_get_clientdata(client);
-
-	free_irq(cyapa->irq, cyapa);
-	input_unregister_device(cyapa->input);
-	cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
-	kfree(cyapa);
+	/* Register the device in input subsystem */
+	error = input_register_device(cyapa->input);
+	if (error) {
+		dev_err(dev, "failed to register input device: %d\n", error);
+		return error;
+	}
 
 	return 0;
 }
 
 static int __maybe_unused cyapa_suspend(struct device *dev)
 {
-	int ret;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct cyapa *cyapa = i2c_get_clientdata(client);
+	struct input_dev *input = cyapa->input;
 	u8 power_mode;
-	struct cyapa *cyapa = dev_get_drvdata(dev);
+	int error;
+
+	error = mutex_lock_interruptible(&input->mutex);
+	if (error)
+		return error;
 
-	disable_irq(cyapa->irq);
+	disable_irq(client->irq);
 
 	/*
 	 * Set trackpad device to idle mode if wakeup is allowed,
@@ -919,28 +932,42 @@ static int __maybe_unused cyapa_suspend(struct device *dev)
 	 */
 	power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE
 					    : PWR_MODE_OFF;
-	ret = cyapa_set_power_mode(cyapa, power_mode);
-	if (ret < 0)
-		dev_err(dev, "set power mode failed, %d\n", ret);
+	error = cyapa_set_power_mode(cyapa, power_mode);
+	if (error)
+		dev_err(dev, "resume: set power mode to %d failed: %d\n",
+			 power_mode, error);
 
 	if (device_may_wakeup(dev))
 		cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0);
+
+	mutex_unlock(&input->mutex);
+
 	return 0;
 }
 
 static int __maybe_unused cyapa_resume(struct device *dev)
 {
-	int ret;
-	struct cyapa *cyapa = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct cyapa *cyapa = i2c_get_clientdata(client);
+	struct input_dev *input = cyapa->input;
+	u8 power_mode;
+	int error;
+
+	mutex_lock(&input->mutex);
 
 	if (device_may_wakeup(dev) && cyapa->irq_wake)
 		disable_irq_wake(cyapa->irq);
 
-	ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
-	if (ret)
-		dev_warn(dev, "resume active power failed, %d\n", ret);
+	power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF;
+	error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
+	if (error)
+		dev_warn(dev, "resume: set power mode to %d failed: %d\n",
+			 power_mode, error);
 
 	enable_irq(cyapa->irq);
+
+	mutex_unlock(&input->mutex);
+
 	return 0;
 }
 
@@ -960,7 +987,6 @@ static struct i2c_driver cyapa_driver = {
 	},
 
 	.probe = cyapa_probe,
-	.remove = cyapa_remove,
 	.id_table = cyapa_id_table,
 };
 

  reply	other threads:[~2014-11-09 21:25 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-03  8:32 [PATCH v9 01/18] input: cyapa: instruction of cyapa patches Dudley Du
2014-11-03  8:32 ` [PATCH v9 01/18] input: cyapa: add device resource management infrastructure support Dudley Du
2014-11-09 21:25   ` Dmitry Torokhov [this message]
2014-11-10  2:48     ` Dudley Du
2014-11-10  3:30       ` Dmitry Torokhov
2014-11-03  8:32 ` [PATCH v9 02/18] input: cyapa: re-design driver to support multi-trackpad in one driver Dudley Du
2014-11-10  8:18   ` Dmitry Torokhov
2014-11-10 11:04     ` Dudley Du
2014-11-03  8:32 ` [PATCH v9 03/18] input: cyapa: add gen3 trackpad device basic functions support Dudley Du
2014-11-10  8:30   ` Dmitry Torokhov
2014-11-10 11:05     ` Dudley Du
2014-11-03  8:32 ` [PATCH v9 04/18] input: cyapa: add gen5 " Dudley Du
2014-11-03  8:32 ` [PATCH v9 05/18] input: cyapa: add power management interfaces supported for the device Dudley Du
2014-11-10  8:38   ` Dmitry Torokhov
2014-11-10 11:05     ` Dudley Du
2014-11-03  8:32 ` [PATCH v9 06/18] input: cyapa: add runtime " Dudley Du
2014-11-03  8:32 ` [PATCH v9 07/18] input: cyapa: add sysfs interfaces supported in the cyapa driver Dudley Du
2014-11-03  8:33 ` [PATCH v9 08/18] input: cyapa: add gen3 trackpad device firmware update function support Dudley Du
2014-11-03  8:33 ` [PATCH v9 09/18] input: cyapa: add gen3 trackpad device read baseline " Dudley Du
2014-11-03  8:33 ` [PATCH v9 10/18] input: cyapa: add gen3 trackpad device force re-calibrate " Dudley Du
2014-11-03  8:33 ` [PATCH v9 11/18] input: cyapa: add gen5 trackpad device firmware update " Dudley Du
2014-11-03  8:33 ` [PATCH v9 12/18] input: cyapa: add gen5 trackpad device read baseline " Dudley Du
2014-11-03  8:33 ` [PATCH v9 13/18] input: cyapa: add gen5 trackpad device force re-calibrate " Dudley Du
2014-11-03  8:33 ` [PATCH v9 14/18] input: cyapa: add read firmware image debugfs interface support Dudley Du
2014-11-03  8:33 ` [PATCH v9 15/18] input: cyapa: add gen3 trackpad device read firmware image function support Dudley Du
2014-11-10  8:39   ` Dmitry Torokhov
2014-11-10 11:05     ` Dudley Du
2014-12-04 17:46       ` Dmitry Torokhov
2014-12-04 17:46         ` Dmitry Torokhov
2014-12-05  1:43         ` Dudley Du
2014-12-05  1:43           ` Dudley Du
2014-11-03  8:33 ` [PATCH v9 16/18] input: cyapa: add gen5 " Dudley Du
2014-11-03  8:33 ` [PATCH v9 17/18] input: cyapa: add read sensors raw data debugfs interface support Dudley Du
2014-11-03  8:33 ` [PATCH v9 18/18] input: cyapa: add gen5 trackpad device read raw data function support Dudley Du

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141109212541.GC37384@dtor-ws \
    --to=dmitry.torokhov@gmail.com \
    --cc=bleung@google.com \
    --cc=dudl@cypress.com \
    --cc=dudley.dulixin@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rydberg@euromail.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.