diff options
author | Timo Teräs <timo.teras@iki.fi> | 2016-02-12 06:43:04 +0000 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2016-02-12 06:43:04 +0000 |
commit | e58b060fb95244ba28880441a379ae69cc2b92c4 (patch) | |
tree | a95494fc6e802458254b7e6a917b55c1a778bd4c /main/linux-rpi | |
parent | f27f4c412ff313a05dfaeb7a63414df879248893 (diff) | |
download | aports-e58b060fb95244ba28880441a379ae69cc2b92c4.tar.bz2 aports-e58b060fb95244ba28880441a379ae69cc2b92c4.tar.xz |
main/linux-rpi: upgrade to 4.1.17
Diffstat (limited to 'main/linux-rpi')
-rw-r--r-- | main/linux-rpi/APKBUILD | 24 | ||||
-rw-r--r-- | main/linux-rpi/rotary-encoder-fix.patch | 721 |
2 files changed, 692 insertions, 53 deletions
diff --git a/main/linux-rpi/APKBUILD b/main/linux-rpi/APKBUILD index ad2d15782..291ebfbfc 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 0d9c6ba59..3d599f3d0 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; |