diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2018-03-27 09:34:40 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2018-03-27 09:34:40 -0400 |
commit | 89b0b4e2d3686dfc499c018922028791b954d7d9 (patch) | |
tree | b6a5fd2a8e8957ab05071d88b8816de196d8f1b1 | |
parent | 6cb9215baeb9c1ed336a5e8905f7ad7c4698acc9 (diff) | |
parent | 691bf5d5a7bfedc60b7218f4d9b915bf356df767 (diff) |
Merge branch 'gpio-reserved-ranges' into devel
-rw-r--r-- | Documentation/devicetree/bindings/gpio/gpio.txt | 7 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-of.c | 24 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 66 | ||||
-rw-r--r-- | drivers/pinctrl/qcom/pinctrl-msm.c | 65 | ||||
-rw-r--r-- | include/linux/gpio/driver.h | 16 |
5 files changed, 167 insertions, 11 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index b5de08e3b1a2..a7c31de29362 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt | |||
@@ -151,9 +151,9 @@ in a lot of designs, some using all 32 bits, some using 18 and some using | |||
151 | first 18 GPIOs, at local offset 0 .. 17, are in use. | 151 | first 18 GPIOs, at local offset 0 .. 17, are in use. |
152 | 152 | ||
153 | If these GPIOs do not happen to be the first N GPIOs at offset 0...N-1, an | 153 | If these GPIOs do not happen to be the first N GPIOs at offset 0...N-1, an |
154 | additional bitmask is needed to specify which GPIOs are actually in use, | 154 | additional set of tuples is needed to specify which GPIOs are unusable, with |
155 | and which are dummies. The bindings for this case has not yet been | 155 | the gpio-reserved-ranges binding. This property indicates the start and size |
156 | specified, but should be specified if/when such hardware appears. | 156 | of the GPIOs that can't be used. |
157 | 157 | ||
158 | Optionally, a GPIO controller may have a "gpio-line-names" property. This is | 158 | Optionally, a GPIO controller may have a "gpio-line-names" property. This is |
159 | an array of strings defining the names of the GPIO lines going out of the | 159 | an array of strings defining the names of the GPIO lines going out of the |
@@ -178,6 +178,7 @@ gpio-controller@00000000 { | |||
178 | gpio-controller; | 178 | gpio-controller; |
179 | #gpio-cells = <2>; | 179 | #gpio-cells = <2>; |
180 | ngpios = <18>; | 180 | ngpios = <18>; |
181 | gpio-reserved-ranges = <0 4>, <12 2>; | ||
181 | gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R", | 182 | gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R", |
182 | "LED G", "LED B", "Col A", "Col B", "Col C", "Col D", | 183 | "LED G", "LED B", "Col A", "Col B", "Col C", "Col D", |
183 | "Row A", "Row B", "Row C", "Row D", "NMI button", | 184 | "Row A", "Row B", "Row C", "Row D", "NMI button", |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 84e5a9df2344..ed81d9a6316f 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -511,6 +511,28 @@ void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc) | |||
511 | } | 511 | } |
512 | EXPORT_SYMBOL(of_mm_gpiochip_remove); | 512 | EXPORT_SYMBOL(of_mm_gpiochip_remove); |
513 | 513 | ||
514 | static void of_gpiochip_init_valid_mask(struct gpio_chip *chip) | ||
515 | { | ||
516 | int len, i; | ||
517 | u32 start, count; | ||
518 | struct device_node *np = chip->of_node; | ||
519 | |||
520 | len = of_property_count_u32_elems(np, "gpio-reserved-ranges"); | ||
521 | if (len < 0 || len % 2 != 0) | ||
522 | return; | ||
523 | |||
524 | for (i = 0; i < len; i += 2) { | ||
525 | of_property_read_u32_index(np, "gpio-reserved-ranges", | ||
526 | i, &start); | ||
527 | of_property_read_u32_index(np, "gpio-reserved-ranges", | ||
528 | i + 1, &count); | ||
529 | if (start >= chip->ngpio || start + count >= chip->ngpio) | ||
530 | continue; | ||
531 | |||
532 | bitmap_clear(chip->valid_mask, start, count); | ||
533 | } | ||
534 | }; | ||
535 | |||
514 | #ifdef CONFIG_PINCTRL | 536 | #ifdef CONFIG_PINCTRL |
515 | static int of_gpiochip_add_pin_range(struct gpio_chip *chip) | 537 | static int of_gpiochip_add_pin_range(struct gpio_chip *chip) |
516 | { | 538 | { |
@@ -615,6 +637,8 @@ int of_gpiochip_add(struct gpio_chip *chip) | |||
615 | if (chip->of_gpio_n_cells > MAX_PHANDLE_ARGS) | 637 | if (chip->of_gpio_n_cells > MAX_PHANDLE_ARGS) |
616 | return -EINVAL; | 638 | return -EINVAL; |
617 | 639 | ||
640 | of_gpiochip_init_valid_mask(chip); | ||
641 | |||
618 | status = of_gpiochip_add_pin_range(chip); | 642 | status = of_gpiochip_add_pin_range(chip); |
619 | if (status) | 643 | if (status) |
620 | return status; | 644 | return status; |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f220d844b607..43aeb07343ec 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -337,6 +337,57 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) | |||
337 | return 0; | 337 | return 0; |
338 | } | 338 | } |
339 | 339 | ||
340 | static unsigned long *gpiochip_allocate_mask(struct gpio_chip *chip) | ||
341 | { | ||
342 | unsigned long *p; | ||
343 | |||
344 | p = kmalloc_array(BITS_TO_LONGS(chip->ngpio), sizeof(*p), GFP_KERNEL); | ||
345 | if (!p) | ||
346 | return NULL; | ||
347 | |||
348 | /* Assume by default all GPIOs are valid */ | ||
349 | bitmap_fill(p, chip->ngpio); | ||
350 | |||
351 | return p; | ||
352 | } | ||
353 | |||
354 | static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip) | ||
355 | { | ||
356 | #ifdef CONFIG_OF_GPIO | ||
357 | int size; | ||
358 | struct device_node *np = gpiochip->of_node; | ||
359 | |||
360 | size = of_property_count_u32_elems(np, "gpio-reserved-ranges"); | ||
361 | if (size > 0 && size % 2 == 0) | ||
362 | gpiochip->need_valid_mask = true; | ||
363 | #endif | ||
364 | |||
365 | if (!gpiochip->need_valid_mask) | ||
366 | return 0; | ||
367 | |||
368 | gpiochip->valid_mask = gpiochip_allocate_mask(gpiochip); | ||
369 | if (!gpiochip->valid_mask) | ||
370 | return -ENOMEM; | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static void gpiochip_free_valid_mask(struct gpio_chip *gpiochip) | ||
376 | { | ||
377 | kfree(gpiochip->valid_mask); | ||
378 | gpiochip->valid_mask = NULL; | ||
379 | } | ||
380 | |||
381 | bool gpiochip_line_is_valid(const struct gpio_chip *gpiochip, | ||
382 | unsigned int offset) | ||
383 | { | ||
384 | /* No mask means all valid */ | ||
385 | if (likely(!gpiochip->valid_mask)) | ||
386 | return true; | ||
387 | return test_bit(offset, gpiochip->valid_mask); | ||
388 | } | ||
389 | EXPORT_SYMBOL_GPL(gpiochip_line_is_valid); | ||
390 | |||
340 | /* | 391 | /* |
341 | * GPIO line handle management | 392 | * GPIO line handle management |
342 | */ | 393 | */ |
@@ -1261,6 +1312,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, | |||
1261 | if (status) | 1312 | if (status) |
1262 | goto err_remove_from_list; | 1313 | goto err_remove_from_list; |
1263 | 1314 | ||
1315 | status = gpiochip_init_valid_mask(chip); | ||
1316 | if (status) | ||
1317 | goto err_remove_irqchip_mask; | ||
1318 | |||
1264 | status = gpiochip_add_irqchip(chip, lock_key, request_key); | 1319 | status = gpiochip_add_irqchip(chip, lock_key, request_key); |
1265 | if (status) | 1320 | if (status) |
1266 | goto err_remove_chip; | 1321 | goto err_remove_chip; |
@@ -1290,6 +1345,8 @@ err_remove_chip: | |||
1290 | acpi_gpiochip_remove(chip); | 1345 | acpi_gpiochip_remove(chip); |
1291 | gpiochip_free_hogs(chip); | 1346 | gpiochip_free_hogs(chip); |
1292 | of_gpiochip_remove(chip); | 1347 | of_gpiochip_remove(chip); |
1348 | gpiochip_free_valid_mask(chip); | ||
1349 | err_remove_irqchip_mask: | ||
1293 | gpiochip_irqchip_free_valid_mask(chip); | 1350 | gpiochip_irqchip_free_valid_mask(chip); |
1294 | err_remove_from_list: | 1351 | err_remove_from_list: |
1295 | spin_lock_irqsave(&gpio_lock, flags); | 1352 | spin_lock_irqsave(&gpio_lock, flags); |
@@ -1346,6 +1403,7 @@ void gpiochip_remove(struct gpio_chip *chip) | |||
1346 | acpi_gpiochip_remove(chip); | 1403 | acpi_gpiochip_remove(chip); |
1347 | gpiochip_remove_pin_ranges(chip); | 1404 | gpiochip_remove_pin_ranges(chip); |
1348 | of_gpiochip_remove(chip); | 1405 | of_gpiochip_remove(chip); |
1406 | gpiochip_free_valid_mask(chip); | ||
1349 | /* | 1407 | /* |
1350 | * We accept no more calls into the driver from this point, so | 1408 | * We accept no more calls into the driver from this point, so |
1351 | * NULL the driver data pointer | 1409 | * NULL the driver data pointer |
@@ -1506,14 +1564,10 @@ static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) | |||
1506 | if (!gpiochip->irq.need_valid_mask) | 1564 | if (!gpiochip->irq.need_valid_mask) |
1507 | return 0; | 1565 | return 0; |
1508 | 1566 | ||
1509 | gpiochip->irq.valid_mask = kcalloc(BITS_TO_LONGS(gpiochip->ngpio), | 1567 | gpiochip->irq.valid_mask = gpiochip_allocate_mask(gpiochip); |
1510 | sizeof(long), GFP_KERNEL); | ||
1511 | if (!gpiochip->irq.valid_mask) | 1568 | if (!gpiochip->irq.valid_mask) |
1512 | return -ENOMEM; | 1569 | return -ENOMEM; |
1513 | 1570 | ||
1514 | /* Assume by default all GPIOs are valid */ | ||
1515 | bitmap_fill(gpiochip->irq.valid_mask, gpiochip->ngpio); | ||
1516 | |||
1517 | return 0; | 1571 | return 0; |
1518 | } | 1572 | } |
1519 | 1573 | ||
@@ -1526,6 +1580,8 @@ static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip) | |||
1526 | bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip, | 1580 | bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip, |
1527 | unsigned int offset) | 1581 | unsigned int offset) |
1528 | { | 1582 | { |
1583 | if (!gpiochip_line_is_valid(gpiochip, offset)) | ||
1584 | return false; | ||
1529 | /* No mask means all valid */ | 1585 | /* No mask means all valid */ |
1530 | if (likely(!gpiochip->irq.valid_mask)) | 1586 | if (likely(!gpiochip->irq.valid_mask)) |
1531 | return true; | 1587 | return true; |
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 495432f3341b..e7abc8ba222b 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -105,6 +105,14 @@ static const struct pinctrl_ops msm_pinctrl_ops = { | |||
105 | .dt_free_map = pinctrl_utils_free_map, | 105 | .dt_free_map = pinctrl_utils_free_map, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static int msm_pinmux_request(struct pinctrl_dev *pctldev, unsigned offset) | ||
109 | { | ||
110 | struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | ||
111 | struct gpio_chip *chip = &pctrl->chip; | ||
112 | |||
113 | return gpiochip_line_is_valid(chip, offset) ? 0 : -EINVAL; | ||
114 | } | ||
115 | |||
108 | static int msm_get_functions_count(struct pinctrl_dev *pctldev) | 116 | static int msm_get_functions_count(struct pinctrl_dev *pctldev) |
109 | { | 117 | { |
110 | struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); | 118 | struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
@@ -166,6 +174,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, | |||
166 | } | 174 | } |
167 | 175 | ||
168 | static const struct pinmux_ops msm_pinmux_ops = { | 176 | static const struct pinmux_ops msm_pinmux_ops = { |
177 | .request = msm_pinmux_request, | ||
169 | .get_functions_count = msm_get_functions_count, | 178 | .get_functions_count = msm_get_functions_count, |
170 | .get_function_name = msm_get_function_name, | 179 | .get_function_name = msm_get_function_name, |
171 | .get_function_groups = msm_get_function_groups, | 180 | .get_function_groups = msm_get_function_groups, |
@@ -506,6 +515,9 @@ static void msm_gpio_dbg_show_one(struct seq_file *s, | |||
506 | "pull up" | 515 | "pull up" |
507 | }; | 516 | }; |
508 | 517 | ||
518 | if (!gpiochip_line_is_valid(chip, offset)) | ||
519 | return; | ||
520 | |||
509 | g = &pctrl->soc->groups[offset]; | 521 | g = &pctrl->soc->groups[offset]; |
510 | ctl_reg = readl(pctrl->regs + g->ctl_reg); | 522 | ctl_reg = readl(pctrl->regs + g->ctl_reg); |
511 | 523 | ||
@@ -517,6 +529,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s, | |||
517 | seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func); | 529 | seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func); |
518 | seq_printf(s, " %dmA", msm_regval_to_drive(drive)); | 530 | seq_printf(s, " %dmA", msm_regval_to_drive(drive)); |
519 | seq_printf(s, " %s", pulls[pull]); | 531 | seq_printf(s, " %s", pulls[pull]); |
532 | seq_puts(s, "\n"); | ||
520 | } | 533 | } |
521 | 534 | ||
522 | static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 535 | static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
@@ -524,10 +537,8 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
524 | unsigned gpio = chip->base; | 537 | unsigned gpio = chip->base; |
525 | unsigned i; | 538 | unsigned i; |
526 | 539 | ||
527 | for (i = 0; i < chip->ngpio; i++, gpio++) { | 540 | for (i = 0; i < chip->ngpio; i++, gpio++) |
528 | msm_gpio_dbg_show_one(s, NULL, chip, i, gpio); | 541 | msm_gpio_dbg_show_one(s, NULL, chip, i, gpio); |
529 | seq_puts(s, "\n"); | ||
530 | } | ||
531 | } | 542 | } |
532 | 543 | ||
533 | #else | 544 | #else |
@@ -808,6 +819,46 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) | |||
808 | chained_irq_exit(chip, desc); | 819 | chained_irq_exit(chip, desc); |
809 | } | 820 | } |
810 | 821 | ||
822 | static int msm_gpio_init_valid_mask(struct gpio_chip *chip, | ||
823 | struct msm_pinctrl *pctrl) | ||
824 | { | ||
825 | int ret; | ||
826 | unsigned int len, i; | ||
827 | unsigned int max_gpios = pctrl->soc->ngpios; | ||
828 | u16 *tmp; | ||
829 | |||
830 | /* The number of GPIOs in the ACPI tables */ | ||
831 | len = ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0); | ||
832 | if (ret < 0) | ||
833 | return 0; | ||
834 | |||
835 | if (ret > max_gpios) | ||
836 | return -EINVAL; | ||
837 | |||
838 | tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL); | ||
839 | if (!tmp) | ||
840 | return -ENOMEM; | ||
841 | |||
842 | ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp, len); | ||
843 | if (ret < 0) { | ||
844 | dev_err(pctrl->dev, "could not read list of GPIOs\n"); | ||
845 | goto out; | ||
846 | } | ||
847 | |||
848 | bitmap_zero(chip->valid_mask, max_gpios); | ||
849 | for (i = 0; i < len; i++) | ||
850 | set_bit(tmp[i], chip->valid_mask); | ||
851 | |||
852 | out: | ||
853 | kfree(tmp); | ||
854 | return ret; | ||
855 | } | ||
856 | |||
857 | static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl) | ||
858 | { | ||
859 | return device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0) > 0; | ||
860 | } | ||
861 | |||
811 | static int msm_gpio_init(struct msm_pinctrl *pctrl) | 862 | static int msm_gpio_init(struct msm_pinctrl *pctrl) |
812 | { | 863 | { |
813 | struct gpio_chip *chip; | 864 | struct gpio_chip *chip; |
@@ -824,6 +875,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) | |||
824 | chip->parent = pctrl->dev; | 875 | chip->parent = pctrl->dev; |
825 | chip->owner = THIS_MODULE; | 876 | chip->owner = THIS_MODULE; |
826 | chip->of_node = pctrl->dev->of_node; | 877 | chip->of_node = pctrl->dev->of_node; |
878 | chip->need_valid_mask = msm_gpio_needs_valid_mask(pctrl); | ||
827 | 879 | ||
828 | ret = gpiochip_add_data(&pctrl->chip, pctrl); | 880 | ret = gpiochip_add_data(&pctrl->chip, pctrl); |
829 | if (ret) { | 881 | if (ret) { |
@@ -831,6 +883,13 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) | |||
831 | return ret; | 883 | return ret; |
832 | } | 884 | } |
833 | 885 | ||
886 | ret = msm_gpio_init_valid_mask(chip, pctrl); | ||
887 | if (ret) { | ||
888 | dev_err(pctrl->dev, "Failed to setup irq valid bits\n"); | ||
889 | gpiochip_remove(&pctrl->chip); | ||
890 | return ret; | ||
891 | } | ||
892 | |||
834 | ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio); | 893 | ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio); |
835 | if (ret) { | 894 | if (ret) { |
836 | dev_err(pctrl->dev, "Failed to add pin range\n"); | 895 | dev_err(pctrl->dev, "Failed to add pin range\n"); |
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 1ba9a331ec51..5382b5183b7e 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h | |||
@@ -288,6 +288,21 @@ struct gpio_chip { | |||
288 | struct gpio_irq_chip irq; | 288 | struct gpio_irq_chip irq; |
289 | #endif | 289 | #endif |
290 | 290 | ||
291 | /** | ||
292 | * @need_valid_mask: | ||
293 | * | ||
294 | * If set core allocates @valid_mask with all bits set to one. | ||
295 | */ | ||
296 | bool need_valid_mask; | ||
297 | |||
298 | /** | ||
299 | * @valid_mask: | ||
300 | * | ||
301 | * If not %NULL holds bitmask of GPIOs which are valid to be used | ||
302 | * from the chip. | ||
303 | */ | ||
304 | unsigned long *valid_mask; | ||
305 | |||
291 | #if defined(CONFIG_OF_GPIO) | 306 | #if defined(CONFIG_OF_GPIO) |
292 | /* | 307 | /* |
293 | * If CONFIG_OF is enabled, then all GPIO controllers described in the | 308 | * If CONFIG_OF is enabled, then all GPIO controllers described in the |
@@ -384,6 +399,7 @@ bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset); | |||
384 | 399 | ||
385 | /* Sleep persistence inquiry for drivers */ | 400 | /* Sleep persistence inquiry for drivers */ |
386 | bool gpiochip_line_is_persistent(struct gpio_chip *chip, unsigned int offset); | 401 | bool gpiochip_line_is_persistent(struct gpio_chip *chip, unsigned int offset); |
402 | bool gpiochip_line_is_valid(const struct gpio_chip *chip, unsigned int offset); | ||
387 | 403 | ||
388 | /* get driver data */ | 404 | /* get driver data */ |
389 | void *gpiochip_get_data(struct gpio_chip *chip); | 405 | void *gpiochip_get_data(struct gpio_chip *chip); |