summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/intel/pinctrl-intel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/intel/pinctrl-intel.c')
-rw-r--r--drivers/pinctrl/intel/pinctrl-intel.c378
1 files changed, 216 insertions, 162 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index a18d6eefe672..74fdfd2b9ff5 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/interrupt.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)
@@ -52,6 +52,7 @@
#define PADCFG0_GPIROUTNMI BIT(17)
#define PADCFG0_PMODE_SHIFT 10
#define PADCFG0_PMODE_MASK GENMASK(13, 10)
+#define PADCFG0_PMODE_GPIO 0
#define PADCFG0_GPIORXDIS BIT(9)
#define PADCFG0_GPIOTXDIS BIT(8)
#define PADCFG0_GPIORXSTATE BIT(1)
@@ -71,7 +72,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;
@@ -84,37 +85,6 @@ struct intel_community_context {
u32 *hostown;
};
-struct intel_pinctrl_context {
- struct intel_pad_context *pads;
- struct intel_community_context *communities;
-};
-
-/**
- * struct intel_pinctrl - Intel pinctrl private structure
- * @dev: Pointer to the device structure
- * @lock: Lock to serialize register access
- * @pctldesc: Pin controller description
- * @pctldev: Pointer to the pin controller device
- * @chip: GPIO chip in this pin controller
- * @soc: SoC/PCH specific pin configuration data
- * @communities: All communities in this pin controller
- * @ncommunities: Number of communities in this pin controller
- * @context: Configuration saved over system sleep
- * @irq: pinctrl/GPIO chip irq number
- */
-struct intel_pinctrl {
- struct device *dev;
- raw_spinlock_t lock;
- struct pinctrl_desc pctldesc;
- struct pinctrl_dev *pctldev;
- struct gpio_chip chip;
- const struct intel_pinctrl_soc_data *soc;
- struct intel_community *communities;
- size_t ncommunities;
- struct intel_pinctrl_context context;
- int irq;
-};
-
#define pin_to_padno(c, p) ((p) - (c)->pin_base)
#define padgroup_offset(g, p) ((p) - (g)->base)
@@ -165,7 +135,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 +190,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 +288,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");
@@ -305,7 +300,7 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1));
mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
- if (!mode)
+ if (mode == PADCFG0_PMODE_GPIO)
seq_puts(s, "GPIO ");
else
seq_printf(s, "mode %d ", mode);
@@ -322,11 +317,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, "]");
@@ -426,6 +426,11 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
writel(value, padcfg0);
}
+static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
+{
+ return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
+}
+
static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
{
u32 value;
@@ -448,13 +453,31 @@ 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);
+
+ /*
+ * If pin is already configured in GPIO mode, we assume that
+ * firmware provides correct settings. In such case we avoid
+ * potential glitches on the pin. Otherwise, for the pin in
+ * alternative mode, consumer has to supply respective flags.
+ */
+ if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) {
+ raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ return 0;
+ }
+
intel_gpio_set_gpio_mode(padcfg0);
+
/* Disable TX buffer and enable RX (this will be input) */
__intel_gpio_set_direction(padcfg0, true);
@@ -566,7 +589,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 +706,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 +819,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 __maybe_unused 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);
@@ -865,7 +911,10 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
if (padcfg0 & PADCFG0_PMODE_MASK)
return -EINVAL;
- return !!(padcfg0 & PADCFG0_GPIOTXDIS);
+ if (padcfg0 & PADCFG0_GPIOTXDIS)
+ return GPIO_LINE_DIRECTION_IN;
+
+ return GPIO_LINE_DIRECTION_OUT;
}
static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
@@ -1052,7 +1101,7 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
pending &= enabled;
for_each_set_bit(gpp_offset, &pending, padgrp->size) {
- unsigned irq;
+ unsigned int irq;
irq = irq_find_mapping(gc->irq.domain,
padgrp->gpio_base + gpp_offset);
@@ -1081,18 +1130,8 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
return ret;
}
-static struct irq_chip intel_gpio_irqchip = {
- .name = "intel-gpio",
- .irq_ack = intel_gpio_irq_ack,
- .irq_mask = intel_gpio_irq_mask,
- .irq_unmask = intel_gpio_irq_unmask,
- .irq_set_type = intel_gpio_irq_type,
- .irq_set_wake = intel_gpio_irq_wake,
- .flags = IRQCHIP_MASK_ON_SUSPEND,
-};
-
-static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
- const struct intel_community *community)
+static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl,
+ const struct intel_community *community)
{
int ret = 0, i;
@@ -1112,7 +1151,25 @@ static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
return ret;
}
-static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
+static int intel_gpio_add_pin_ranges(struct gpio_chip *gc)
+{
+ struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+ int ret, i;
+
+ for (i = 0; i < pctrl->ncommunities; i++) {
+ struct intel_community *community = &pctrl->communities[i];
+
+ ret = intel_gpio_add_community_ranges(pctrl, community);
+ if (ret) {
+ dev_err(pctrl->dev, "failed to add GPIO pin range\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
{
const struct intel_community *community;
unsigned int ngpio = 0;
@@ -1136,36 +1193,31 @@ static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
{
- int ret, i;
+ int ret;
+ struct gpio_irq_chip *girq;
pctrl->chip = intel_gpio_chip;
+ /* Setup GPIO chip */
pctrl->chip.ngpio = intel_gpio_ngpio(pctrl);
pctrl->chip.label = dev_name(pctrl->dev);
pctrl->chip.parent = pctrl->dev;
pctrl->chip.base = -1;
+ pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges;
pctrl->irq = irq;
- ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
- if (ret) {
- dev_err(pctrl->dev, "failed to register gpiochip\n");
- return ret;
- }
-
- for (i = 0; i < pctrl->ncommunities; i++) {
- struct intel_community *community = &pctrl->communities[i];
-
- ret = intel_gpio_add_pin_ranges(pctrl, community);
- if (ret) {
- dev_err(pctrl->dev, "failed to add GPIO pin range\n");
- return ret;
- }
- }
+ /* Setup IRQ chip */
+ pctrl->irqchip.name = dev_name(pctrl->dev);
+ pctrl->irqchip.irq_ack = intel_gpio_irq_ack;
+ pctrl->irqchip.irq_mask = intel_gpio_irq_mask;
+ pctrl->irqchip.irq_unmask = intel_gpio_irq_unmask;
+ pctrl->irqchip.irq_set_type = intel_gpio_irq_type;
+ pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake;
+ pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND;
/*
- * We need to request the interrupt here (instead of providing chip
- * to the irq directly) because on some platforms several GPIO
- * controllers share the same interrupt line.
+ * On some platforms several GPIO controllers share the same interrupt
+ * line.
*/
ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
IRQF_SHARED | IRQF_NO_THREAD,
@@ -1175,15 +1227,20 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
return ret;
}
- ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0,
- handle_bad_irq, IRQ_TYPE_NONE);
+ girq = &pctrl->chip.irq;
+ girq->chip = &pctrl->irqchip;
+ /* This will let us handle the IRQ in the driver */
+ girq->parent_handler = NULL;
+ girq->num_parents = 0;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->handler = handle_bad_irq;
+
+ ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
if (ret) {
- dev_err(pctrl->dev, "failed to add irqchip\n");
+ dev_err(pctrl->dev, "failed to register gpiochip\n");
return ret;
}
- gpiochip_set_chained_irqchip(&pctrl->chip, &intel_gpio_irqchip, irq,
- NULL);
return 0;
}
@@ -1313,15 +1370,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 +1399,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 +1470,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 +1490,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;
@@ -1527,16 +1574,65 @@ intel_gpio_is_requested(struct gpio_chip *chip, int base, unsigned int size)
return requested;
}
-static u32
-intel_gpio_update_pad_mode(void __iomem *hostown, u32 mask, u32 value)
+static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value)
{
u32 curr, updated;
- curr = readl(hostown);
+ curr = readl(reg);
+
updated = (curr & ~mask) | (value & mask);
- writel(updated, hostown);
+ if (curr == updated)
+ return false;
- return curr;
+ writel(updated, reg);
+ return true;
+}
+
+static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c,
+ void __iomem *base, unsigned int gpp, u32 saved)
+{
+ const struct intel_community *community = &pctrl->communities[c];
+ const struct intel_padgroup *padgrp = &community->gpps[gpp];
+ struct device *dev = pctrl->dev;
+ u32 requested;
+
+ if (padgrp->gpio_base < 0)
+ return;
+
+ requested = intel_gpio_is_requested(&pctrl->chip, padgrp->gpio_base, padgrp->size);
+ if (!intel_gpio_update_reg(base + gpp * 4, requested, saved))
+ return;
+
+ dev_dbg(dev, "restored hostown %u/%u %#08x\n", c, gpp, readl(base + gpp * 4));
+}
+
+static void intel_restore_intmask(struct intel_pinctrl *pctrl, unsigned int c,
+ void __iomem *base, unsigned int gpp, u32 saved)
+{
+ struct device *dev = pctrl->dev;
+
+ if (!intel_gpio_update_reg(base + gpp * 4, ~0U, saved))
+ return;
+
+ dev_dbg(dev, "restored mask %u/%u %#08x\n", c, gpp, readl(base + gpp * 4));
+}
+
+static void intel_restore_padcfg(struct intel_pinctrl *pctrl, unsigned int pin,
+ unsigned int reg, u32 saved)
+{
+ u32 mask = (reg == PADCFG0) ? PADCFG0_GPIORXSTATE : 0;
+ unsigned int n = reg / sizeof(u32);
+ struct device *dev = pctrl->dev;
+ void __iomem *padcfg;
+
+ padcfg = intel_get_padcfg(pctrl, pin, reg);
+ if (!padcfg)
+ return;
+
+ if (!intel_gpio_update_reg(padcfg, ~mask, saved))
+ return;
+
+ dev_dbg(dev, "restored pin %u padcfg%u %#08x\n", pin, n, readl(padcfg));
}
int intel_pinctrl_resume_noirq(struct device *dev)
@@ -1552,37 +1648,13 @@ int intel_pinctrl_resume_noirq(struct device *dev)
pads = pctrl->context.pads;
for (i = 0; i < pctrl->soc->npins; i++) {
const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
- void __iomem *padcfg;
- u32 val;
if (!intel_pinctrl_should_save(pctrl, desc->number))
continue;
- padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);
- val = readl(padcfg) & ~PADCFG0_GPIORXSTATE;
- if (val != pads[i].padcfg0) {
- writel(pads[i].padcfg0, padcfg);
- dev_dbg(dev, "restored pin %u padcfg0 %#08x\n",
- desc->number, readl(padcfg));
- }
-
- padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG1);
- val = readl(padcfg);
- if (val != pads[i].padcfg1) {
- writel(pads[i].padcfg1, padcfg);
- dev_dbg(dev, "restored pin %u padcfg1 %#08x\n",
- desc->number, readl(padcfg));
- }
-
- padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG2);
- if (padcfg) {
- val = readl(padcfg);
- if (val != pads[i].padcfg2) {
- writel(pads[i].padcfg2, padcfg);
- dev_dbg(dev, "restored pin %u padcfg2 %#08x\n",
- desc->number, readl(padcfg));
- }
- }
+ intel_restore_padcfg(pctrl, desc->number, PADCFG0, pads[i].padcfg0);
+ intel_restore_padcfg(pctrl, desc->number, PADCFG1, pads[i].padcfg1);
+ intel_restore_padcfg(pctrl, desc->number, PADCFG2, pads[i].padcfg2);
}
communities = pctrl->context.communities;
@@ -1592,30 +1664,12 @@ int intel_pinctrl_resume_noirq(struct device *dev)
unsigned int gpp;
base = community->regs + community->ie_offset;
- for (gpp = 0; gpp < community->ngpps; gpp++) {
- writel(communities[i].intmask[gpp], base + gpp * 4);
- dev_dbg(dev, "restored mask %d/%u %#08x\n", i, gpp,
- readl(base + gpp * 4));
- }
+ for (gpp = 0; gpp < community->ngpps; gpp++)
+ intel_restore_intmask(pctrl, i, base, gpp, communities[i].intmask[gpp]);
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);
- }
- }
+ for (gpp = 0; gpp < community->ngpps; gpp++)
+ intel_restore_hostown(pctrl, i, base, gpp, communities[i].hostown[gpp]);
}
return 0;
OpenPOWER on IntegriCloud