Lines Matching +full:gpio +full:- +full:ctrl1
1 // SPDX-License-Identifier: GPL-2.0
8 * This driver is based on the original Cherryview GPIO driver by
15 #include <linux/gpio/driver.h>
23 #include <linux/pinctrl/pinconf-generic.h>
28 #include "pinctrl-intel.h"
81 * struct intel_community_context - community context for Cherryview
82 * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space)
97 .size = (end) - (start) + 1, \
270 * Southwest community can generate GPIO interrupts only for the first 8
271 * interrupts. The upper half (8-15) can only be used to trigger GPEs.
364 * North community can generate GPIO interrupts only for the first 8
365 * interrupts. The upper half (8-15) can only be used to trigger GPEs.
564 * concurrent accesses across the 4 GPIO controllers.
573 const struct intel_community *community = &pctrl->communities[0]; in chv_pctrl_readl()
575 return readl(community->regs + offset); in chv_pctrl_readl()
580 const struct intel_community *community = &pctrl->communities[0]; in chv_pctrl_writel()
581 void __iomem *reg = community->regs + offset; in chv_pctrl_writel()
591 const struct intel_community *community = &pctrl->communities[0]; in chv_padreg()
597 return community->pad_regs + offset + reg; in chv_padreg()
625 u32 ctrl0, ctrl1; in chv_pin_dbg_show() local
631 ctrl1 = chv_readl(pctrl, offset, CHV_PADCTRL1); in chv_pin_dbg_show()
637 seq_puts(s, "GPIO "); in chv_pin_dbg_show()
647 seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1); in chv_pin_dbg_show()
664 struct device *dev = pctrl->dev; in chv_pinmux_set_mux()
669 grp = &pctrl->soc->groups[group]; in chv_pinmux_set_mux()
674 for (i = 0; i < grp->grp.npins; i++) { in chv_pinmux_set_mux()
675 if (chv_pad_locked(pctrl, grp->grp.pins[i])) { in chv_pinmux_set_mux()
677 dev_warn(dev, "unable to set mode for locked pin %u\n", grp->grp.pins[i]); in chv_pinmux_set_mux()
678 return -EBUSY; in chv_pinmux_set_mux()
682 for (i = 0; i < grp->grp.npins; i++) { in chv_pinmux_set_mux()
683 int pin = grp->grp.pins[i]; in chv_pinmux_set_mux()
688 /* Check if there is pin-specific config */ in chv_pinmux_set_mux()
689 if (grp->modes) in chv_pinmux_set_mux()
690 mode = grp->modes[i]; in chv_pinmux_set_mux()
692 mode = grp->mode; in chv_pinmux_set_mux()
699 /* Disable GPIO mode */ in chv_pinmux_set_mux()
728 * One some devices the GPIO should output the inverted value from what in chv_gpio_clear_triggering()
729 * device-drivers / ACPI code expects (inverted external buffer?). The in chv_gpio_clear_triggering()
731 * preserve this flag if the pin is already setup as GPIO. in chv_gpio_clear_triggering()
758 return -EBUSY; in chv_gpio_request_enable()
761 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_request_enable()
765 for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) { in chv_gpio_request_enable()
766 if (cctx->intr_lines[i] == offset) { in chv_gpio_request_enable()
767 cctx->intr_lines[i] = CHV_INVALID_HWIRQ; in chv_gpio_request_enable()
787 /* Switch to a GPIO mode */ in chv_gpio_request_enable()
850 u32 ctrl0, ctrl1; in chv_config_get() local
856 ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); in chv_config_get()
864 return -EINVAL; in chv_config_get()
869 return -EINVAL; in chv_config_get()
887 return -EINVAL; in chv_config_get()
906 return -EINVAL; in chv_config_get()
911 if (ctrl1 & CHV_PADCTRL1_ODEN) in chv_config_get()
912 return -EINVAL; in chv_config_get()
916 if (!(ctrl1 & CHV_PADCTRL1_ODEN)) in chv_config_get()
917 return -EINVAL; in chv_config_get()
922 return -ENOTSUPP; in chv_config_get()
959 return -EINVAL; in chv_config_set_pull()
977 return -EINVAL; in chv_config_set_pull()
985 return -EINVAL; in chv_config_set_pull()
998 u32 ctrl1; in chv_config_set_oden() local
1001 ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); in chv_config_set_oden()
1004 ctrl1 |= CHV_PADCTRL1_ODEN; in chv_config_set_oden()
1006 ctrl1 &= ~CHV_PADCTRL1_ODEN; in chv_config_set_oden()
1008 chv_writel(pctrl, pin, CHV_PADCTRL1, ctrl1); in chv_config_set_oden()
1018 struct device *dev = pctrl->dev; in chv_config_set()
1024 return -EBUSY; in chv_config_set()
1052 return -ENOTSUPP; in chv_config_set()
1175 return pinctrl_gpio_direction_input(chip->base + offset); in chv_gpio_direction_input()
1182 return pinctrl_gpio_direction_output(chip->base + offset); in chv_gpio_direction_output()
1261 * In that case ->irq_set_type() will never be called so we need to in chv_gpio_irq_startup()
1268 struct device *dev = pctrl->dev; in chv_gpio_irq_startup()
1269 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_irq_startup()
1286 if (cctx->intr_lines[intsel] == CHV_INVALID_HWIRQ) { in chv_gpio_irq_startup()
1290 cctx->intr_lines[intsel] = hwirq; in chv_gpio_irq_startup()
1301 struct device *dev = pctrl->dev; in chv_gpio_set_intr_line()
1302 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_set_intr_line()
1303 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_set_intr_line()
1310 if (cctx->intr_lines[intsel] == pin) in chv_gpio_set_intr_line()
1313 if (cctx->intr_lines[intsel] == CHV_INVALID_HWIRQ) { in chv_gpio_set_intr_line()
1315 cctx->intr_lines[intsel] = pin; in chv_gpio_set_intr_line()
1327 cctx->intr_lines[intsel], pin); in chv_gpio_set_intr_line()
1330 return -EBUSY; in chv_gpio_set_intr_line()
1336 for (i = community->nirqs - 1; i >= 0; i--) { in chv_gpio_set_intr_line()
1337 if (cctx->intr_lines[i] == CHV_INVALID_HWIRQ) in chv_gpio_set_intr_line()
1341 return -EBUSY; in chv_gpio_set_intr_line()
1347 cctx->intr_lines[i] = pin; in chv_gpio_set_intr_line()
1414 .name = "chv-gpio",
1428 struct device *dev = pctrl->dev; in chv_gpio_irq_handler()
1429 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_irq_handler()
1430 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_irq_handler()
1442 for_each_set_bit(intr_line, &pending, community->nirqs) { in chv_gpio_irq_handler()
1445 offset = cctx->intr_lines[intr_line]; in chv_gpio_irq_handler()
1452 generic_handle_domain_irq(gc->irq.domain, offset); in chv_gpio_irq_handler()
1504 const struct intel_community *community = &pctrl->communities[0]; in chv_init_irq_valid_mask()
1508 for (i = 0; i < pctrl->soc->npins; i++) { in chv_init_irq_valid_mask()
1512 desc = &pctrl->soc->pins[i]; in chv_init_irq_valid_mask()
1514 intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); in chv_init_irq_valid_mask()
1518 if (intsel >= community->nirqs) in chv_init_irq_valid_mask()
1519 clear_bit(desc->number, valid_mask); in chv_init_irq_valid_mask()
1526 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_irq_init_hw()
1535 if (!pctrl->chip.irq.init_valid_mask) { in chv_gpio_irq_init_hw()
1540 chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs)); in chv_gpio_irq_init_hw()
1552 struct device *dev = pctrl->dev; in chv_gpio_add_pin_ranges()
1553 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_add_pin_ranges()
1557 for (i = 0; i < community->ngpps; i++) { in chv_gpio_add_pin_ranges()
1558 gpp = &community->gpps[i]; in chv_gpio_add_pin_ranges()
1559 ret = gpiochip_add_pin_range(chip, dev_name(dev), gpp->base, gpp->base, gpp->size); in chv_gpio_add_pin_ranges()
1561 dev_err(dev, "failed to add GPIO pin range\n"); in chv_gpio_add_pin_ranges()
1571 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_probe()
1573 struct gpio_chip *chip = &pctrl->chip; in chv_gpio_probe()
1574 struct device *dev = pctrl->dev; in chv_gpio_probe()
1580 chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1; in chv_gpio_probe()
1581 chip->label = dev_name(dev); in chv_gpio_probe()
1582 chip->add_pin_ranges = chv_gpio_add_pin_ranges; in chv_gpio_probe()
1583 chip->parent = dev; in chv_gpio_probe()
1584 chip->base = -1; in chv_gpio_probe()
1586 pctrl->irq = irq; in chv_gpio_probe()
1588 gpio_irq_chip_set_chip(&chip->irq, &chv_gpio_irq_chip); in chv_gpio_probe()
1589 chip->irq.init_hw = chv_gpio_irq_init_hw; in chv_gpio_probe()
1590 chip->irq.parent_handler = chv_gpio_irq_handler; in chv_gpio_probe()
1591 chip->irq.num_parents = 1; in chv_gpio_probe()
1592 chip->irq.parents = &pctrl->irq; in chv_gpio_probe()
1593 chip->irq.default_type = IRQ_TYPE_NONE; in chv_gpio_probe()
1594 chip->irq.handler = handle_bad_irq; in chv_gpio_probe()
1596 chip->irq.init_valid_mask = chv_init_irq_valid_mask; in chv_gpio_probe()
1598 irq_base = devm_irq_alloc_descs(dev, -1, 0, pctrl->soc->npins, NUMA_NO_NODE); in chv_gpio_probe()
1612 for (i = 0; i < community->ngpps; i++) { in chv_gpio_probe()
1613 gpp = &community->gpps[i]; in chv_gpio_probe()
1615 irq_domain_associate_many(chip->irq.domain, irq_base, in chv_gpio_probe()
1616 gpp->base, gpp->size); in chv_gpio_probe()
1617 irq_base += gpp->size; in chv_gpio_probe()
1651 struct device *dev = &pdev->dev; in chv_pinctrl_probe()
1663 return -ENOMEM; in chv_pinctrl_probe()
1665 pctrl->dev = dev; in chv_pinctrl_probe()
1666 pctrl->soc = soc_data; in chv_pinctrl_probe()
1668 pctrl->ncommunities = pctrl->soc->ncommunities; in chv_pinctrl_probe()
1669 pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities, in chv_pinctrl_probe()
1670 pctrl->ncommunities * sizeof(*pctrl->communities), in chv_pinctrl_probe()
1672 if (!pctrl->communities) in chv_pinctrl_probe()
1673 return -ENOMEM; in chv_pinctrl_probe()
1675 community = &pctrl->communities[0]; in chv_pinctrl_probe()
1676 community->regs = devm_platform_ioremap_resource(pdev, 0); in chv_pinctrl_probe()
1677 if (IS_ERR(community->regs)) in chv_pinctrl_probe()
1678 return PTR_ERR(community->regs); in chv_pinctrl_probe()
1680 community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF; in chv_pinctrl_probe()
1683 pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins, in chv_pinctrl_probe()
1684 sizeof(*pctrl->context.pads), in chv_pinctrl_probe()
1686 if (!pctrl->context.pads) in chv_pinctrl_probe()
1687 return -ENOMEM; in chv_pinctrl_probe()
1690 pctrl->context.communities = devm_kcalloc(dev, pctrl->soc->ncommunities, in chv_pinctrl_probe()
1691 sizeof(*pctrl->context.communities), in chv_pinctrl_probe()
1693 if (!pctrl->context.communities) in chv_pinctrl_probe()
1694 return -ENOMEM; in chv_pinctrl_probe()
1696 cctx = &pctrl->context.communities[0]; in chv_pinctrl_probe()
1697 for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) in chv_pinctrl_probe()
1698 cctx->intr_lines[i] = CHV_INVALID_HWIRQ; in chv_pinctrl_probe()
1704 pctrl->pctldesc = chv_pinctrl_desc; in chv_pinctrl_probe()
1705 pctrl->pctldesc.name = dev_name(dev); in chv_pinctrl_probe()
1706 pctrl->pctldesc.pins = pctrl->soc->pins; in chv_pinctrl_probe()
1707 pctrl->pctldesc.npins = pctrl->soc->npins; in chv_pinctrl_probe()
1709 pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); in chv_pinctrl_probe()
1710 if (IS_ERR(pctrl->pctldev)) { in chv_pinctrl_probe()
1712 return PTR_ERR(pctrl->pctldev); in chv_pinctrl_probe()
1720 community->acpi_space_id, in chv_pinctrl_probe()
1734 const struct intel_community *community = &pctrl->communities[0]; in chv_pinctrl_remove()
1736 acpi_remove_address_space_handler(ACPI_HANDLE(&pdev->dev), in chv_pinctrl_remove()
1737 community->acpi_space_id, in chv_pinctrl_remove()
1746 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_pinctrl_suspend_noirq()
1752 cctx->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); in chv_pinctrl_suspend_noirq()
1754 for (i = 0; i < pctrl->soc->npins; i++) { in chv_pinctrl_suspend_noirq()
1756 struct intel_pad_context *ctx = &pctrl->context.pads[i]; in chv_pinctrl_suspend_noirq()
1758 desc = &pctrl->soc->pins[i]; in chv_pinctrl_suspend_noirq()
1759 if (chv_pad_locked(pctrl, desc->number)) in chv_pinctrl_suspend_noirq()
1762 ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); in chv_pinctrl_suspend_noirq()
1763 ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; in chv_pinctrl_suspend_noirq()
1765 ctx->padctrl1 = chv_readl(pctrl, desc->number, CHV_PADCTRL1); in chv_pinctrl_suspend_noirq()
1776 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_pinctrl_resume_noirq()
1783 * Mask all interrupts before restoring per-pin configuration in chv_pinctrl_resume_noirq()
1789 for (i = 0; i < pctrl->soc->npins; i++) { in chv_pinctrl_resume_noirq()
1791 struct intel_pad_context *ctx = &pctrl->context.pads[i]; in chv_pinctrl_resume_noirq()
1794 desc = &pctrl->soc->pins[i]; in chv_pinctrl_resume_noirq()
1795 if (chv_pad_locked(pctrl, desc->number)) in chv_pinctrl_resume_noirq()
1799 val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); in chv_pinctrl_resume_noirq()
1801 if (ctx->padctrl0 != val) { in chv_pinctrl_resume_noirq()
1802 chv_writel(pctrl, desc->number, CHV_PADCTRL0, ctx->padctrl0); in chv_pinctrl_resume_noirq()
1803 dev_dbg(dev, "restored pin %2u ctrl0 0x%08x\n", desc->number, in chv_pinctrl_resume_noirq()
1804 chv_readl(pctrl, desc->number, CHV_PADCTRL0)); in chv_pinctrl_resume_noirq()
1807 val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); in chv_pinctrl_resume_noirq()
1808 if (ctx->padctrl1 != val) { in chv_pinctrl_resume_noirq()
1809 chv_writel(pctrl, desc->number, CHV_PADCTRL1, ctx->padctrl1); in chv_pinctrl_resume_noirq()
1810 dev_dbg(dev, "restored pin %2u ctrl1 0x%08x\n", desc->number, in chv_pinctrl_resume_noirq()
1811 chv_readl(pctrl, desc->number, CHV_PADCTRL1)); in chv_pinctrl_resume_noirq()
1820 chv_pctrl_writel(pctrl, CHV_INTMASK, cctx->saved_intmask); in chv_pinctrl_resume_noirq()
1840 .name = "cherryview-pinctrl",