summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mockup.c
diff options
context:
space:
mode:
authorBartosz Golaszewski <brgl@bgdev.pl>2017-08-14 07:20:56 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-08-20 18:12:30 -0400
commitb4c495f03ae3d332e3304eb62b4748b31f1170dd (patch)
treeac2975915c1b81ebec6fec9c6b16566302aa2448 /drivers/gpio/gpio-mockup.c
parent4342ec5fba2bc9e6654259c5d891999a7592d9fa (diff)
gpio: mockup: use irq_sim
Shrink the driver by removing the code dealing with dummy interrupts and replacing it with calls to the irq_sim API. Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-mockup.c')
-rw-r--r--drivers/gpio/gpio-mockup.c77
1 files changed, 7 insertions, 70 deletions
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
index a6565e128f9e..6db7163e6d98 100644
--- a/drivers/gpio/gpio-mockup.c
+++ b/drivers/gpio/gpio-mockup.c
@@ -20,7 +20,7 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/irq_work.h> 23#include <linux/irq_sim.h>
24#include <linux/debugfs.h> 24#include <linux/debugfs.h>
25#include <linux/uaccess.h> 25#include <linux/uaccess.h>
26 26
@@ -47,18 +47,12 @@ enum {
47struct gpio_mockup_line_status { 47struct gpio_mockup_line_status {
48 int dir; 48 int dir;
49 bool value; 49 bool value;
50 bool irq_enabled;
51};
52
53struct gpio_mockup_irq_context {
54 struct irq_work work;
55 int irq;
56}; 50};
57 51
58struct gpio_mockup_chip { 52struct gpio_mockup_chip {
59 struct gpio_chip gc; 53 struct gpio_chip gc;
60 struct gpio_mockup_line_status *lines; 54 struct gpio_mockup_line_status *lines;
61 struct gpio_mockup_irq_context irq_ctx; 55 struct irq_sim irqsim;
62 struct dentry *dbg_dir; 56 struct dentry *dbg_dir;
63}; 57};
64 58
@@ -144,65 +138,11 @@ static int gpio_mockup_name_lines(struct device *dev,
144 return 0; 138 return 0;
145} 139}
146 140
147static int gpio_mockup_to_irq(struct gpio_chip *chip, unsigned int offset) 141static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
148{
149 return chip->irq_base + offset;
150}
151
152static void gpio_mockup_irqmask(struct irq_data *data)
153{ 142{
154 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
155 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 143 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
156 144
157 chip->lines[data->irq - gc->irq_base].irq_enabled = false; 145 return irq_sim_irqnum(&chip->irqsim, offset);
158}
159
160static void gpio_mockup_irqunmask(struct irq_data *data)
161{
162 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
163 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
164
165 chip->lines[data->irq - gc->irq_base].irq_enabled = true;
166}
167
168static struct irq_chip gpio_mockup_irqchip = {
169 .name = GPIO_MOCKUP_NAME,
170 .irq_mask = gpio_mockup_irqmask,
171 .irq_unmask = gpio_mockup_irqunmask,
172};
173
174static void gpio_mockup_handle_irq(struct irq_work *work)
175{
176 struct gpio_mockup_irq_context *irq_ctx;
177
178 irq_ctx = container_of(work, struct gpio_mockup_irq_context, work);
179 handle_simple_irq(irq_to_desc(irq_ctx->irq));
180}
181
182static int gpio_mockup_irqchip_setup(struct device *dev,
183 struct gpio_mockup_chip *chip)
184{
185 struct gpio_chip *gc = &chip->gc;
186 int irq_base, i;
187
188 irq_base = devm_irq_alloc_descs(dev, -1, 0, gc->ngpio, 0);
189 if (irq_base < 0)
190 return irq_base;
191
192 gc->irq_base = irq_base;
193 gc->irqchip = &gpio_mockup_irqchip;
194
195 for (i = 0; i < gc->ngpio; i++) {
196 irq_set_chip(irq_base + i, gc->irqchip);
197 irq_set_chip_data(irq_base + i, gc);
198 irq_set_handler(irq_base + i, &handle_simple_irq);
199 irq_modify_status(irq_base + i,
200 IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
201 }
202
203 init_irq_work(&chip->irq_ctx.work, gpio_mockup_handle_irq);
204
205 return 0;
206} 146}
207 147
208static ssize_t gpio_mockup_event_write(struct file *file, 148static ssize_t gpio_mockup_event_write(struct file *file,
@@ -228,11 +168,8 @@ static ssize_t gpio_mockup_event_write(struct file *file,
228 chip = priv->chip; 168 chip = priv->chip;
229 gc = &chip->gc; 169 gc = &chip->gc;
230 170
231 if (chip->lines[priv->offset].irq_enabled) { 171 gpiod_set_value_cansleep(desc, val);
232 gpiod_set_value_cansleep(desc, val); 172 irq_sim_fire(&chip->irqsim, priv->offset);
233 priv->chip->irq_ctx.irq = gc->irq_base + priv->offset;
234 irq_work_queue(&priv->chip->irq_ctx.work);
235 }
236 173
237 return size; 174 return size;
238} 175}
@@ -319,7 +256,7 @@ static int gpio_mockup_add(struct device *dev,
319 return ret; 256 return ret;
320 } 257 }
321 258
322 ret = gpio_mockup_irqchip_setup(dev, chip); 259 ret = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
323 if (ret) 260 if (ret)
324 return ret; 261 return ret;
325 262