[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