Source
x
/*
* Copyright (C) 2015-2017 Broadcom
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
enum gio_reg_index {
GIO_REG_ODEN = 0,
GIO_REG_DATA,
GIO_REG_IODIR,
GIO_REG_EC,
GIO_REG_EI,
GIO_REG_MASK,
GIO_REG_LEVEL,
GIO_REG_STAT,
NUMBER_OF_GIO_REGISTERS
};
struct brcmstb_gpio_bank {
struct list_head node;
int id;
struct gpio_chip gc;
struct brcmstb_gpio_priv *parent_priv;
u32 width;
u32 wake_active;
u32 saved_regs[GIO_REG_STAT]; /* Don't save and restore GIO_REG_STAT */
};
struct brcmstb_gpio_priv {
struct list_head bank_list;
void __iomem *reg_base;
struct platform_device *pdev;
struct irq_domain *irq_domain;
struct irq_chip irq_chip;
int parent_irq;
int gpio_base;
int num_gpios;
int parent_wake_irq;
};
/* assumes MAX_GPIO_PER_BANK is a multiple of 2 */
static inline struct brcmstb_gpio_priv *
brcmstb_gpio_gc_to_priv(struct gpio_chip *gc)
{
struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc);
return bank->parent_priv;
}
static unsigned long
__brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
{
void __iomem *reg_base = bank->parent_priv->reg_base;
return bank->gc.read_reg(reg_base + GIO_STAT(bank->id)) &
bank->gc.read_reg(reg_base + GIO_MASK(bank->id));
}
static unsigned long
brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
{
unsigned long status;