Merge tag 'v4.19-rc6' into devel
This is the 4.19-rc6 release I needed to merge this in because of extensive conflicts in the MSM and Intel pin control drivers. I know how to resolve them, so let's do it like this. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
@@ -1040,7 +1040,7 @@ static int madera_pin_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* if the configuration is provided through pdata, apply it */
|
||||
if (pdata) {
|
||||
if (pdata && pdata->gpio_configs) {
|
||||
ret = pinctrl_register_mappings(pdata->gpio_configs,
|
||||
pdata->n_gpio_configs);
|
||||
if (ret) {
|
||||
|
@@ -15,10 +15,11 @@
|
||||
|
||||
#include "pinctrl-intel.h"
|
||||
|
||||
#define CNL_PAD_OWN 0x020
|
||||
#define CNL_PADCFGLOCK 0x080
|
||||
#define CNL_HOSTSW_OWN 0x0b0
|
||||
#define CNL_GPI_IE 0x120
|
||||
#define CNL_PAD_OWN 0x020
|
||||
#define CNL_PADCFGLOCK 0x080
|
||||
#define CNL_LP_HOSTSW_OWN 0x0b0
|
||||
#define CNL_H_HOSTSW_OWN 0x0c0
|
||||
#define CNL_GPI_IE 0x120
|
||||
|
||||
#define CNL_GPP(r, s, e, g) \
|
||||
{ \
|
||||
@@ -30,12 +31,12 @@
|
||||
|
||||
#define CNL_NO_GPIO -1
|
||||
|
||||
#define CNL_COMMUNITY(b, s, e, g) \
|
||||
#define CNL_COMMUNITY(b, s, e, o, g) \
|
||||
{ \
|
||||
.barno = (b), \
|
||||
.padown_offset = CNL_PAD_OWN, \
|
||||
.padcfglock_offset = CNL_PADCFGLOCK, \
|
||||
.hostown_offset = CNL_HOSTSW_OWN, \
|
||||
.hostown_offset = (o), \
|
||||
.ie_offset = CNL_GPI_IE, \
|
||||
.pin_base = (s), \
|
||||
.npins = ((e) - (s) + 1), \
|
||||
@@ -43,6 +44,12 @@
|
||||
.ngpps = ARRAY_SIZE(g), \
|
||||
}
|
||||
|
||||
#define CNLLP_COMMUNITY(b, s, e, g) \
|
||||
CNL_COMMUNITY(b, s, e, CNL_LP_HOSTSW_OWN, g)
|
||||
|
||||
#define CNLH_COMMUNITY(b, s, e, g) \
|
||||
CNL_COMMUNITY(b, s, e, CNL_H_HOSTSW_OWN, g)
|
||||
|
||||
/* Cannon Lake-H */
|
||||
static const struct pinctrl_pin_desc cnlh_pins[] = {
|
||||
/* GPP_A */
|
||||
@@ -379,7 +386,7 @@ static const struct intel_padgroup cnlh_community1_gpps[] = {
|
||||
static const struct intel_padgroup cnlh_community3_gpps[] = {
|
||||
CNL_GPP(0, 155, 178, 192), /* GPP_K */
|
||||
CNL_GPP(1, 179, 202, 224), /* GPP_H */
|
||||
CNL_GPP(2, 203, 215, 258), /* GPP_E */
|
||||
CNL_GPP(2, 203, 215, 256), /* GPP_E */
|
||||
CNL_GPP(3, 216, 239, 288), /* GPP_F */
|
||||
CNL_GPP(4, 240, 248, CNL_NO_GPIO), /* SPI */
|
||||
};
|
||||
@@ -442,10 +449,10 @@ static const struct intel_function cnlh_functions[] = {
|
||||
};
|
||||
|
||||
static const struct intel_community cnlh_communities[] = {
|
||||
CNL_COMMUNITY(0, 0, 50, cnlh_community0_gpps),
|
||||
CNL_COMMUNITY(1, 51, 154, cnlh_community1_gpps),
|
||||
CNL_COMMUNITY(2, 155, 248, cnlh_community3_gpps),
|
||||
CNL_COMMUNITY(3, 249, 298, cnlh_community4_gpps),
|
||||
CNLH_COMMUNITY(0, 0, 50, cnlh_community0_gpps),
|
||||
CNLH_COMMUNITY(1, 51, 154, cnlh_community1_gpps),
|
||||
CNLH_COMMUNITY(2, 155, 248, cnlh_community3_gpps),
|
||||
CNLH_COMMUNITY(3, 249, 298, cnlh_community4_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data cnlh_soc_data = {
|
||||
@@ -803,9 +810,9 @@ static const struct intel_padgroup cnllp_community4_gpps[] = {
|
||||
};
|
||||
|
||||
static const struct intel_community cnllp_communities[] = {
|
||||
CNL_COMMUNITY(0, 0, 67, cnllp_community0_gpps),
|
||||
CNL_COMMUNITY(1, 68, 180, cnllp_community1_gpps),
|
||||
CNL_COMMUNITY(2, 181, 243, cnllp_community4_gpps),
|
||||
CNLLP_COMMUNITY(0, 0, 67, cnllp_community0_gpps),
|
||||
CNLLP_COMMUNITY(1, 68, 180, cnllp_community1_gpps),
|
||||
CNLLP_COMMUNITY(2, 181, 243, cnllp_community4_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data cnllp_soc_data = {
|
||||
|
@@ -750,91 +750,11 @@ static const struct pinctrl_desc intel_pinctrl_desc = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
u32 padcfg0;
|
||||
|
||||
reg = intel_get_padcfg(pctrl, offset, PADCFG0);
|
||||
if (!reg)
|
||||
return -EINVAL;
|
||||
|
||||
padcfg0 = readl(reg);
|
||||
if (!(padcfg0 & PADCFG0_GPIOTXDIS))
|
||||
return !!(padcfg0 & PADCFG0_GPIOTXSTATE);
|
||||
|
||||
return !!(padcfg0 & PADCFG0_GPIORXSTATE);
|
||||
}
|
||||
|
||||
static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
void __iomem *reg;
|
||||
u32 padcfg0;
|
||||
|
||||
reg = intel_get_padcfg(pctrl, offset, PADCFG0);
|
||||
if (!reg)
|
||||
return;
|
||||
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
padcfg0 = readl(reg);
|
||||
if (value)
|
||||
padcfg0 |= PADCFG0_GPIOTXSTATE;
|
||||
else
|
||||
padcfg0 &= ~PADCFG0_GPIOTXSTATE;
|
||||
writel(padcfg0, reg);
|
||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||
}
|
||||
|
||||
static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
u32 padcfg0;
|
||||
|
||||
reg = intel_get_padcfg(pctrl, offset, PADCFG0);
|
||||
if (!reg)
|
||||
return -EINVAL;
|
||||
|
||||
padcfg0 = readl(reg);
|
||||
|
||||
if (padcfg0 & PADCFG0_PMODE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return !!(padcfg0 & PADCFG0_GPIOTXDIS);
|
||||
}
|
||||
|
||||
static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return pinctrl_gpio_direction_input(chip->base + offset);
|
||||
}
|
||||
|
||||
static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
intel_gpio_set(chip, offset, value);
|
||||
return pinctrl_gpio_direction_output(chip->base + offset);
|
||||
}
|
||||
|
||||
static const struct gpio_chip intel_gpio_chip = {
|
||||
.owner = THIS_MODULE,
|
||||
.request = gpiochip_generic_request,
|
||||
.free = gpiochip_generic_free,
|
||||
.get_direction = intel_gpio_get_direction,
|
||||
.direction_input = intel_gpio_direction_input,
|
||||
.direction_output = intel_gpio_direction_output,
|
||||
.get = intel_gpio_get,
|
||||
.set = intel_gpio_set,
|
||||
.set_config = gpiochip_generic_config,
|
||||
};
|
||||
|
||||
/**
|
||||
* intel_gpio_to_pin() - Translate from GPIO offset to pin number
|
||||
* @pctrl: Pinctrl structure
|
||||
* @offset: GPIO offset from gpiolib
|
||||
* @community: Community is filled here if not %NULL
|
||||
* @commmunity: Community is filled here if not %NULL
|
||||
* @padgrp: Pad group is filled here if not %NULL
|
||||
*
|
||||
* When coming through gpiolib irqchip, the GPIO offset is not
|
||||
@@ -875,36 +795,101 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int intel_gpio_irq_reqres(struct irq_data *d)
|
||||
static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
|
||||
int pin;
|
||||
int ret;
|
||||
|
||||
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
|
||||
if (pin >= 0) {
|
||||
ret = gpiochip_lock_as_irq(gc, pin);
|
||||
if (ret) {
|
||||
dev_err(pctrl->dev, "unable to lock HW IRQ %d for IRQ\n",
|
||||
pin);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_gpio_irq_relres(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
u32 padcfg0;
|
||||
int pin;
|
||||
|
||||
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
|
||||
if (pin >= 0)
|
||||
gpiochip_unlock_as_irq(gc, pin);
|
||||
pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
|
||||
if (pin < 0)
|
||||
return -EINVAL;
|
||||
|
||||
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
|
||||
if (!reg)
|
||||
return -EINVAL;
|
||||
|
||||
padcfg0 = readl(reg);
|
||||
if (!(padcfg0 & PADCFG0_GPIOTXDIS))
|
||||
return !!(padcfg0 & PADCFG0_GPIOTXSTATE);
|
||||
|
||||
return !!(padcfg0 & PADCFG0_GPIORXSTATE);
|
||||
}
|
||||
|
||||
static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
void __iomem *reg;
|
||||
u32 padcfg0;
|
||||
int pin;
|
||||
|
||||
pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
|
||||
if (pin < 0)
|
||||
return;
|
||||
|
||||
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
|
||||
if (!reg)
|
||||
return;
|
||||
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
padcfg0 = readl(reg);
|
||||
if (value)
|
||||
padcfg0 |= PADCFG0_GPIOTXSTATE;
|
||||
else
|
||||
padcfg0 &= ~PADCFG0_GPIOTXSTATE;
|
||||
writel(padcfg0, reg);
|
||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||
}
|
||||
|
||||
static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
u32 padcfg0;
|
||||
int pin;
|
||||
|
||||
pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
|
||||
if (pin < 0)
|
||||
return -EINVAL;
|
||||
|
||||
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
|
||||
if (!reg)
|
||||
return -EINVAL;
|
||||
|
||||
padcfg0 = readl(reg);
|
||||
|
||||
if (padcfg0 & PADCFG0_PMODE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return !!(padcfg0 & PADCFG0_GPIOTXDIS);
|
||||
}
|
||||
|
||||
static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return pinctrl_gpio_direction_input(chip->base + offset);
|
||||
}
|
||||
|
||||
static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
intel_gpio_set(chip, offset, value);
|
||||
return pinctrl_gpio_direction_output(chip->base + offset);
|
||||
}
|
||||
|
||||
static const struct gpio_chip intel_gpio_chip = {
|
||||
.owner = THIS_MODULE,
|
||||
.request = gpiochip_generic_request,
|
||||
.free = gpiochip_generic_free,
|
||||
.get_direction = intel_gpio_get_direction,
|
||||
.direction_input = intel_gpio_direction_input,
|
||||
.direction_output = intel_gpio_direction_output,
|
||||
.get = intel_gpio_get,
|
||||
.set = intel_gpio_set,
|
||||
.set_config = gpiochip_generic_config,
|
||||
};
|
||||
|
||||
static void intel_gpio_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
@@ -1120,8 +1105,6 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
|
||||
|
||||
static struct irq_chip intel_gpio_irqchip = {
|
||||
.name = "intel-gpio",
|
||||
.irq_request_resources = intel_gpio_irq_reqres,
|
||||
.irq_release_resources = intel_gpio_irq_relres,
|
||||
.irq_enable = intel_gpio_irq_enable,
|
||||
.irq_ack = intel_gpio_irq_ack,
|
||||
.irq_mask = intel_gpio_irq_mask,
|
||||
|
@@ -348,21 +348,12 @@ static void amd_gpio_irq_enable(struct irq_data *d)
|
||||
unsigned long flags;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
|
||||
u32 mask = BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF);
|
||||
|
||||
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
|
||||
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
|
||||
pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
|
||||
pin_reg |= BIT(INTERRUPT_MASK_OFF);
|
||||
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
|
||||
/*
|
||||
* When debounce logic is enabled it takes ~900 us before interrupts
|
||||
* can be enabled. During this "debounce warm up" period the
|
||||
* "INTERRUPT_ENABLE" bit will read as 0. Poll the bit here until it
|
||||
* reads back as 1, signaling that interrupts are now enabled.
|
||||
*/
|
||||
while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
|
||||
continue;
|
||||
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
||||
}
|
||||
|
||||
@@ -426,7 +417,7 @@ static void amd_gpio_irq_eoi(struct irq_data *d)
|
||||
static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 pin_reg;
|
||||
u32 pin_reg, pin_reg_irq_en, mask;
|
||||
unsigned long flags, irq_flags;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
|
||||
@@ -495,6 +486,28 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
}
|
||||
|
||||
pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF;
|
||||
/*
|
||||
* If WAKE_INT_MASTER_REG.MaskStsEn is set, a software write to the
|
||||
* debounce registers of any GPIO will block wake/interrupt status
|
||||
* generation for *all* GPIOs for a lenght of time that depends on
|
||||
* WAKE_INT_MASTER_REG.MaskStsLength[11:0]. During this period the
|
||||
* INTERRUPT_ENABLE bit will read as 0.
|
||||
*
|
||||
* We temporarily enable irq for the GPIO whose configuration is
|
||||
* changing, and then wait for it to read back as 1 to know when
|
||||
* debounce has settled and then disable the irq again.
|
||||
* We do this polling with the spinlock held to ensure other GPIO
|
||||
* access routines do not read an incorrect value for the irq enable
|
||||
* bit of other GPIOs. We keep the GPIO masked while polling to avoid
|
||||
* spurious irqs, and disable the irq again after polling.
|
||||
*/
|
||||
mask = BIT(INTERRUPT_ENABLE_OFF);
|
||||
pin_reg_irq_en = pin_reg;
|
||||
pin_reg_irq_en |= mask;
|
||||
pin_reg_irq_en &= ~BIT(INTERRUPT_MASK_OFF);
|
||||
writel(pin_reg_irq_en, gpio_dev->base + (d->hwirq)*4);
|
||||
while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
|
||||
continue;
|
||||
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
|
||||
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
||||
|
||||
|
@@ -1227,7 +1227,7 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
|
||||
|
||||
err = pinctrl_generic_add_group(jzpc->pctl, group->name,
|
||||
group->pins, group->num_pins, group->data);
|
||||
if (err) {
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Failed to register group %s\n",
|
||||
group->name);
|
||||
return err;
|
||||
@@ -1240,7 +1240,7 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
|
||||
err = pinmux_generic_add_function(jzpc->pctl, func->name,
|
||||
func->group_names, func->num_group_names,
|
||||
func->data);
|
||||
if (err) {
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Failed to register function %s\n",
|
||||
func->name);
|
||||
return err;
|
||||
|
@@ -669,6 +669,29 @@ static void msm_gpio_irq_mask(struct irq_data *d)
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
val = msm_readl_intr_cfg(pctrl, g);
|
||||
/*
|
||||
* There are two bits that control interrupt forwarding to the CPU. The
|
||||
* RAW_STATUS_EN bit causes the level or edge sensed on the line to be
|
||||
* latched into the interrupt status register when the hardware detects
|
||||
* an irq that it's configured for (either edge for edge type or level
|
||||
* for level type irq). The 'non-raw' status enable bit causes the
|
||||
* hardware to assert the summary interrupt to the CPU if the latched
|
||||
* status bit is set. There's a bug though, the edge detection logic
|
||||
* seems to have a problem where toggling the RAW_STATUS_EN bit may
|
||||
* cause the status bit to latch spuriously when there isn't any edge
|
||||
* so we can't touch that bit for edge type irqs and we have to keep
|
||||
* the bit set anyway so that edges are latched while the line is masked.
|
||||
*
|
||||
* To make matters more complicated, leaving the RAW_STATUS_EN bit
|
||||
* enabled all the time causes level interrupts to re-latch into the
|
||||
* status register because the level is still present on the line after
|
||||
* we ack it. We clear the raw status enable bit during mask here and
|
||||
* set the bit on unmask so the interrupt can't latch into the hardware
|
||||
* while it's masked.
|
||||
*/
|
||||
if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
|
||||
val &= ~BIT(g->intr_raw_status_bit);
|
||||
|
||||
val &= ~BIT(g->intr_enable_bit);
|
||||
msm_writel_intr_cfg(val, pctrl, g);
|
||||
|
||||
@@ -690,6 +713,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
val = msm_readl_intr_cfg(pctrl, g);
|
||||
val |= BIT(g->intr_raw_status_bit);
|
||||
val |= BIT(g->intr_enable_bit);
|
||||
msm_writel_intr_cfg(val, pctrl, g);
|
||||
|
||||
|
Reference in New Issue
Block a user