Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bus: imx-weim: support multiple address ranges per child node

Ensure that timing values for the child node are applied to
all chip selects in the child's address ranges.

Note that this does not support multiple timing settings per
child; this can be added in the future if required.

Example:
&weim {
acme@0 {
compatible = "acme,whatever";
reg = <0 0 0x100>, <0 0x400000 0x800>,
<1 0x400000 0x800>;
fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
0x00000000 0xa0000240 0x00000000>;
};
};

Signed-off-by: Sven Van Asbroeck <TheSven73@googlemail.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>

authored by

Sven Van Asbroeck and committed by
Shawn Guo
8b8cb52a 4c783b01

+26 -11
+26 -11
drivers/bus/imx-weim.c
··· 46 46 }; 47 47 48 48 #define MAX_CS_REGS_COUNT 6 49 + #define OF_REG_SIZE 3 49 50 50 51 static const struct of_device_id weim_id_table[] = { 51 52 /* i.MX1/21 */ ··· 117 116 { 118 117 u32 cs_idx, value[MAX_CS_REGS_COUNT]; 119 118 int i, ret; 119 + int reg_idx, num_regs; 120 120 121 121 if (WARN_ON(devtype->cs_regs_count > MAX_CS_REGS_COUNT)) 122 - return -EINVAL; 123 - 124 - /* get the CS index from this child node's "reg" property. */ 125 - ret = of_property_read_u32(np, "reg", &cs_idx); 126 - if (ret) 127 - return ret; 128 - 129 - if (cs_idx >= devtype->cs_count) 130 122 return -EINVAL; 131 123 132 124 ret = of_property_read_u32_array(np, "fsl,weim-cs-timing", ··· 127 133 if (ret) 128 134 return ret; 129 135 130 - /* set the timing for WEIM */ 131 - for (i = 0; i < devtype->cs_regs_count; i++) 132 - writel(value[i], base + cs_idx * devtype->cs_stride + i * 4); 136 + /* 137 + * the child node's "reg" property may contain multiple address ranges, 138 + * extract the chip select for each. 139 + */ 140 + num_regs = of_property_count_elems_of_size(np, "reg", OF_REG_SIZE); 141 + if (num_regs < 0) 142 + return num_regs; 143 + if (!num_regs) 144 + return -EINVAL; 145 + for (reg_idx = 0; reg_idx < num_regs; reg_idx++) { 146 + /* get the CS index from this child node's "reg" property. */ 147 + ret = of_property_read_u32_index(np, "reg", 148 + reg_idx * OF_REG_SIZE, &cs_idx); 149 + if (ret) 150 + break; 151 + 152 + if (cs_idx >= devtype->cs_count) 153 + return -EINVAL; 154 + 155 + /* set the timing for WEIM */ 156 + for (i = 0; i < devtype->cs_regs_count; i++) 157 + writel(value[i], 158 + base + cs_idx * devtype->cs_stride + i * 4); 159 + } 133 160 134 161 return 0; 135 162 }