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()
199 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_ack() local
203 gisr = gpio_reg_and_bit(&priv->chip, gpio, GISR, &shift); in tng_irq_ack()
205 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_ack()
210 static void tng_irq_unmask_mask(struct tng_gpio *priv, u32 gpio, bool unmask) in tng_irq_unmask_mask() argument
216 gimr = gpio_reg_and_bit(&priv->chip, gpio, GIMR, &shift); in tng_irq_unmask_mask()
218 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_unmask_mask()
231 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_mask() local
233 tng_irq_unmask_mask(priv, gpio, false); in tng_irq_mask()
234 gpiochip_disable_irq(&priv->chip, gpio); in tng_irq_mask()
240 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_unmask() local
242 gpiochip_enable_irq(&priv->chip, gpio); in tng_irq_unmask()
243 tng_irq_unmask_mask(priv, gpio, true); in tng_irq_unmask()
250 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_set_type() local
251 void __iomem *grer = gpio_reg(&priv->chip, gpio, GRER); in tng_irq_set_type()
252 void __iomem *gfer = gpio_reg(&priv->chip, gpio, GFER); in tng_irq_set_type()
253 void __iomem *gitr = gpio_reg(&priv->chip, gpio, GITR); in tng_irq_set_type()
254 void __iomem *glpr = gpio_reg(&priv->chip, gpio, GLPR); in tng_irq_set_type()
255 u8 shift = gpio % 32; in tng_irq_set_type()
258 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_set_type()
306 irq_hw_number_t gpio = irqd_to_hwirq(d); in tng_irq_set_wake() local
307 void __iomem *gwmr = gpio_reg(&priv->chip, gpio, priv->wake_regs.gwmr); in tng_irq_set_wake()
308 void __iomem *gwsr = gpio_reg(&priv->chip, gpio, priv->wake_regs.gwsr); in tng_irq_set_wake()
309 u8 shift = gpio % 32; in tng_irq_set_wake()
312 dev_dbg(priv->dev, "%s wake for gpio %lu\n", str_enable_disable(on), gpio); in tng_irq_set_wake()
314 guard(raw_spinlock_irqsave)(&priv->lock); in tng_irq_set_wake()
330 .name = "gpio-tangier",
345 unsigned long base, gpio; in tng_irq_handler() local
349 /* Check GPIO controller to check which pin triggered the interrupt */ in tng_irq_handler()
350 for (base = 0; base < priv->chip.ngpio; base += 32) { in tng_irq_handler()
351 void __iomem *gisr = gpio_reg(&priv->chip, base, GISR); in tng_irq_handler()
352 void __iomem *gimr = gpio_reg(&priv->chip, base, GIMR); in tng_irq_handler()
361 for_each_set_bit(gpio, &pending, 32) in tng_irq_handler()
362 generic_handle_domain_irq(gc->irq.domain, base + gpio); in tng_irq_handler()
374 for (base = 0; base < priv->chip.ngpio; base += 32) { in tng_irq_init_hw()
375 /* Clear the rising-edge detect register */ in tng_irq_init_hw()
376 reg = gpio_reg(&priv->chip, base, GRER); in tng_irq_init_hw()
379 /* Clear the falling-edge detect register */ in tng_irq_init_hw()
380 reg = gpio_reg(&priv->chip, base, GFER); in tng_irq_init_hw()
390 const struct tng_gpio_pinrange *range; in tng_gpio_add_pin_ranges() local
394 for (i = 0; i < priv->pin_info.nranges; i++) { in tng_gpio_add_pin_ranges()
395 range = &priv->pin_info.pin_ranges[i]; in tng_gpio_add_pin_ranges()
396 ret = gpiochip_add_pin_range(&priv->chip, in tng_gpio_add_pin_ranges()
397 priv->pin_info.name, in tng_gpio_add_pin_ranges()
398 range->gpio_base, in tng_gpio_add_pin_ranges()
399 range->pin_base, in tng_gpio_add_pin_ranges()
400 range->npins); in tng_gpio_add_pin_ranges()
402 dev_err(priv->dev, "failed to add GPIO pin range\n"); in tng_gpio_add_pin_ranges()
410 int devm_tng_gpio_probe(struct device *dev, struct tng_gpio *gpio) in devm_tng_gpio_probe() argument
412 const struct tng_gpio_info *info = &gpio->info; in devm_tng_gpio_probe()
413 size_t nctx = DIV_ROUND_UP(info->ngpio, 32); in devm_tng_gpio_probe()
417 gpio->ctx = devm_kcalloc(dev, nctx, sizeof(*gpio->ctx), GFP_KERNEL); in devm_tng_gpio_probe()
418 if (!gpio->ctx) in devm_tng_gpio_probe()
419 return -ENOMEM; in devm_tng_gpio_probe()
421 gpio->chip.label = dev_name(dev); in devm_tng_gpio_probe()
422 gpio->chip.parent = dev; in devm_tng_gpio_probe()
423 gpio->chip.request = gpiochip_generic_request; in devm_tng_gpio_probe()
424 gpio->chip.free = gpiochip_generic_free; in devm_tng_gpio_probe()
425 gpio->chip.direction_input = tng_gpio_direction_input; in devm_tng_gpio_probe()
426 gpio->chip.direction_output = tng_gpio_direction_output; in devm_tng_gpio_probe()
427 gpio->chip.get = tng_gpio_get; in devm_tng_gpio_probe()
428 gpio->chip.set = tng_gpio_set; in devm_tng_gpio_probe()
429 gpio->chip.get_direction = tng_gpio_get_direction; in devm_tng_gpio_probe()
430 gpio->chip.set_config = tng_gpio_set_config; in devm_tng_gpio_probe()
431 gpio->chip.base = info->base; in devm_tng_gpio_probe()
432 gpio->chip.ngpio = info->ngpio; in devm_tng_gpio_probe()
433 gpio->chip.can_sleep = false; in devm_tng_gpio_probe()
434 gpio->chip.add_pin_ranges = tng_gpio_add_pin_ranges; in devm_tng_gpio_probe()
436 raw_spin_lock_init(&gpio->lock); in devm_tng_gpio_probe()
438 girq = &gpio->chip.irq; in devm_tng_gpio_probe()
440 girq->init_hw = tng_irq_init_hw; in devm_tng_gpio_probe()
441 girq->parent_handler = tng_irq_handler; in devm_tng_gpio_probe()
442 girq->num_parents = 1; in devm_tng_gpio_probe()
443 girq->parents = devm_kcalloc(dev, girq->num_parents, in devm_tng_gpio_probe()
444 sizeof(*girq->parents), GFP_KERNEL); in devm_tng_gpio_probe()
445 if (!girq->parents) in devm_tng_gpio_probe()
446 return -ENOMEM; in devm_tng_gpio_probe()
448 girq->parents[0] = gpio->irq; in devm_tng_gpio_probe()
449 girq->first = info->first; in devm_tng_gpio_probe()
450 girq->default_type = IRQ_TYPE_NONE; in devm_tng_gpio_probe()
451 girq->handler = handle_bad_irq; in devm_tng_gpio_probe()
453 ret = devm_gpiochip_add_data(dev, &gpio->chip, gpio); in devm_tng_gpio_probe()
464 struct tng_gpio_context *ctx = priv->ctx; in tng_gpio_suspend()
467 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_suspend()
469 for (base = 0; base < priv->chip.ngpio; base += 32, ctx++) { in tng_gpio_suspend()
471 ctx->level = readl(gpio_reg(&priv->chip, base, GPLR)); in tng_gpio_suspend()
473 ctx->gpdr = readl(gpio_reg(&priv->chip, base, GPDR)); in tng_gpio_suspend()
474 ctx->grer = readl(gpio_reg(&priv->chip, base, GRER)); in tng_gpio_suspend()
475 ctx->gfer = readl(gpio_reg(&priv->chip, base, GFER)); in tng_gpio_suspend()
476 ctx->gimr = readl(gpio_reg(&priv->chip, base, GIMR)); in tng_gpio_suspend()
478 ctx->gwmr = readl(gpio_reg(&priv->chip, base, priv->wake_regs.gwmr)); in tng_gpio_suspend()
487 struct tng_gpio_context *ctx = priv->ctx; in tng_gpio_resume()
490 guard(raw_spinlock_irqsave)(&priv->lock); in tng_gpio_resume()
492 for (base = 0; base < priv->chip.ngpio; base += 32, ctx++) { in tng_gpio_resume()
494 writel(ctx->level, gpio_reg(&priv->chip, base, GPSR)); in tng_gpio_resume()
496 writel(ctx->gpdr, gpio_reg(&priv->chip, base, GPDR)); in tng_gpio_resume()
497 writel(ctx->grer, gpio_reg(&priv->chip, base, GRER)); in tng_gpio_resume()
498 writel(ctx->gfer, gpio_reg(&priv->chip, base, GFER)); in tng_gpio_resume()
499 writel(ctx->gimr, gpio_reg(&priv->chip, base, GIMR)); in tng_gpio_resume()
501 writel(ctx->gwmr, gpio_reg(&priv->chip, base, priv->wake_regs.gwmr)); in tng_gpio_resume()
512 MODULE_DESCRIPTION("Intel Tangier GPIO driver");