diff options
Diffstat (limited to 'drivers/gpio/gpio-uniphier.c')
| -rw-r--r-- | drivers/gpio/gpio-uniphier.c | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/drivers/gpio/gpio-uniphier.c b/drivers/gpio/gpio-uniphier.c index 0f662b297a95..0574dde5b5bb 100644 --- a/drivers/gpio/gpio-uniphier.c +++ b/drivers/gpio/gpio-uniphier.c @@ -9,15 +9,12 @@ #include <linux/irqdomain.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/spinlock.h> #include <dt-bindings/gpio/uniphier-gpio.h> -#define UNIPHIER_GPIO_BANK_MASK \ - GENMASK((UNIPHIER_GPIO_LINES_PER_BANK) - 1, 0) - #define UNIPHIER_GPIO_IRQ_MAX_NUM 24 #define UNIPHIER_GPIO_PORT_DATA 0x0 /* data */ @@ -33,7 +30,7 @@ struct uniphier_gpio_priv { struct irq_domain *domain; void __iomem *regs; spinlock_t lock; - u32 saved_vals[0]; + u32 saved_vals[]; }; static unsigned int uniphier_gpio_bank_to_reg(unsigned int bank) @@ -113,7 +110,10 @@ static int uniphier_gpio_offset_read(struct gpio_chip *chip, static int uniphier_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - return uniphier_gpio_offset_read(chip, offset, UNIPHIER_GPIO_PORT_DIR); + if (uniphier_gpio_offset_read(chip, offset, UNIPHIER_GPIO_PORT_DIR)) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; } static int uniphier_gpio_direction_input(struct gpio_chip *chip, @@ -138,28 +138,28 @@ static int uniphier_gpio_get(struct gpio_chip *chip, unsigned int offset) return uniphier_gpio_offset_read(chip, offset, UNIPHIER_GPIO_PORT_DATA); } -static void uniphier_gpio_set(struct gpio_chip *chip, - unsigned int offset, int val) +static int uniphier_gpio_set(struct gpio_chip *chip, + unsigned int offset, int val) { uniphier_gpio_offset_write(chip, offset, UNIPHIER_GPIO_PORT_DATA, val); + + return 0; } -static void uniphier_gpio_set_multiple(struct gpio_chip *chip, - unsigned long *mask, unsigned long *bits) +static int uniphier_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) { - unsigned int bank, shift, bank_mask, bank_bits; - int i; + unsigned long i, bank, bank_mask, bank_bits; - for (i = 0; i < chip->ngpio; i += UNIPHIER_GPIO_LINES_PER_BANK) { + for_each_set_clump8(i, bank_mask, mask, chip->ngpio) { bank = i / UNIPHIER_GPIO_LINES_PER_BANK; - shift = i % BITS_PER_LONG; - bank_mask = (mask[BIT_WORD(i)] >> shift) & - UNIPHIER_GPIO_BANK_MASK; - bank_bits = bits[BIT_WORD(i)] >> shift; + bank_bits = bitmap_get_value8(bits, i); uniphier_gpio_bank_write(chip, bank, UNIPHIER_GPIO_PORT_DATA, bank_mask, bank_bits); } + + return 0; } static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) @@ -169,7 +169,7 @@ static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) if (offset < UNIPHIER_GPIO_IRQ_OFFSET) return -ENXIO; - fwspec.fwnode = of_node_to_fwnode(chip->parent->of_node); + fwspec.fwnode = dev_fwnode(chip->parent); fwspec.param_count = 2; fwspec.param[0] = offset - UNIPHIER_GPIO_IRQ_OFFSET; /* @@ -183,28 +183,28 @@ static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) static void uniphier_gpio_irq_mask(struct irq_data *data) { - struct uniphier_gpio_priv *priv = data->chip_data; - u32 mask = BIT(data->hwirq); + struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); + u32 mask = BIT(irqd_to_hwirq(data)); uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, 0); - return irq_chip_mask_parent(data); + irq_chip_mask_parent(data); } static void uniphier_gpio_irq_unmask(struct irq_data *data) { - struct uniphier_gpio_priv *priv = data->chip_data; - u32 mask = BIT(data->hwirq); + struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); + u32 mask = BIT(irqd_to_hwirq(data)); uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, mask); - return irq_chip_unmask_parent(data); + irq_chip_unmask_parent(data); } static int uniphier_gpio_irq_set_type(struct irq_data *data, unsigned int type) { - struct uniphier_gpio_priv *priv = data->chip_data; - u32 mask = BIT(data->hwirq); + struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); + u32 mask = BIT(irqd_to_hwirq(data)); u32 val = 0; if (type == IRQ_TYPE_EDGE_BOTH) { @@ -301,7 +301,8 @@ static int uniphier_gpio_irq_domain_activate(struct irq_domain *domain, struct uniphier_gpio_priv *priv = domain->host_data; struct gpio_chip *chip = &priv->chip; - return gpiochip_lock_as_irq(chip, data->hwirq + UNIPHIER_GPIO_IRQ_OFFSET); + return gpiochip_lock_as_irq(chip, + irqd_to_hwirq(data) + UNIPHIER_GPIO_IRQ_OFFSET); } static void uniphier_gpio_irq_domain_deactivate(struct irq_domain *domain, @@ -310,7 +311,8 @@ static void uniphier_gpio_irq_domain_deactivate(struct irq_domain *domain, struct uniphier_gpio_priv *priv = domain->host_data; struct gpio_chip *chip = &priv->chip; - gpiochip_unlock_as_irq(chip, data->hwirq + UNIPHIER_GPIO_IRQ_OFFSET); + gpiochip_unlock_as_irq(chip, + irqd_to_hwirq(data) + UNIPHIER_GPIO_IRQ_OFFSET); } static const struct irq_domain_ops uniphier_gpio_irq_domain_ops = { @@ -346,7 +348,6 @@ static int uniphier_gpio_probe(struct platform_device *pdev) struct uniphier_gpio_priv *priv; struct gpio_chip *chip; struct irq_chip *irq_chip; - struct resource *regs; unsigned int nregs; u32 ngpios; int ret; @@ -370,8 +371,7 @@ static int uniphier_gpio_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->regs = devm_ioremap_resource(dev, regs); + priv->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->regs)) return PTR_ERR(priv->regs); @@ -409,7 +409,7 @@ static int uniphier_gpio_probe(struct platform_device *pdev) priv->domain = irq_domain_create_hierarchy( parent_domain, 0, UNIPHIER_GPIO_IRQ_MAX_NUM, - of_node_to_fwnode(dev->of_node), + dev_fwnode(dev), &uniphier_gpio_irq_domain_ops, priv); if (!priv->domain) return -ENOMEM; @@ -419,16 +419,14 @@ static int uniphier_gpio_probe(struct platform_device *pdev) return 0; } -static int uniphier_gpio_remove(struct platform_device *pdev) +static void uniphier_gpio_remove(struct platform_device *pdev) { struct uniphier_gpio_priv *priv = platform_get_drvdata(pdev); irq_domain_remove(priv->domain); - - return 0; } -static int __maybe_unused uniphier_gpio_suspend(struct device *dev) +static int uniphier_gpio_suspend(struct device *dev) { struct uniphier_gpio_priv *priv = dev_get_drvdata(dev); unsigned int nbanks = uniphier_gpio_get_nbanks(priv->chip.ngpio); @@ -450,7 +448,7 @@ static int __maybe_unused uniphier_gpio_suspend(struct device *dev) return 0; } -static int __maybe_unused uniphier_gpio_resume(struct device *dev) +static int uniphier_gpio_resume(struct device *dev) { struct uniphier_gpio_priv *priv = dev_get_drvdata(dev); unsigned int nbanks = uniphier_gpio_get_nbanks(priv->chip.ngpio); @@ -475,8 +473,7 @@ static int __maybe_unused uniphier_gpio_resume(struct device *dev) } static const struct dev_pm_ops uniphier_gpio_pm_ops = { - SET_LATE_SYSTEM_SLEEP_PM_OPS(uniphier_gpio_suspend, - uniphier_gpio_resume) + LATE_SYSTEM_SLEEP_PM_OPS(uniphier_gpio_suspend, uniphier_gpio_resume) }; static const struct of_device_id uniphier_gpio_match[] = { @@ -491,7 +488,7 @@ static struct platform_driver uniphier_gpio_driver = { .driver = { .name = "uniphier-gpio", .of_match_table = uniphier_gpio_match, - .pm = &uniphier_gpio_pm_ops, + .pm = pm_sleep_ptr(&uniphier_gpio_pm_ops), }, }; module_platform_driver(uniphier_gpio_driver); |
