Lines Matching +full:lock +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015-2018 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
14 struct mutex lock; member
30 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); in gpio_siox_set_data()
32 mutex_lock(&ddata->lock); in gpio_siox_set_data()
33 buf[0] = ddata->setdata[0]; in gpio_siox_set_data()
34 mutex_unlock(&ddata->lock); in gpio_siox_set_data()
41 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); in gpio_siox_get_data()
42 size_t offset; in gpio_siox_get_data() local
45 mutex_lock(&ddata->lock); in gpio_siox_get_data()
47 raw_spin_lock_irq(&ddata->irqlock); in gpio_siox_get_data()
49 for (offset = 0; offset < 12; ++offset) { in gpio_siox_get_data()
50 unsigned int bitpos = 11 - offset; in gpio_siox_get_data()
53 ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); in gpio_siox_get_data()
54 u32 irq_type = ddata->irq_type[offset]; in gpio_siox_get_data()
59 ddata->irq_status |= 1 << offset; in gpio_siox_get_data()
63 ddata->irq_status |= 1 << offset; in gpio_siox_get_data()
67 trigger = ddata->irq_status & ddata->irq_enable; in gpio_siox_get_data()
69 raw_spin_unlock_irq(&ddata->irqlock); in gpio_siox_get_data()
71 ddata->getdata[0] = buf[0]; in gpio_siox_get_data()
72 ddata->getdata[1] = buf[1]; in gpio_siox_get_data()
73 ddata->getdata[2] = buf[2]; in gpio_siox_get_data()
75 mutex_unlock(&ddata->lock); in gpio_siox_get_data()
77 for (offset = 0; offset < 12; ++offset) { in gpio_siox_get_data()
78 if (trigger & (1 << offset)) { in gpio_siox_get_data()
79 struct irq_domain *irqdomain = ddata->gchip.irq.domain; in gpio_siox_get_data()
80 unsigned int irq = irq_find_mapping(irqdomain, offset); in gpio_siox_get_data()
87 raw_spin_lock_irq(&ddata->irqlock); in gpio_siox_get_data()
88 ddata->irq_status &= ~(1 << offset); in gpio_siox_get_data()
89 raw_spin_unlock_irq(&ddata->irqlock); in gpio_siox_get_data()
104 raw_spin_lock(&ddata->irqlock); in gpio_siox_irq_ack()
105 ddata->irq_status &= ~(1 << d->hwirq); in gpio_siox_irq_ack()
106 raw_spin_unlock(&ddata->irqlock); in gpio_siox_irq_ack()
115 raw_spin_lock(&ddata->irqlock); in gpio_siox_irq_mask()
116 ddata->irq_enable &= ~(1 << d->hwirq); in gpio_siox_irq_mask()
117 raw_spin_unlock(&ddata->irqlock); in gpio_siox_irq_mask()
126 raw_spin_lock(&ddata->irqlock); in gpio_siox_irq_unmask()
127 ddata->irq_enable |= 1 << d->hwirq; in gpio_siox_irq_unmask()
128 raw_spin_unlock(&ddata->irqlock); in gpio_siox_irq_unmask()
137 raw_spin_lock(&ddata->irqlock); in gpio_siox_irq_set_type()
138 ddata->irq_type[d->hwirq] = type; in gpio_siox_irq_set_type()
139 raw_spin_unlock(&ddata->irqlock); in gpio_siox_irq_set_type()
144 static int gpio_siox_get(struct gpio_chip *chip, unsigned int offset) in gpio_siox_get() argument
150 mutex_lock(&ddata->lock); in gpio_siox_get()
152 if (offset >= 12) { in gpio_siox_get()
153 unsigned int bitpos = 19 - offset; in gpio_siox_get()
155 ret = ddata->setdata[0] & (1 << bitpos); in gpio_siox_get()
157 unsigned int bitpos = 11 - offset; in gpio_siox_get()
159 ret = ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); in gpio_siox_get()
162 mutex_unlock(&ddata->lock); in gpio_siox_get()
168 unsigned int offset, int value) in gpio_siox_set() argument
172 u8 mask = 1 << (19 - offset); in gpio_siox_set()
174 mutex_lock(&ddata->lock); in gpio_siox_set()
177 ddata->setdata[0] |= mask; in gpio_siox_set()
179 ddata->setdata[0] &= ~mask; in gpio_siox_set()
181 mutex_unlock(&ddata->lock); in gpio_siox_set()
185 unsigned int offset) in gpio_siox_direction_input() argument
187 if (offset >= 12) in gpio_siox_direction_input()
188 return -EINVAL; in gpio_siox_direction_input()
194 unsigned int offset, int value) in gpio_siox_direction_output() argument
196 if (offset < 12) in gpio_siox_direction_output()
197 return -EINVAL; in gpio_siox_direction_output()
199 gpio_siox_set(chip, offset, value); in gpio_siox_direction_output()
203 static int gpio_siox_get_direction(struct gpio_chip *chip, unsigned int offset) in gpio_siox_get_direction() argument
205 if (offset < 12) in gpio_siox_get_direction()
215 struct device *dev = &sdevice->dev; in gpio_siox_probe()
220 return -ENOMEM; in gpio_siox_probe()
224 mutex_init(&ddata->lock); in gpio_siox_probe()
225 raw_spin_lock_init(&ddata->irqlock); in gpio_siox_probe()
227 ddata->gchip.base = -1; in gpio_siox_probe()
228 ddata->gchip.can_sleep = 1; in gpio_siox_probe()
229 ddata->gchip.parent = dev; in gpio_siox_probe()
230 ddata->gchip.owner = THIS_MODULE; in gpio_siox_probe()
231 ddata->gchip.get = gpio_siox_get; in gpio_siox_probe()
232 ddata->gchip.set = gpio_siox_set; in gpio_siox_probe()
233 ddata->gchip.direction_input = gpio_siox_direction_input; in gpio_siox_probe()
234 ddata->gchip.direction_output = gpio_siox_direction_output; in gpio_siox_probe()
235 ddata->gchip.get_direction = gpio_siox_get_direction; in gpio_siox_probe()
236 ddata->gchip.ngpio = 20; in gpio_siox_probe()
238 ddata->ichip.name = "siox-gpio"; in gpio_siox_probe()
239 ddata->ichip.irq_ack = gpio_siox_irq_ack; in gpio_siox_probe()
240 ddata->ichip.irq_mask = gpio_siox_irq_mask; in gpio_siox_probe()
241 ddata->ichip.irq_unmask = gpio_siox_irq_unmask; in gpio_siox_probe()
242 ddata->ichip.irq_set_type = gpio_siox_irq_set_type; in gpio_siox_probe()
244 girq = &ddata->gchip.irq; in gpio_siox_probe()
245 girq->chip = &ddata->ichip; in gpio_siox_probe()
246 girq->default_type = IRQ_TYPE_NONE; in gpio_siox_probe()
247 girq->handler = handle_level_irq; in gpio_siox_probe()
248 girq->threaded = true; in gpio_siox_probe()
250 ret = devm_gpiochip_add_data(dev, &ddata->gchip, NULL); in gpio_siox_probe()
262 .name = "gpio-siox",
267 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");