pinctrl: msm: Remove explicit barriers from mmio ops where unneeded

For the vast majority of mmio operations in this driver, explicit memory
barriers aren't needed either because a data dependency between a read
and write already exists, or because of the presence of the spin locks
which execute a full memory barrier.

Removing all the unneeded explicit barriers considerably reduces
overhead for pinctrl operations, which in turn benefits things like i2c.

Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
Signed-off-by: Ruchit <ruchitmarathe@gmail.com>
fourteen
Sultan Alsawaf 4 years ago committed by Jenna
parent 603c9c59a5
commit 899365ef6e
  1. 72
      drivers/pinctrl/qcom/pinctrl-msm.c

@ -275,14 +275,14 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->ctl_reg);
val = readl_relaxed(base + g->ctl_reg);
val &= ~mask;
val |= i << g->mux_bit;
/* Check if egpio present and enable that feature */
if (val & BIT(g->egpio_present))
val |= BIT(g->egpio_enable);
writel(val, base + g->ctl_reg);
writel_relaxed(val, base + g->ctl_reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
@ -367,7 +367,7 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
if (ret < 0)
return ret;
val = readl(base + g->ctl_reg);
val = readl_relaxed(base + g->ctl_reg);
arg = (val >> bit) & mask;
/* Convert register value to pinconf value */
@ -406,7 +406,7 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
if (!arg)
return -EINVAL;
val = readl(base + g->io_reg);
val = readl_relaxed(base + g->io_reg);
arg = !!(val & BIT(g->in_bit));
break;
case PIN_CONFIG_INPUT_ENABLE:
@ -490,12 +490,12 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
case PIN_CONFIG_OUTPUT:
/* set output value */
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->io_reg);
val = readl_relaxed(base + g->io_reg);
if (arg)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, base + g->io_reg);
writel_relaxed(val, base + g->io_reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
/* enable output */
@ -518,10 +518,10 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
}
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->ctl_reg);
val = readl_relaxed(base + g->ctl_reg);
val &= ~(mask << bit);
val |= arg << bit;
writel(val, base + g->ctl_reg);
writel_relaxed(val, base + g->ctl_reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
@ -586,9 +586,9 @@ static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
base = reassign_pctrl_reg(pctrl->soc, offset);
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->ctl_reg);
val = readl_relaxed(base + g->ctl_reg);
val &= ~BIT(g->oe_bit);
writel(val, base + g->ctl_reg);
writel_relaxed(val, base + g->ctl_reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
@ -608,16 +608,16 @@ static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, in
base = reassign_pctrl_reg(pctrl->soc, offset);
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->io_reg);
val = readl_relaxed(base + g->io_reg);
if (value)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, base + g->io_reg);
writel_relaxed(val, base + g->io_reg);
val = readl(base + g->ctl_reg);
val = readl_relaxed(base + g->ctl_reg);
val |= BIT(g->oe_bit);
writel(val, base + g->ctl_reg);
writel_relaxed(val, base + g->ctl_reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
@ -667,12 +667,12 @@ static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->io_reg);
val = readl_relaxed(base + g->io_reg);
if (value)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, base + g->io_reg);
writel_relaxed(val, base + g->io_reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
@ -909,14 +909,14 @@ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
base = reassign_pctrl_reg(pctrl->soc, d->hwirq);
do {
val = readl(base + g->io_reg) & BIT(g->in_bit);
val = readl_relaxed(base + g->io_reg) & BIT(g->in_bit);
pol = readl(base + g->intr_cfg_reg);
pol = readl_relaxed(base + g->intr_cfg_reg);
pol ^= BIT(g->intr_polarity_bit);
writel(pol, base + g->intr_cfg_reg);
writel_relaxed(pol, base + g->intr_cfg_reg);
val2 = readl(base + g->io_reg) & BIT(g->in_bit);
intstat = readl(base + g->intr_status_reg);
val2 = readl_relaxed(base + g->io_reg) & BIT(g->in_bit);
intstat = readl_relaxed(base + g->intr_status_reg);
if (intstat || (val == val2))
return;
} while (loop_limit-- > 0);
@ -938,9 +938,9 @@ static void msm_gpio_irq_mask(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->intr_cfg_reg);
val = readl_relaxed(base + g->intr_cfg_reg);
val &= ~BIT(g->intr_enable_bit);
writel(val, base + g->intr_cfg_reg);
writel_relaxed(val, base + g->intr_cfg_reg);
clear_bit(d->hwirq, pctrl->enabled_irqs);
@ -967,13 +967,13 @@ static void msm_gpio_irq_enable(struct irq_data *d)
* any erraneous interrupts that would have got latched
* when the intterupt is not in use.
*/
val = readl(base + g->intr_status_reg);
val = readl_relaxed(base + g->intr_status_reg);
val &= ~BIT(g->intr_status_bit);
writel(val, base + g->intr_status_reg);
writel_relaxed(val, base + g->intr_status_reg);
val = readl(base + g->intr_cfg_reg);
val = readl_relaxed(base + g->intr_cfg_reg);
val |= BIT(g->intr_enable_bit);
writel(val, base + g->intr_cfg_reg);
writel_relaxed(val, base + g->intr_cfg_reg);
set_bit(d->hwirq, pctrl->enabled_irqs);
@ -1004,9 +1004,9 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
writel_relaxed(val, pctrl->regs + g->intr_status_reg);
}
val = readl(base + g->intr_cfg_reg);
val = readl_relaxed(base + g->intr_cfg_reg);
val |= BIT(g->intr_enable_bit);
writel(val, base + g->intr_cfg_reg);
writel_relaxed(val, base + g->intr_cfg_reg);
set_bit(d->hwirq, pctrl->enabled_irqs);
@ -1030,12 +1030,12 @@ static void msm_gpio_irq_ack(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(base + g->intr_status_reg);
val = readl_relaxed(base + g->intr_status_reg);
if (g->intr_ack_high)
val |= BIT(g->intr_status_bit);
else
val &= ~BIT(g->intr_status_bit);
writel(val, base + g->intr_status_reg);
writel_relaxed(val, base + g->intr_status_reg);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
@ -1066,17 +1066,17 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
clear_bit(d->hwirq, pctrl->dual_edge_irqs);
/* Route interrupts to application cpu */
val = readl(base + g->intr_target_reg);
val = readl_relaxed(base + g->intr_target_reg);
val &= ~(7 << g->intr_target_bit);
val |= g->intr_target_kpss_val << g->intr_target_bit;
writel(val, base + g->intr_target_reg);
writel_relaxed(val, base + g->intr_target_reg);
/* Update configuration for gpio.
* RAW_STATUS_EN is left on for all gpio irqs. Due to the
* internal circuitry of TLMM, toggling the RAW_STATUS
* could cause the INTR_STATUS to be set for EDGE interrupts.
*/
val = readl(base + g->intr_cfg_reg);
val = readl_relaxed(base + g->intr_cfg_reg);
val |= BIT(g->intr_raw_status_bit);
if (g->intr_detection_width == 2) {
val &= ~(3 << g->intr_detection_bit);
@ -1124,7 +1124,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
} else {
BUG();
}
writel(val, base + g->intr_cfg_reg);
writel_relaxed(val, base + g->intr_cfg_reg);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
@ -1846,7 +1846,7 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
g = &pctrl->soc->groups[i];
base = reassign_pctrl_reg(pctrl->soc, i);
val = readl(base + g->intr_status_reg);
val = readl_relaxed(base + g->intr_status_reg);
if (val & BIT(g->intr_status_bit)) {
irq_pin = irq_find_mapping(gc->irqdomain, i);
generic_handle_irq(irq_pin);

Loading…
Cancel
Save