aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2016-02-12 06:43:04 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2016-03-02 16:47:13 +0100
commit0eadfe2aa1e52a99681eb23da67a065b694cd2a6 (patch)
tree8731c8cd324cfb0f0845c4f35c2f14ed6cb42d07
parent392c679066bd7d80a74e3a73a304934be636ce52 (diff)
downloadaports-0eadfe2aa1e52a99681eb23da67a065b694cd2a6.tar.bz2
aports-0eadfe2aa1e52a99681eb23da67a065b694cd2a6.tar.xz
main/linux-rpi: upgrade to 4.1.17
(cherry picked from commit e58b060fb95244ba28880441a379ae69cc2b92c4)
-rw-r--r--main/linux-rpi/APKBUILD24
-rw-r--r--main/linux-rpi/rotary-encoder-fix.patch721
2 files changed, 692 insertions, 53 deletions
diff --git a/main/linux-rpi/APKBUILD b/main/linux-rpi/APKBUILD
index ad2d157820..291ebfbfc0 100644
--- a/main/linux-rpi/APKBUILD
+++ b/main/linux-rpi/APKBUILD
@@ -2,12 +2,12 @@
_mainflavor=rpi
pkgname=linux-$_mainflavor
-pkgver=4.1.15
+pkgver=4.1.17
case $pkgver in
*.*.*) _kernver=${pkgver%.*};;
*.*) _kernver=${pkgver};;
esac
-pkgrel=1
+pkgrel=0
pkgdesc="Linux kernel with Raspberry Pi patches"
url=https://github.com/raspberrypi/linux
depends="mkinitfs linux-firmware"
@@ -16,7 +16,7 @@ options="!strip"
install=
source="http://ftp.kernel.org/pub/linux/kernel/v4.x/linux-$_kernver.tar.xz
http://ftp.kernel.org/pub/linux/kernel/v4.x/patch-$pkgver.xz
- http://dev.alpinelinux.org/~tteras/linux-4.1.y-rpi-20160105.patch
+ http://dev.alpinelinux.org/~tteras/linux-4.1.y-rpi-20160209.patch
rpi-cirrus-4.1.y-20151218.patch
gpio-mcp23s08-pullups.patch
rotary-encoder-fix.patch
@@ -199,31 +199,31 @@ dev() {
}
md5sums="fe9dc0f6729f36400ea81aa41d614c37 linux-4.1.tar.xz
-5ec05841161a172f8ae1a7f38bb382b0 patch-4.1.15.xz
-c5bf5a6389520729d0e17bf02ab44504 linux-4.1.y-rpi-20160105.patch
+49c68f18968fa809e20a7b20423fd1d2 patch-4.1.17.xz
+b21c5bee698bb499a4fc4cdaf26a7150 linux-4.1.y-rpi-20160209.patch
d4b70738cf06dbd70534d5e873442951 rpi-cirrus-4.1.y-20151218.patch
b66e8aa4991ca5c2ccd61559ed7e6491 gpio-mcp23s08-pullups.patch
-53112c9e4422d407463ad6c45faa789c rotary-encoder-fix.patch
+892ab7d20855cef17eb8add060f99c87 rotary-encoder-fix.patch
29281b74d2cef6965fa4ab6d826a2aa4 issue-4973.patch
3b645eef5408cbbcf9c6b13581ef775a config-rpi.armhf
1c21e249ea27b70dd5e0a7b69820fdee config-rpi2.armhf
e587cae1dca2f5992555d9bcf53deecf markdt"
sha256sums="caf51f085aac1e1cea4d00dbbf3093ead07b551fc07b31b2a989c05f8ea72d9f linux-4.1.tar.xz
-0ffca8557f1aa191da2f2260ad279c9cc858e6308a8af8a76f7ca3d3c0540344 patch-4.1.15.xz
-d093ece97f5ae05b255cfd3923a9f2683c41e77d5d83aa8c1ac92f163c1657c5 linux-4.1.y-rpi-20160105.patch
+60e5c4fb93705a1e7d075d528975661303d3a87c522f731b69da2e00f3170b10 patch-4.1.17.xz
+64c0d751f8ebc54dbb02aa05c80127f5affc6a64336a9d4e29b1cd8481a7bdcd linux-4.1.y-rpi-20160209.patch
5aa17a1554598c3b364b7e8aea84bacfc13e8aca9b9101e58d89c211674a3d5a rpi-cirrus-4.1.y-20151218.patch
b389a556bbd98053881b43deef1adf20640f980557c5f37cfd7ece2daeecbda9 gpio-mcp23s08-pullups.patch
-8f810099810660436a49f029429aadb573aec756b07fcefbcc2ca2ffd21d6ecb rotary-encoder-fix.patch
+aaa1da7d9cac68206a8ddf1e1b8c08bc62696f789468ebfd6894c891d8700533 rotary-encoder-fix.patch
3a16e927ce53a8c56e7f1dd86fe8ad08b1c06466f5206c521a7e2de1e4796d6c issue-4973.patch
7eb3025189c64f4023db864169dcc9d64d029fc871d0ffbc59621292a338772a config-rpi.armhf
10318f14c68a7fafe3b1a8f3208c8586dabce5c01598a4bf7a2da76166b273b4 config-rpi2.armhf
0f6681fc5c3590e1dbe13a2bde796403bd1529cf0fe19720899eaa0db79bcb49 markdt"
sha512sums="168ef84a4e67619f9f53f3574e438542a5747f9b43443363cb83597fcdac9f40d201625c66e375a23226745eaada9176eb006ca023613cec089349e91751f3c0 linux-4.1.tar.xz
-646daf16c01fb8c3013c7c9919c18c3635eb6bd37560623cb56cc7a6d0b22fb13290cee8865dfbcc435cd8544cc3ecb6f3aae538d10c9e0b1098806f233155a3 patch-4.1.15.xz
-bdd4caf18762e1705536227d573321164f62d7c194dec06848764ad1a2a91e2eaa5a4e032a4bfb94d2264a6d9a77ab28e5659c34e011b9465557be03d6e343dc linux-4.1.y-rpi-20160105.patch
+fa8675bac395ad7255693728ee601cd84a02aeee660ee5f2bf5684a6af053c9cf07afb0abb3324b1eb149305701a0bb9252053e840edc2aebb6499139dc12edd patch-4.1.17.xz
+522089ff412f64eb9c8dd802592c639178385b818d19f66098351a9afa540f7fe02f7b363e953d67a7e59517c270423adfc8d3958c129fb1ac8552293e6f50b0 linux-4.1.y-rpi-20160209.patch
843afc1f2a72fa9618935dd67d4ac33a22ee78f20114af349f8d93e54864375b3ef192c8d8fde814d6685d5fe675c2a850743834ef89640eedce9f4db5ffdb67 rpi-cirrus-4.1.y-20151218.patch
36724ba56cb8fdf3a3d347cffb67ae1cc3d7b1052d526b6b5134ebf6baae9f9724b586c97833453dc7697ab24699426f0749af78b6a80be36967a80033a0cf40 gpio-mcp23s08-pullups.patch
-e948ce9c44bc7f20a632519f9ca49f0b9c8c256cdf75d5632a184d41d6a9995c122232d7812d5224def7d119192d4d18f6f9acb9cf6adc8f1df52bea4970731b rotary-encoder-fix.patch
+12794c6e75d6a58253eac8f0778ba8bb6de1dca1541f0bcb58c25f13dab7261f89f2e1b87dacca09b6ed297f2d3e1a159229aab57e7472e041d6aa611b6634fa rotary-encoder-fix.patch
501c91bf2538a18102da59bbccc3097f9c3c90079acc0e946ff075074160c09b8a66934e5ce5470e170f0e4f93d114709a95230367426d0bb7ea02c4bdf4cc9b issue-4973.patch
51f7fcacb9fb05aa14e7ee7890f7726ce4b0001496cfe9ca2152693c2acf5fefbfa654d2d4f26058aa3b617141f29cff7e0427c30e291209829ab1e44c6412ba config-rpi.armhf
1e249312b12e5d247ca7e250653afbacb5bc9d23983eaa4d552ff5b28c2dc0b0302a1c6af499fa59fa166a31e067fddae191bd977b0bd13773a66c81ca398f93 config-rpi2.armhf
diff --git a/main/linux-rpi/rotary-encoder-fix.patch b/main/linux-rpi/rotary-encoder-fix.patch
index 0d9c6ba59f..3d599f3d0b 100644
--- a/main/linux-rpi/rotary-encoder-fix.patch
+++ b/main/linux-rpi/rotary-encoder-fix.patch
@@ -1,62 +1,701 @@
-From e2b19ed7b2284e808dfca3e9207ad52c09e11104 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
-Date: Wed, 23 Dec 2015 16:37:00 +0200
-Subject: [PATCH] Input: rotary-encoder: use request_any_context_irq and
- gpio_get_value_cansleep
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows to use GPIO expanders behind I2C or SPI bus.
-
-Signed-off-by: Timo Teräs <timo.teras@iki.fi>
----
- drivers/input/misc/rotary_encoder.c | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
+commit 47ec6e5a5f57f96d7d382e2d9f8dc5a5bdb45259
+Author: Sylvain Rochet <sylvain.rochet@finsecur.com>
+Date: Tue Oct 13 23:24:36 2015 -0700
+ Input: rotary_encoder - add wake up support
+
+ This patch adds wake up support to GPIO rotary encoders.
+
+ Signed-off-by: Sylvain Rochet <sylvain.rochet@finsecur.com>
+ Reviewed-by: Johan Hovold <johan@kernel.org>
+ Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.txt b/Documentation/devicetree/bindings/input/rotary-encoder.txt
+index 3315495..891ddba 100644
+--- a/Documentation/devicetree/bindings/input/rotary-encoder.txt
++++ b/Documentation/devicetree/bindings/input/rotary-encoder.txt
+@@ -15,6 +15,7 @@ Optional properties:
+ - rotary-encoder,rollover: Automatic rollove when the rotary value becomes
+ greater than the specified steps or smaller than 0. For absolute axis only.
+ - rotary-encoder,half-period: Makes the driver work on half-period mode.
++- wakeup-source: Boolean, rotary encoder can wake up the system.
+
+ See Documentation/input/rotary-encoder.txt for more information.
+
+diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt
+index 5737e35..bddbee1 100644
+--- a/Documentation/input/rotary-encoder.txt
++++ b/Documentation/input/rotary-encoder.txt
+@@ -109,6 +109,7 @@ static struct rotary_encoder_platform_data my_rotary_encoder_info = {
+ .inverted_a = 0,
+ .inverted_b = 0,
+ .half_period = false,
++ .wakeup_source = false,
+ };
+
+ static struct platform_device rotary_encoder_device = {
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
-index 8aee719..8bedd7b 100644
+index f27f81e..d166554 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
-@@ -48,8 +48,8 @@ struct rotary_encoder {
+@@ -26,6 +26,7 @@
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
+ #include <linux/of_gpio.h>
++#include <linux/pm.h>
- 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);
+ #define DRV_NAME "rotary-encoder"
- a ^= pdata->inverted_a;
- b ^= pdata->inverted_b;
-@@ -335,18 +335,18 @@ static int rotary_encoder_probe(struct platform_device *pdev)
- goto exit_free_gpio_b;
+@@ -180,6 +181,8 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
+ "rotary-encoder,rollover", NULL);
+ pdata->half_period = !!of_get_property(np,
+ "rotary-encoder,half-period", NULL);
++ pdata->wakeup_source = !!of_get_property(np,
++ "wakeup-source", NULL);
+
+ return pdata;
+ }
+@@ -280,6 +283,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
+ goto exit_free_irq_b;
+ }
+
++ device_init_wakeup(&pdev->dev, pdata->wakeup_source);
++
+ platform_set_drvdata(pdev, encoder);
+
+ return 0;
+@@ -306,6 +311,8 @@ 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);
+@@ -320,11 +327,41 @@ static int rotary_encoder_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++#ifdef CONFIG_PM_SLEEP
++static int rotary_encoder_suspend(struct device *dev)
++{
++ struct rotary_encoder *encoder = dev_get_drvdata(dev);
++
++ if (device_may_wakeup(dev)) {
++ enable_irq_wake(encoder->irq_a);
++ enable_irq_wake(encoder->irq_b);
++ }
++
++ return 0;
++}
++
++static int rotary_encoder_resume(struct device *dev)
++{
++ struct rotary_encoder *encoder = dev_get_drvdata(dev);
++
++ if (device_may_wakeup(dev)) {
++ disable_irq_wake(encoder->irq_a);
++ disable_irq_wake(encoder->irq_b);
++ }
++
++ return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(rotary_encoder_pm_ops,
++ rotary_encoder_suspend, rotary_encoder_resume);
++
+ static struct platform_driver rotary_encoder_driver = {
+ .probe = rotary_encoder_probe,
+ .remove = rotary_encoder_remove,
+ .driver = {
+ .name = DRV_NAME,
++ .pm = &rotary_encoder_pm_ops,
+ .of_match_table = of_match_ptr(rotary_encoder_of_match),
+ }
+ };
+diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h
+index 3f594dc..b33f2d2 100644
+--- a/include/linux/rotary_encoder.h
++++ b/include/linux/rotary_encoder.h
+@@ -11,6 +11,7 @@ struct rotary_encoder_platform_data {
+ bool relative_axis;
+ bool rollover;
+ bool half_period;
++ bool wakeup_source;
+ };
+
+ #endif /* __ROTARY_ENCODER_H__ */
+
+commit 648b15cb79e90d80f7b53d0184bdb14132a03754
+Author: Ben Gamari <bgamari.foss@gmail.com>
+Date: Tue Oct 13 23:37:28 2015 -0700
+
+ Input: rotary-encoder - use of_property_read_bool
+
+ This commit makes uses of_property_read_bool() to read
+ boolean properties. This is just cosmetic cleanup.
+
+ Signed-off-by: Ben Gamari <bgamari.foss@gmail.com>
+ Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
+index d166554..962f9e8 100644
+--- a/drivers/input/misc/rotary_encoder.c
++++ b/drivers/input/misc/rotary_encoder.c
+@@ -175,14 +175,12 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
+ pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
+ pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
+
+- pdata->relative_axis = !!of_get_property(np,
+- "rotary-encoder,relative-axis", NULL);
+- pdata->rollover = !!of_get_property(np,
+- "rotary-encoder,rollover", NULL);
+- pdata->half_period = !!of_get_property(np,
+- "rotary-encoder,half-period", NULL);
+- pdata->wakeup_source = !!of_get_property(np,
+- "wakeup-source", NULL);
++ pdata->relative_axis =
++ of_property_read_bool(np, "rotary-encoder,relative-axis");
++ pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
++ pdata->half_period =
++ of_property_read_bool(np, "rotary-encoder,half-period");
++ pdata->wakeup_source = of_property_read_bool(np, "wakeup-source");
+
+ return pdata;
+ }
+
+commit 3a341a4c30d427fd05617087db1564a595f65093
+Author: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Date: Tue Oct 13 23:39:50 2015 -0700
+
+ Input: rotary-encoder - add support for quarter-period mode
+
+ Some encoders have both outputs low in stable states, others also have
+ a stable state with both outputs high (half-period mode) and some have
+ a stable state in all steps (quarter-period mode). The driver used to
+ support the former states and with this change it can also support the
+ later.
+
+ This commit also deprecates the 'half-period' property and introduces
+ a new property 'steps-per-period'. This property specifies the
+ number of steps (stable states) produced by the rotary encoder
+ for each GPIO period.
+
+ Signed-off-by: Guido Martínez <guido@vanguardiasur.com.ar>
+ Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+ Acked-by: Rob Herring <robh@kernel.org>
+ Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.txt b/Documentation/devicetree/bindings/input/rotary-encoder.txt
+index 891ddba..de99cbb 100644
+--- a/Documentation/devicetree/bindings/input/rotary-encoder.txt
++++ b/Documentation/devicetree/bindings/input/rotary-encoder.txt
+@@ -14,9 +14,18 @@ Optional properties:
+ device, hence no steps need to be passed.
+ - rotary-encoder,rollover: Automatic rollove when the rotary value becomes
+ greater than the specified steps or smaller than 0. For absolute axis only.
+-- rotary-encoder,half-period: Makes the driver work on half-period mode.
++- rotary-encoder,steps-per-period: Number of steps (stable states) per period.
++ The values have the following meaning:
++ 1: Full-period mode (default)
++ 2: Half-period mode
++ 4: Quarter-period mode
+ - wakeup-source: Boolean, rotary encoder can wake up the system.
+
++Deprecated properties:
++- rotary-encoder,half-period: Makes the driver work on half-period mode.
++ This property is deprecated. Instead, a 'steps-per-period ' value should
++ be used, such as "rotary-encoder,steps-per-period = <2>".
++
+ See Documentation/input/rotary-encoder.txt for more information.
+
+ Example:
+diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt
+index bddbee1..46a74f0 100644
+--- a/Documentation/input/rotary-encoder.txt
++++ b/Documentation/input/rotary-encoder.txt
+@@ -9,8 +9,9 @@ peripherals with two wires. The outputs are phase-shifted by 90 degrees
+ and by triggering on falling and rising edges, the turn direction can
+ be determined.
+
+-Some encoders have both outputs low in stable states, whereas others also have
+-a stable state with both outputs high (half-period mode).
++Some encoders have both outputs low in stable states, others also have
++a stable state with both outputs high (half-period mode) and some have
++a stable state in all steps (quarter-period mode).
+
+ The phase diagram of these two outputs look like this:
+
+@@ -32,6 +33,9 @@ The phase diagram of these two outputs look like this:
+ |<-->|
+ one step (half-period mode)
+
++ |<>|
++ one step (quarter-period mode)
++
+ For more information, please see
+ https://en.wikipedia.org/wiki/Rotary_encoder
+
+diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
+index 962f9e8..8aee719 100644
+--- a/drivers/input/misc/rotary_encoder.c
++++ b/drivers/input/misc/rotary_encoder.c
+@@ -143,6 +143,55 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
++static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
++{
++ struct rotary_encoder *encoder = dev_id;
++ unsigned char sum;
++ int state;
++
++ state = rotary_encoder_get_state(encoder->pdata);
++
++ /*
++ * We encode the previous and the current state using a byte.
++ * The previous state in the MSB nibble, the current state in the LSB
++ * nibble. Then use a table to decide the direction of the turn.
++ */
++ sum = (encoder->last_stable << 4) + state;
++ switch (sum) {
++ case 0x31:
++ case 0x10:
++ case 0x02:
++ case 0x23:
++ encoder->dir = 0; /* clockwise */
++ break;
++
++ case 0x13:
++ case 0x01:
++ case 0x20:
++ case 0x32:
++ encoder->dir = 1; /* counter-clockwise */
++ break;
++
++ default:
++ /*
++ * Ignore all other values. This covers the case when the
++ * state didn't change (a spurious interrupt) and the
++ * cases where the state changed by two steps, making it
++ * impossible to tell the direction.
++ *
++ * In either case, don't report any event and save the
++ * state for later.
++ */
++ goto out;
++ }
++
++ rotary_encoder_report_event(encoder);
++
++out:
++ encoder->last_stable = state;
++ return IRQ_HANDLED;
++}
++
+ #ifdef CONFIG_OF
+ static const struct of_device_id rotary_encoder_of_match[] = {
+ { .compatible = "rotary-encoder", },
+@@ -157,6 +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;
+
+ if (!of_id || !np)
+ return NULL;
+@@ -178,8 +228,23 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
+ pdata->relative_axis =
+ of_property_read_bool(np, "rotary-encoder,relative-axis");
+ pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
+- pdata->half_period =
+- of_property_read_bool(np, "rotary-encoder,half-period");
++
++ error = of_property_read_u32(np, "rotary-encoder,steps-per-period",
++ &pdata->steps_per_period);
++ if (error) {
++ /*
++ * The 'half-period' property has been deprecated, you must use
++ * 'steps-per-period' and set an appropriate value, but we still
++ * need to parse it to maintain compatibility.
++ */
++ if (of_property_read_bool(np, "rotary-encoder,half-period")) {
++ pdata->steps_per_period = 2;
++ } else {
++ /* Fallback to one step per period behavior */
++ pdata->steps_per_period = 1;
++ }
++ }
++
+ pdata->wakeup_source = of_property_read_bool(np, "wakeup-source");
+
+ return pdata;
+@@ -251,12 +316,23 @@ static int rotary_encoder_probe(struct platform_device *pdev)
+ encoder->irq_a = gpio_to_irq(pdata->gpio_a);
+ encoder->irq_b = gpio_to_irq(pdata->gpio_b);
+
+- /* request the IRQs */
+- if (pdata->half_period) {
++ switch (pdata->steps_per_period) {
++ case 4:
++ handler = &rotary_encoder_quarter_period_irq;
++ encoder->last_stable = rotary_encoder_get_state(pdata);
++ break;
++ case 2:
+ handler = &rotary_encoder_half_period_irq;
+ encoder->last_stable = rotary_encoder_get_state(pdata);
+- } else {
++ break;
++ case 1:
+ handler = &rotary_encoder_irq;
++ break;
++ 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;
+ }
+
+ err = request_irq(encoder->irq_a, handler,
+diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h
+index b33f2d2..fe3dc64 100644
+--- a/include/linux/rotary_encoder.h
++++ b/include/linux/rotary_encoder.h
+@@ -8,9 +8,9 @@ struct rotary_encoder_platform_data {
+ unsigned int gpio_b;
+ unsigned int inverted_a;
+ unsigned int inverted_b;
++ unsigned int steps_per_period;
+ bool relative_axis;
+ bool rollover;
+- bool half_period;
+ bool wakeup_source;
+ };
+
+
+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);
-- if (err) {
-+ err = request_any_context_irq(encoder->irq_a, handler,
-+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-+ DRV_NAME, encoder);
-+ if (err < 0) {
++ 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;
+- goto exit_free_gpio_b;
++ return err;
}
- err = request_irq(encoder->irq_b, handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- DRV_NAME, encoder);
-- if (err) {
-+ err = request_any_context_irq(encoder->irq_b, handler,
-+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-+ DRV_NAME, encoder);
-+ if (err < 0) {
++ 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;
+- 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;
}
---
-2.6.4
+
+ 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;