diff options
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cedarfork.c | 18 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 66 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.h | 11 |
4 files changed, 78 insertions, 19 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 241384ead4ed..18d9ad504194 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1710,6 +1710,8 @@ static int byt_gpio_probe(struct byt_gpio *vg) #ifdef CONFIG_PM_SLEEP vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, sizeof(*vg->saved_context), GFP_KERNEL); + if (!vg->saved_context) + return -ENOMEM; #endif ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg); if (ret) { diff --git a/drivers/pinctrl/intel/pinctrl-cedarfork.c b/drivers/pinctrl/intel/pinctrl-cedarfork.c index b7d632f1dbf6..aa6f9040d3d8 100644 --- a/drivers/pinctrl/intel/pinctrl-cedarfork.c +++ b/drivers/pinctrl/intel/pinctrl-cedarfork.c @@ -91,13 +91,13 @@ static const struct pinctrl_pin_desc cdf_pins[] = { PINCTRL_PIN(43, "MEMTRIP_N"), PINCTRL_PIN(44, "UART0_RXD"), PINCTRL_PIN(45, "UART0_TXD"), - PINCTRL_PIN(46, "UART1_RXD"), - PINCTRL_PIN(47, "UART1_TXD"), + PINCTRL_PIN(46, "GBE_UART_RXD"), + PINCTRL_PIN(47, "GBE_UART_TXD"), /* WEST01 */ PINCTRL_PIN(48, "GBE_GPIO13"), PINCTRL_PIN(49, "AUX_PWR"), - PINCTRL_PIN(50, "CPU_GP_2"), - PINCTRL_PIN(51, "CPU_GP_3"), + PINCTRL_PIN(50, "UART0_RTS"), + PINCTRL_PIN(51, "UART0_CTS"), PINCTRL_PIN(52, "FAN_PWM_0"), PINCTRL_PIN(53, "FAN_PWM_1"), PINCTRL_PIN(54, "FAN_PWM_2"), @@ -201,8 +201,8 @@ static const struct pinctrl_pin_desc cdf_pins[] = { /* WESTF */ PINCTRL_PIN(145, "NAC_RMII_CLK"), PINCTRL_PIN(146, "NAC_RGMII_CLK"), - PINCTRL_PIN(147, "NAC_SPARE0"), - PINCTRL_PIN(148, "NAC_SPARE1"), + PINCTRL_PIN(147, "NAC_GBE_SMB_CLK_TX_N2S"), + PINCTRL_PIN(148, "NAC_GBE_SMB_DATA_TX_N2S"), PINCTRL_PIN(149, "NAC_SPARE2"), PINCTRL_PIN(150, "NAC_INIT_SX_WAKE_N"), PINCTRL_PIN(151, "NAC_GBE_GPIO0_S2N"), @@ -219,8 +219,8 @@ static const struct pinctrl_pin_desc cdf_pins[] = { PINCTRL_PIN(162, "NAC_NCSI_TXD1"), PINCTRL_PIN(163, "NAC_NCSI_ARB_OUT"), PINCTRL_PIN(164, "NAC_NCSI_OE_N"), - PINCTRL_PIN(165, "NAC_GBE_SMB_CLK"), - PINCTRL_PIN(166, "NAC_GBE_SMB_DATA"), + PINCTRL_PIN(165, "NAC_GBE_SMB_CLK_RX_S2N"), + PINCTRL_PIN(166, "NAC_GBE_SMB_DATA_RX_S2N"), PINCTRL_PIN(167, "NAC_GBE_SMB_ALRT_N"), /* EAST2 */ PINCTRL_PIN(168, "USB_OC0_N"), @@ -232,7 +232,7 @@ static const struct pinctrl_pin_desc cdf_pins[] = { PINCTRL_PIN(174, "GBE_GPIO5"), PINCTRL_PIN(175, "GBE_GPIO6"), PINCTRL_PIN(176, "GBE_GPIO7"), - PINCTRL_PIN(177, "GBE_GPIO8"), + PINCTRL_PIN(177, "SPI_TPM_CS_N"), PINCTRL_PIN(178, "GBE_GPIO9"), PINCTRL_PIN(179, "GBE_GPIO10"), PINCTRL_PIN(180, "GBE_GPIO11"), diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 3b1818184207..d7acbb79cdf7 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -81,6 +81,7 @@ struct intel_pad_context { struct intel_community_context { u32 *intmask; + u32 *hostown; }; struct intel_pinctrl_context { @@ -1284,7 +1285,7 @@ static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl) for (i = 0; i < pctrl->ncommunities; i++) { struct intel_community *community = &pctrl->communities[i]; - u32 *intmask; + u32 *intmask, *hostown; intmask = devm_kcalloc(pctrl->dev, community->ngpps, sizeof(*intmask), GFP_KERNEL); @@ -1292,6 +1293,13 @@ static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl) return -ENOMEM; communities[i].intmask = intmask; + + hostown = devm_kcalloc(pctrl->dev, community->ngpps, + sizeof(*hostown), GFP_KERNEL); + if (!hostown) + return -ENOMEM; + + communities[i].hostown = hostown; } pctrl->context.pads = pads; @@ -1466,7 +1474,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int return false; } -int intel_pinctrl_suspend(struct device *dev) +int intel_pinctrl_suspend_noirq(struct device *dev) { struct intel_pinctrl *pctrl = dev_get_drvdata(dev); struct intel_community_context *communities; @@ -1501,11 +1509,15 @@ int intel_pinctrl_suspend(struct device *dev) base = community->regs + community->ie_offset; for (gpp = 0; gpp < community->ngpps; gpp++) communities[i].intmask[gpp] = readl(base + gpp * 4); + + base = community->regs + community->hostown_offset; + for (gpp = 0; gpp < community->ngpps; gpp++) + communities[i].hostown[gpp] = readl(base + gpp * 4); } return 0; } -EXPORT_SYMBOL_GPL(intel_pinctrl_suspend); +EXPORT_SYMBOL_GPL(intel_pinctrl_suspend_noirq); static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) { @@ -1527,7 +1539,32 @@ static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) } } -int intel_pinctrl_resume(struct device *dev) +static u32 +intel_gpio_is_requested(struct gpio_chip *chip, int base, unsigned int size) +{ + u32 requested = 0; + unsigned int i; + + for (i = 0; i < size; i++) + if (gpiochip_is_requested(chip, base + i)) + requested |= BIT(i); + + return requested; +} + +static u32 +intel_gpio_update_pad_mode(void __iomem *hostown, u32 mask, u32 value) +{ + u32 curr, updated; + + curr = readl(hostown); + updated = (curr & ~mask) | (value & mask); + writel(updated, hostown); + + return curr; +} + +int intel_pinctrl_resume_noirq(struct device *dev) { struct intel_pinctrl *pctrl = dev_get_drvdata(dev); const struct intel_community_context *communities; @@ -1585,11 +1622,30 @@ int intel_pinctrl_resume(struct device *dev) dev_dbg(dev, "restored mask %d/%u %#08x\n", i, gpp, readl(base + gpp * 4)); } + + base = community->regs + community->hostown_offset; + for (gpp = 0; gpp < community->ngpps; gpp++) { + const struct intel_padgroup *padgrp = &community->gpps[gpp]; + u32 requested = 0, value = 0; + u32 saved = communities[i].hostown[gpp]; + + if (padgrp->gpio_base < 0) + continue; + + requested = intel_gpio_is_requested(&pctrl->chip, + padgrp->gpio_base, padgrp->size); + value = intel_gpio_update_pad_mode(base + gpp * 4, + requested, saved); + if ((value ^ saved) & requested) { + dev_warn(dev, "restore hostown %d/%u %#8x->%#8x\n", + i, gpp, value, saved); + } + } } return 0; } -EXPORT_SYMBOL_GPL(intel_pinctrl_resume); +EXPORT_SYMBOL_GPL(intel_pinctrl_resume_noirq); #endif MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>"); diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index b8a07d37d18f..a8e958f1dcf5 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -177,13 +177,14 @@ int intel_pinctrl_probe_by_hid(struct platform_device *pdev); int intel_pinctrl_probe_by_uid(struct platform_device *pdev); #ifdef CONFIG_PM_SLEEP -int intel_pinctrl_suspend(struct device *dev); -int intel_pinctrl_resume(struct device *dev); +int intel_pinctrl_suspend_noirq(struct device *dev); +int intel_pinctrl_resume_noirq(struct device *dev); #endif -#define INTEL_PINCTRL_PM_OPS(_name) \ -const struct dev_pm_ops _name = { \ - SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend, intel_pinctrl_resume) \ +#define INTEL_PINCTRL_PM_OPS(_name) \ +const struct dev_pm_ops _name = { \ + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend_noirq, \ + intel_pinctrl_resume_noirq) \ } #endif /* PINCTRL_INTEL_H */ |