diff options
Diffstat (limited to 'drivers/gpio/gpio-cadence.c')
| -rw-r--r-- | drivers/gpio/gpio-cadence.c | 59 | 
1 files changed, 27 insertions, 32 deletions
diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c index e9dd2564c54f..c647953521c7 100644 --- a/drivers/gpio/gpio-cadence.c +++ b/drivers/gpio/gpio-cadence.c @@ -8,9 +8,11 @@   *  Boris Brezillon <boris.brezillon@free-electrons.com>   */ -#include <linux/gpio/driver.h> +#include <linux/cleanup.h>  #include <linux/clk.h> +#include <linux/gpio/driver.h>  #include <linux/interrupt.h> +#include <linux/gpio/generic.h>  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/platform_device.h> @@ -30,7 +32,7 @@  #define CDNS_GPIO_IRQ_ANY_EDGE		0x2c  struct cdns_gpio_chip { -	struct gpio_chip gc; +	struct gpio_generic_chip gen_gc;  	void __iomem *regs;  	u32 bypass_orig;  }; @@ -38,29 +40,24 @@ struct cdns_gpio_chip {  static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)  {  	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip); -	unsigned long flags; -	raw_spin_lock_irqsave(&chip->bgpio_lock, flags); +	guard(gpio_generic_lock)(&cgpio->gen_gc);  	iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),  		  cgpio->regs + CDNS_GPIO_BYPASS_MODE); -	raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);  	return 0;  }  static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)  {  	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip); -	unsigned long flags; -	raw_spin_lock_irqsave(&chip->bgpio_lock, flags); +	guard(gpio_generic_lock)(&cgpio->gen_gc);  	iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |  		  (BIT(offset) & cgpio->bypass_orig),  		  cgpio->regs + CDNS_GPIO_BYPASS_MODE); - -	raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);  }  static void cdns_gpio_irq_mask(struct irq_data *d) @@ -85,13 +82,12 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)  {  	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);  	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip); -	unsigned long flags;  	u32 int_value;  	u32 int_type;  	u32 mask = BIT(d->hwirq);  	int ret = 0; -	raw_spin_lock_irqsave(&chip->bgpio_lock, flags); +	guard(gpio_generic_lock)(&cgpio->gen_gc);  	int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;  	int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask; @@ -108,15 +104,12 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)  	} else if (type == IRQ_TYPE_LEVEL_LOW) {  		int_type |= mask;  	} else { -		ret = -EINVAL; -		goto err_irq_type; +		return -EINVAL;  	}  	iowrite32(int_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE);  	iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE); -err_irq_type: -	raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);  	return ret;  } @@ -150,6 +143,7 @@ static const struct irq_chip cdns_gpio_irqchip = {  static int cdns_gpio_probe(struct platform_device *pdev)  { +	struct gpio_generic_chip_config config = { };  	struct cdns_gpio_chip *cgpio;  	int ret, irq;  	u32 dir_prev; @@ -176,32 +170,33 @@ static int cdns_gpio_probe(struct platform_device *pdev)  	 * gpiochip_lock_as_irq:  	 * tried to flag a GPIO set as output for IRQ  	 * Generic GPIO driver stores the direction value internally, -	 * so it needs to be changed before bgpio_init() is called. +	 * so it needs to be changed before gpio_generic_chip_init() is called.  	 */  	dir_prev = ioread32(cgpio->regs + CDNS_GPIO_DIRECTION_MODE);  	iowrite32(GENMASK(num_gpios - 1, 0),  		  cgpio->regs + CDNS_GPIO_DIRECTION_MODE); -	ret = bgpio_init(&cgpio->gc, &pdev->dev, 4, -			 cgpio->regs + CDNS_GPIO_INPUT_VALUE, -			 cgpio->regs + CDNS_GPIO_OUTPUT_VALUE, -			 NULL, -			 NULL, -			 cgpio->regs + CDNS_GPIO_DIRECTION_MODE, -			 BGPIOF_READ_OUTPUT_REG_SET); +	config.dev = &pdev->dev; +	config.sz = 4; +	config.dat = cgpio->regs + CDNS_GPIO_INPUT_VALUE; +	config.set = cgpio->regs + CDNS_GPIO_OUTPUT_VALUE; +	config.dirin = cgpio->regs + CDNS_GPIO_DIRECTION_MODE; +	config.flags = BGPIOF_READ_OUTPUT_REG_SET; + +	ret = gpio_generic_chip_init(&cgpio->gen_gc, &config);  	if (ret) {  		dev_err(&pdev->dev, "Failed to register generic gpio, %d\n",  			ret);  		goto err_revert_dir;  	} -	cgpio->gc.label = dev_name(&pdev->dev); -	cgpio->gc.ngpio = num_gpios; -	cgpio->gc.parent = &pdev->dev; -	cgpio->gc.base = -1; -	cgpio->gc.owner = THIS_MODULE; -	cgpio->gc.request = cdns_gpio_request; -	cgpio->gc.free = cdns_gpio_free; +	cgpio->gen_gc.gc.label = dev_name(&pdev->dev); +	cgpio->gen_gc.gc.ngpio = num_gpios; +	cgpio->gen_gc.gc.parent = &pdev->dev; +	cgpio->gen_gc.gc.base = -1; +	cgpio->gen_gc.gc.owner = THIS_MODULE; +	cgpio->gen_gc.gc.request = cdns_gpio_request; +	cgpio->gen_gc.gc.free = cdns_gpio_free;  	clk = devm_clk_get_enabled(&pdev->dev, NULL);  	if (IS_ERR(clk)) { @@ -218,7 +213,7 @@ static int cdns_gpio_probe(struct platform_device *pdev)  	if (irq >= 0) {  		struct gpio_irq_chip *girq; -		girq = &cgpio->gc.irq; +		girq = &cgpio->gen_gc.gc.irq;  		gpio_irq_chip_set_chip(girq, &cdns_gpio_irqchip);  		girq->parent_handler = cdns_gpio_irq_handler;  		girq->num_parents = 1; @@ -234,7 +229,7 @@ static int cdns_gpio_probe(struct platform_device *pdev)  		girq->handler = handle_level_irq;  	} -	ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio); +	ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gen_gc.gc, cgpio);  	if (ret < 0) {  		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);  		goto err_revert_dir;  | 
