Lines Matching +full:lock +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * GPIO driver for the SMSC SCH311x Super-I/O chips
20 #define DRV_NAME "gpio-sch311x"
44 spinlock_t lock; /* lock for this GPIO block */ member
93 * Super-IO functions
102 return -EBUSY; in sch311x_sio_enter()
132 static int sch311x_gpio_request(struct gpio_chip *chip, unsigned offset) in sch311x_gpio_request() argument
136 if (block->config_regs[offset] == 0) /* GPIO is not available */ in sch311x_gpio_request()
137 return -ENODEV; in sch311x_gpio_request()
139 if (!request_region(block->runtime_reg + block->config_regs[offset], in sch311x_gpio_request()
141 dev_err(chip->parent, "Failed to request region 0x%04x.\n", in sch311x_gpio_request()
142 block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_request()
143 return -EBUSY; in sch311x_gpio_request()
148 static void sch311x_gpio_free(struct gpio_chip *chip, unsigned offset) in sch311x_gpio_free() argument
152 if (block->config_regs[offset] == 0) /* GPIO is not available */ in sch311x_gpio_free()
155 release_region(block->runtime_reg + block->config_regs[offset], 1); in sch311x_gpio_free()
158 static int sch311x_gpio_get(struct gpio_chip *chip, unsigned offset) in sch311x_gpio_get() argument
163 spin_lock(&block->lock); in sch311x_gpio_get()
164 data = inb(block->runtime_reg + block->data_reg); in sch311x_gpio_get()
165 spin_unlock(&block->lock); in sch311x_gpio_get()
167 return !!(data & BIT(offset)); in sch311x_gpio_get()
171 unsigned offset, int value) in __sch311x_gpio_set() argument
173 u8 data = inb(block->runtime_reg + block->data_reg); in __sch311x_gpio_set()
175 data |= BIT(offset); in __sch311x_gpio_set()
177 data &= ~BIT(offset); in __sch311x_gpio_set()
178 outb(data, block->runtime_reg + block->data_reg); in __sch311x_gpio_set()
181 static void sch311x_gpio_set(struct gpio_chip *chip, unsigned offset, in sch311x_gpio_set() argument
186 spin_lock(&block->lock); in sch311x_gpio_set()
187 __sch311x_gpio_set(block, offset, value); in sch311x_gpio_set()
188 spin_unlock(&block->lock); in sch311x_gpio_set()
191 static int sch311x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) in sch311x_gpio_direction_in() argument
196 spin_lock(&block->lock); in sch311x_gpio_direction_in()
197 data = inb(block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_direction_in()
199 outb(data, block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_direction_in()
200 spin_unlock(&block->lock); in sch311x_gpio_direction_in()
205 static int sch311x_gpio_direction_out(struct gpio_chip *chip, unsigned offset, in sch311x_gpio_direction_out() argument
211 spin_lock(&block->lock); in sch311x_gpio_direction_out()
213 data = inb(block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_direction_out()
215 outb(data, block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_direction_out()
216 __sch311x_gpio_set(block, offset, value); in sch311x_gpio_direction_out()
218 spin_unlock(&block->lock); in sch311x_gpio_direction_out()
222 static int sch311x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) in sch311x_gpio_get_direction() argument
227 spin_lock(&block->lock); in sch311x_gpio_get_direction()
228 data = inb(block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_get_direction()
229 spin_unlock(&block->lock); in sch311x_gpio_get_direction()
237 static int sch311x_gpio_set_config(struct gpio_chip *chip, unsigned offset, in sch311x_gpio_set_config() argument
246 spin_lock(&block->lock); in sch311x_gpio_set_config()
247 data = inb(block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_set_config()
249 outb(data, block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_set_config()
250 spin_unlock(&block->lock); in sch311x_gpio_set_config()
253 spin_lock(&block->lock); in sch311x_gpio_set_config()
254 data = inb(block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_set_config()
256 outb(data, block->runtime_reg + block->config_regs[offset]); in sch311x_gpio_set_config()
257 spin_unlock(&block->lock); in sch311x_gpio_set_config()
262 return -ENOTSUPP; in sch311x_gpio_set_config()
267 struct sch311x_pdev_data *pdata = dev_get_platdata(&pdev->dev); in sch311x_gpio_probe()
273 if (!devm_request_region(&pdev->dev, pdata->runtime_reg + GP1, 6, in sch311x_gpio_probe()
275 dev_err(&pdev->dev, "Failed to request region 0x%04x-0x%04x.\n", in sch311x_gpio_probe()
276 pdata->runtime_reg + GP1, pdata->runtime_reg + GP1 + 5); in sch311x_gpio_probe()
277 return -EBUSY; in sch311x_gpio_probe()
280 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in sch311x_gpio_probe()
282 return -ENOMEM; in sch311x_gpio_probe()
284 for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) { in sch311x_gpio_probe()
285 block = &priv->blocks[i]; in sch311x_gpio_probe()
287 spin_lock_init(&block->lock); in sch311x_gpio_probe()
289 block->chip.label = DRV_NAME; in sch311x_gpio_probe()
290 block->chip.owner = THIS_MODULE; in sch311x_gpio_probe()
291 block->chip.request = sch311x_gpio_request; in sch311x_gpio_probe()
292 block->chip.free = sch311x_gpio_free; in sch311x_gpio_probe()
293 block->chip.direction_input = sch311x_gpio_direction_in; in sch311x_gpio_probe()
294 block->chip.direction_output = sch311x_gpio_direction_out; in sch311x_gpio_probe()
295 block->chip.get_direction = sch311x_gpio_get_direction; in sch311x_gpio_probe()
296 block->chip.set_config = sch311x_gpio_set_config; in sch311x_gpio_probe()
297 block->chip.get = sch311x_gpio_get; in sch311x_gpio_probe()
298 block->chip.set = sch311x_gpio_set; in sch311x_gpio_probe()
299 block->chip.ngpio = 8; in sch311x_gpio_probe()
300 block->chip.parent = &pdev->dev; in sch311x_gpio_probe()
301 block->chip.base = sch311x_gpio_blocks[i].base; in sch311x_gpio_probe()
302 block->config_regs = sch311x_gpio_blocks[i].config_regs; in sch311x_gpio_probe()
303 block->data_reg = sch311x_gpio_blocks[i].data_reg; in sch311x_gpio_probe()
304 block->runtime_reg = pdata->runtime_reg; in sch311x_gpio_probe()
306 err = devm_gpiochip_add_data(&pdev->dev, &block->chip, block); in sch311x_gpio_probe()
308 dev_err(&pdev->dev, in sch311x_gpio_probe()
312 dev_info(&pdev->dev, in sch311x_gpio_probe()
352 err = -ENODEV; in sch311x_detect()
368 err = -ENODEV; in sch311x_detect()
387 sch311x_gpio_pdev = platform_device_alloc(DRV_NAME, -1); in sch311x_gpio_pdev_add()
389 return -ENOMEM; in sch311x_gpio_pdev_add()
420 return -ENODEV; in sch311x_gpio_init()
449 MODULE_ALIAS("platform:gpio-sch311x");