aports/main/linux-rpi/rotary-encoder-fix.patch
Timo Teräs b928439ad0 main/linux-rpi: upgrade to 4.4.6
CONFIG_CPU_SW_DOMAIN_PAN is disabled until upstream is fixed:
https://github.com/raspberrypi/linux/issues/1381

rpi2 kernel changed to CONFIG_VMSPLIT_3G_OPT.
2016-03-28 11:35:56 +00:00

325 lines
9.9 KiB
Diff

commit 0f940be407b87ca629fa2f3085f613483a075b16
Author: Timo Teräs <timo.teras@iki.fi>
Date: Fri Jan 15 15:24:14 2016 +0200
Input: rotary_encoder - convert to devm-* api
Use managed resource API for simplifying error paths.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
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;
}
- 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);
- 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;
}
commit 3467a8dafd27e2c6c1545028ea4e4a78701031df
Author: Timo Teräs <timo.teras@iki.fi>
Date: Fri Jan 15 15:37:00 2016 +0200
Input: rotary_encoder - fix device tree error handling
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>
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
commit 85bec2ad5ac7ee79b3f1d264947a5b4dc4c5ef6e (HEAD -> master)
Author: Timo Teräs <timo.teras@iki.fi>
Date: Fri Jan 15 15:55:48 2016 +0200
Input: rotary_encoder - use threaded irqs
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>
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;