Lines Matching +full:gpio +full:- +full:range

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Intel Tangier GPIO driver
22 #include <linux/pinctrl/pinconf-generic.h>
28 #include <linux/gpio/driver.h>
30 #include "gpio-tangier.h"
46 * struct tng_gpio_context - Context to be saved during suspend-resume
69 return priv->reg_base + reg + reg_offset * 4; in gpio_reg()
80 return priv->reg_base + reg + reg_offset * 4; in gpio_reg_and_bit()
101 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_set()
115 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_direction_input()
134 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_direction_output()
166 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_set_debounce()
192 return -ENOTSUPP; in tng_gpio_set_config()
200 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_ack() local
204 gisr = gpio_reg_and_bit(&priv->chip, gpio, GISR, &shift); in tng_irq_ack()
206 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_ack()
211 static void tng_irq_unmask_mask(struct tng_gpio *priv, u32 gpio, bool unmask) in tng_irq_unmask_mask() argument
217 gimr = gpio_reg_and_bit(&priv->chip, gpio, GIMR, &shift); in tng_irq_unmask_mask()
219 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_unmask_mask()
233 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_mask() local
235 tng_irq_unmask_mask(priv, gpio, false); in tng_irq_mask()
236 gpiochip_disable_irq(&priv->chip, gpio); in tng_irq_mask()
243 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_unmask() local
245 gpiochip_enable_irq(&priv->chip, gpio); in tng_irq_unmask()
246 tng_irq_unmask_mask(priv, gpio, true); in tng_irq_unmask()
253 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_set_type() local
254 void __iomem *grer = gpio_reg(&priv->chip, gpio, GRER); in tng_irq_set_type()
255 void __iomem *gfer = gpio_reg(&priv->chip, gpio, GFER); in tng_irq_set_type()
256 void __iomem *gitr = gpio_reg(&priv->chip, gpio, GITR); in tng_irq_set_type()
257 void __iomem *glpr = gpio_reg(&priv->chip, gpio, GLPR); in tng_irq_set_type()
258 u8 shift = gpio % 32; in tng_irq_set_type()
261 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_set_type()
309 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_set_wake() local
310 void __iomem *gwmr = gpio_reg(&priv->chip, gpio, priv->wake_regs.gwmr); in tng_irq_set_wake()
311 void __iomem *gwsr = gpio_reg(&priv->chip, gpio, priv->wake_regs.gwsr); in tng_irq_set_wake()
312 u8 shift = gpio % 32; in tng_irq_set_wake()
315 dev_dbg(priv->dev, "%s wake for gpio %lu\n", str_enable_disable(on), gpio); in tng_irq_set_wake()
317 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_set_wake()
333 .name = "gpio-tangier",
348 unsigned long base, gpio; in tng_irq_handler() local
352 /* Check GPIO controller to check which pin triggered the interrupt */ in tng_irq_handler()
353 for (base = 0; base < priv->chip.ngpio; base += 32) { in tng_irq_handler()
354 void __iomem *gisr = gpio_reg(&priv->chip, base, GISR); in tng_irq_handler()
355 void __iomem *gimr = gpio_reg(&priv->chip, base, GIMR); in tng_irq_handler()
364 for_each_set_bit(gpio, &pending, 32) in tng_irq_handler()
365 generic_handle_domain_irq(gc->irq.domain, base + gpio); in tng_irq_handler()
377 for (base = 0; base < priv->chip.ngpio; base += 32) { in tng_irq_init_hw()
378 /* Clear the rising-edge detect register */ in tng_irq_init_hw()
379 reg = gpio_reg(&priv->chip, base, GRER); in tng_irq_init_hw()
382 /* Clear the falling-edge detect register */ in tng_irq_init_hw()
383 reg = gpio_reg(&priv->chip, base, GFER); in tng_irq_init_hw()
393 const struct tng_gpio_pinrange *range; in tng_gpio_add_pin_ranges() local
397 for (i = 0; i < priv->pin_info.nranges; i++) { in tng_gpio_add_pin_ranges()
398 range = &priv->pin_info.pin_ranges[i]; in tng_gpio_add_pin_ranges()
399 ret = gpiochip_add_pin_range(&priv->chip, in tng_gpio_add_pin_ranges()
400 priv->pin_info.name, in tng_gpio_add_pin_ranges()
401 range->gpio_base, in tng_gpio_add_pin_ranges()
402 range->pin_base, in tng_gpio_add_pin_ranges()
403 range->npins); in tng_gpio_add_pin_ranges()
405 dev_err(priv->dev, "failed to add GPIO pin range\n"); in tng_gpio_add_pin_ranges()
413 int devm_tng_gpio_probe(struct device *dev, struct tng_gpio *gpio) in devm_tng_gpio_probe() argument
415 const struct tng_gpio_info *info = &gpio->info; in devm_tng_gpio_probe()
416 size_t nctx = DIV_ROUND_UP(info->ngpio, 32); in devm_tng_gpio_probe()
420 gpio->ctx = devm_kcalloc(dev, nctx, sizeof(*gpio->ctx), GFP_KERNEL); in devm_tng_gpio_probe()
421 if (!gpio->ctx) in devm_tng_gpio_probe()
422 return -ENOMEM; in devm_tng_gpio_probe()
424 gpio->chip.label = dev_name(dev); in devm_tng_gpio_probe()
425 gpio->chip.parent = dev; in devm_tng_gpio_probe()
426 gpio->chip.request = gpiochip_generic_request; in devm_tng_gpio_probe()
427 gpio->chip.free = gpiochip_generic_free; in devm_tng_gpio_probe()
428 gpio->chip.direction_input = tng_gpio_direction_input; in devm_tng_gpio_probe()
429 gpio->chip.direction_output = tng_gpio_direction_output; in devm_tng_gpio_probe()
430 gpio->chip.get = tng_gpio_get; in devm_tng_gpio_probe()
431 gpio->chip.set = tng_gpio_set; in devm_tng_gpio_probe()
432 gpio->chip.get_direction = tng_gpio_get_direction; in devm_tng_gpio_probe()
433 gpio->chip.set_config = tng_gpio_set_config; in devm_tng_gpio_probe()
434 gpio->chip.base = info->base; in devm_tng_gpio_probe()
435 gpio->chip.ngpio = info->ngpio; in devm_tng_gpio_probe()
436 gpio->chip.can_sleep = false; in devm_tng_gpio_probe()
437 gpio->chip.add_pin_ranges = tng_gpio_add_pin_ranges; in devm_tng_gpio_probe()
439 raw_spin_lock_init(&gpio->lock); in devm_tng_gpio_probe()
441 girq = &gpio->chip.irq; in devm_tng_gpio_probe()
443 girq->init_hw = tng_irq_init_hw; in devm_tng_gpio_probe()
444 girq->parent_handler = tng_irq_handler; in devm_tng_gpio_probe()
445 girq->num_parents = 1; in devm_tng_gpio_probe()
446 girq->parents = devm_kcalloc(dev, girq->num_parents, in devm_tng_gpio_probe()
447 sizeof(*girq->parents), GFP_KERNEL); in devm_tng_gpio_probe()
448 if (!girq->parents) in devm_tng_gpio_probe()
449 return -ENOMEM; in devm_tng_gpio_probe()
451 girq->parents[0] = gpio->irq; in devm_tng_gpio_probe()
452 girq->first = info->first; in devm_tng_gpio_probe()
453 girq->default_type = IRQ_TYPE_NONE; in devm_tng_gpio_probe()
454 girq->handler = handle_bad_irq; in devm_tng_gpio_probe()
456 ret = devm_gpiochip_add_data(dev, &gpio->chip, gpio); in devm_tng_gpio_probe()
467 struct tng_gpio_context *ctx = priv->ctx; in tng_gpio_suspend()
470 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_suspend()
472 for (base = 0; base < priv->chip.ngpio; base += 32, ctx++) { in tng_gpio_suspend()
474 ctx->level = readl(gpio_reg(&priv->chip, base, GPLR)); in tng_gpio_suspend()
476 ctx->gpdr = readl(gpio_reg(&priv->chip, base, GPDR)); in tng_gpio_suspend()
477 ctx->grer = readl(gpio_reg(&priv->chip, base, GRER)); in tng_gpio_suspend()
478 ctx->gfer = readl(gpio_reg(&priv->chip, base, GFER)); in tng_gpio_suspend()
479 ctx->gimr = readl(gpio_reg(&priv->chip, base, GIMR)); in tng_gpio_suspend()
481 ctx->gwmr = readl(gpio_reg(&priv->chip, base, priv->wake_regs.gwmr)); in tng_gpio_suspend()
490 struct tng_gpio_context *ctx = priv->ctx; in tng_gpio_resume()
493 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_resume()
495 for (base = 0; base < priv->chip.ngpio; base += 32, ctx++) { in tng_gpio_resume()
497 writel(ctx->level, gpio_reg(&priv->chip, base, GPSR)); in tng_gpio_resume()
499 writel(ctx->gpdr, gpio_reg(&priv->chip, base, GPDR)); in tng_gpio_resume()
500 writel(ctx->grer, gpio_reg(&priv->chip, base, GRER)); in tng_gpio_resume()
501 writel(ctx->gfer, gpio_reg(&priv->chip, base, GFER)); in tng_gpio_resume()
502 writel(ctx->gimr, gpio_reg(&priv->chip, base, GIMR)); in tng_gpio_resume()
504 writel(ctx->gwmr, gpio_reg(&priv->chip, base, priv->wake_regs.gwmr)); in tng_gpio_resume()
515 MODULE_DESCRIPTION("Intel Tangier GPIO driver");