diff options
author | Colin Pitrat <colin.pitrat@gmail.com> | 2016-06-18 14:05:04 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-07-04 10:50:40 -0400 |
commit | 87041a58d3b19455d39baed2a5e5bb43b58fb915 (patch) | |
tree | 12fcc0a782e3b9b90621e599937014fc0a5e1ecc | |
parent | a99cde438de0c4c0cecc1d1af1a55a75b10bfdef (diff) |
gpio: sch: Fix Oops on module load on Asus Eee PC 1201
This fixes the issue descirbe in bug 117531
(https://bugzilla.kernel.org/show_bug.cgi?id=117531).
It's a regression introduced in linux 4.5 that causes a Oops at load of
gpio_sch and prevents powering off the computer.
The issue is that sch_gpio_reg_set is called in sch_gpio_probe before
gpio_chip data is initialized with the pointer to the sch_gpio struct. As
sch_gpio_reg_set calls gpiochip_get_data, it returns NULL which causes
the Oops.
The patch follows Mika's advice (https://lkml.org/lkml/2016/5/9/61) and
consists in modifying sch_gpio_reg_get and sch_gpio_reg_set to take a
sch_gpio struct directly instead of a gpio_chip, which avoids the call to
gpiochip_get_data.
Thanks Mika for your patience with me :-)
Cc: stable@vger.kernel.org
Signed-off-by: Colin Pitrat <colin.pitrat@gmail.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/gpio/gpio-sch.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index e85e7539cf5d..eb43ae4835c1 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -61,9 +61,8 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio) | |||
61 | return gpio % 8; | 61 | return gpio % 8; |
62 | } | 62 | } |
63 | 63 | ||
64 | static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg) | 64 | static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned gpio, unsigned reg) |
65 | { | 65 | { |
66 | struct sch_gpio *sch = gpiochip_get_data(gc); | ||
67 | unsigned short offset, bit; | 66 | unsigned short offset, bit; |
68 | u8 reg_val; | 67 | u8 reg_val; |
69 | 68 | ||
@@ -75,10 +74,9 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg) | |||
75 | return reg_val; | 74 | return reg_val; |
76 | } | 75 | } |
77 | 76 | ||
78 | static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg, | 77 | static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg, |
79 | int val) | 78 | int val) |
80 | { | 79 | { |
81 | struct sch_gpio *sch = gpiochip_get_data(gc); | ||
82 | unsigned short offset, bit; | 80 | unsigned short offset, bit; |
83 | u8 reg_val; | 81 | u8 reg_val; |
84 | 82 | ||
@@ -98,14 +96,15 @@ static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num) | |||
98 | struct sch_gpio *sch = gpiochip_get_data(gc); | 96 | struct sch_gpio *sch = gpiochip_get_data(gc); |
99 | 97 | ||
100 | spin_lock(&sch->lock); | 98 | spin_lock(&sch->lock); |
101 | sch_gpio_reg_set(gc, gpio_num, GIO, 1); | 99 | sch_gpio_reg_set(sch, gpio_num, GIO, 1); |
102 | spin_unlock(&sch->lock); | 100 | spin_unlock(&sch->lock); |
103 | return 0; | 101 | return 0; |
104 | } | 102 | } |
105 | 103 | ||
106 | static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num) | 104 | static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num) |
107 | { | 105 | { |
108 | return sch_gpio_reg_get(gc, gpio_num, GLV); | 106 | struct sch_gpio *sch = gpiochip_get_data(gc); |
107 | return sch_gpio_reg_get(sch, gpio_num, GLV); | ||
109 | } | 108 | } |
110 | 109 | ||
111 | static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) | 110 | static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) |
@@ -113,7 +112,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) | |||
113 | struct sch_gpio *sch = gpiochip_get_data(gc); | 112 | struct sch_gpio *sch = gpiochip_get_data(gc); |
114 | 113 | ||
115 | spin_lock(&sch->lock); | 114 | spin_lock(&sch->lock); |
116 | sch_gpio_reg_set(gc, gpio_num, GLV, val); | 115 | sch_gpio_reg_set(sch, gpio_num, GLV, val); |
117 | spin_unlock(&sch->lock); | 116 | spin_unlock(&sch->lock); |
118 | } | 117 | } |
119 | 118 | ||
@@ -123,7 +122,7 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num, | |||
123 | struct sch_gpio *sch = gpiochip_get_data(gc); | 122 | struct sch_gpio *sch = gpiochip_get_data(gc); |
124 | 123 | ||
125 | spin_lock(&sch->lock); | 124 | spin_lock(&sch->lock); |
126 | sch_gpio_reg_set(gc, gpio_num, GIO, 0); | 125 | sch_gpio_reg_set(sch, gpio_num, GIO, 0); |
127 | spin_unlock(&sch->lock); | 126 | spin_unlock(&sch->lock); |
128 | 127 | ||
129 | /* | 128 | /* |
@@ -182,13 +181,13 @@ static int sch_gpio_probe(struct platform_device *pdev) | |||
182 | * GPIO7 is configured by the CMC as SLPIOVR | 181 | * GPIO7 is configured by the CMC as SLPIOVR |
183 | * Enable GPIO[9:8] core powered gpios explicitly | 182 | * Enable GPIO[9:8] core powered gpios explicitly |
184 | */ | 183 | */ |
185 | sch_gpio_reg_set(&sch->chip, 8, GEN, 1); | 184 | sch_gpio_reg_set(sch, 8, GEN, 1); |
186 | sch_gpio_reg_set(&sch->chip, 9, GEN, 1); | 185 | sch_gpio_reg_set(sch, 9, GEN, 1); |
187 | /* | 186 | /* |
188 | * SUS_GPIO[2:0] enabled by default | 187 | * SUS_GPIO[2:0] enabled by default |
189 | * Enable SUS_GPIO3 resume powered gpio explicitly | 188 | * Enable SUS_GPIO3 resume powered gpio explicitly |
190 | */ | 189 | */ |
191 | sch_gpio_reg_set(&sch->chip, 13, GEN, 1); | 190 | sch_gpio_reg_set(sch, 13, GEN, 1); |
192 | break; | 191 | break; |
193 | 192 | ||
194 | case PCI_DEVICE_ID_INTEL_ITC_LPC: | 193 | case PCI_DEVICE_ID_INTEL_ITC_LPC: |