diff options
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
| -rw-r--r-- | drivers/gpio/gpio-rcar.c | 85 | 
1 files changed, 26 insertions, 59 deletions
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index d9ab0cd1d205..681c93fb9e70 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -196,44 +196,6 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)  	return 0;  } -static void gpio_rcar_irq_bus_lock(struct irq_data *d) -{ -	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -	struct gpio_rcar_priv *p = gpiochip_get_data(gc); - -	pm_runtime_get_sync(&p->pdev->dev); -} - -static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d) -{ -	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -	struct gpio_rcar_priv *p = gpiochip_get_data(gc); - -	pm_runtime_put(&p->pdev->dev); -} - - -static int gpio_rcar_irq_request_resources(struct irq_data *d) -{ -	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -	struct gpio_rcar_priv *p = gpiochip_get_data(gc); -	int error; - -	error = pm_runtime_get_sync(&p->pdev->dev); -	if (error < 0) -		return error; - -	return 0; -} - -static void gpio_rcar_irq_release_resources(struct irq_data *d) -{ -	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -	struct gpio_rcar_priv *p = gpiochip_get_data(gc); - -	pm_runtime_put(&p->pdev->dev); -} -  static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)  {  	struct gpio_rcar_priv *p = dev_id; @@ -280,32 +242,18 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,  static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset)  { -	struct gpio_rcar_priv *p = gpiochip_get_data(chip); -	int error; - -	error = pm_runtime_get_sync(&p->pdev->dev); -	if (error < 0) -		return error; - -	error = pinctrl_request_gpio(chip->base + offset); -	if (error) -		pm_runtime_put(&p->pdev->dev); - -	return error; +	return pinctrl_request_gpio(chip->base + offset);  }  static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset)  { -	struct gpio_rcar_priv *p = gpiochip_get_data(chip); -  	pinctrl_free_gpio(chip->base + offset); -	/* Set the GPIO as an input to ensure that the next GPIO request won't +	/* +	 * Set the GPIO as an input to ensure that the next GPIO request won't  	 * drive the GPIO pin as an output.  	 */  	gpio_rcar_config_general_input_output_mode(chip, offset, false); - -	pm_runtime_put(&p->pdev->dev);  }  static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset) @@ -336,6 +284,25 @@ static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value)  	spin_unlock_irqrestore(&p->lock, flags);  } +static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask, +				   unsigned long *bits) +{ +	struct gpio_rcar_priv *p = gpiochip_get_data(chip); +	unsigned long flags; +	u32 val, bankmask; + +	bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0); +	if (!bankmask) +		return; + +	spin_lock_irqsave(&p->lock, flags); +	val = gpio_rcar_read(p, OUTDT); +	val &= ~bankmask; +	val |= (bankmask & bits[0]); +	gpio_rcar_write(p, OUTDT, val); +	spin_unlock_irqrestore(&p->lock, flags); +} +  static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,  				      int value)  { @@ -452,6 +419,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)  	}  	pm_runtime_enable(dev); +	pm_runtime_get_sync(dev);  	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -476,6 +444,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)  	gpio_chip->get = gpio_rcar_get;  	gpio_chip->direction_output = gpio_rcar_direction_output;  	gpio_chip->set = gpio_rcar_set; +	gpio_chip->set_multiple = gpio_rcar_set_multiple;  	gpio_chip->label = name;  	gpio_chip->parent = dev;  	gpio_chip->owner = THIS_MODULE; @@ -488,10 +457,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)  	irq_chip->irq_unmask = gpio_rcar_irq_enable;  	irq_chip->irq_set_type = gpio_rcar_irq_set_type;  	irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; -	irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock; -	irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock; -	irq_chip->irq_request_resources = gpio_rcar_irq_request_resources; -	irq_chip->irq_release_resources = gpio_rcar_irq_release_resources;  	irq_chip->flags	= IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;  	ret = gpiochip_add_data(gpio_chip, p); @@ -522,6 +487,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)  err1:  	gpiochip_remove(gpio_chip);  err0: +	pm_runtime_put(dev);  	pm_runtime_disable(dev);  	return ret;  } @@ -532,6 +498,7 @@ static int gpio_rcar_remove(struct platform_device *pdev)  	gpiochip_remove(&p->gpio_chip); +	pm_runtime_put(&pdev->dev);  	pm_runtime_disable(&pdev->dev);  	return 0;  }  | 
