| @@ -19,6 +19,7 @@ · 18 unmodified lines |
| 19 | 19 | #include <linux/irq.h> |
| 20 | 20 | #include <linux/irq_sim.h> |
| 21 | 21 | #include <linux/list.h> |
| 22 | +#include <linux/minmax.h> |
| 22 | 23 | #include <linux/mod_devicetable.h> |
| 23 | 24 | #include <linux/module.h> |
| 24 | 25 | #include <linux/mutex.h> |
| @@ -685,52 +686,32 @@ gpio_sim_device_config_live_show(struct config_item *item, char *page) · 660 unmodified lines |
| 685 | 686 | return sprintf(page, "%c\n", live ? '1' : '0'); |
| 686 | 687 | } |
| 687 | 688 | |
| 688 | | −static char **gpio_sim_make_line_names(struct gpio_sim_bank *bank, |
| 689 | | − unsigned int *line_names_size) |
| 689 | +static unsigned int gpio_sim_get_line_names_size(struct gpio_sim_bank *bank) |
| 690 | 690 | { |
| 691 | | − unsigned int max_offset = 0; |
| 692 | | − bool has_line_names = false; |
| 693 | 691 | struct gpio_sim_line *line; |
| 694 | | − char **line_names; |
| 692 | + unsigned int size = 0; |
| 695 | 693 | |
| 696 | 694 | list_for_each_entry(line, &bank->line_list, siblings) { |
| 697 | | − if (line->offset >= bank->num_lines) |
| 695 | + if (!line->name || (line->offset >= bank->num_lines)) |
| 698 | 696 | continue; |
| 699 | 697 | |
| 700 | | − if (line->name) { |
| 701 | | − if (line->offset > max_offset) |
| 702 | | − max_offset = line->offset; |
| 703 | | − |
| 704 | | − /* |
| 705 | | − * max_offset can stay at 0 so it's not an indicator |
| 706 | | − * of whether line names were configured at all. |
| 707 | | − */ |
| 708 | | − has_line_names = true; |
| 709 | | − } |
| 698 | + size = max(size, line->offset + 1); |
| 710 | 699 | } |
| 711 | 700 | |
| 712 | | − if (!has_line_names) |
| 713 | | − /* |
| 714 | | − * This is not an error - NULL means, there are no line |
| 715 | | − * names configured. |
| 716 | | − */ |
| 717 | | − return NULL; |
| 718 | | − |
| 719 | | − *line_names_size = max_offset + 1; |
| 701 | + return size; |
| 702 | +} |
| 720 | 703 | |
| 721 | | − line_names = kcalloc(*line_names_size, sizeof(*line_names), GFP_KERNEL); |
| 722 | | − if (!line_names) |
| 723 | | − return ERR_PTR(-ENOMEM); |
| 704 | +static void |
| 705 | +gpio_sim_set_line_names(struct gpio_sim_bank *bank, char **line_names) |
| 706 | +{ |
| 707 | + struct gpio_sim_line *line; |
| 724 | 708 | |
| 725 | 709 | list_for_each_entry(line, &bank->line_list, siblings) { |
| 726 | | − if (line->offset >= bank->num_lines) |
| 710 | + if (!line->name || (line->offset >= bank->num_lines)) |
| 727 | 711 | continue; |
| 728 | 712 | |
| 729 | | − if (line->name && (line->offset <= max_offset)) |
| 730 | | − line_names[line->offset] = line->name; |
| 713 | + line_names[line->offset] = line->name; |
| 731 | 714 | } |
| 732 | | − |
| 733 | | − return line_names; |
| 734 | 715 | } |
| 735 | 716 | |
| 736 | 717 | static void gpio_sim_remove_hogs(struct gpio_sim_device *dev) |
| @@ -834,7 +815,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 97 unmodified lines |
| 834 | 815 | struct fwnode_handle *parent) |
| 835 | 816 | { |
| 836 | 817 | struct property_entry properties[GPIO_SIM_PROP_MAX]; |
| 837 | | − unsigned int prop_idx = 0, line_names_size = 0; |
| 818 | + unsigned int prop_idx = 0, line_names_size; |
| 838 | 819 | char **line_names __free(kfree) = NULL; |
| 839 | 820 | |
| 840 | 821 | memset(properties, 0, sizeof(properties)); |
| @@ -845,14 +826,19 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 4 unmodified lines |
| 845 | 826 | properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", |
| 846 | 827 | bank->label); |
| 847 | 828 | |
| 848 | | − line_names = gpio_sim_make_line_names(bank, &line_names_size); |
| 849 | | − if (IS_ERR(line_names)) |
| 850 | | − return ERR_CAST(line_names); |
| 829 | + line_names_size = gpio_sim_get_line_names_size(bank); |
| 830 | + if (line_names_size) { |
| 831 | + line_names = kcalloc(line_names_size, sizeof(*line_names), |
| 832 | + GFP_KERNEL); |
| 833 | + if (!line_names) |
| 834 | + return ERR_PTR(-ENOMEM); |
| 835 | + |
| 836 | + gpio_sim_set_line_names(bank, line_names); |
| 851 | 837 | |
| 852 | | − if (line_names) |
| 853 | 838 | properties[prop_idx++] = PROPERTY_ENTRY_STRING_ARRAY_LEN( |
| 854 | 839 | "gpio-line-names", |
| 855 | 840 | line_names, line_names_size); |
| 841 | + } |
| 856 | 842 | |
| 857 | 843 | return fwnode_create_software_node(properties, parent); |
| 858 | 844 | } |