diff options
Diffstat (limited to 'drivers/gpio/gpio-crystalcove.c')
| -rw-r--r-- | drivers/gpio/gpio-crystalcove.c | 70 | 
1 files changed, 37 insertions, 33 deletions
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index b55c74a5e064..1ee62cd58582 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -15,6 +15,7 @@  #include <linux/platform_device.h>  #include <linux/regmap.h>  #include <linux/seq_file.h> +#include <linux/types.h>  #define CRYSTALCOVE_GPIO_NUM	16  #define CRYSTALCOVE_VGPIO_NUM	95 @@ -110,8 +111,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)  	return reg + gpio % 8;  } -static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, -					int gpio) +static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, int gpio)  {  	u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0;  	int mask = BIT(gpio % 8); @@ -140,8 +140,7 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)  	return regmap_write(cg->regmap, reg, CTLO_INPUT_SET);  } -static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, -				    int value) +static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, int value)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip);  	int reg = to_reg(gpio, CTRL_OUT); @@ -168,8 +167,7 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)  	return val & 0x1;  } -static void crystalcove_gpio_set(struct gpio_chip *chip, -				 unsigned int gpio, int value) +static void crystalcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip);  	int reg = to_reg(gpio, CTRL_OUT); @@ -185,10 +183,10 @@ static void crystalcove_gpio_set(struct gpio_chip *chip,  static int crystalcove_irq_type(struct irq_data *data, unsigned int type)  { -	struct crystalcove_gpio *cg = -		gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	irq_hw_number_t hwirq = irqd_to_hwirq(data); -	if (data->hwirq >= CRYSTALCOVE_GPIO_NUM) +	if (hwirq >= CRYSTALCOVE_GPIO_NUM)  		return 0;  	switch (type) { @@ -215,22 +213,20 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned int type)  static void crystalcove_bus_lock(struct irq_data *data)  { -	struct crystalcove_gpio *cg = -		gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));  	mutex_lock(&cg->buslock);  }  static void crystalcove_bus_sync_unlock(struct irq_data *data)  { -	struct crystalcove_gpio *cg = -		gpiochip_get_data(irq_data_get_irq_chip_data(data)); -	int gpio = data->hwirq; +	struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	irq_hw_number_t hwirq = irqd_to_hwirq(data);  	if (cg->update & UPDATE_IRQ_TYPE) -		crystalcove_update_irq_ctrl(cg, gpio); +		crystalcove_update_irq_ctrl(cg, hwirq);  	if (cg->update & UPDATE_IRQ_MASK) -		crystalcove_update_irq_mask(cg, gpio); +		crystalcove_update_irq_mask(cg, hwirq);  	cg->update = 0;  	mutex_unlock(&cg->buslock); @@ -238,34 +234,43 @@ static void crystalcove_bus_sync_unlock(struct irq_data *data)  static void crystalcove_irq_unmask(struct irq_data *data)  { -	struct crystalcove_gpio *cg = -		gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	struct gpio_chip *gc = irq_data_get_irq_chip_data(data); +	struct crystalcove_gpio *cg = gpiochip_get_data(gc); +	irq_hw_number_t hwirq = irqd_to_hwirq(data); -	if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { -		cg->set_irq_mask = false; -		cg->update |= UPDATE_IRQ_MASK; -	} +	if (hwirq >= CRYSTALCOVE_GPIO_NUM) +		return; + +	gpiochip_enable_irq(gc, hwirq); + +	cg->set_irq_mask = false; +	cg->update |= UPDATE_IRQ_MASK;  }  static void crystalcove_irq_mask(struct irq_data *data)  { -	struct crystalcove_gpio *cg = -		gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	struct gpio_chip *gc = irq_data_get_irq_chip_data(data); +	struct crystalcove_gpio *cg = gpiochip_get_data(gc); +	irq_hw_number_t hwirq = irqd_to_hwirq(data); -	if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { -		cg->set_irq_mask = true; -		cg->update |= UPDATE_IRQ_MASK; -	} +	if (hwirq >= CRYSTALCOVE_GPIO_NUM) +		return; + +	cg->set_irq_mask = true; +	cg->update |= UPDATE_IRQ_MASK; + +	gpiochip_disable_irq(gc, hwirq);  } -static struct irq_chip crystalcove_irqchip = { +static const struct irq_chip crystalcove_irqchip = {  	.name			= "Crystal Cove",  	.irq_mask		= crystalcove_irq_mask,  	.irq_unmask		= crystalcove_irq_unmask,  	.irq_set_type		= crystalcove_irq_type,  	.irq_bus_lock		= crystalcove_bus_lock,  	.irq_bus_sync_unlock	= crystalcove_bus_sync_unlock, -	.flags			= IRQCHIP_SKIP_SET_WAKE, +	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, +	GPIOCHIP_IRQ_RESOURCE_HELPERS,  };  static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) @@ -293,8 +298,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)  	return IRQ_HANDLED;  } -static void crystalcove_gpio_dbg_show(struct seq_file *s, -				      struct gpio_chip *chip) +static void crystalcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip);  	int gpio, offset; @@ -353,7 +357,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)  	cg->regmap = pmic->regmap;  	girq = &cg->chip.irq; -	girq->chip = &crystalcove_irqchip; +	gpio_irq_chip_set_chip(girq, &crystalcove_irqchip);  	/* This will let us handle the parent IRQ in the driver */  	girq->parent_handler = NULL;  	girq->num_parents = 0;  | 
