diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-apple-gpio.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-apple-gpio.c | 105 |
1 files changed, 47 insertions, 58 deletions
diff --git a/drivers/pinctrl/pinctrl-apple-gpio.c b/drivers/pinctrl/pinctrl-apple-gpio.c index a7861079a650..72f4dd2466e1 100644 --- a/drivers/pinctrl/pinctrl-apple-gpio.c +++ b/drivers/pinctrl/pinctrl-apple-gpio.c @@ -11,6 +11,7 @@ */ #include <dt-bindings/pinctrl/apple.h> +#include <linux/bits.h> #include <linux/gpio/driver.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -36,7 +37,7 @@ struct apple_gpio_pinctrl { struct pinctrl_desc pinctrl_desc; struct gpio_chip gpio_chip; struct irq_chip irq_chip; - u8 irqgrps[0]; + u8 irqgrps[]; }; #define REG_GPIO(x) (4 * (x)) @@ -70,31 +71,35 @@ struct regmap_config regmap_config = { .cache_type = REGCACHE_FLAT, .max_register = 512 * sizeof(u32), .num_reg_defaults_raw = 512, - .use_relaxed_mmio = true + .use_relaxed_mmio = true, }; -// No locking needed to mask/unmask IRQs as the interrupt mode is per pin-register. +/* No locking needed to mask/unmask IRQs as the interrupt mode is per pin-register. */ static void apple_gpio_set_reg(struct apple_gpio_pinctrl *pctl, - unsigned int pin, u32 mask, u32 value) + unsigned int pin, u32 mask, u32 value) { regmap_update_bits(pctl->map, REG_GPIO(pin), mask, value); } -static uint32_t apple_gpio_get_reg(struct apple_gpio_pinctrl *pctl, - unsigned int pin) +static u32 apple_gpio_get_reg(struct apple_gpio_pinctrl *pctl, + unsigned int pin) { - unsigned int val = 0; + int ret; + u32 val; + + ret = regmap_read(pctl->map, REG_GPIO(pin), &val); + if (ret) + return 0; - regmap_read(pctl->map, REG_GPIO(pin), &val); return val; } /* Pin controller functions */ static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *node, - struct pinctrl_map **map, - unsigned *num_maps) + struct device_node *node, + struct pinctrl_map **map, + unsigned *num_maps) { unsigned reserved_maps; struct apple_gpio_pinctrl *pctl; @@ -114,13 +119,12 @@ static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, dev_err(pctl->dev, "missing or empty pinmux property in node %pOFn.\n", node); - return ret; + return ret ? ret : -EINVAL; } num_pins = ret; - ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, num_maps, - num_pins); + ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, num_maps, num_pins); if (ret) return ret; @@ -138,11 +142,10 @@ static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, } group_name = pinctrl_generic_get_group_name(pctldev, pin); - function_name = - pinmux_generic_get_function_name(pctl->pctldev, func); + function_name = pinmux_generic_get_function_name(pctl->pctldev, func); ret = pinctrl_utils_add_map_mux(pctl->pctldev, map, - &reserved_maps, num_maps, - group_name, function_name); + &reserved_maps, num_maps, + group_name, function_name); if (ret) goto free_map; } @@ -165,7 +168,7 @@ static const struct pinctrl_ops apple_gpio_pinctrl_ops = { /* Pin multiplexer functions */ static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned func, - unsigned group) + unsigned group) { struct apple_gpio_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); @@ -186,14 +189,14 @@ static const struct pinmux_ops apple_gpio_pinmux_ops = { /* GPIO chip functions */ -static int apple_gpio_get_direction(struct gpio_chip *chip, - unsigned int offset) +static int apple_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip); unsigned int reg = apple_gpio_get_reg(pctl, offset); - return (FIELD_GET(REG_GPIOx_MODE, reg) == REG_GPIOx_OUT) ? - GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; + if (FIELD_GET(REG_GPIOx_MODE, reg) == REG_GPIOx_OUT) + return GPIO_LINE_DIRECTION_OUT; + return GPIO_LINE_DIRECTION_IN; } static int apple_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -211,17 +214,14 @@ static int apple_gpio_get(struct gpio_chip *chip, unsigned offset) return !!(reg & REG_GPIOx_DATA); } -static void apple_gpio_set(struct gpio_chip *chip, unsigned int offset, - int value) +static void apple_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip); - apple_gpio_set_reg(pctl, offset, REG_GPIOx_DATA, - value ? REG_GPIOx_DATA : 0); + apple_gpio_set_reg(pctl, offset, REG_GPIOx_DATA, value ? REG_GPIOx_DATA : 0); } -static int apple_gpio_direction_input(struct gpio_chip *chip, - unsigned int offset) +static int apple_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip); @@ -234,7 +234,7 @@ static int apple_gpio_direction_input(struct gpio_chip *chip, } static int apple_gpio_direction_output(struct gpio_chip *chip, - unsigned int offset, int value) + unsigned int offset, int value) { struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip); @@ -249,13 +249,10 @@ static int apple_gpio_direction_output(struct gpio_chip *chip, static void apple_gpio_irq_ack(struct irq_data *data) { - struct apple_gpio_pinctrl *pctl = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); - unsigned int irqgrp = - FIELD_GET(REG_GPIOx_GRP, apple_gpio_get_reg(pctl, data->hwirq)); + struct apple_gpio_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(data)); + unsigned int irqgrp = FIELD_GET(REG_GPIOx_GRP, apple_gpio_get_reg(pctl, data->hwirq)); - writel(BIT(data->hwirq & 31), - pctl->base + REG_IRQ(irqgrp, data->hwirq)); + writel(BIT(data->hwirq % 32), pctl->base + REG_IRQ(irqgrp, data->hwirq)); } static unsigned int apple_gpio_irq_type(unsigned int type) @@ -278,20 +275,19 @@ static unsigned int apple_gpio_irq_type(unsigned int type) static void apple_gpio_irq_mask(struct irq_data *data) { - struct apple_gpio_pinctrl *pctl = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct apple_gpio_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(data)); + apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, - FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_IN_IRQ_OFF)); + FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_IN_IRQ_OFF)); } static void apple_gpio_irq_unmask(struct irq_data *data) { - struct apple_gpio_pinctrl *pctl = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct apple_gpio_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(data)); unsigned int irqtype = apple_gpio_irq_type(irqd_get_trigger_type(data)); apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, - FIELD_PREP(REG_GPIOx_MODE, irqtype)); + FIELD_PREP(REG_GPIOx_MODE, irqtype)); } static unsigned int apple_gpio_irq_startup(struct irq_data *data) @@ -300,7 +296,7 @@ static unsigned int apple_gpio_irq_startup(struct irq_data *data) struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip); apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_GRP, - FIELD_PREP(REG_GPIOx_GRP, 0)); + FIELD_PREP(REG_GPIOx_GRP, 0)); apple_gpio_direction_input(chip, data->hwirq); apple_gpio_irq_unmask(data); @@ -308,18 +304,16 @@ static unsigned int apple_gpio_irq_startup(struct irq_data *data) return 0; } -static int apple_gpio_irq_set_type(struct irq_data *data, - unsigned int type) +static int apple_gpio_irq_set_type(struct irq_data *data, unsigned int type) { - struct apple_gpio_pinctrl *pctl = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct apple_gpio_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(data)); unsigned int irqtype = apple_gpio_irq_type(type); if (irqtype == REG_GPIOx_IN_IRQ_OFF) return -EINVAL; apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, - FIELD_PREP(REG_GPIOx_MODE, irqtype)); + FIELD_PREP(REG_GPIOx_MODE, irqtype)); if (type & IRQ_TYPE_LEVEL_MASK) irq_set_handler_locked(data, handle_level_irq); @@ -366,10 +360,6 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) void **irq_data = NULL; int ret; - if (!of_property_read_bool(pctl->dev->of_node, "gpio-controller")) - return dev_err_probe(pctl->dev, -ENODEV, - "No gpio-controller property\n"); - pctl->irq_chip = apple_gpio_irqchip; pctl->gpio_chip.label = dev_name(pctl->dev); @@ -383,7 +373,6 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) pctl->gpio_chip.base = -1; pctl->gpio_chip.ngpio = pctl->pinctrl_desc.npins; pctl->gpio_chip.parent = pctl->dev; - pctl->gpio_chip.of_node = pctl->dev->of_node; if (girq->num_parents) { int i; @@ -398,14 +387,13 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) GFP_KERNEL); if (!girq->parents || !irq_data) { ret = -ENOMEM; - goto out; + goto out_free_irq_data; } for (i = 0; i < girq->num_parents; i++) { - ret = platform_get_irq(to_platform_device(pctl->dev), - i); + ret = platform_get_irq(to_platform_device(pctl->dev), i); if (ret < 0) - goto out; + goto out_free_irq_data; girq->parents[i] = ret; pctl->irqgrps[i] = i; @@ -419,7 +407,8 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) } ret = devm_gpiochip_add_data(pctl->dev, &pctl->gpio_chip, pctl); -out: + +out_free_irq_data: kfree(girq->parents); kfree(irq_data); |