diff options
author | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 2018-10-04 09:01:06 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-10-08 15:32:49 -0400 |
commit | 460cdeca546fc75f2450914c96e701f990396285 (patch) | |
tree | 7a610da79206aad6dac00c6ee6a3dd98ef87397d | |
parent | 4edc00adfd58768b065204968948c52f5e5b07b1 (diff) |
mtd: maps: gpio-addr-flash: Use order instead of size
By using the order of the window instead of the size, we can replace a
lot of expensive division and modulus on the code with simple bit
operations.
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
-rw-r--r-- | drivers/mtd/maps/gpio-addr-flash.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index 84404dcc7824..89cc8cce161b 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | 27 | ||
28 | #define win_mask(x) ((BIT(x)) - 1) | ||
29 | |||
28 | #define DRIVER_NAME "gpio-addr-flash" | 30 | #define DRIVER_NAME "gpio-addr-flash" |
29 | 31 | ||
30 | /** | 32 | /** |
@@ -34,7 +36,7 @@ | |||
34 | * @gpio_count: number of GPIOs used to address | 36 | * @gpio_count: number of GPIOs used to address |
35 | * @gpio_addrs: array of GPIOs to twiddle | 37 | * @gpio_addrs: array of GPIOs to twiddle |
36 | * @gpio_values: cached GPIO values | 38 | * @gpio_values: cached GPIO values |
37 | * @win_size: dedicated memory size (if no GPIOs) | 39 | * @win_order: dedicated memory size (if no GPIOs) |
38 | */ | 40 | */ |
39 | struct async_state { | 41 | struct async_state { |
40 | struct mtd_info *mtd; | 42 | struct mtd_info *mtd; |
@@ -42,7 +44,7 @@ struct async_state { | |||
42 | size_t gpio_count; | 44 | size_t gpio_count; |
43 | unsigned *gpio_addrs; | 45 | unsigned *gpio_addrs; |
44 | int *gpio_values; | 46 | int *gpio_values; |
45 | unsigned long win_size; | 47 | unsigned int win_order; |
46 | }; | 48 | }; |
47 | #define gf_map_info_to_state(mi) ((struct async_state *)(mi)->map_priv_1) | 49 | #define gf_map_info_to_state(mi) ((struct async_state *)(mi)->map_priv_1) |
48 | 50 | ||
@@ -60,7 +62,8 @@ static void gf_set_gpios(struct async_state *state, unsigned long ofs) | |||
60 | { | 62 | { |
61 | size_t i = 0; | 63 | size_t i = 0; |
62 | int value; | 64 | int value; |
63 | ofs /= state->win_size; | 65 | |
66 | ofs >>= state->win_order; | ||
64 | do { | 67 | do { |
65 | value = ofs & (1 << i); | 68 | value = ofs & (1 << i); |
66 | if (state->gpio_values[i] != value) { | 69 | if (state->gpio_values[i] != value) { |
@@ -83,7 +86,7 @@ static map_word gf_read(struct map_info *map, unsigned long ofs) | |||
83 | 86 | ||
84 | gf_set_gpios(state, ofs); | 87 | gf_set_gpios(state, ofs); |
85 | 88 | ||
86 | word = readw(map->virt + (ofs % state->win_size)); | 89 | word = readw(map->virt + (ofs & win_mask(state->win_order))); |
87 | test.x[0] = word; | 90 | test.x[0] = word; |
88 | return test; | 91 | return test; |
89 | } | 92 | } |
@@ -105,14 +108,14 @@ static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssi | |||
105 | int this_len; | 108 | int this_len; |
106 | 109 | ||
107 | while (len) { | 110 | while (len) { |
108 | if ((from % state->win_size) + len > state->win_size) | 111 | this_len = from & win_mask(state->win_order); |
109 | this_len = state->win_size - (from % state->win_size); | 112 | this_len = BIT(state->win_order) - this_len; |
110 | else | 113 | this_len = min_t(int, len, this_len); |
111 | this_len = len; | ||
112 | 114 | ||
113 | gf_set_gpios(state, from); | 115 | gf_set_gpios(state, from); |
114 | memcpy_fromio(to, map->virt + (from % state->win_size), | 116 | memcpy_fromio(to, |
115 | this_len); | 117 | map->virt + (from & win_mask(state->win_order)), |
118 | this_len); | ||
116 | len -= this_len; | 119 | len -= this_len; |
117 | from += this_len; | 120 | from += this_len; |
118 | to += this_len; | 121 | to += this_len; |
@@ -132,7 +135,7 @@ static void gf_write(struct map_info *map, map_word d1, unsigned long ofs) | |||
132 | gf_set_gpios(state, ofs); | 135 | gf_set_gpios(state, ofs); |
133 | 136 | ||
134 | d = d1.x[0]; | 137 | d = d1.x[0]; |
135 | writew(d, map->virt + (ofs % state->win_size)); | 138 | writew(d, map->virt + (ofs & win_mask(state->win_order))); |
136 | } | 139 | } |
137 | 140 | ||
138 | /** | 141 | /** |
@@ -152,13 +155,13 @@ static void gf_copy_to(struct map_info *map, unsigned long to, | |||
152 | int this_len; | 155 | int this_len; |
153 | 156 | ||
154 | while (len) { | 157 | while (len) { |
155 | if ((to % state->win_size) + len > state->win_size) | 158 | this_len = to & win_mask(state->win_order); |
156 | this_len = state->win_size - (to % state->win_size); | 159 | this_len = BIT(state->win_order) - this_len; |
157 | else | 160 | this_len = min_t(int, len, this_len); |
158 | this_len = len; | ||
159 | 161 | ||
160 | gf_set_gpios(state, to); | 162 | gf_set_gpios(state, to); |
161 | memcpy_toio(map->virt + (to % state->win_size), from, len); | 163 | memcpy_toio(map->virt + (to & win_mask(state->win_order)), |
164 | from, len); | ||
162 | 165 | ||
163 | len -= this_len; | 166 | len -= this_len; |
164 | to += this_len; | 167 | to += this_len; |
@@ -224,7 +227,7 @@ static int gpio_flash_probe(struct platform_device *pdev) | |||
224 | state->gpio_count = gpios->end; | 227 | state->gpio_count = gpios->end; |
225 | state->gpio_addrs = (void *)(unsigned long)gpios->start; | 228 | state->gpio_addrs = (void *)(unsigned long)gpios->start; |
226 | state->gpio_values = (void *)(state + 1); | 229 | state->gpio_values = (void *)(state + 1); |
227 | state->win_size = resource_size(memory); | 230 | state->win_order = get_bitmask_order(resource_size(memory)) - 1; |
228 | memset(state->gpio_values, 0xff, arr_size); | 231 | memset(state->gpio_values, 0xff, arr_size); |
229 | 232 | ||
230 | state->map.name = DRIVER_NAME; | 233 | state->map.name = DRIVER_NAME; |
@@ -233,7 +236,7 @@ static int gpio_flash_probe(struct platform_device *pdev) | |||
233 | state->map.write = gf_write; | 236 | state->map.write = gf_write; |
234 | state->map.copy_to = gf_copy_to; | 237 | state->map.copy_to = gf_copy_to; |
235 | state->map.bankwidth = pdata->width; | 238 | state->map.bankwidth = pdata->width; |
236 | state->map.size = state->win_size * (1 << state->gpio_count); | 239 | state->map.size = BIT(state->win_order + state->gpio_count); |
237 | state->map.virt = devm_ioremap_resource(&pdev->dev, memory); | 240 | state->map.virt = devm_ioremap_resource(&pdev->dev, memory); |
238 | if (IS_ERR(state->map.virt)) | 241 | if (IS_ERR(state->map.virt)) |
239 | return PTR_ERR(state->map.virt); | 242 | return PTR_ERR(state->map.virt); |