/** * struct altera_gpio_chip * @gc : GPIO chip structure. * @regs : memory mapped IO address for the controller registers. * @gpio_lock : synchronization lock so that new irq/set/get requests * will be blocked until the current one completes. * @interrupt_trigger : specifies the hardware configured IRQ trigger type * (rising, falling, both, high)
*/ struct altera_gpio_chip { struct gpio_chip gc; void __iomem *regs;
raw_spinlock_t gpio_lock; int interrupt_trigger;
};
/* * This controller's IRQ type is synthesized in hardware, so this function * just checks if the requested set_type matches the synthesized IRQ type
*/ staticint altera_gpio_irq_set_type(struct irq_data *d, unsignedint type)
{ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);
if (type == IRQ_TYPE_NONE) {
irq_set_handler_locked(d, handle_bad_irq); return0;
} if (type == altera_gc->interrupt_trigger) { if (type == IRQ_TYPE_LEVEL_HIGH)
irq_set_handler_locked(d, handle_level_irq); else
irq_set_handler_locked(d, handle_simple_irq); return0;
}
irq_set_handler_locked(d, handle_bad_irq); return -EINVAL;
}
altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL); if (!altera_gc) return -ENOMEM;
raw_spin_lock_init(&altera_gc->gpio_lock);
if (device_property_read_u32(dev, "altr,ngpio", ®)) /* By default assume maximum ngpio */
altera_gc->gc.ngpio = ALTERA_GPIO_MAX_NGPIO; else
altera_gc->gc.ngpio = reg;
if (altera_gc->gc.ngpio > ALTERA_GPIO_MAX_NGPIO) {
dev_warn(&pdev->dev, "ngpio is greater than %d, defaulting to %d\n",
ALTERA_GPIO_MAX_NGPIO, ALTERA_GPIO_MAX_NGPIO);
altera_gc->gc.ngpio = ALTERA_GPIO_MAX_NGPIO;
}
altera_gc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", dev_fwnode(dev)); if (!altera_gc->gc.label) return -ENOMEM;
altera_gc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(altera_gc->regs)) return dev_err_probe(dev, PTR_ERR(altera_gc->regs), "failed to ioremap memory resource\n");
mapped_irq = platform_get_irq_optional(pdev, 0); if (mapped_irq < 0) goto skip_irq;
if (device_property_read_u32(dev, "altr,interrupt-type", ®)) {
dev_err(&pdev->dev, "altr,interrupt-type value not set in device tree\n"); return -EINVAL;
}
altera_gc->interrupt_trigger = reg;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.