[Uclinux-dist-devel] [PATCH] mtd/maps: gpio-addr-flash: new driver for GPIO assisted flash addressing
Mike Frysinger
vapier.adi at gmail.com
Tue Jun 2 19:37:18 EDT 2009
On Tue, Jun 2, 2009 at 18:58, Ben Dooks wrote:
> On Tue, Jun 02, 2009 at 12:07:30AM -0400, Mike Frysinger wrote:
>> +struct async_state {
>> + struct mtd_info *mtd;
>> + struct map_info map;
>> + size_t gpio_count;
>> + unsigned *gpio_addrs;
>> + int *gpio_values;
>> + unsigned long win_size;
>> +};
>
> no kerneldoc for this?
guess i could figure that out and add it
>> +static void gf_set_gpios(struct async_state *state, unsigned long ofs)
>> +{
>> + size_t i;
>> + int value;
>> + for (i = 0; i < state->gpio_count; ++i) {
>> + value = !!((ofs / state->win_size) & (1 << i));
>> + if (state->gpio_values[i] != value) {
>> + gpio_set_value(state->gpio_addrs[i], value);
>> + state->gpio_values[i] = value;
>> + }
>> + }
>> +}
>> +
>> +static map_word gf_read(struct map_info *map, unsigned long ofs)
>> +{
>> + struct async_state *state = (struct async_state *)map->map_priv_1;
>> + u16 word;
>> + map_word test;
>> +
>> + gf_set_gpios(state, ofs);
>> +
>> + word = readw(map->virt + (ofs % state->win_size));
>> + test.x[0] = word;
>> + return test;
>> +}
>> +
>> +static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
>> +{
>> + struct async_state *state = (struct async_state *)map->map_priv_1;
>> +
>> + gf_set_gpios(state, from);
>> +
>> + /* BUG if operation crosss the win_size */
>> + BUG_ON(!((from + len) % state->win_size <= (from + len)));
>> +
>> + /* operation does not cross the win_size, so one shot it */
>> + memcpy_fromio(to, map->virt + (from % state->win_size), len);
>> +}
>> +
>> +static void gf_write(struct map_info *map, map_word d1, unsigned long ofs)
>> +{
>> + struct async_state *state = (struct async_state *)map->map_priv_1;
>> + u16 d;
>> +
>> + gf_set_gpios(state, ofs);
>> +
>> + d = d1.x[0];
>> + writew(d, map->virt + (ofs % state->win_size));
>> +}
>> +
>> +static void gf_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
>> +{
>> + struct async_state *state = (struct async_state *)map->map_priv_1;
>> +
>> + gf_set_gpios(state, to);
>> +
>> + /* BUG if operation crosss the win_size */
>> + BUG_ON(!((to + len) % state->win_size <= (to + len)));
>> +
>> + /* operation does not cross the win_size, so one shot it */
>> + memcpy_toio(map->virt + (to % state->win_size), from, len);
>> +}
>> +
>> +#ifdef CONFIG_MTD_PARTITIONS
>> +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
>> +#endif
>> +
>> +static int __devinit gpio_flash_probe(struct platform_device *pdev)
>> +{
>> + int ret;
>> + size_t i;
>> + struct physmap_flash_data *pdata = pdev->dev.platform_data;
>> + struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + struct resource *gpios = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
>> + struct async_state *state;
>
> both memory and gpios wrap, please put the platform_get_resource()
> onto their own lines.
looks fine to me
> gpios = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
>
> nope, not irqs. maybe someone should propose IORESOURCE_GPIO.
IORESOURCE_IRQ is the closest thing as it represents a pin. the
existing masks allows for only 4 types and they're already allocated.
if someone felt like tackling that crap, i'd have no problem
converting the driver.
>> + state = kzalloc(sizeof(*state) + (sizeof(int) * gpios->end * 2), GFP_KERNEL);
>
> hmm, why not keep the pointer to the resource you just got instead?
the GPIO array is duplicated and i could keep a reference to that, but
the rest would add overhead. i would need two pointers anyways, so
simply caching the calculated values (gpio_count and win_size) instead
makes more sense.
-mike
More information about the linux-mtd
mailing list