diff options
author | William Breathitt Gray <vilhelm.gray@gmail.com> | 2016-07-19 12:25:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2016-08-15 10:39:32 -0400 |
commit | 45e98152850c36560484f3fa3bb857a4bfe1a419 (patch) | |
tree | 0f464698c427cca55d973d2c432f996fb8b45f60 | |
parent | f8adf645db03345af2d9a8b6095b02327ea50885 (diff) |
iio: stx104: Unregister IIO device on remove callback
The devm_iio_device_register function should not be used if custom
operations must be performed in the remove callback. This patch replaces
the dem_iio_device_register call with a iio_device_register call and
respective iio_device_unregister call in the remove callback.
Fixes: 765550e4d98d ("iio: stx104: Add GPIO support for the Apex Embedded Systems STX104")
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | drivers/iio/dac/stx104.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/iio/dac/stx104.c b/drivers/iio/dac/stx104.c index 792a97164cb2..bebbd00304ce 100644 --- a/drivers/iio/dac/stx104.c +++ b/drivers/iio/dac/stx104.c | |||
@@ -65,6 +65,16 @@ struct stx104_gpio { | |||
65 | unsigned int out_state; | 65 | unsigned int out_state; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /** | ||
69 | * struct stx104_dev - STX104 device private data structure | ||
70 | * @indio_dev: IIO device | ||
71 | * @chip: instance of the gpio_chip | ||
72 | */ | ||
73 | struct stx104_dev { | ||
74 | struct iio_dev *indio_dev; | ||
75 | struct gpio_chip *chip; | ||
76 | }; | ||
77 | |||
68 | static int stx104_read_raw(struct iio_dev *indio_dev, | 78 | static int stx104_read_raw(struct iio_dev *indio_dev, |
69 | struct iio_chan_spec const *chan, int *val, int *val2, long mask) | 79 | struct iio_chan_spec const *chan, int *val, int *val2, long mask) |
70 | { | 80 | { |
@@ -107,6 +117,7 @@ static const struct iio_chan_spec stx104_channels[STX104_NUM_CHAN] = { | |||
107 | static int stx104_gpio_get_direction(struct gpio_chip *chip, | 117 | static int stx104_gpio_get_direction(struct gpio_chip *chip, |
108 | unsigned int offset) | 118 | unsigned int offset) |
109 | { | 119 | { |
120 | /* GPIO 0-3 are input only, while the rest are output only */ | ||
110 | if (offset < 4) | 121 | if (offset < 4) |
111 | return 1; | 122 | return 1; |
112 | 123 | ||
@@ -169,6 +180,7 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
169 | struct iio_dev *indio_dev; | 180 | struct iio_dev *indio_dev; |
170 | struct stx104_iio *priv; | 181 | struct stx104_iio *priv; |
171 | struct stx104_gpio *stx104gpio; | 182 | struct stx104_gpio *stx104gpio; |
183 | struct stx104_dev *stx104dev; | ||
172 | int err; | 184 | int err; |
173 | 185 | ||
174 | indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); | 186 | indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); |
@@ -179,6 +191,10 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
179 | if (!stx104gpio) | 191 | if (!stx104gpio) |
180 | return -ENOMEM; | 192 | return -ENOMEM; |
181 | 193 | ||
194 | stx104dev = devm_kzalloc(dev, sizeof(*stx104dev), GFP_KERNEL); | ||
195 | if (!stx104dev) | ||
196 | return -ENOMEM; | ||
197 | |||
182 | if (!devm_request_region(dev, base[id], STX104_EXTENT, | 198 | if (!devm_request_region(dev, base[id], STX104_EXTENT, |
183 | dev_name(dev))) { | 199 | dev_name(dev))) { |
184 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", | 200 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", |
@@ -199,12 +215,6 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
199 | outw(0, base[id] + 4); | 215 | outw(0, base[id] + 4); |
200 | outw(0, base[id] + 6); | 216 | outw(0, base[id] + 6); |
201 | 217 | ||
202 | err = devm_iio_device_register(dev, indio_dev); | ||
203 | if (err) { | ||
204 | dev_err(dev, "IIO device registering failed (%d)\n", err); | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | stx104gpio->chip.label = dev_name(dev); | 218 | stx104gpio->chip.label = dev_name(dev); |
209 | stx104gpio->chip.parent = dev; | 219 | stx104gpio->chip.parent = dev; |
210 | stx104gpio->chip.owner = THIS_MODULE; | 220 | stx104gpio->chip.owner = THIS_MODULE; |
@@ -220,7 +230,9 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
220 | 230 | ||
221 | spin_lock_init(&stx104gpio->lock); | 231 | spin_lock_init(&stx104gpio->lock); |
222 | 232 | ||
223 | dev_set_drvdata(dev, stx104gpio); | 233 | stx104dev->indio_dev = indio_dev; |
234 | stx104dev->chip = &stx104gpio->chip; | ||
235 | dev_set_drvdata(dev, stx104dev); | ||
224 | 236 | ||
225 | err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); | 237 | err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); |
226 | if (err) { | 238 | if (err) { |
@@ -228,14 +240,22 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
228 | return err; | 240 | return err; |
229 | } | 241 | } |
230 | 242 | ||
243 | err = iio_device_register(indio_dev); | ||
244 | if (err) { | ||
245 | dev_err(dev, "IIO device registering failed (%d)\n", err); | ||
246 | gpiochip_remove(&stx104gpio->chip); | ||
247 | return err; | ||
248 | } | ||
249 | |||
231 | return 0; | 250 | return 0; |
232 | } | 251 | } |
233 | 252 | ||
234 | static int stx104_remove(struct device *dev, unsigned int id) | 253 | static int stx104_remove(struct device *dev, unsigned int id) |
235 | { | 254 | { |
236 | struct stx104_gpio *const stx104gpio = dev_get_drvdata(dev); | 255 | struct stx104_dev *const stx104dev = dev_get_drvdata(dev); |
237 | 256 | ||
238 | gpiochip_remove(&stx104gpio->chip); | 257 | iio_device_unregister(stx104dev->indio_dev); |
258 | gpiochip_remove(stx104dev->chip); | ||
239 | 259 | ||
240 | return 0; | 260 | return 0; |
241 | } | 261 | } |