* [PATCH 2/3] Input: rotary_encoder - fix device tree error handling
2016-01-15 20:33 [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Timo Teräs
@ 2016-01-15 20:33 ` Timo Teräs
2016-01-16 19:02 ` Dmitry Torokhov
2016-01-15 20:33 ` [PATCH 3/3] Input: rotary_encoder - use threaded irqs Timo Teräs
2016-01-17 4:43 ` [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Dmitry Torokhov
2 siblings, 1 reply; 6+ messages in thread
From: Timo Teräs @ 2016-01-15 20:33 UTC (permalink / raw)
To: linux-input@vger.kernel.org; +Cc: Timo Teräs
of_get_gpio_flags() can fail, so pass through the error code
properly. Most important use case is when it returns EPROBE_DEFER
so that the probe gets called again later.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
drivers/input/misc/rotary_encoder.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 0f23d32..156f40f 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -206,7 +206,7 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
struct device_node *np = dev->of_node;
struct rotary_encoder_platform_data *pdata;
enum of_gpio_flags flags;
- int error;
+ int ret;
if (!of_id || !np)
return NULL;
@@ -219,19 +219,25 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps);
of_property_read_u32(np, "linux,axis", &pdata->axis);
- pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
+ ret = of_get_gpio_flags(np, 0, &flags);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ pdata->gpio_a = ret;
pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
- pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
+ ret = of_get_gpio_flags(np, 1, &flags);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ pdata->gpio_b = ret;
pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
pdata->relative_axis =
of_property_read_bool(np, "rotary-encoder,relative-axis");
pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
- error = of_property_read_u32(np, "rotary-encoder,steps-per-period",
- &pdata->steps_per_period);
- if (error) {
+ ret = of_property_read_u32(np, "rotary-encoder,steps-per-period",
+ &pdata->steps_per_period);
+ if (ret) {
/*
* The 'half-period' property has been deprecated, you must use
* 'steps-per-period' and set an appropriate value, but we still
--
2.7.0
--
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 related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] Input: rotary_encoder - fix device tree error handling
2016-01-15 20:33 ` [PATCH 2/3] Input: rotary_encoder - fix device tree error handling Timo Teräs
@ 2016-01-16 19:02 ` Dmitry Torokhov
2016-01-18 14:00 ` Timo Teras
0 siblings, 1 reply; 6+ messages in thread
From: Dmitry Torokhov @ 2016-01-16 19:02 UTC (permalink / raw)
To: Timo Teräs; +Cc: linux-input@vger.kernel.org
Hi Timo,
On Fri, Jan 15, 2016 at 10:33:49PM +0200, Timo Teräs wrote:
> of_get_gpio_flags() can fail, so pass through the error code
> properly. Most important use case is when it returns EPROBE_DEFER
> so that the probe gets called again later.
>
> Signed-off-by: Timo Teräs <timo.teras@iki.fi>
> ---
> drivers/input/misc/rotary_encoder.c | 18 ++++++++++++------
> 1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
> index 0f23d32..156f40f 100644
> --- a/drivers/input/misc/rotary_encoder.c
> +++ b/drivers/input/misc/rotary_encoder.c
> @@ -206,7 +206,7 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
> struct device_node *np = dev->of_node;
> struct rotary_encoder_platform_data *pdata;
> enum of_gpio_flags flags;
> - int error;
> + int ret;
I strongly prefer variables holding error codes and not being returned
to caller in success path to be called "error".
>
> if (!of_id || !np)
> return NULL;
> @@ -219,19 +219,25 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
> of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps);
> of_property_read_u32(np, "linux,axis", &pdata->axis);
>
> - pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
> + ret = of_get_gpio_flags(np, 0, &flags);
> + if (ret < 0)
> + return ERR_PTR(ret);
> + pdata->gpio_a = ret;
Instead of doing this maybe we could switch to gpiod interface that
handles polarity internally and does not depend on OF? The only issue is
that we have a few board files in tree that use raw gpio numbers so
we'll need to convert them...
Thanks.
> pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
>
> - pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
> + ret = of_get_gpio_flags(np, 1, &flags);
> + if (ret < 0)
> + return ERR_PTR(ret);
> + pdata->gpio_b = ret;
> pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
>
> pdata->relative_axis =
> of_property_read_bool(np, "rotary-encoder,relative-axis");
> pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
>
> - error = of_property_read_u32(np, "rotary-encoder,steps-per-period",
> - &pdata->steps_per_period);
> - if (error) {
> + ret = of_property_read_u32(np, "rotary-encoder,steps-per-period",
> + &pdata->steps_per_period);
> + if (ret) {
> /*
> * The 'half-period' property has been deprecated, you must use
> * 'steps-per-period' and set an appropriate value, but we still
> --
> 2.7.0
>
> --
> 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
--
Dmitry
--
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 [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] Input: rotary_encoder - fix device tree error handling
2016-01-16 19:02 ` Dmitry Torokhov
@ 2016-01-18 14:00 ` Timo Teras
0 siblings, 0 replies; 6+ messages in thread
From: Timo Teras @ 2016-01-18 14:00 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input@vger.kernel.org
On Sat, 16 Jan 2016 11:02:43 -0800
Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Fri, Jan 15, 2016 at 10:33:49PM +0200, Timo Teräs wrote:
> > of_get_gpio_flags() can fail, so pass through the error code
> > properly. Most important use case is when it returns EPROBE_DEFER
> > so that the probe gets called again later.
> >
> > Signed-off-by: Timo Teräs <timo.teras@iki.fi>
> > ---
> > drivers/input/misc/rotary_encoder.c | 18 ++++++++++++------
> > 1 file changed, 12 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/input/misc/rotary_encoder.c
> > b/drivers/input/misc/rotary_encoder.c index 0f23d32..156f40f 100644
> > --- a/drivers/input/misc/rotary_encoder.c
> > +++ b/drivers/input/misc/rotary_encoder.c
> > @@ -206,7 +206,7 @@ static struct rotary_encoder_platform_data
> > *rotary_encoder_parse_dt(struct devic struct device_node *np =
> > dev->of_node; struct rotary_encoder_platform_data *pdata;
> > enum of_gpio_flags flags;
> > - int error;
> > + int ret;
>
> I strongly prefer variables holding error codes and not being returned
> to caller in success path to be called "error".
Uh. Ok. My preference was on 'ret' or similar as the return value is
used on success path for something useful. But error be it.
> > if (!of_id || !np)
> > return NULL;
> > @@ -219,19 +219,25 @@ static struct rotary_encoder_platform_data
> > *rotary_encoder_parse_dt(struct devic of_property_read_u32(np,
> > "rotary-encoder,steps", &pdata->steps); of_property_read_u32(np,
> > "linux,axis", &pdata->axis);
> > - pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
> > + ret = of_get_gpio_flags(np, 0, &flags);
> > + if (ret < 0)
> > + return ERR_PTR(ret);
> > + pdata->gpio_a = ret;
>
> Instead of doing this maybe we could switch to gpiod interface that
> handles polarity internally and does not depend on OF? The only issue
> is that we have a few board files in tree that use raw gpio numbers so
> we'll need to convert them...
This is kinda two unrelated things... of course using gpiod_get_array()
would simplify the error path handling and other parts. And as side
effect probably fix the issue at hand too.
The only place where the platform data is used that I found is:
arch/arm/mach-pxa/raumfeld.c
So it should be relatively constrained change.
Could you perhaps also push what you already committed from me (dunno
what you decided with patch #3). If I do gpiod_* conversion, it'll
conflict with the last patch.
Thanks,
Timo
--
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 [flat|nested] 6+ messages in thread
* [PATCH 3/3] Input: rotary_encoder - use threaded irqs
2016-01-15 20:33 [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Timo Teräs
2016-01-15 20:33 ` [PATCH 2/3] Input: rotary_encoder - fix device tree error handling Timo Teräs
@ 2016-01-15 20:33 ` Timo Teräs
2016-01-17 4:43 ` [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Dmitry Torokhov
2 siblings, 0 replies; 6+ messages in thread
From: Timo Teräs @ 2016-01-15 20:33 UTC (permalink / raw)
To: linux-input@vger.kernel.org; +Cc: Timo Teräs
Convert to use threaded IRQs to support GPIOs that can sleep.
Protect the irq handler with mutex as it can be triggered from
two different irq lines accessing the same state.
This allows using GPIO expanders behind I2C or SPI bus.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
drivers/input/misc/rotary_encoder.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 156f40f..a2d47ce 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -33,6 +33,7 @@
struct rotary_encoder {
struct input_dev *input;
const struct rotary_encoder_platform_data *pdata;
+ struct mutex access_mutex;
unsigned int axis;
unsigned int pos;
@@ -48,8 +49,8 @@ struct rotary_encoder {
static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata)
{
- int a = !!gpio_get_value(pdata->gpio_a);
- int b = !!gpio_get_value(pdata->gpio_b);
+ int a = !!gpio_get_value_cansleep(pdata->gpio_a);
+ int b = !!gpio_get_value_cansleep(pdata->gpio_b);
a ^= pdata->inverted_a;
b ^= pdata->inverted_b;
@@ -94,6 +95,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
struct rotary_encoder *encoder = dev_id;
int state;
+ mutex_lock(&encoder->access_mutex);
state = rotary_encoder_get_state(encoder->pdata);
switch (state) {
@@ -114,6 +116,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
encoder->armed = true;
break;
}
+ mutex_unlock(&encoder->access_mutex);
return IRQ_HANDLED;
}
@@ -123,6 +126,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
struct rotary_encoder *encoder = dev_id;
int state;
+ mutex_lock(&encoder->access_mutex);
state = rotary_encoder_get_state(encoder->pdata);
switch (state) {
@@ -139,6 +143,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
encoder->dir = (encoder->last_stable + state) & 0x01;
break;
}
+ mutex_unlock(&encoder->access_mutex);
return IRQ_HANDLED;
}
@@ -149,6 +154,7 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
unsigned char sum;
int state;
+ mutex_lock(&encoder->access_mutex);
state = rotary_encoder_get_state(encoder->pdata);
/*
@@ -189,6 +195,8 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
out:
encoder->last_stable = state;
+ mutex_unlock(&encoder->access_mutex);
+
return IRQ_HANDLED;
}
@@ -288,6 +296,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
if (!encoder || !input)
return -ENOMEM;
+ mutex_init(&encoder->access_mutex);
+
encoder->input = input;
encoder->pdata = pdata;
@@ -338,17 +348,17 @@ static int rotary_encoder_probe(struct platform_device *pdev)
return-EINVAL;
}
- err = devm_request_irq(dev, encoder->irq_a, handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- DRV_NAME, encoder);
+ err = devm_request_threaded_irq(dev, encoder->irq_a, NULL, handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ DRV_NAME, encoder);
if (err) {
dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a);
return err;
}
- err = devm_request_irq(dev, encoder->irq_b, handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- DRV_NAME, encoder);
+ err = devm_request_threaded_irq(dev, encoder->irq_b, NULL, handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ DRV_NAME, encoder);
if (err) {
dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
return err;
--
2.7.0
--
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 related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] Input: rotary_encoder - convert to devm-* api
2016-01-15 20:33 [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Timo Teräs
2016-01-15 20:33 ` [PATCH 2/3] Input: rotary_encoder - fix device tree error handling Timo Teräs
2016-01-15 20:33 ` [PATCH 3/3] Input: rotary_encoder - use threaded irqs Timo Teräs
@ 2016-01-17 4:43 ` Dmitry Torokhov
2 siblings, 0 replies; 6+ messages in thread
From: Dmitry Torokhov @ 2016-01-17 4:43 UTC (permalink / raw)
To: Timo Teräs; +Cc: linux-input@vger.kernel.org
On Fri, Jan 15, 2016 at 10:33:48PM +0200, Timo Teräs wrote:
> Use managed resource API for simplifying error paths.
>
> Signed-off-by: Timo Teräs <timo.teras@iki.fi>
> ---
> drivers/input/misc/rotary_encoder.c | 73 ++++++++++---------------------------
> 1 file changed, 20 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
> index 8aee719..0f23d32 100644
> --- a/drivers/input/misc/rotary_encoder.c
> +++ b/drivers/input/misc/rotary_encoder.c
> @@ -211,8 +211,8 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
> if (!of_id || !np)
> return NULL;
>
> - pdata = kzalloc(sizeof(struct rotary_encoder_platform_data),
> - GFP_KERNEL);
> + pdata = devm_kzalloc(dev, sizeof(struct rotary_encoder_platform_data),
> + GFP_KERNEL);
> if (!pdata)
> return ERR_PTR(-ENOMEM);
>
> @@ -277,12 +277,10 @@ static int rotary_encoder_probe(struct platform_device *pdev)
> }
> }
>
> - encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
> - input = input_allocate_device();
> - if (!encoder || !input) {
> - err = -ENOMEM;
> - goto exit_free_mem;
> - }
> + encoder = devm_kzalloc(dev, sizeof(struct rotary_encoder), GFP_KERNEL);
> + input = devm_input_allocate_device(dev);
> + if (!encoder || !input)
> + return -ENOMEM;
>
> encoder->input = input;
> encoder->pdata = pdata;
> @@ -301,16 +299,16 @@ static int rotary_encoder_probe(struct platform_device *pdev)
> }
>
> /* request the GPIOs */
> - err = gpio_request_one(pdata->gpio_a, GPIOF_IN, dev_name(dev));
> + err = devm_gpio_request_one(dev, pdata->gpio_a, GPIOF_IN, dev_name(dev));
> if (err) {
> dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a);
> - goto exit_free_mem;
> + return err;
> }
>
> - err = gpio_request_one(pdata->gpio_b, GPIOF_IN, dev_name(dev));
> + err = devm_gpio_request_one(dev, pdata->gpio_b, GPIOF_IN, dev_name(dev));
> if (err) {
> dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_b);
> - goto exit_free_gpio_a;
> + return err;
> }
>
> encoder->irq_a = gpio_to_irq(pdata->gpio_a);
> @@ -331,30 +329,29 @@ static int rotary_encoder_probe(struct platform_device *pdev)
> default:
> dev_err(dev, "'%d' is not a valid steps-per-period value\n",
> pdata->steps_per_period);
> - err = -EINVAL;
> - goto exit_free_gpio_b;
> + return-EINVAL;
It is customary to put a space between return and return value.
> }
>
> - err = request_irq(encoder->irq_a, handler,
> - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> - DRV_NAME, encoder);
> + err = devm_request_irq(dev, encoder->irq_a, handler,
> + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> + DRV_NAME, encoder);
> if (err) {
> dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a);
> - goto exit_free_gpio_b;
> + return err;
> }
>
> - err = request_irq(encoder->irq_b, handler,
> - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> - DRV_NAME, encoder);
> + err = devm_request_irq(dev, encoder->irq_b, handler,
> + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> + DRV_NAME, encoder);
> if (err) {
> dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
> - goto exit_free_irq_a;
> + return err;
> }
>
> err = input_register_device(input);
> if (err) {
> dev_err(dev, "failed to register input device\n");
> - goto exit_free_irq_b;
> + return err;
> }
>
> device_init_wakeup(&pdev->dev, pdata->wakeup_source);
> @@ -362,42 +359,12 @@ static int rotary_encoder_probe(struct platform_device *pdev)
> platform_set_drvdata(pdev, encoder);
>
> return 0;
> -
> -exit_free_irq_b:
> - free_irq(encoder->irq_b, encoder);
> -exit_free_irq_a:
> - free_irq(encoder->irq_a, encoder);
> -exit_free_gpio_b:
> - gpio_free(pdata->gpio_b);
> -exit_free_gpio_a:
> - gpio_free(pdata->gpio_a);
> -exit_free_mem:
> - input_free_device(input);
> - kfree(encoder);
> - if (!dev_get_platdata(&pdev->dev))
> - kfree(pdata);
> -
> - return err;
> }
>
> static int rotary_encoder_remove(struct platform_device *pdev)
> {
> - struct rotary_encoder *encoder = platform_get_drvdata(pdev);
> - const struct rotary_encoder_platform_data *pdata = encoder->pdata;
> -
> device_init_wakeup(&pdev->dev, false);
I think we can get rid of this as well (most of the drivers do not reset
wakeup capability on unbind, and if this is needed it is better be done
at bus level), so rotary_encoder_remove() can be removed altogether.
>
> - free_irq(encoder->irq_a, encoder);
> - free_irq(encoder->irq_b, encoder);
> - gpio_free(pdata->gpio_a);
> - gpio_free(pdata->gpio_b);
> -
> - input_unregister_device(encoder->input);
> - kfree(encoder);
> -
> - if (!dev_get_platdata(&pdev->dev))
> - kfree(pdata);
> -
> return 0;
> }
I fixed up the above points and applied.
Thanks.
--
Dmitry
--
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 [flat|nested] 6+ messages in thread