• Home
  • Raw
  • Download

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>
24 #include <linux/pinctrl/pinconf-generic.h>
26 #include "pinctrl-intel.h"
77 * struct intel_community_context - community context for Cherryview
78 * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space)
93 .size = (end) - (start) + 1, \
266 * Southwest community can generate GPIO interrupts only for the first 8
267 * interrupts. The upper half (8-15) can only be used to trigger GPEs.
360 * North community can generate GPIO interrupts only for the first 8
361 * interrupts. The upper half (8-15) can only be used to trigger GPEs.
560 * concurrent accesses across the 4 GPIO controllers.
569 const struct intel_community *community = &pctrl->communities[0]; in chv_pctrl_readl()
571 return readl(community->regs + offset); in chv_pctrl_readl()
576 const struct intel_community *community = &pctrl->communities[0]; in chv_pctrl_writel()
577 void __iomem *reg = community->regs + offset; in chv_pctrl_writel()
587 const struct intel_community *community = &pctrl->communities[0]; in chv_padreg()
593 return community->pad_regs + offset + reg; in chv_padreg()
620 return pctrl->soc->ngroups; in chv_get_groups_count()
628 return pctrl->soc->groups[group].name; in chv_get_group_name()
636 *pins = pctrl->soc->groups[group].pins; in chv_get_group_pins()
637 *npins = pctrl->soc->groups[group].npins; in chv_get_group_pins()
646 u32 ctrl0, ctrl1; in chv_pin_dbg_show() local
652 ctrl1 = chv_readl(pctrl, offset, CHV_PADCTRL1); in chv_pin_dbg_show()
658 seq_puts(s, "GPIO "); in chv_pin_dbg_show()
668 seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1); in chv_pin_dbg_show()
685 return pctrl->soc->nfunctions; in chv_get_functions_count()
693 return pctrl->soc->functions[function].name; in chv_get_function_name()
703 *groups = pctrl->soc->functions[function].groups; in chv_get_function_groups()
704 *ngroups = pctrl->soc->functions[function].ngroups; in chv_get_function_groups()
716 grp = &pctrl->soc->groups[group]; in chv_pinmux_set_mux()
721 for (i = 0; i < grp->npins; i++) { in chv_pinmux_set_mux()
722 if (chv_pad_locked(pctrl, grp->pins[i])) { in chv_pinmux_set_mux()
723 dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n", in chv_pinmux_set_mux()
724 grp->pins[i]); in chv_pinmux_set_mux()
726 return -EBUSY; in chv_pinmux_set_mux()
730 for (i = 0; i < grp->npins; i++) { in chv_pinmux_set_mux()
731 int pin = grp->pins[i]; in chv_pinmux_set_mux()
736 /* Check if there is pin-specific config */ in chv_pinmux_set_mux()
737 if (grp->modes) in chv_pinmux_set_mux()
738 mode = grp->modes[i]; in chv_pinmux_set_mux()
740 mode = grp->mode; in chv_pinmux_set_mux()
747 /* Disable GPIO mode */ in chv_pinmux_set_mux()
760 dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n", in chv_pinmux_set_mux()
776 * One some devices the GPIO should output the inverted value from what in chv_gpio_clear_triggering()
777 * device-drivers / ACPI code expects (inverted external buffer?). The in chv_gpio_clear_triggering()
779 * preserve this flag if the pin is already setup as GPIO. in chv_gpio_clear_triggering()
806 return -EBUSY; in chv_gpio_request_enable()
809 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_request_enable()
813 for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) { in chv_gpio_request_enable()
814 if (cctx->intr_lines[i] == offset) { in chv_gpio_request_enable()
815 cctx->intr_lines[i] = 0; in chv_gpio_request_enable()
835 /* Switch to a GPIO mode */ in chv_gpio_request_enable()
898 u32 ctrl0, ctrl1; in chv_config_get() local
904 ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); in chv_config_get()
912 return -EINVAL; in chv_config_get()
917 return -EINVAL; in chv_config_get()
935 return -EINVAL; in chv_config_get()
954 return -EINVAL; in chv_config_get()
959 if (ctrl1 & CHV_PADCTRL1_ODEN) in chv_config_get()
960 return -EINVAL; in chv_config_get()
964 if (!(ctrl1 & CHV_PADCTRL1_ODEN)) in chv_config_get()
965 return -EINVAL; in chv_config_get()
970 return -ENOTSUPP; in chv_config_get()
1007 return -EINVAL; in chv_config_set_pull()
1025 return -EINVAL; in chv_config_set_pull()
1033 return -EINVAL; in chv_config_set_pull()
1046 u32 ctrl1; in chv_config_set_oden() local
1049 ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); in chv_config_set_oden()
1052 ctrl1 |= CHV_PADCTRL1_ODEN; in chv_config_set_oden()
1054 ctrl1 &= ~CHV_PADCTRL1_ODEN; in chv_config_set_oden()
1056 chv_writel(pctrl, pin, CHV_PADCTRL1, ctrl1); in chv_config_set_oden()
1071 return -EBUSY; in chv_config_set()
1099 return -ENOTSUPP; in chv_config_set()
1102 dev_dbg(pctrl->dev, "pin %d set config %d arg %u\n", pin, in chv_config_set()
1223 return pinctrl_gpio_direction_input(chip->base + offset); in chv_gpio_direction_input()
1230 return pinctrl_gpio_direction_output(chip->base + offset); in chv_gpio_direction_output()
1303 * In that case ->irq_set_type() will never be called so we need to in chv_gpio_irq_startup()
1310 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_irq_startup()
1327 if (!cctx->intr_lines[intsel]) { in chv_gpio_irq_startup()
1329 cctx->intr_lines[intsel] = pin; in chv_gpio_irq_startup()
1342 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_irq_type()
1387 cctx->intr_lines[value] = pin; in chv_gpio_irq_type()
1403 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_irq_handler()
1404 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_gpio_irq_handler()
1416 for_each_set_bit(intr_line, &pending, community->nirqs) { in chv_gpio_irq_handler()
1419 offset = cctx->intr_lines[intr_line]; in chv_gpio_irq_handler()
1420 irq = irq_find_mapping(gc->irq.domain, offset); in chv_gpio_irq_handler()
1473 const struct intel_community *community = &pctrl->communities[0]; in chv_init_irq_valid_mask()
1477 for (i = 0; i < pctrl->soc->npins; i++) { in chv_init_irq_valid_mask()
1481 desc = &pctrl->soc->pins[i]; in chv_init_irq_valid_mask()
1483 intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); in chv_init_irq_valid_mask()
1487 if (intsel >= community->nirqs) in chv_init_irq_valid_mask()
1488 clear_bit(desc->number, valid_mask); in chv_init_irq_valid_mask()
1495 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_irq_init_hw()
1504 if (!pctrl->chip.irq.init_valid_mask) { in chv_gpio_irq_init_hw()
1509 chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs)); in chv_gpio_irq_init_hw()
1521 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_add_pin_ranges()
1525 for (i = 0; i < community->ngpps; i++) { in chv_gpio_add_pin_ranges()
1526 gpp = &community->gpps[i]; in chv_gpio_add_pin_ranges()
1527 ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), in chv_gpio_add_pin_ranges()
1528 gpp->base, gpp->base, in chv_gpio_add_pin_ranges()
1529 gpp->size); in chv_gpio_add_pin_ranges()
1531 dev_err(pctrl->dev, "failed to add GPIO pin range\n"); in chv_gpio_add_pin_ranges()
1541 const struct intel_community *community = &pctrl->communities[0]; in chv_gpio_probe()
1543 struct gpio_chip *chip = &pctrl->chip; in chv_gpio_probe()
1549 chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1; in chv_gpio_probe()
1550 chip->label = dev_name(pctrl->dev); in chv_gpio_probe()
1551 chip->add_pin_ranges = chv_gpio_add_pin_ranges; in chv_gpio_probe()
1552 chip->parent = pctrl->dev; in chv_gpio_probe()
1553 chip->base = -1; in chv_gpio_probe()
1555 pctrl->irq = irq; in chv_gpio_probe()
1556 pctrl->irqchip.name = "chv-gpio"; in chv_gpio_probe()
1557 pctrl->irqchip.irq_startup = chv_gpio_irq_startup; in chv_gpio_probe()
1558 pctrl->irqchip.irq_ack = chv_gpio_irq_ack; in chv_gpio_probe()
1559 pctrl->irqchip.irq_mask = chv_gpio_irq_mask; in chv_gpio_probe()
1560 pctrl->irqchip.irq_unmask = chv_gpio_irq_unmask; in chv_gpio_probe()
1561 pctrl->irqchip.irq_set_type = chv_gpio_irq_type; in chv_gpio_probe()
1562 pctrl->irqchip.flags = IRQCHIP_SKIP_SET_WAKE; in chv_gpio_probe()
1564 chip->irq.chip = &pctrl->irqchip; in chv_gpio_probe()
1565 chip->irq.init_hw = chv_gpio_irq_init_hw; in chv_gpio_probe()
1566 chip->irq.parent_handler = chv_gpio_irq_handler; in chv_gpio_probe()
1567 chip->irq.num_parents = 1; in chv_gpio_probe()
1568 chip->irq.parents = &pctrl->irq; in chv_gpio_probe()
1569 chip->irq.default_type = IRQ_TYPE_NONE; in chv_gpio_probe()
1570 chip->irq.handler = handle_bad_irq; in chv_gpio_probe()
1572 chip->irq.init_valid_mask = chv_init_irq_valid_mask; in chv_gpio_probe()
1574 irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, in chv_gpio_probe()
1575 pctrl->soc->npins, NUMA_NO_NODE); in chv_gpio_probe()
1577 dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); in chv_gpio_probe()
1582 ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); in chv_gpio_probe()
1584 dev_err(pctrl->dev, "Failed to register gpiochip\n"); in chv_gpio_probe()
1589 for (i = 0; i < community->ngpps; i++) { in chv_gpio_probe()
1590 gpp = &community->gpps[i]; in chv_gpio_probe()
1592 irq_domain_associate_many(chip->irq.domain, irq_base, in chv_gpio_probe()
1593 gpp->base, gpp->size); in chv_gpio_probe()
1594 irq_base += gpp->size; in chv_gpio_probe()
1627 struct device *dev = &pdev->dev; in chv_pinctrl_probe()
1638 return -ENOMEM; in chv_pinctrl_probe()
1640 pctrl->dev = dev; in chv_pinctrl_probe()
1641 pctrl->soc = soc_data; in chv_pinctrl_probe()
1643 pctrl->ncommunities = pctrl->soc->ncommunities; in chv_pinctrl_probe()
1644 pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities, in chv_pinctrl_probe()
1645 pctrl->ncommunities * sizeof(*pctrl->communities), in chv_pinctrl_probe()
1647 if (!pctrl->communities) in chv_pinctrl_probe()
1648 return -ENOMEM; in chv_pinctrl_probe()
1650 community = &pctrl->communities[0]; in chv_pinctrl_probe()
1651 community->regs = devm_platform_ioremap_resource(pdev, 0); in chv_pinctrl_probe()
1652 if (IS_ERR(community->regs)) in chv_pinctrl_probe()
1653 return PTR_ERR(community->regs); in chv_pinctrl_probe()
1655 community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF; in chv_pinctrl_probe()
1658 pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins, in chv_pinctrl_probe()
1659 sizeof(*pctrl->context.pads), in chv_pinctrl_probe()
1661 if (!pctrl->context.pads) in chv_pinctrl_probe()
1662 return -ENOMEM; in chv_pinctrl_probe()
1665 pctrl->context.communities = devm_kcalloc(dev, pctrl->soc->ncommunities, in chv_pinctrl_probe()
1666 sizeof(*pctrl->context.communities), in chv_pinctrl_probe()
1668 if (!pctrl->context.communities) in chv_pinctrl_probe()
1669 return -ENOMEM; in chv_pinctrl_probe()
1675 pctrl->pctldesc = chv_pinctrl_desc; in chv_pinctrl_probe()
1676 pctrl->pctldesc.name = dev_name(dev); in chv_pinctrl_probe()
1677 pctrl->pctldesc.pins = pctrl->soc->pins; in chv_pinctrl_probe()
1678 pctrl->pctldesc.npins = pctrl->soc->npins; in chv_pinctrl_probe()
1680 pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); in chv_pinctrl_probe()
1681 if (IS_ERR(pctrl->pctldev)) { in chv_pinctrl_probe()
1683 return PTR_ERR(pctrl->pctldev); in chv_pinctrl_probe()
1691 community->acpi_space_id, in chv_pinctrl_probe()
1705 const struct intel_community *community = &pctrl->communities[0]; in chv_pinctrl_remove()
1707 acpi_remove_address_space_handler(ACPI_HANDLE(&pdev->dev), in chv_pinctrl_remove()
1708 community->acpi_space_id, in chv_pinctrl_remove()
1718 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_pinctrl_suspend_noirq()
1724 cctx->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); in chv_pinctrl_suspend_noirq()
1726 for (i = 0; i < pctrl->soc->npins; i++) { in chv_pinctrl_suspend_noirq()
1728 struct intel_pad_context *ctx = &pctrl->context.pads[i]; in chv_pinctrl_suspend_noirq()
1730 desc = &pctrl->soc->pins[i]; in chv_pinctrl_suspend_noirq()
1731 if (chv_pad_locked(pctrl, desc->number)) in chv_pinctrl_suspend_noirq()
1734 ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); in chv_pinctrl_suspend_noirq()
1735 ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; in chv_pinctrl_suspend_noirq()
1737 ctx->padctrl1 = chv_readl(pctrl, desc->number, CHV_PADCTRL1); in chv_pinctrl_suspend_noirq()
1748 struct intel_community_context *cctx = &pctrl->context.communities[0]; in chv_pinctrl_resume_noirq()
1755 * Mask all interrupts before restoring per-pin configuration in chv_pinctrl_resume_noirq()
1761 for (i = 0; i < pctrl->soc->npins; i++) { in chv_pinctrl_resume_noirq()
1763 struct intel_pad_context *ctx = &pctrl->context.pads[i]; in chv_pinctrl_resume_noirq()
1766 desc = &pctrl->soc->pins[i]; in chv_pinctrl_resume_noirq()
1767 if (chv_pad_locked(pctrl, desc->number)) in chv_pinctrl_resume_noirq()
1771 val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); in chv_pinctrl_resume_noirq()
1773 if (ctx->padctrl0 != val) { in chv_pinctrl_resume_noirq()
1774 chv_writel(pctrl, desc->number, CHV_PADCTRL0, ctx->padctrl0); in chv_pinctrl_resume_noirq()
1775 dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n", in chv_pinctrl_resume_noirq()
1776 desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL0)); in chv_pinctrl_resume_noirq()
1779 val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); in chv_pinctrl_resume_noirq()
1780 if (ctx->padctrl1 != val) { in chv_pinctrl_resume_noirq()
1781 chv_writel(pctrl, desc->number, CHV_PADCTRL1, ctx->padctrl1); in chv_pinctrl_resume_noirq()
1782 dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n", in chv_pinctrl_resume_noirq()
1783 desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL1)); in chv_pinctrl_resume_noirq()
1792 chv_pctrl_writel(pctrl, CHV_INTMASK, cctx->saved_intmask); in chv_pinctrl_resume_noirq()
1815 .name = "cherryview-pinctrl",