intel-pinctrl for v5.2-1
Non-critical fixes for Intel Baytrail and Intel Cedarfork. Couple of fixes for all pinctrl-intel based drivers with regard to IRQ handling, i.e. moving PM calls to noirq level to avoid IRQ lose and restore ownership of pins to prevent IRQ masking side effect. The following is an automated git shortlog grouped by driver: baytrail: - Fix potential NULL pointer dereference cedarfork: - Update pin names according to v1.13c intel: - Increase readability of intel_gpio_update_pad_mode() - Retain HOSTSW_OWN for requested gpio pin - move gpio suspend/resume to noirq phase -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqaflIX74DDDzMJJtb7wzTHR8rCgFAlzGyScACgkQb7wzTHR8 rCjR6w/+OHPEzftvLzlgdOQ8sopxLt/LXoDcDcIufT83VTYdz+QVi0rMPj0fBkDA OWCvvdehJS0VkyOJPw91z8GAxvtjOkqqGoQ8n4V+vzLphjkmNu9R6d243mMH7nCl Trda4MLkmdDtTCQ/iF+tZmzuimKHTLpQfy1Bld0mcNcxdfMLqqe+BD7OtAwIfKr6 LooTVtoqTx+GobmdSWBTaa0+D+nYVsbMwBW/cd+8j/f2MnZ3czhApygCwilAZdU5 etUm2SmCJf2spdkcoxDJ10tih8NH8+dJgmIjU2LTn98pqaSllkT9egfv5tpUq+ag /sRnI1yxi9nmijXMbXl03XUynKxDIlNXcm9hza5EZoLDMAOixwiUSX8ypLTZtSqZ mfC37FMCUKomMvcUtKeya0v8uTJRTLEszS4LuL6q+fopm/sV6nicP3/WIfsAbBwf Kzk8QNZL9CaSRyOxXmnrZvG/CkBYIjVZfJloX7Ia5fZYJBmJ/3U9qfvUqDDJQmn7 EHmhROXRckAjtABa48CyV7BnTQeuhZP6cDFRKZ4AiqHHC8mhJVsSfPq7OUYnET8H V0qix20b5315+VY7I1nYFU7BCJ+gLdef0Hg1znTZFf8Z1poG18feesjujZ3/x2dg fDcS+Il3Z8JXaZT1ljgi+cffzAgWUNpkFn15iBqP3uP6MBbshLU= =tsfB -----END PGP SIGNATURE----- Merge tag 'intel-pinctrl-v5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel intel-pinctrl for v5.2-1 Non-critical fixes for Intel Baytrail and Intel Cedarfork. Couple of fixes for all pinctrl-intel based drivers with regard to IRQ handling, i.e. moving PM calls to noirq level to avoid IRQ lose and restore ownership of pins to prevent IRQ masking side effect. The following is an automated git shortlog grouped by driver: baytrail: - Fix potential NULL pointer dereference cedarfork: - Update pin names according to v1.13c intel: - Increase readability of intel_gpio_update_pad_mode() - Retain HOSTSW_OWN for requested gpio pin - move gpio suspend/resume to noirq phase
This commit is contained in:
Коммит
48f6ae0d75
|
@ -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) {
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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>");
|
||||
|
|
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче