^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Intel pinctrl/GPIO core driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Mika Westerberg <mika.westerberg@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "pinctrl-intel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* Offset from regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define REVID 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define REVID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define REVID_MASK GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PADBAR 0x00c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PADOWN_BITS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PADOWN_MASK(p) (GENMASK(3, 0) << PADOWN_SHIFT(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PADOWN_GPP(p) ((p) / 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Offset from pad_regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PADCFG0 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PADCFG0_RXEVCFG_SHIFT 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PADCFG0_RXEVCFG_MASK GENMASK(26, 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PADCFG0_RXEVCFG_LEVEL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PADCFG0_RXEVCFG_EDGE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PADCFG0_RXEVCFG_DISABLED 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PADCFG0_RXEVCFG_EDGE_BOTH 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PADCFG0_PREGFRXSEL BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PADCFG0_RXINV BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PADCFG0_GPIROUTIOXAPIC BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PADCFG0_GPIROUTSCI BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PADCFG0_GPIROUTSMI BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PADCFG0_GPIROUTNMI BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PADCFG0_PMODE_SHIFT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PADCFG0_PMODE_MASK GENMASK(13, 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PADCFG0_PMODE_GPIO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PADCFG0_GPIORXDIS BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PADCFG0_GPIOTXDIS BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PADCFG0_GPIORXSTATE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PADCFG0_GPIOTXSTATE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PADCFG1 0x004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PADCFG1_TERM_UP BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PADCFG1_TERM_SHIFT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PADCFG1_TERM_MASK GENMASK(12, 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PADCFG1_TERM_20K BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PADCFG1_TERM_5K BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define PADCFG1_TERM_1K BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PADCFG1_TERM_833 (BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PADCFG2 0x008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PADCFG2_DEBEN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PADCFG2_DEBOUNCE_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define DEBOUNCE_PERIOD_NSEC 31250
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct intel_pad_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u32 padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u32 padcfg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u32 padcfg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct intel_community_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u32 *intmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 *hostown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define pin_to_padno(c, p) ((p) - (c)->pin_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define padgroup_offset(g, p) ((p) - (g)->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (pin >= community->pin_base &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pin < community->pin_base + community->npins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dev_warn(pctrl->dev, "failed to find community for pin %u\n", pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const struct intel_padgroup *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) intel_community_get_padgroup(const struct intel_community *community,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) for (i = 0; i < community->ngpps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct intel_padgroup *padgrp = &community->gpps[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (pin >= padgrp->base && pin < padgrp->base + padgrp->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int pin, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int padno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) size_t nregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) padno = pin_to_padno(community, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (reg >= nregs * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return community->pad_regs + reg + padno * nregs * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) const struct intel_padgroup *padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int gpp, offset, gpp_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) void __iomem *padown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (!community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (!community->padown_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) padgrp = intel_community_get_padgroup(community, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!padgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) gpp_offset = padgroup_offset(padgrp, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) gpp = PADOWN_GPP(gpp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) offset = community->padown_offset + padgrp->padown_num * 4 + gpp * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) padown = community->regs + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return !(readl(padown) & PADOWN_MASK(gpp_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) const struct intel_padgroup *padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unsigned int offset, gpp_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void __iomem *hostown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!community->hostown_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) padgrp = intel_community_get_padgroup(community, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!padgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) gpp_offset = padgroup_offset(padgrp, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) offset = community->hostown_offset + padgrp->reg_num * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) hostown = community->regs + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return !(readl(hostown) & BIT(gpp_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * enum - Locking variants of the pad configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @PAD_UNLOCKED: pad is fully controlled by the configuration registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @PAD_LOCKED: pad configuration registers, except TX state, are locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @PAD_LOCKED_TX: pad configuration TX state is locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @PAD_LOCKED_FULL: pad configuration registers are locked completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Locking is considered as read-only mode for corresponding registers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * their respective fields. That said, TX state bit is locked separately from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * the main locking scheme.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) PAD_UNLOCKED = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) PAD_LOCKED = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) PAD_LOCKED_TX = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) const struct intel_padgroup *padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned int offset, gpp_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int ret = PAD_UNLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return PAD_LOCKED_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!community->padcfglock_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return PAD_UNLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) padgrp = intel_community_get_padgroup(community, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!padgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return PAD_LOCKED_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) gpp_offset = padgroup_offset(padgrp, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * the pad is considered unlocked. Any other case means that it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * either fully or partially locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) value = readl(community->regs + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (value & BIT(gpp_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret |= PAD_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) value = readl(community->regs + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (value & BIT(gpp_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret |= PAD_LOCKED_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int intel_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return pctrl->soc->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static const char *intel_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned int group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return pctrl->soc->groups[group].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) const unsigned int **pins, unsigned int *npins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *pins = pctrl->soc->groups[group].pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *npins = pctrl->soc->groups[group].npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) void __iomem *padcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u32 cfg0, cfg1, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) bool acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!intel_pad_owned_by_host(pctrl, pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) seq_puts(s, "not available");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) cfg0 = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (mode == PADCFG0_PMODE_GPIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) seq_puts(s, "GPIO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) seq_printf(s, "mode %d ", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Dump the additional PADCFG registers if available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) padcfg = intel_get_padcfg(pctrl, pin, PADCFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (padcfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) seq_printf(s, " 0x%08x", readl(padcfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) locked = intel_pad_locked(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) acpi = intel_pad_acpi_mode(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (locked || acpi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) seq_puts(s, " [");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) seq_puts(s, "LOCKED");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) seq_puts(s, " tx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) seq_puts(s, " full");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (locked && acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) seq_puts(s, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) seq_puts(s, "ACPI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) seq_puts(s, "]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static const struct pinctrl_ops intel_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .get_groups_count = intel_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .get_group_name = intel_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .get_group_pins = intel_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .pin_dbg_show = intel_pin_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int intel_get_functions_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return pctrl->soc->nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static const char *intel_get_function_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned int function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return pctrl->soc->functions[function].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static int intel_get_function_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned int function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) unsigned int * const ngroups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *groups = pctrl->soc->functions[function].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) *ngroups = pctrl->soc->functions[function].ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned int function, unsigned int group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) const struct intel_pingroup *grp = &pctrl->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * All pins in the groups needs to be accessible and writable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * before we can enable the mux for this group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) for (i = 0; i < grp->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (!intel_pad_usable(pctrl, grp->pins[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* Now enable the mux setting for each pin in the group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) for (i = 0; i < grp->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) void __iomem *padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) padcfg0 = intel_get_padcfg(pctrl, grp->pins[i], PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) value = readl(padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) value &= ~PADCFG0_PMODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (grp->modes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) value |= grp->modes[i] << PADCFG0_PMODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) value |= grp->mode << PADCFG0_PMODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) writel(value, padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) value = readl(padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) value &= ~PADCFG0_GPIORXDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) value |= PADCFG0_GPIOTXDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) value &= ~PADCFG0_GPIOTXDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) value |= PADCFG0_GPIORXDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) writel(value, padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) value = readl(padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* Put the pad into GPIO mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) value &= ~PADCFG0_PMODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) value |= PADCFG0_PMODE_GPIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Disable TX buffer and enable RX (this will be input) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) value &= ~PADCFG0_GPIORXDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) value |= PADCFG0_GPIOTXDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* Disable SCI/SMI/NMI generation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) writel(value, padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) void __iomem *padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!intel_pad_owned_by_host(pctrl, pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (!intel_pad_is_unlocked(pctrl, pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * If pin is already configured in GPIO mode, we assume that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * firmware provides correct settings. In such case we avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * potential glitches on the pin. Otherwise, for the pin in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * alternative mode, consumer has to supply respective flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) intel_gpio_set_gpio_mode(padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned int pin, bool input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) void __iomem *padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) __intel_gpio_set_direction(padcfg0, input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static const struct pinmux_ops intel_pinmux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .get_functions_count = intel_get_functions_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .get_function_name = intel_get_function_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .get_function_groups = intel_get_function_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .set_mux = intel_pinmux_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .gpio_request_enable = intel_gpio_request_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .gpio_set_direction = intel_gpio_set_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) enum pin_config_param param, u32 *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) void __iomem *padcfg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) u32 value, term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) value = readl(padcfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!term || !(value & PADCFG1_TERM_UP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) switch (term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case PADCFG1_TERM_833:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) *arg = 833;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) case PADCFG1_TERM_1K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *arg = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) case PADCFG1_TERM_5K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) *arg = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) case PADCFG1_TERM_20K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *arg = 20000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!term || value & PADCFG1_TERM_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) switch (term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case PADCFG1_TERM_833:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!(community->features & PINCTRL_FEATURE_1K_PD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) *arg = 833;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) case PADCFG1_TERM_1K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!(community->features & PINCTRL_FEATURE_1K_PD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) *arg = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case PADCFG1_TERM_5K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *arg = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case PADCFG1_TERM_20K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *arg = 20000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) enum pin_config_param param, u32 *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) void __iomem *padcfg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) unsigned long v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u32 value2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!padcfg2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) value2 = readl(padcfg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (!(value2 & PADCFG2_DEBEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) v = (value2 & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) enum pin_config_param param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u32 arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (!intel_pad_owned_by_host(pctrl, pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ret = intel_config_get_pull(pctrl, pin, param, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case PIN_CONFIG_INPUT_DEBOUNCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = intel_config_get_debounce(pctrl, pin, param, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) unsigned long config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) unsigned int param = pinconf_to_config_param(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) unsigned int arg = pinconf_to_config_argument(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) void __iomem *padcfg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) value = readl(padcfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) value &= ~(PADCFG1_TERM_MASK | PADCFG1_TERM_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) value &= ~PADCFG1_TERM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) value |= PADCFG1_TERM_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* Set default strength value in case none is given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (arg == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) arg = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) switch (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case 20000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case 5000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case 1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case 833:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) value |= PADCFG1_TERM_833 << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* Set default strength value in case none is given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (arg == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) arg = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) switch (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case 20000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case 5000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case 1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (!(community->features & PINCTRL_FEATURE_1K_PD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case 833:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!(community->features & PINCTRL_FEATURE_1K_PD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) value |= PADCFG1_TERM_833 << PADCFG1_TERM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) writel(value, padcfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) unsigned int pin, unsigned int debounce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) void __iomem *padcfg0, *padcfg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) u32 value0, value2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!padcfg2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) value0 = readl(padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) value2 = readl(padcfg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* Disable glitch filter and debouncer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) value0 &= ~PADCFG0_PREGFRXSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) value2 &= ~(PADCFG2_DEBEN | PADCFG2_DEBOUNCE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (debounce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) unsigned long v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (v < 3 || v > 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* Enable glitch filter and debouncer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) value0 |= PADCFG0_PREGFRXSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) value2 |= v << PADCFG2_DEBOUNCE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) value2 |= PADCFG2_DEBEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) writel(value0, padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) writel(value2, padcfg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) unsigned long *configs, unsigned int nconfigs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (!intel_pad_usable(pctrl, pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) for (i = 0; i < nconfigs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) switch (pinconf_to_config_param(configs[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ret = intel_config_set_pull(pctrl, pin, configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) case PIN_CONFIG_INPUT_DEBOUNCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ret = intel_config_set_debounce(pctrl, pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) pinconf_to_config_argument(configs[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static const struct pinconf_ops intel_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .pin_config_get = intel_config_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .pin_config_set = intel_config_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static const struct pinctrl_desc intel_pinctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .pctlops = &intel_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .pmxops = &intel_pinmux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .confops = &intel_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * intel_gpio_to_pin() - Translate from GPIO offset to pin number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * @pctrl: Pinctrl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * @offset: GPIO offset from gpiolib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * @community: Community is filled here if not %NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * @padgrp: Pad group is filled here if not %NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * When coming through gpiolib irqchip, the GPIO offset is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * automatically translated to pinctrl pin number. This function can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * used to find out the corresponding pinctrl pin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) const struct intel_community **community,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) const struct intel_padgroup **padgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) const struct intel_community *comm = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) for (j = 0; j < comm->ngpps; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) const struct intel_padgroup *pgrp = &comm->gpps[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (pgrp->gpio_base == INTEL_GPIO_BASE_NOMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (offset >= pgrp->gpio_base &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) offset < pgrp->gpio_base + pgrp->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) pin = pgrp->base + offset - pgrp->gpio_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) *community = comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (padgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) *padgrp = pgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * intel_pin_to_gpio() - Translate from pin number to GPIO offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * @pctrl: Pinctrl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * @pin: pin number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * Translate the pin number of pinctrl to GPIO offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static __maybe_unused int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) const struct intel_padgroup *padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) community = intel_get_community(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) padgrp = intel_community_get_padgroup(community, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (!padgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return pin - padgrp->base + padgrp->gpio_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) u32 padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (pin < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) reg = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) padcfg0 = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (!(padcfg0 & PADCFG0_GPIOTXDIS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return !!(padcfg0 & PADCFG0_GPIOTXSTATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return !!(padcfg0 & PADCFG0_GPIORXSTATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) u32 padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (pin < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) reg = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) padcfg0 = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) padcfg0 |= PADCFG0_GPIOTXSTATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) padcfg0 &= ~PADCFG0_GPIOTXSTATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) writel(padcfg0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) u32 padcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (pin < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) reg = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) padcfg0 = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (padcfg0 & PADCFG0_PMODE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (padcfg0 & PADCFG0_GPIOTXDIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return pinctrl_gpio_direction_input(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) intel_gpio_set(chip, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return pinctrl_gpio_direction_output(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static const struct gpio_chip intel_gpio_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) .request = gpiochip_generic_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .free = gpiochip_generic_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .get_direction = intel_gpio_get_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .direction_input = intel_gpio_direction_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .direction_output = intel_gpio_direction_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .get = intel_gpio_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .set = intel_gpio_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .set_config = gpiochip_generic_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static void intel_gpio_irq_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) const struct intel_padgroup *padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (pin >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) unsigned int gpp, gpp_offset, is_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) gpp = padgrp->reg_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) gpp_offset = padgroup_offset(padgrp, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) is_offset = community->is_offset + gpp * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) raw_spin_lock(&pctrl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) writel(BIT(gpp_offset), community->regs + is_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) raw_spin_unlock(&pctrl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) const struct intel_padgroup *padgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (pin >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) unsigned int gpp, gpp_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) void __iomem *reg, *is;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) gpp = padgrp->reg_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) gpp_offset = padgroup_offset(padgrp, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) reg = community->regs + community->ie_offset + gpp * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) is = community->regs + community->is_offset + gpp * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Clear interrupt status first to avoid unexpected interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) writel(BIT(gpp_offset), is);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) value = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) value &= ~BIT(gpp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) value |= BIT(gpp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) writel(value, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static void intel_gpio_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) intel_gpio_irq_mask_unmask(d, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static void intel_gpio_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) intel_gpio_irq_mask_unmask(d, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) reg = intel_get_padcfg(pctrl, pin, PADCFG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * If the pin is in ACPI mode it is still usable as a GPIO but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * cannot be used as IRQ because GPI_IS status bit will not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * updated by the host controller hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (intel_pad_acpi_mode(pctrl, pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_warn(pctrl->dev, "pin %u cannot be used as IRQ\n", pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) intel_gpio_set_gpio_mode(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) value = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) value |= PADCFG0_RXEVCFG_EDGE_BOTH << PADCFG0_RXEVCFG_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) } else if (type & IRQ_TYPE_EDGE_FALLING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) value |= PADCFG0_RXINV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) } else if (type & IRQ_TYPE_EDGE_RISING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) } else if (type & IRQ_TYPE_LEVEL_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (type & IRQ_TYPE_LEVEL_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) value |= PADCFG0_RXINV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) value |= PADCFG0_RXEVCFG_DISABLED << PADCFG0_RXEVCFG_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) writel(value, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (type & IRQ_TYPE_EDGE_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) irq_set_handler_locked(d, handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) else if (type & IRQ_TYPE_LEVEL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) irq_set_handler_locked(d, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) enable_irq_wake(pctrl->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) disable_irq_wake(pctrl->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) const struct intel_community *community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct gpio_chip *gc = &pctrl->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) unsigned int gpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) for (gpp = 0; gpp < community->ngpps; gpp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) const struct intel_padgroup *padgrp = &community->gpps[gpp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) unsigned long pending, enabled, gpp_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) raw_spin_lock_irqsave(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) pending = readl(community->regs + community->is_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) padgrp->reg_num * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) enabled = readl(community->regs + community->ie_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) padgrp->reg_num * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) raw_spin_unlock_irqrestore(&pctrl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) /* Only interrupts that are enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) pending &= enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) for_each_set_bit(gpp_offset, &pending, padgrp->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) irq = irq_find_mapping(gc->irq.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) padgrp->gpio_base + gpp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ret += pending ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static irqreturn_t intel_gpio_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct intel_pinctrl *pctrl = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /* Need to check all communities for pending interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ret += intel_gpio_community_irq_handler(pctrl, community);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return IRQ_RETVAL(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) unsigned int gpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) base = community->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) for (gpp = 0; gpp < community->ngpps; gpp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* Mask and clear all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) writel(0, base + community->ie_offset + gpp * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) writel(0xffff, base + community->is_offset + gpp * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int intel_gpio_irq_init_hw(struct gpio_chip *gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * Make sure the interrupt lines are in a proper state before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * further configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) intel_gpio_irq_init(pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) const struct intel_community *community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) int ret = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) for (i = 0; i < community->ngpps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) const struct intel_padgroup *gpp = &community->gpps[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) gpp->gpio_base, gpp->base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) gpp->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static int intel_gpio_add_pin_ranges(struct gpio_chip *gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct intel_community *community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) ret = intel_gpio_add_community_ranges(pctrl, community);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) dev_err(pctrl->dev, "failed to add GPIO pin range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) const struct intel_community *community;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) unsigned int ngpio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) for (j = 0; j < community->ngpps; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) const struct intel_padgroup *gpp = &community->gpps[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (gpp->gpio_base + gpp->size > ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ngpio = gpp->gpio_base + gpp->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return ngpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct gpio_irq_chip *girq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) pctrl->chip = intel_gpio_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /* Setup GPIO chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) pctrl->chip.ngpio = intel_gpio_ngpio(pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) pctrl->chip.label = dev_name(pctrl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) pctrl->chip.parent = pctrl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) pctrl->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) pctrl->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /* Setup IRQ chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) pctrl->irqchip.name = dev_name(pctrl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) pctrl->irqchip.irq_ack = intel_gpio_irq_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) pctrl->irqchip.irq_mask = intel_gpio_irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) pctrl->irqchip.irq_unmask = intel_gpio_irq_unmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) pctrl->irqchip.irq_set_type = intel_gpio_irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) * On some platforms several GPIO controllers share the same interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) IRQF_SHARED | IRQF_NO_THREAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) dev_name(pctrl->dev), pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) dev_err(pctrl->dev, "failed to request interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) girq = &pctrl->chip.irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) girq->chip = &pctrl->irqchip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) /* This will let us handle the IRQ in the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) girq->parent_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) girq->num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) girq->default_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) girq->handler = handle_bad_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) girq->init_hw = intel_gpio_irq_init_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) dev_err(pctrl->dev, "failed to register gpiochip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct intel_community *community)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct intel_padgroup *gpps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) unsigned int npins = community->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) unsigned int padown_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) size_t ngpps, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (community->gpps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ngpps = community->ngpps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ngpps = DIV_ROUND_UP(community->npins, community->gpp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (!gpps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) for (i = 0; i < ngpps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (community->gpps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) gpps[i] = community->gpps[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) unsigned int gpp_size = community->gpp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) gpps[i].reg_num = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) gpps[i].base = community->pin_base + i * gpp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) gpps[i].size = min(gpp_size, npins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) npins -= gpps[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (gpps[i].size > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /* Special treatment for GPIO base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) switch (gpps[i].gpio_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) case INTEL_GPIO_BASE_MATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) gpps[i].gpio_base = gpps[i].base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) case INTEL_GPIO_BASE_ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) gpps[i].gpio_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case INTEL_GPIO_BASE_NOMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) gpps[i].padown_num = padown_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * In older hardware the number of padown registers per
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * group is fixed regardless of the group size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (community->gpp_num_padown_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) padown_num += community->gpp_num_padown_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) community->ngpps = ngpps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) community->gpps = gpps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) const struct intel_pinctrl_soc_data *soc = pctrl->soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct intel_community_context *communities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct intel_pad_context *pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) pads = devm_kcalloc(pctrl->dev, soc->npins, sizeof(*pads), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (!pads)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) communities = devm_kcalloc(pctrl->dev, pctrl->ncommunities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) sizeof(*communities), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (!communities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct intel_community *community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) u32 *intmask, *hostown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) intmask = devm_kcalloc(pctrl->dev, community->ngpps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) sizeof(*intmask), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (!intmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) communities[i].intmask = intmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) hostown = devm_kcalloc(pctrl->dev, community->ngpps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) sizeof(*hostown), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (!hostown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) communities[i].hostown = hostown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) pctrl->context.pads = pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) pctrl->context.communities = communities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) static int intel_pinctrl_probe(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) const struct intel_pinctrl_soc_data *soc_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct intel_pinctrl *pctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) int i, ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (!pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) pctrl->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) pctrl->soc = soc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) raw_spin_lock_init(&pctrl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * Make a copy of the communities which we can use to hold pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * to the registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) pctrl->ncommunities = pctrl->soc->ncommunities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) pctrl->communities = devm_kcalloc(&pdev->dev, pctrl->ncommunities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) sizeof(*pctrl->communities), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (!pctrl->communities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct intel_community *community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) u32 padbar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) *community = pctrl->soc->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) regs = devm_platform_ioremap_resource(pdev, community->barno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) * Determine community features based on the revision if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * not specified already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (!community->features) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) u32 rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (rev >= 0x94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) community->features |= PINCTRL_FEATURE_DEBOUNCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) community->features |= PINCTRL_FEATURE_1K_PD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) /* Read offset of the pad configuration registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) padbar = readl(regs + PADBAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) community->regs = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) community->pad_regs = regs + padbar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) ret = intel_pinctrl_add_padgroups(pctrl, community);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) ret = intel_pinctrl_pm_init(pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) pctrl->pctldesc = intel_pinctrl_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) pctrl->pctldesc.name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) pctrl->pctldesc.pins = pctrl->soc->pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) pctrl->pctldesc.npins = pctrl->soc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (IS_ERR(pctrl->pctldev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) dev_err(&pdev->dev, "failed to register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return PTR_ERR(pctrl->pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) ret = intel_gpio_probe(pctrl, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) platform_set_drvdata(pdev, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) int intel_pinctrl_probe_by_hid(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) const struct intel_pinctrl_soc_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) data = device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return intel_pinctrl_probe(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) int intel_pinctrl_probe_by_uid(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) const struct intel_pinctrl_soc_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) data = intel_pinctrl_get_soc_data(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) return intel_pinctrl_probe(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) const struct intel_pinctrl_soc_data *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) const struct intel_pinctrl_soc_data **table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) struct acpi_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) adev = ACPI_COMPANION(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (adev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) const void *match = device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) table = (const struct intel_pinctrl_soc_data **)match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) for (i = 0; table[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (!strcmp(adev->pnp.unique_id, table[i]->uid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) data = table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) const struct platform_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) id = platform_get_device_id(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) table = (const struct intel_pinctrl_soc_data **)id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) data = table[pdev->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return data ?: ERR_PTR(-ENODATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (!pd || !intel_pad_usable(pctrl, pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) * Only restore the pin if it is actually in use by the kernel (or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) * by userspace). It is possible that some pins are used by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) * BIOS during resume and those are not always locked down so leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) * them alone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (pd->mux_owner || pd->gpio_owner ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) int intel_pinctrl_suspend_noirq(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) struct intel_pinctrl *pctrl = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) struct intel_community_context *communities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) struct intel_pad_context *pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) pads = pctrl->context.pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) for (i = 0; i < pctrl->soc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) void __iomem *padcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (!intel_pinctrl_should_save(pctrl, desc->number))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) pads[i].padcfg0 = val & ~PADCFG0_GPIORXSTATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) pads[i].padcfg1 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (padcfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) pads[i].padcfg2 = readl(padcfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) communities = pctrl->context.communities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) struct intel_community *community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) unsigned int gpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) base = community->regs + community->ie_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) for (gpp = 0; gpp < community->ngpps; gpp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) communities[i].intmask[gpp] = readl(base + gpp * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) base = community->regs + community->hostown_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) for (gpp = 0; gpp < community->ngpps; gpp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) communities[i].hostown[gpp] = readl(base + gpp * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) EXPORT_SYMBOL_GPL(intel_pinctrl_suspend_noirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) u32 curr, updated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) curr = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) updated = (curr & ~mask) | (value & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (curr == updated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) writel(updated, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) void __iomem *base, unsigned int gpp, u32 saved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) const struct intel_community *community = &pctrl->communities[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) const struct intel_padgroup *padgrp = &community->gpps[gpp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) struct device *dev = pctrl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) const char *dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) u32 requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) for_each_requested_gpio_in_range(&pctrl->chip, i, padgrp->gpio_base, padgrp->size, dummy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) requested |= BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (!intel_gpio_update_reg(base + gpp * 4, requested, saved))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) dev_dbg(dev, "restored hostown %u/%u %#08x\n", c, gpp, readl(base + gpp * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) static void intel_restore_intmask(struct intel_pinctrl *pctrl, unsigned int c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) void __iomem *base, unsigned int gpp, u32 saved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct device *dev = pctrl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (!intel_gpio_update_reg(base + gpp * 4, ~0U, saved))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) dev_dbg(dev, "restored mask %u/%u %#08x\n", c, gpp, readl(base + gpp * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) static void intel_restore_padcfg(struct intel_pinctrl *pctrl, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) unsigned int reg, u32 saved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) u32 mask = (reg == PADCFG0) ? PADCFG0_GPIORXSTATE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) unsigned int n = reg / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) struct device *dev = pctrl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) void __iomem *padcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) padcfg = intel_get_padcfg(pctrl, pin, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (!padcfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (!intel_gpio_update_reg(padcfg, ~mask, saved))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) dev_dbg(dev, "restored pin %u padcfg%u %#08x\n", pin, n, readl(padcfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) int intel_pinctrl_resume_noirq(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) struct intel_pinctrl *pctrl = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) const struct intel_community_context *communities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) const struct intel_pad_context *pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) /* Mask all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) intel_gpio_irq_init(pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) pads = pctrl->context.pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) for (i = 0; i < pctrl->soc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (!intel_pinctrl_should_save(pctrl, desc->number))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) intel_restore_padcfg(pctrl, desc->number, PADCFG0, pads[i].padcfg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) intel_restore_padcfg(pctrl, desc->number, PADCFG1, pads[i].padcfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) intel_restore_padcfg(pctrl, desc->number, PADCFG2, pads[i].padcfg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) communities = pctrl->context.communities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) for (i = 0; i < pctrl->ncommunities; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) struct intel_community *community = &pctrl->communities[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) unsigned int gpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) base = community->regs + community->ie_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) for (gpp = 0; gpp < community->ngpps; gpp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) intel_restore_intmask(pctrl, i, base, gpp, communities[i].intmask[gpp]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) base = community->regs + community->hostown_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) for (gpp = 0; gpp < community->ngpps; gpp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) intel_restore_hostown(pctrl, i, base, gpp, communities[i].hostown[gpp]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) EXPORT_SYMBOL_GPL(intel_pinctrl_resume_noirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) MODULE_DESCRIPTION("Intel pinctrl/GPIO core driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) MODULE_LICENSE("GPL v2");