Skip to content

Commit

Permalink
pinctrl: baytrail: Update irq chip operations
Browse files Browse the repository at this point in the history
This patch updates the irq chip implementation in order
to interact with the pin control chip model: the chip
contains reference to SOC data and pin/group/community
information is retrieved through the SOC reference.

Signed-off-by: Cristina Ciocan <cristina.ciocan@intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Cristina Ciocan authored and Linus Walleij committed Apr 4, 2016
1 parent 86e3ef8 commit 9f573b9
Showing 1 changed file with 51 additions and 46 deletions.
97 changes: 51 additions & 46 deletions drivers/pinctrl/intel/pinctrl-baytrail.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,41 +1120,6 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned int offset)
return 0;
}

static int byt_irq_type(struct irq_data *d, unsigned type)
{
struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
u32 offset = irqd_to_hwirq(d);
u32 value;
unsigned long flags;
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);

if (offset >= vg->chip.ngpio)
return -EINVAL;

raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(reg);

WARN(value & BYT_DIRECT_IRQ_EN,
"Bad pad config for io mode, force direct_irq_en bit clearing");

/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
* are used to indicate high and low level triggering
*/
value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
BYT_TRIG_LVL);

writel(value, reg);

if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
else if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(d, handle_level_irq);

raw_spin_unlock_irqrestore(&vg->lock, flags);

return 0;
}

static void byt_get_pull_strength(u32 reg, u16 *strength)
{
switch (reg & BYT_PULL_STR_MASK) {
Expand Down Expand Up @@ -1565,12 +1530,23 @@ static void byt_irq_ack(struct irq_data *d)
unsigned offset = irqd_to_hwirq(d);
void __iomem *reg;

raw_spin_lock(&vg->lock);
reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
if (!reg)
return;

raw_spin_lock(&vg->lock);
writel(BIT(offset % 32), reg);
raw_spin_unlock(&vg->lock);
}

static void byt_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct byt_gpio *vg = gpiochip_get_data(gc);

byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
}

static void byt_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
Expand All @@ -1581,6 +1557,8 @@ static void byt_irq_unmask(struct irq_data *d)
u32 value;

reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
if (!reg)
return;

raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(reg);
Expand All @@ -1606,21 +1584,48 @@ static void byt_irq_unmask(struct irq_data *d)
raw_spin_unlock_irqrestore(&vg->lock, flags);
}

static void byt_irq_mask(struct irq_data *d)
static int byt_irq_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct byt_gpio *vg = gpiochip_get_data(gc);
struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
u32 offset = irqd_to_hwirq(d);
u32 value;
unsigned long flags;
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);

byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
if (!reg || offset >= vg->chip.ngpio)
return -EINVAL;

raw_spin_lock_irqsave(&vg->lock, flags);
value = readl(reg);

WARN(value & BYT_DIRECT_IRQ_EN,
"Bad pad config for io mode, force direct_irq_en bit clearing");

/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
* are used to indicate high and low level triggering
*/
value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
BYT_TRIG_LVL);

writel(value, reg);

if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
else if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(d, handle_level_irq);

raw_spin_unlock_irqrestore(&vg->lock, flags);

return 0;
}

static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
.irq_ack = byt_irq_ack,
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
.flags = IRQCHIP_SKIP_SET_WAKE,
.name = "BYT-GPIO",
.irq_ack = byt_irq_ack,
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
.flags = IRQCHIP_SKIP_SET_WAKE,
};

static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
Expand Down

0 comments on commit 9f573b9

Please sign in to comment.