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 = of_node_to_fwnode(chip->parent->of_node); 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()
182 struct uniphier_gpio_priv *priv = data->chip_data; in uniphier_gpio_irq_mask()
183 u32 mask = BIT(data->hwirq); in uniphier_gpio_irq_mask()
192 struct uniphier_gpio_priv *priv = data->chip_data; in uniphier_gpio_irq_unmask()
193 u32 mask = BIT(data->hwirq); in uniphier_gpio_irq_unmask()
202 struct uniphier_gpio_priv *priv = data->chip_data; in uniphier_gpio_irq_set_type()
203 u32 mask = BIT(data->hwirq); in uniphier_gpio_irq_set_type()
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()
300 return gpiochip_lock_as_irq(chip, data->hwirq + UNIPHIER_GPIO_IRQ_OFFSET); in uniphier_gpio_irq_domain_activate()
306 struct uniphier_gpio_priv *priv = domain->host_data; in uniphier_gpio_irq_domain_deactivate()
307 struct gpio_chip *chip = &priv->chip; in uniphier_gpio_irq_domain_deactivate()
309 gpiochip_unlock_as_irq(chip, data->hwirq + UNIPHIER_GPIO_IRQ_OFFSET); in uniphier_gpio_irq_domain_deactivate()
325 * noise from the irq lines. It does not work for GPIO input, so GPIO in uniphier_gpio_hw_init()
329 writel(0xff, priv->regs + UNIPHIER_GPIO_IRQ_FLT_CYC); in uniphier_gpio_hw_init()
339 struct device *dev = &pdev->dev; in uniphier_gpio_probe()
349 parent_np = of_irq_find_parent(dev->of_node); in uniphier_gpio_probe()
351 return -ENXIO; in uniphier_gpio_probe()
356 return -EPROBE_DEFER; in uniphier_gpio_probe()
358 ret = of_property_read_u32(dev->of_node, "ngpios", &ngpios); in uniphier_gpio_probe()
366 return -ENOMEM; in uniphier_gpio_probe()
368 priv->regs = devm_platform_ioremap_resource(pdev, 0); in uniphier_gpio_probe()
369 if (IS_ERR(priv->regs)) in uniphier_gpio_probe()
370 return PTR_ERR(priv->regs); in uniphier_gpio_probe()
372 spin_lock_init(&priv->lock); in uniphier_gpio_probe()
374 chip = &priv->chip; in uniphier_gpio_probe()
375 chip->label = dev_name(dev); in uniphier_gpio_probe()
376 chip->parent = dev; in uniphier_gpio_probe()
377 chip->request = gpiochip_generic_request; in uniphier_gpio_probe()
378 chip->free = gpiochip_generic_free; in uniphier_gpio_probe()
379 chip->get_direction = uniphier_gpio_get_direction; in uniphier_gpio_probe()
380 chip->direction_input = uniphier_gpio_direction_input; in uniphier_gpio_probe()
381 chip->direction_output = uniphier_gpio_direction_output; in uniphier_gpio_probe()
382 chip->get = uniphier_gpio_get; in uniphier_gpio_probe()
383 chip->set = uniphier_gpio_set; in uniphier_gpio_probe()
384 chip->set_multiple = uniphier_gpio_set_multiple; in uniphier_gpio_probe()
385 chip->to_irq = uniphier_gpio_to_irq; in uniphier_gpio_probe()
386 chip->base = -1; in uniphier_gpio_probe()
387 chip->ngpio = ngpios; in uniphier_gpio_probe()
389 irq_chip = &priv->irq_chip; in uniphier_gpio_probe()
390 irq_chip->name = dev_name(dev); in uniphier_gpio_probe()
391 irq_chip->irq_mask = uniphier_gpio_irq_mask; in uniphier_gpio_probe()
392 irq_chip->irq_unmask = uniphier_gpio_irq_unmask; in uniphier_gpio_probe()
393 irq_chip->irq_eoi = irq_chip_eoi_parent; in uniphier_gpio_probe()
394 irq_chip->irq_set_affinity = irq_chip_set_affinity_parent; in uniphier_gpio_probe()
395 irq_chip->irq_set_type = uniphier_gpio_irq_set_type; in uniphier_gpio_probe()
403 priv->domain = irq_domain_create_hierarchy( in uniphier_gpio_probe()
406 of_node_to_fwnode(dev->of_node), in uniphier_gpio_probe()
408 if (!priv->domain) in uniphier_gpio_probe()
409 return -ENOMEM; in uniphier_gpio_probe()
420 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");