History

gpio: mockup: add set_config to support pull up/down

Add support for the pull up/down state set via gpiolib line requests to be reflected in the state of the mockup. Use case is for testing of the GPIO uAPI, specifically the pull up/down flags.

Kent Gibson committed 7 years ago

Commit 64e71121 parent 2821ae51 file · +60 −34Browse files

Unified · Split

drivers/gpio/gpio-mockup.c+60−34
@@ -141,6 +141,61 @@ static void gpio_mockup_set_multiple(struct gpio_chip *gc, · 140 unmodified lines
141141 mutex_unlock(&chip->lock);
142142 }
143143
144+static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
145+ unsigned int offset, int value)
146+{
147+ struct gpio_desc *desc;
148+ struct gpio_chip *gc;
149+ struct irq_sim *sim;
150+ int curr, irq, irq_type;
151+
152+ gc = &chip->gc;
153+ desc = &gc->gpiodev->descs[offset];
154+ sim = &chip->irqsim;
155+
156+ mutex_lock(&chip->lock);
157+
158+ if (test_bit(FLAG_REQUESTED, &desc->flags) &&
159+ !test_bit(FLAG_IS_OUT, &desc->flags)) {
160+ curr = __gpio_mockup_get(chip, offset);
161+ if (curr == value)
162+ goto out;
163+
164+ irq = irq_sim_irqnum(sim, offset);
165+ irq_type = irq_get_trigger_type(irq);
166+
167+ if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
168+ (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
169+ irq_sim_fire(sim, offset);
170+ }
171+
172+ /* Change the value unless we're actively driving the line. */
173+ if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
174+ !test_bit(FLAG_IS_OUT, &desc->flags))
175+ __gpio_mockup_set(chip, offset, value);
176+
177+out:
178+ chip->lines[offset].pull = value;
179+ mutex_unlock(&chip->lock);
180+ return 0;
181+}
182+
183+static int gpio_mockup_set_config(struct gpio_chip *gc,
184+ unsigned int offset, unsigned long config)
185+{
186+ struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
187+
188+ switch (pinconf_to_config_param(config)) {
189+ case PIN_CONFIG_BIAS_PULL_UP:
190+ return gpio_mockup_apply_pull(chip, offset, 1);
191+ case PIN_CONFIG_BIAS_PULL_DOWN:
192+ return gpio_mockup_apply_pull(chip, offset, 0);
193+ default:
194+ break;
195+ }
196+ return -ENOTSUPP;
197+}
198+
144199 static int gpio_mockup_dirout(struct gpio_chip *gc,
145200 unsigned int offset, int value)
146201 {
@@ -221,12 +276,8 @@ static ssize_t gpio_mockup_debugfs_write(struct file *file, · 74 unmodified lines
221276 size_t size, loff_t *ppos)
222277 {
223278 struct gpio_mockup_dbgfs_private *priv;
224− int rv, val, curr, irq, irq_type;
225− struct gpio_mockup_chip *chip;
279+ int rv, val;
226280 struct seq_file *sfile;
227− struct gpio_desc *desc;
228− struct gpio_chip *gc;
229− struct irq_sim *sim;
230281
231282 if (*ppos != 0)
232283 return -EINVAL;
@@ -239,35 +290,9 @@ static ssize_t gpio_mockup_debugfs_write(struct file *file, · 6 unmodified lines
239290
240291 sfile = file->private_data;
241292 priv = sfile->private;
242− chip = priv->chip;
243− gc = &chip->gc;
244− desc = &gc->gpiodev->descs[priv->offset];
245− sim = &chip->irqsim;
246−
247− mutex_lock(&chip->lock);
248−
249− if (test_bit(FLAG_REQUESTED, &desc->flags) &&
250− !test_bit(FLAG_IS_OUT, &desc->flags)) {
251− curr = __gpio_mockup_get(chip, priv->offset);
252− if (curr == val)
253− goto out;
254−
255− irq = irq_sim_irqnum(sim, priv->offset);
256− irq_type = irq_get_trigger_type(irq);
257−
258− if ((val == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
259− (val == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
260− irq_sim_fire(sim, priv->offset);
261− }
262−
263− /* Change the value unless we're actively driving the line. */
264− if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
265− !test_bit(FLAG_IS_OUT, &desc->flags))
266− __gpio_mockup_set(chip, priv->offset, val);
267−
268−out:
269− chip->lines[priv->offset].pull = val;
270− mutex_unlock(&chip->lock);
293+ rv = gpio_mockup_apply_pull(priv->chip, priv->offset, val);
294+ if (rv)
295+ return rv;
271296
272297 return size;
273298 }
@@ -413,6 +438,7 @@ static int gpio_mockup_probe(struct platform_device *pdev) · 139 unmodified lines
413438 gc->direction_output = gpio_mockup_dirout;
414439 gc->direction_input = gpio_mockup_dirin;
415440 gc->get_direction = gpio_mockup_get_direction;
441+ gc->set_config = gpio_mockup_set_config;
416442 gc->to_irq = gpio_mockup_to_irq;
417443 gc->free = gpio_mockup_free;
418444