Skip to content

Commit

Permalink
Merge tag 'intel-pinctrl-v5.2-1' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/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
  • Loading branch information
Linus Walleij committed May 3, 2019
2 parents 8293b3c + 5f61d95 commit 48f6ae0
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 19 deletions.
2 changes: 2 additions & 0 deletions drivers/pinctrl/intel/pinctrl-baytrail.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
18 changes: 9 additions & 9 deletions drivers/pinctrl/intel/pinctrl-cedarfork.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down Expand Up @@ -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"),
Expand All @@ -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"),
Expand All @@ -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"),
Expand Down
66 changes: 61 additions & 5 deletions drivers/pinctrl/intel/pinctrl-intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct intel_pad_context {

struct intel_community_context {
u32 *intmask;
u32 *hostown;
};

struct intel_pinctrl_context {
Expand Down Expand Up @@ -1284,14 +1285,21 @@ 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);
if (!intmask)
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down Expand Up @@ -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>");
Expand Down
11 changes: 6 additions & 5 deletions drivers/pinctrl/intel/pinctrl-intel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 48f6ae0

Please sign in to comment.