Lines Matching +full:uniphier +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/gpio/driver.h>
16 #include <dt-bindings/gpio/uniphier-gpio.h>
43 * Unfortunately, the GPIO port registers are not contiguous because in uniphier_gpio_bank_to_reg()
44 * offset 0x90-0x9f is used for IRQ. Add 0x10 when crossing the region. in uniphier_gpio_bank_to_reg()
65 spin_lock_irqsave(&priv->lock, flags); in uniphier_gpio_reg_update()
66 tmp = readl(priv->regs + reg); in uniphier_gpio_reg_update()
69 writel(tmp, priv->regs + reg); in uniphier_gpio_reg_update()
70 spin_unlock_irqrestore(&priv->lock, flags); in uniphier_gpio_reg_update()
107 return !!(readl(priv->regs + reg_offset) & mask); in uniphier_gpio_offset_read()
152 for_each_set_clump8(i, bank_mask, mask, chip->ngpio) { in uniphier_gpio_set_multiple()
166 return -ENXIO; in uniphier_gpio_to_irq()
168 fwspec.fwnode = dev_fwnode(chip->parent); in uniphier_gpio_to_irq()
170 fwspec.param[0] = offset - UNIPHIER_GPIO_IRQ_OFFSET; in uniphier_gpio_to_irq()
173 * temporarily. Anyway, ->irq_set_type() will override it later. in uniphier_gpio_to_irq()
221 struct device_node *np = priv->chip.parent->of_node; in uniphier_gpio_irq_get_parent_hwirq()
226 range = of_get_property(np, "socionext,interrupt-ranges", &len); in uniphier_gpio_irq_get_parent_hwirq()
228 return -EINVAL; in uniphier_gpio_irq_get_parent_hwirq()
232 for (; len >= 3; len -= 3) { in uniphier_gpio_irq_get_parent_hwirq()
238 return hwirq - base + parent_base; in uniphier_gpio_irq_get_parent_hwirq()
241 return -ENOENT; in uniphier_gpio_irq_get_parent_hwirq()
249 if (WARN_ON(fwspec->param_count < 2)) in uniphier_gpio_irq_domain_translate()
250 return -EINVAL; in uniphier_gpio_irq_domain_translate()
252 *out_hwirq = fwspec->param[0]; in uniphier_gpio_irq_domain_translate()
253 *out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in uniphier_gpio_irq_domain_translate()
262 struct uniphier_gpio_priv *priv = domain->host_data; in uniphier_gpio_irq_domain_alloc()
269 return -EINVAL; in uniphier_gpio_irq_domain_alloc()
279 /* parent is UniPhier AIDET */ in uniphier_gpio_irq_domain_alloc()
280 parent_fwspec.fwnode = domain->parent->fwnode; in uniphier_gpio_irq_domain_alloc()
287 &priv->irq_chip, priv); in uniphier_gpio_irq_domain_alloc()
297 struct uniphier_gpio_priv *priv = domain->host_data; in uniphier_gpio_irq_domain_activate()
298 struct gpio_chip *chip = &priv->chip; in uniphier_gpio_irq_domain_activate()
307 struct uniphier_gpio_priv *priv = domain->host_data; in uniphier_gpio_irq_domain_deactivate()
308 struct gpio_chip *chip = &priv->chip; in uniphier_gpio_irq_domain_deactivate()
327 * noise from the irq lines. It does not work for GPIO input, so GPIO in uniphier_gpio_hw_init()
331 writel(0xff, priv->regs + UNIPHIER_GPIO_IRQ_FLT_CYC); in uniphier_gpio_hw_init()
341 struct device *dev = &pdev->dev; in uniphier_gpio_probe()
351 parent_np = of_irq_find_parent(dev->of_node); in uniphier_gpio_probe()
353 return -ENXIO; in uniphier_gpio_probe()
358 return -EPROBE_DEFER; in uniphier_gpio_probe()
360 ret = of_property_read_u32(dev->of_node, "ngpios", &ngpios); in uniphier_gpio_probe()
368 return -ENOMEM; in uniphier_gpio_probe()
370 priv->regs = devm_platform_ioremap_resource(pdev, 0); in uniphier_gpio_probe()
371 if (IS_ERR(priv->regs)) in uniphier_gpio_probe()
372 return PTR_ERR(priv->regs); in uniphier_gpio_probe()
374 spin_lock_init(&priv->lock); in uniphier_gpio_probe()
376 chip = &priv->chip; in uniphier_gpio_probe()
377 chip->label = dev_name(dev); in uniphier_gpio_probe()
378 chip->parent = dev; in uniphier_gpio_probe()
379 chip->request = gpiochip_generic_request; in uniphier_gpio_probe()
380 chip->free = gpiochip_generic_free; in uniphier_gpio_probe()
381 chip->get_direction = uniphier_gpio_get_direction; in uniphier_gpio_probe()
382 chip->direction_input = uniphier_gpio_direction_input; in uniphier_gpio_probe()
383 chip->direction_output = uniphier_gpio_direction_output; in uniphier_gpio_probe()
384 chip->get = uniphier_gpio_get; in uniphier_gpio_probe()
385 chip->set = uniphier_gpio_set; in uniphier_gpio_probe()
386 chip->set_multiple = uniphier_gpio_set_multiple; in uniphier_gpio_probe()
387 chip->to_irq = uniphier_gpio_to_irq; in uniphier_gpio_probe()
388 chip->base = -1; in uniphier_gpio_probe()
389 chip->ngpio = ngpios; in uniphier_gpio_probe()
391 irq_chip = &priv->irq_chip; in uniphier_gpio_probe()
392 irq_chip->name = dev_name(dev); in uniphier_gpio_probe()
393 irq_chip->irq_mask = uniphier_gpio_irq_mask; in uniphier_gpio_probe()
394 irq_chip->irq_unmask = uniphier_gpio_irq_unmask; in uniphier_gpio_probe()
395 irq_chip->irq_eoi = irq_chip_eoi_parent; in uniphier_gpio_probe()
396 irq_chip->irq_set_affinity = irq_chip_set_affinity_parent; in uniphier_gpio_probe()
397 irq_chip->irq_set_type = uniphier_gpio_irq_set_type; in uniphier_gpio_probe()
405 priv->domain = irq_domain_create_hierarchy( in uniphier_gpio_probe()
410 if (!priv->domain) in uniphier_gpio_probe()
411 return -ENOMEM; in uniphier_gpio_probe()
422 irq_domain_remove(priv->domain); in uniphier_gpio_remove()
428 unsigned int nbanks = uniphier_gpio_get_nbanks(priv->chip.ngpio); in uniphier_gpio_suspend()
429 u32 *val = priv->saved_vals; in uniphier_gpio_suspend()
436 *val++ = readl(priv->regs + reg + UNIPHIER_GPIO_PORT_DATA); in uniphier_gpio_suspend()
437 *val++ = readl(priv->regs + reg + UNIPHIER_GPIO_PORT_DIR); in uniphier_gpio_suspend()
440 *val++ = readl(priv->regs + UNIPHIER_GPIO_IRQ_EN); in uniphier_gpio_suspend()
441 *val++ = readl(priv->regs + UNIPHIER_GPIO_IRQ_MODE); in uniphier_gpio_suspend()
442 *val++ = readl(priv->regs + UNIPHIER_GPIO_IRQ_FLT_EN); in uniphier_gpio_suspend()
450 unsigned int nbanks = uniphier_gpio_get_nbanks(priv->chip.ngpio); in uniphier_gpio_resume()
451 const u32 *val = priv->saved_vals; in uniphier_gpio_resume()
458 writel(*val++, priv->regs + reg + UNIPHIER_GPIO_PORT_DATA); in uniphier_gpio_resume()
459 writel(*val++, priv->regs + reg + UNIPHIER_GPIO_PORT_DIR); in uniphier_gpio_resume()
462 writel(*val++, priv->regs + UNIPHIER_GPIO_IRQ_EN); in uniphier_gpio_resume()
463 writel(*val++, priv->regs + UNIPHIER_GPIO_IRQ_MODE); in uniphier_gpio_resume()
464 writel(*val++, priv->regs + UNIPHIER_GPIO_IRQ_FLT_EN); in uniphier_gpio_resume()
477 { .compatible = "socionext,uniphier-gpio" },
486 .name = "uniphier-gpio",
494 MODULE_DESCRIPTION("UniPhier GPIO driver");