diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2019-09-04 10:54:26 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-09-04 10:54:26 +0200 |
commit | bacada1c3fb4f116c8a1ebc864a9bd4ffd14e2d2 (patch) | |
tree | c7b11f7db2d70e8bc28c7a4a2bf7fb5684c7f036 /drivers/pinctrl | |
parent | 501398b75385aae33737ee938b6ed6df36e9c6c6 (diff) | |
parent | 6cb0880f08229360c6c57416de075aa96930be78 (diff) |
Merge tag 'intel-pinctrl-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel
intel-pinctrl for v5.4
A collection of improvements and fixes for Intel pinctrl drivers
including:
- Converting drivers to use new devm_platform_ioremap_resource()
helper function.
- Make Interrupt Status (IS) register configurable.
- Allow locked pins to be requested and used as long as they are not
modified.
- Fix intel_pinctrl_should_save() to translate pin number to GPIO
number where needed. This fixes Asus X571GT touchpad
unresponsiveness issue after suspend/resume cycle.
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 67 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-broxton.c | 4 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cannonlake.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cherryview.c | 8 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-denverton.c | 53 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-geminilake.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-icelake.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 120 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.h | 9 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-lewisburg.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-merrifield.c | 4 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-sunrisepoint.c | 2 |
12 files changed, 156 insertions, 119 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index e5a112a8e067..db6c5ca9e2d6 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -98,13 +98,6 @@ struct byt_gpio_pin_context { u32 val; }; -struct byt_community { - unsigned int pin_base; - size_t npins; - const unsigned int *pad_map; - void __iomem *reg_base; -}; - #define COMMUNITY(p, n, map) \ { \ .pin_base = (p), \ @@ -112,26 +105,14 @@ struct byt_community { .pad_map = (map),\ } -struct byt_pinctrl_soc_data { - const char *uid; - const struct pinctrl_pin_desc *pins; - size_t npins; - const struct intel_pingroup *groups; - size_t ngroups; - const struct intel_function *functions; - size_t nfunctions; - const struct byt_community *communities; - size_t ncommunities; -}; - struct byt_gpio { struct gpio_chip chip; struct platform_device *pdev; struct pinctrl_dev *pctl_dev; struct pinctrl_desc pctl_desc; raw_spinlock_t lock; - const struct byt_pinctrl_soc_data *soc_data; - struct byt_community *communities_copy; + const struct intel_pinctrl_soc_data *soc_data; + struct intel_community *communities_copy; struct byt_gpio_pin_context *saved_context; }; @@ -383,11 +364,11 @@ static const struct intel_function byt_score_functions[] = { FUNCTION("gpio", byt_score_gpio_groups), }; -static const struct byt_community byt_score_communities[] = { +static const struct intel_community byt_score_communities[] = { COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), }; -static const struct byt_pinctrl_soc_data byt_score_soc_data = { +static const struct intel_pinctrl_soc_data byt_score_soc_data = { .uid = BYT_SCORE_ACPI_UID, .pins = byt_score_pins, .npins = ARRAY_SIZE(byt_score_pins), @@ -496,11 +477,11 @@ static const struct intel_function byt_sus_functions[] = { FUNCTION("gpio", byt_sus_gpio_groups), }; -static const struct byt_community byt_sus_communities[] = { +static const struct intel_community byt_sus_communities[] = { COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), }; -static const struct byt_pinctrl_soc_data byt_sus_soc_data = { +static const struct intel_pinctrl_soc_data byt_sus_soc_data = { .uid = BYT_SUS_ACPI_UID, .pins = byt_sus_pins, .npins = ARRAY_SIZE(byt_sus_pins), @@ -549,11 +530,11 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 3, 6, 10, 13, 2, 5, 9, 7, }; -static const struct byt_community byt_ncore_communities[] = { +static const struct intel_community byt_ncore_communities[] = { COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), }; -static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { +static const struct intel_pinctrl_soc_data byt_ncore_soc_data = { .uid = BYT_NCORE_ACPI_UID, .pins = byt_ncore_pins, .npins = ARRAY_SIZE(byt_ncore_pins), @@ -561,17 +542,17 @@ static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { .ncommunities = ARRAY_SIZE(byt_ncore_communities), }; -static const struct byt_pinctrl_soc_data *byt_soc_data[] = { +static const struct intel_pinctrl_soc_data *byt_soc_data[] = { &byt_score_soc_data, &byt_sus_soc_data, &byt_ncore_soc_data, NULL }; -static struct byt_community *byt_get_community(struct byt_gpio *vg, - unsigned int pin) +static struct intel_community *byt_get_community(struct byt_gpio *vg, + unsigned int pin) { - struct byt_community *comm; + struct intel_community *comm; int i; for (i = 0; i < vg->soc_data->ncommunities; i++) { @@ -586,7 +567,7 @@ static struct byt_community *byt_get_community(struct byt_gpio *vg, static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, int reg) { - struct byt_community *comm = byt_get_community(vg, offset); + struct intel_community *comm = byt_get_community(vg, offset); u32 reg_offset; if (!comm) @@ -605,7 +586,7 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, break; } - return comm->reg_base + reg_offset + reg; + return comm->pad_regs + reg_offset + reg; } static int byt_get_groups_count(struct pinctrl_dev *pctldev) @@ -1211,7 +1192,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) u32 conf0, val; for (i = 0; i < vg->soc_data->npins; i++) { - const struct byt_community *comm; + const struct intel_community *comm; const char *pull_str = NULL; const char *pull = NULL; void __iomem *reg; @@ -1566,7 +1547,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) } static int byt_set_soc_data(struct byt_gpio *vg, - const struct byt_pinctrl_soc_data *soc_data) + const struct intel_pinctrl_soc_data *soc_data) { int i; @@ -1579,15 +1560,13 @@ static int byt_set_soc_data(struct byt_gpio *vg, return -ENOMEM; for (i = 0; i < soc_data->ncommunities; i++) { - struct byt_community *comm = vg->communities_copy + i; - struct resource *mem_rc; + struct intel_community *comm = vg->communities_copy + i; *comm = vg->soc_data->communities[i]; - mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0); - comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc); - if (IS_ERR(comm->reg_base)) - return PTR_ERR(comm->reg_base); + comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0); + if (IS_ERR(comm->pad_regs)) + return PTR_ERR(comm->pad_regs); } return 0; @@ -1601,8 +1580,8 @@ static const struct acpi_device_id byt_gpio_acpi_match[] = { static int byt_pinctrl_probe(struct platform_device *pdev) { - const struct byt_pinctrl_soc_data *soc_data = NULL; - const struct byt_pinctrl_soc_data **soc_table; + const struct intel_pinctrl_soc_data *soc_data = NULL; + const struct intel_pinctrl_soc_data **soc_table; struct acpi_device *acpi_dev; struct byt_gpio *vg; int i, ret; @@ -1611,7 +1590,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev) if (!acpi_dev) return -ENODEV; - soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev); + soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev); for (i = 0; soc_table[i]; i++) { if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c index e2d4505d6747..2be7e414f803 100644 --- a/drivers/pinctrl/intel/pinctrl-broxton.c +++ b/drivers/pinctrl/intel/pinctrl-broxton.c @@ -15,8 +15,9 @@ #include "pinctrl-intel.h" #define BXT_PAD_OWN 0x020 -#define BXT_HOSTSW_OWN 0x080 #define BXT_PADCFGLOCK 0x060 +#define BXT_HOSTSW_OWN 0x080 +#define BXT_GPI_IS 0x100 #define BXT_GPI_IE 0x110 #define BXT_COMMUNITY(s, e) \ @@ -24,6 +25,7 @@ .padown_offset = BXT_PAD_OWN, \ .padcfglock_offset = BXT_PADCFGLOCK, \ .hostown_offset = BXT_HOSTSW_OWN, \ + .is_offset = BXT_GPI_IS, \ .ie_offset = BXT_GPI_IE, \ .gpp_size = 32, \ .pin_base = (s), \ diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c index 08024b065033..f51b27bbf9f1 100644 --- a/drivers/pinctrl/intel/pinctrl-cannonlake.c +++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c @@ -19,6 +19,7 @@ #define CNL_PADCFGLOCK 0x080 #define CNL_LP_HOSTSW_OWN 0x0b0 #define CNL_H_HOSTSW_OWN 0x0c0 +#define CNL_GPI_IS 0x100 #define CNL_GPI_IE 0x120 #define CNL_GPP(r, s, e, g) \ @@ -37,6 +38,7 @@ .padown_offset = CNL_PAD_OWN, \ .padcfglock_offset = CNL_PADCFGLOCK, \ .hostown_offset = (o), \ + .is_offset = CNL_GPI_IS, \ .ie_offset = CNL_GPI_IE, \ .pin_base = (s), \ .npins = ((e) - (s) + 1), \ diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 03ec7a5d9d0b..cfb7168fe766 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1667,7 +1667,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev) { struct chv_pinctrl *pctrl; struct acpi_device *adev; - struct resource *res; acpi_status status; int ret, irq, i; @@ -1697,16 +1696,13 @@ static int chv_pinctrl_probe(struct platform_device *pdev) return -ENOMEM; #endif - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pctrl->regs = devm_ioremap_resource(&pdev->dev, res); + pctrl->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pctrl->regs)) return PTR_ERR(pctrl->regs); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get interrupt number\n"); + if (irq < 0) return irq; - } pctrl->pctldesc = chv_pinctrl_desc; pctrl->pctldesc.name = dev_name(&pdev->dev); diff --git a/drivers/pinctrl/intel/pinctrl-denverton.c b/drivers/pinctrl/intel/pinctrl-denverton.c index 3a4932b557b4..f26d030b9b41 100644 --- a/drivers/pinctrl/intel/pinctrl-denverton.c +++ b/drivers/pinctrl/intel/pinctrl-denverton.c @@ -15,8 +15,9 @@ #include "pinctrl-intel.h" #define DNV_PAD_OWN 0x020 -#define DNV_HOSTSW_OWN 0x0C0 #define DNV_PADCFGLOCK 0x090 +#define DNV_HOSTSW_OWN 0x0C0 +#define DNV_GPI_IS 0x100 #define DNV_GPI_IE 0x120 #define DNV_GPP(n, s, e) \ @@ -32,6 +33,7 @@ .padown_offset = DNV_PAD_OWN, \ .padcfglock_offset = DNV_PADCFGLOCK, \ .hostown_offset = DNV_HOSTSW_OWN, \ + .is_offset = DNV_GPI_IS, \ .ie_offset = DNV_GPI_IE, \ .pin_base = (s), \ .npins = ((e) - (s) + 1), \ @@ -39,6 +41,7 @@ .ngpps = ARRAY_SIZE(g), \ } +/* Denverton */ static const struct pinctrl_pin_desc dnv_pins[] = { /* North ALL */ PINCTRL_PIN(0, "GBE0_SDP0"), @@ -59,7 +62,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(15, "NCSI_CLK_IN"), PINCTRL_PIN(16, "NCSI_RXD1"), PINCTRL_PIN(17, "NCSI_CRS_DV"), - PINCTRL_PIN(18, "NCSI_ARB_IN"), + PINCTRL_PIN(18, "IDSLDO_VID_TICKLE"), PINCTRL_PIN(19, "NCSI_TX_EN"), PINCTRL_PIN(20, "NCSI_TXD0"), PINCTRL_PIN(21, "NCSI_TXD1"), @@ -68,14 +71,14 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(24, "GBE0_LED1"), PINCTRL_PIN(25, "GBE1_LED0"), PINCTRL_PIN(26, "GBE1_LED1"), - PINCTRL_PIN(27, "GPIO_0"), + PINCTRL_PIN(27, "SPARE_0"), PINCTRL_PIN(28, "PCIE_CLKREQ0_N"), PINCTRL_PIN(29, "PCIE_CLKREQ1_N"), PINCTRL_PIN(30, "PCIE_CLKREQ2_N"), PINCTRL_PIN(31, "PCIE_CLKREQ3_N"), PINCTRL_PIN(32, "PCIE_CLKREQ4_N"), - PINCTRL_PIN(33, "GPIO_1"), - PINCTRL_PIN(34, "GPIO_2"), + PINCTRL_PIN(33, "GBE_MDC"), + PINCTRL_PIN(34, "GBE_MDIO"), PINCTRL_PIN(35, "SVID_ALERT_N"), PINCTRL_PIN(36, "SVID_DATA"), PINCTRL_PIN(37, "SVID_CLK"), @@ -102,15 +105,15 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(57, "DFX_PORT14"), PINCTRL_PIN(58, "DFX_PORT15"), /* South GPP0 */ - PINCTRL_PIN(59, "GPIO_12"), - PINCTRL_PIN(60, "SMB5_GBE_ALRT_N"), + PINCTRL_PIN(59, "SPI_TPM_CS_N"), + PINCTRL_PIN(60, "UART2_CTS"), PINCTRL_PIN(61, "PCIE_CLKREQ5_N"), PINCTRL_PIN(62, "PCIE_CLKREQ6_N"), PINCTRL_PIN(63, "PCIE_CLKREQ7_N"), PINCTRL_PIN(64, "UART0_RXD"), PINCTRL_PIN(65, "UART0_TXD"), - PINCTRL_PIN(66, "SMB5_GBE_CLK"), - PINCTRL_PIN(67, "SMB5_GBE_DATA"), + PINCTRL_PIN(66, "CPU_RESET_N"), + PINCTRL_PIN(67, "NMI"), PINCTRL_PIN(68, "ERROR2_N"), PINCTRL_PIN(69, "ERROR1_N"), PINCTRL_PIN(70, "ERROR0_N"), @@ -129,20 +132,20 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(83, "USB_OC0_N"), PINCTRL_PIN(84, "FLEX_CLK_SE0"), PINCTRL_PIN(85, "FLEX_CLK_SE1"), - PINCTRL_PIN(86, "GPIO_4"), - PINCTRL_PIN(87, "GPIO_5"), - PINCTRL_PIN(88, "GPIO_6"), - PINCTRL_PIN(89, "GPIO_7"), + PINCTRL_PIN(86, "SPARE_4"), + PINCTRL_PIN(87, "SMB3_IE0_CLK"), + PINCTRL_PIN(88, "SMB3_IE0_DATA"), + PINCTRL_PIN(89, "SMB3_IE0_ALRT_N"), PINCTRL_PIN(90, "SATA0_LED_N"), PINCTRL_PIN(91, "SATA1_LED_N"), PINCTRL_PIN(92, "SATA_PDETECT0"), PINCTRL_PIN(93, "SATA_PDETECT1"), - PINCTRL_PIN(94, "SATA0_SDOUT"), - PINCTRL_PIN(95, "SATA1_SDOUT"), + PINCTRL_PIN(94, "UART1_RTS"), + PINCTRL_PIN(95, "UART1_CTS"), PINCTRL_PIN(96, "UART1_RXD"), PINCTRL_PIN(97, "UART1_TXD"), - PINCTRL_PIN(98, "GPIO_8"), - PINCTRL_PIN(99, "GPIO_9"), + PINCTRL_PIN(98, "SPARE_8"), + PINCTRL_PIN(99, "SPARE_9"), PINCTRL_PIN(100, "TCK"), PINCTRL_PIN(101, "TRST_N"), PINCTRL_PIN(102, "TMS"), @@ -150,11 +153,11 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(104, "TDO"), PINCTRL_PIN(105, "CX_PRDY_N"), PINCTRL_PIN(106, "CX_PREQ_N"), - PINCTRL_PIN(107, "CTBTRIGINOUT"), - PINCTRL_PIN(108, "CTBTRIGOUT"), - PINCTRL_PIN(109, "DFX_SPARE2"), - PINCTRL_PIN(110, "DFX_SPARE3"), - PINCTRL_PIN(111, "DFX_SPARE4"), + PINCTRL_PIN(107, "TAP1_TCK"), + PINCTRL_PIN(108, "TAP1_TRST_N"), + PINCTRL_PIN(109, "TAP1_TMS"), + PINCTRL_PIN(110, "TAP1_TDI"), + PINCTRL_PIN(111, "TAP1_TDO"), /* South GPP1 */ PINCTRL_PIN(112, "SUSPWRDNACK"), PINCTRL_PIN(113, "PMU_SUSCLK"), @@ -183,8 +186,8 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(136, "ESPI_CLK"), PINCTRL_PIN(137, "ESPI_RST_N"), PINCTRL_PIN(138, "ESPI_ALRT0_N"), - PINCTRL_PIN(139, "GPIO_10"), - PINCTRL_PIN(140, "GPIO_11"), + PINCTRL_PIN(139, "ESPI_CS1_N"), + PINCTRL_PIN(140, "ESPI_ALRT1_N"), PINCTRL_PIN(141, "ESPI_CLK_LOOPBK"), PINCTRL_PIN(142, "EMMC_CMD"), PINCTRL_PIN(143, "EMMC_STROBE"), @@ -197,7 +200,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = { PINCTRL_PIN(150, "EMMC_D5"), PINCTRL_PIN(151, "EMMC_D6"), PINCTRL_PIN(152, "EMMC_D7"), - PINCTRL_PIN(153, "GPIO_3"), + PINCTRL_PIN(153, "SPARE_3"), }; static const unsigned int dnv_uart0_pins[] = { 60, 61, 64, 65 }; diff --git a/drivers/pinctrl/intel/pinctrl-geminilake.c b/drivers/pinctrl/intel/pinctrl-geminilake.c index 331b8fd54d88..df02028b40f3 100644 --- a/drivers/pinctrl/intel/pinctrl-geminilake.c +++ b/drivers/pinctrl/intel/pinctrl-geminilake.c @@ -17,6 +17,7 @@ #define GLK_PAD_OWN 0x020 #define GLK_PADCFGLOCK 0x080 #define GLK_HOSTSW_OWN 0x0b0 +#define GLK_GPI_IS 0x100 #define GLK_GPI_IE 0x110 #define GLK_COMMUNITY(s, e) \ @@ -24,6 +25,7 @@ .padown_offset = GLK_PAD_OWN, \ .padcfglock_offset = GLK_PADCFGLOCK, \ .hostown_offset = GLK_HOSTSW_OWN, \ + .is_offset = GLK_GPI_IS, \ .ie_offset = GLK_GPI_IE, \ .gpp_size = 32, \ .pin_base = (s), \ diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c index 5f2f5c61ad41..6489e9bbb61f 100644 --- a/drivers/pinctrl/intel/pinctrl-icelake.c +++ b/drivers/pinctrl/intel/pinctrl-icelake.c @@ -18,6 +18,7 @@ #define ICL_PAD_OWN 0x020 #define ICL_PADCFGLOCK 0x080 #define ICL_HOSTSW_OWN 0x0b0 +#define ICL_GPI_IS 0x100 #define ICL_GPI_IE 0x110 #define ICL_GPP(r, s, e, g) \ @@ -36,6 +37,7 @@ .padown_offset = ICL_PAD_OWN, \ .padcfglock_offset = ICL_PADCFGLOCK, \ .hostown_offset = ICL_HOSTSW_OWN, \ + .is_offset = ICL_GPI_IS, \ .ie_offset = ICL_GPI_IE, \ .pin_base = (s), \ .npins = ((e) - (s) + 1), \ diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index a18d6eefe672..d66fe2b4221b 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -8,12 +8,13 @@ */ #include <linux/acpi.h> -#include <linux/module.h> #include <linux/interrupt.h> #include <linux/gpio/driver.h> #include <linux/log2.h> +#include <linux/module.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/time.h> #include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinmux.h> @@ -29,7 +30,6 @@ #define REVID_MASK GENMASK(31, 16) #define PADBAR 0x00c -#define GPI_IS 0x100 #define PADOWN_BITS 4 #define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS) @@ -71,7 +71,7 @@ #define PADCFG2_DEBOUNCE_SHIFT 1 #define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1) -#define DEBOUNCE_PERIOD 31250 /* ns */ +#define DEBOUNCE_PERIOD_NSEC 31250 struct intel_pad_context { u32 padcfg0; @@ -165,7 +165,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, padno = pin_to_padno(community, pin); nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2; - if (reg == PADCFG2 && !(community->features & PINCTRL_FEATURE_DEBOUNCE)) + if (reg >= nregs * 4) return NULL; return community->pad_regs + reg + padno * nregs * 4; @@ -220,47 +220,71 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin) return !(readl(hostown) & BIT(gpp_offset)); } -static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin) +/** + * enum - Locking variants of the pad configuration + * + * @PAD_UNLOCKED: pad is fully controlled by the configuration registers + * @PAD_LOCKED: pad configuration registers, except TX state, are locked + * @PAD_LOCKED_TX: pad configuration TX state is locked + * @PAD_LOCKED_FULL: pad configuration registers are locked completely + * + * Locking is considered as read-only mode for corresponding registers and + * their respective fields. That said, TX state bit is locked separately from + * the main locking scheme. + */ +enum { + PAD_UNLOCKED = 0, + PAD_LOCKED = 1, + PAD_LOCKED_TX = 2, + PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX, +}; + +static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin) { struct intel_community *community; const struct intel_padgroup *padgrp; unsigned int offset, gpp_offset; u32 value; + int ret = PAD_UNLOCKED; community = intel_get_community(pctrl, pin); if (!community) - return true; + return PAD_LOCKED_FULL; if (!community->padcfglock_offset) - return false; + return PAD_UNLOCKED; padgrp = intel_community_get_padgroup(community, pin); if (!padgrp) - return true; + return PAD_LOCKED_FULL; gpp_offset = padgroup_offset(padgrp, pin); /* * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad, * the pad is considered unlocked. Any other case means that it is - * either fully or partially locked and we don't touch it. + * either fully or partially locked. */ - offset = community->padcfglock_offset + padgrp->reg_num * 8; + offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8; value = readl(community->regs + offset); if (value & BIT(gpp_offset)) - return true; + ret |= PAD_LOCKED; offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8; value = readl(community->regs + offset); if (value & BIT(gpp_offset)) - return true; + ret |= PAD_LOCKED_TX; - return false; + return ret; +} + +static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin) +{ + return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED; } static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin) { - return intel_pad_owned_by_host(pctrl, pin) && - !intel_pad_locked(pctrl, pin); + return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin); } static int intel_get_groups_count(struct pinctrl_dev *pctldev) @@ -294,7 +318,8 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); void __iomem *padcfg; u32 cfg0, cfg1, mode; - bool locked, acpi; + int locked; + bool acpi; if (!intel_pad_owned_by_host(pctrl, pin)) { seq_puts(s, "not available"); @@ -322,11 +347,16 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, if (locked || acpi) { seq_puts(s, " ["); - if (locked) { + if (locked) seq_puts(s, "LOCKED"); - if (acpi) - seq_puts(s, ", "); - } + if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX) + seq_puts(s, " tx"); + else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL) + seq_puts(s, " full"); + + if (locked && acpi) + seq_puts(s, ", "); + if (acpi) seq_puts(s, "ACPI"); seq_puts(s, "]"); @@ -448,11 +478,16 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&pctrl->lock, flags); - if (!intel_pad_usable(pctrl, pin)) { + if (!intel_pad_owned_by_host(pctrl, pin)) { raw_spin_unlock_irqrestore(&pctrl->lock, flags); return -EBUSY; } + if (!intel_pad_is_unlocked(pctrl, pin)) { + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return 0; + } + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); intel_gpio_set_gpio_mode(padcfg0); /* Disable TX buffer and enable RX (this will be input) */ @@ -566,7 +601,7 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, return -EINVAL; v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; - arg = BIT(v) * DEBOUNCE_PERIOD / 1000; + arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; break; } @@ -683,7 +718,7 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, if (debounce) { unsigned long v; - v = order_base_2(debounce * 1000 / DEBOUNCE_PERIOD); + v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); if (v < 3 || v > 15) { ret = -EINVAL; goto exit_unlock; @@ -796,6 +831,29 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, return -EINVAL; } +/** + * intel_pin_to_gpio() - Translate from pin number to GPIO offset + * @pctrl: Pinctrl structure + * @pin: pin number + * + * Translate the pin number of pinctrl to GPIO offset + */ +static int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin) +{ + const struct intel_community *community; + const struct intel_padgroup *padgrp; + + community = intel_get_community(pctrl, pin); + if (!community) + return -EINVAL; + + padgrp = intel_community_get_padgroup(community, pin); + if (!padgrp) + return -EINVAL; + + return pin - padgrp->base + padgrp->gpio_base; +} + static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct intel_pinctrl *pctrl = gpiochip_get_data(chip); @@ -1313,15 +1371,12 @@ static int intel_pinctrl_probe(struct platform_device *pdev, for (i = 0; i < pctrl->ncommunities; i++) { struct intel_community *community = &pctrl->communities[i]; - struct resource *res; void __iomem *regs; u32 padbar; *community = pctrl->soc->communities[i]; - res = platform_get_resource(pdev, IORESOURCE_MEM, - community->barno); - regs = devm_ioremap_resource(&pdev->dev, res); + regs = devm_platform_ioremap_resource(pdev, community->barno); if (IS_ERR(regs)) return PTR_ERR(regs); @@ -1345,19 +1400,14 @@ static int intel_pinctrl_probe(struct platform_device *pdev, community->regs = regs; community->pad_regs = regs + padbar; - if (!community->is_offset) - community->is_offset = GPI_IS; - ret = intel_pinctrl_add_padgroups(pctrl, community); if (ret) return ret; } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get interrupt number\n"); + if (irq < 0) return irq; - } ret = intel_pinctrl_pm_init(pctrl); if (ret) @@ -1421,8 +1471,6 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev) table = (const struct intel_pinctrl_soc_data **)id->driver_data; data = table[pdev->id]; } - if (!data) - return -ENODEV; return intel_pinctrl_probe(pdev, data); } @@ -1443,7 +1491,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int * them alone. */ if (pd->mux_owner || pd->gpio_owner || - gpiochip_line_is_irq(&pctrl->chip, pin)) + gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin))) return true; return false; diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index a8e958f1dcf5..34b38a321760 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -75,9 +75,9 @@ struct intel_padgroup { * @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it * is assumed that the host owns the pin (rather than * ACPI). - * @is_offset: Register offset of GPI_IS from @regs. If %0 then uses the - * default (%0x100). + * @is_offset: Register offset of GPI_IS from @regs. * @ie_offset: Register offset of GPI_IE from @regs. + * @features: Additional features supported by the hardware * @pin_base: Starting pin of pins in this community * @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK, * HOSTSW_OWN, GPI_IS, GPI_IE, etc. Used when @gpps is %NULL. @@ -85,9 +85,9 @@ struct intel_padgroup { * minimum. Use %0 if the number of registers can be * determined by the size of the group. * @npins: Number of pins in this community - * @features: Additional features supported by the hardware * @gpps: Pad groups if the controller has variable size pad groups * @ngpps: Number of pad groups in this community + * @pad_map: Optional non-linear mapping of the pads * @regs: Community specific common registers (reserved for core driver) * @pad_regs: Community specific pad registers (reserved for core driver) * @@ -104,13 +104,14 @@ struct intel_community { unsigned int hostown_offset; unsigned int is_offset; unsigned int ie_offset; + unsigned int features; unsigned int pin_base; unsigned int gpp_size; unsigned int gpp_num_padown_regs; size_t npins; - unsigned int features; const struct intel_padgroup *gpps; size_t ngpps; + const unsigned int *pad_map; /* Reserved for the core driver */ void __iomem *regs; void __iomem *pad_regs; diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c index 03b04c7ae9e8..2e06fb1464ab 100644 --- a/drivers/pinctrl/intel/pinctrl-lewisburg.c +++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c @@ -17,6 +17,7 @@ #define LBG_PAD_OWN 0x020 #define LBG_PADCFGLOCK 0x060 #define LBG_HOSTSW_OWN 0x080 +#define LBG_GPI_IS 0x100 #define LBG_GPI_IE 0x110 #define LBG_COMMUNITY(b, s, e) \ @@ -25,6 +26,7 @@ .padown_offset = LBG_PAD_OWN, \ .padcfglock_offset = LBG_PADCFGLOCK, \ .hostown_offset = LBG_HOSTSW_OWN, \ + .is_offset = LBG_GPI_IS, \ .ie_offset = LBG_GPI_IE, \ .gpp_size = 24, \ .pin_base = (s), \ diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 4b65e1296b8a..04ca8ae95df8 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -885,7 +885,6 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev) { struct mrfld_family *families; struct mrfld_pinctrl *mp; - struct resource *mem; void __iomem *regs; size_t nfamilies; unsigned int i; @@ -897,8 +896,7 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev) mp->dev = &pdev->dev; raw_spin_lock_init(&mp->lock); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(&pdev->dev, mem); + regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c index ccafeea4939c..44d7f50bbc82 100644 --- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -18,6 +18,7 @@ #define SPT_PAD_OWN 0x020 #define SPT_PADCFGLOCK 0x0a0 #define SPT_HOSTSW_OWN 0x0d0 +#define SPT_GPI_IS 0x100 #define SPT_GPI_IE 0x120 #define SPT_COMMUNITY(b, s, e) \ @@ -26,6 +27,7 @@ .padown_offset = SPT_PAD_OWN, \ .padcfglock_offset = SPT_PADCFGLOCK, \ .hostown_offset = SPT_HOSTSW_OWN, \ + .is_offset = SPT_GPI_IS, \ .ie_offset = SPT_GPI_IE, \ .gpp_size = 24, \ .gpp_num_padown_regs = 4, \ |