From: Boris Brezillon Date: Fri, 27 Jan 2017 09:10:37 +0000 (+0100) Subject: memory: atmel-ebi: Properly handle multiple reference to the same CS X-Git-Tag: v4.13~1243^2~6^2~1 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=987e079ecab7298cf5d5b43473d25bc31006e0e0;p=mirror_ubuntu-bionic-kernel.git memory: atmel-ebi: Properly handle multiple reference to the same CS Some devices are defining several sub-ranges within the same CS iomem range. In this case, we should not duplicate the EBI device config. Signed-off-by: Boris Brezillon Signed-off-by: Alexandre Belloni --- diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 2c4c9a1978bc..46657eaaedf6 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -449,12 +449,31 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, struct at91_ebi_dev_config conf = { }; struct device *dev = ebi->dev; struct at91_ebi_dev *ebid; - int ret, numcs = 0, i; + unsigned long cslines = 0; + int ret, numcs = 0, nentries, i; bool apply = false; + u32 cs; - numcs = of_property_count_elems_of_size(np, "reg", - reg_cells * sizeof(u32)); - if (numcs <= 0) { + nentries = of_property_count_elems_of_size(np, "reg", + reg_cells * sizeof(u32)); + for (i = 0; i < nentries; i++) { + ret = of_property_read_u32_index(np, "reg", i * reg_cells, + &cs); + if (ret) + return ret; + + if (cs >= AT91_MATRIX_EBI_NUM_CS || + !(ebi->caps->available_cs & BIT(cs))) { + dev_err(dev, "invalid reg property in %s\n", + np->full_name); + return -EINVAL; + } + + if (!test_and_set_bit(cs, &cslines)) + numcs++; + } + + if (!numcs) { dev_err(dev, "invalid reg property in %s\n", np->full_name); return -EINVAL; } @@ -473,21 +492,8 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, else if (ret) apply = true; - for (i = 0; i < numcs; i++) { - u32 cs; - - ret = of_property_read_u32_index(np, "reg", i * reg_cells, - &cs); - if (ret) - return ret; - - if (cs > AT91_MATRIX_EBI_NUM_CS || - !(ebi->caps->available_cs & BIT(cs))) { - dev_err(dev, "invalid reg property in %s\n", - np->full_name); - return -EINVAL; - } - + i = 0; + for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) { ebid->configs[i].cs = cs; if (apply) { @@ -506,6 +512,8 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, if (ebi->ebi_csa && apply) regmap_field_update_bits(ebi->ebi_csa, BIT(cs), 0); + + i++; } list_add_tail(&ebid->node, &ebi->devs);