static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG); void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG); unsigned long flags; u32 reg_val; spin_lock_irqsave(&vg->lock, flags); /* * Before making any direction modifications, do a check if gpio * is set for direct IRQ. On baytrail, setting GPIO to output does * not make sense, so let's at least warn the caller before they shoot * themselves in the foot. */ WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, "Potential Error: Setting GPIO with direct_irq_en to output"); reg_val = readl(reg) | BYT_DIR_MASK; reg_val &= ~BYT_OUTPUT_EN; if (value) writel(reg_val | BYT_LEVEL, reg); else writel(reg_val & ~BYT_LEVEL, reg); spin_unlock_irqrestore(&vg->lock, flags); return 0; }
static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); u32 value; bool special; /* * In most cases, func pin mux 000 means GPIO function. * But, some pins may have func pin mux 001 represents * GPIO function. Only allow user to export pin with * func pin mux preset as GPIO function by BIOS/FW. */ value = readl(reg) & BYT_PIN_MUX; special = is_special_pin(vg, offset); if ((special && value != 1) || (!special && value)) { dev_err(&vg->pdev->dev, "pin %u cannot be used as GPIO.\n", offset); return -EINVAL; } pm_runtime_get(&vg->pdev->dev); return 0; }
static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc)); struct irq_chip *chip = irq_data_get_irq_chip(data); u32 base, pin, mask; void __iomem *reg; u32 pending; unsigned virq; int looplimit = 0; /* check from GPIO controller which pin triggered the interrupt */ for (base = 0; base < vg->chip.ngpio; base += 32) { reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); while ((pending = readl(reg))) { pin = __ffs(pending); mask = BIT(pin); /* Clear before handling so we can't lose an edge */ writel(mask, reg); virq = irq_find_mapping(vg->chip.irqdomain, base + pin); generic_handle_irq(virq); /* In case bios or user sets triggering incorretly a pin * might remain in "interrupt triggered" state. */ if (looplimit++ > 32) { dev_err(&vg->pdev->dev, "Gpio %d interrupt flood, disabling\n", base + pin); reg = byt_gpio_reg(&vg->chip, base + pin, BYT_CONF0_REG); mask = readl(reg); mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS | BYT_TRIG_LVL); writel(mask, reg); mask = readl(reg); /* flush */ break; } } } chip->irq_eoi(data); }
static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); u32 value; /* clear interrupt triggering */ value = readl(reg); value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); writel(value, reg); pm_runtime_put(&vg->pdev->dev); }
static void byt_gpio_irq_init_hw(struct byt_gpio *vg) { void __iomem *reg; u32 base, value; /* clear interrupt status trigger registers */ for (base = 0; base < vg->chip.ngpio; base += 32) { reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); writel(0xffffffff, reg); /* make sure trigger bits are cleared, if not then a pin might be misconfigured in bios */ value = readl(reg); if (value) dev_err(&vg->pdev->dev, "GPIO interrupt error, pins misconfigured\n"); } }
static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); unsigned long flags; u32 value; spin_lock_irqsave(&vg->lock, flags); value = readl(reg) | BYT_DIR_MASK; value &= ~BYT_INPUT_EN; /* active low */ writel(value, reg); spin_unlock_irqrestore(&vg->lock, flags); return 0; }
static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); unsigned long flags; u32 old_val; spin_lock_irqsave(&vg->lock, flags); old_val = readl(reg); if (value) writel(old_val | BYT_LEVEL, reg); else writel(old_val & ~BYT_LEVEL, reg); spin_unlock_irqrestore(&vg->lock, flags); }
static int byt_irq_type(struct irq_data *d, unsigned type) { struct byt_gpio *vg = to_byt_gpio(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->chip, offset, BYT_CONF0_REG); if (offset >= vg->chip.ngpio) return -EINVAL; spin_lock_irqsave(&vg->lock, flags); value = readl(reg); /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits * are used to indicate high and low level triggering */ value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); switch (type) { case IRQ_TYPE_LEVEL_HIGH: value |= BYT_TRIG_LVL; case IRQ_TYPE_EDGE_RISING: value |= BYT_TRIG_POS; break; case IRQ_TYPE_LEVEL_LOW: value |= BYT_TRIG_LVL; case IRQ_TYPE_EDGE_FALLING: value |= BYT_TRIG_NEG; break; case IRQ_TYPE_EDGE_BOTH: value |= (BYT_TRIG_NEG | BYT_TRIG_POS); break; } writel(value, reg); spin_unlock_irqrestore(&vg->lock, flags); return 0; }
static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG); unsigned long flags; u32 reg_val; spin_lock_irqsave(&vg->lock, flags); reg_val = readl(reg) | BYT_DIR_MASK; reg_val &= ~(BYT_OUTPUT_EN | BYT_INPUT_EN); if (value) writel(reg_val | BYT_LEVEL, reg); else writel(reg_val & ~BYT_LEVEL, reg); spin_unlock_irqrestore(&vg->lock, flags); return 0; }
static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) { void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); return readl(reg) & BYT_LEVEL; }