Revision 38641a52 hw/pxa2xx_gpio.c

b/hw/pxa2xx_gpio.c
16 16
    qemu_irq *pic;
17 17
    int lines;
18 18
    CPUState *cpu_env;
19
    qemu_irq *in;
19 20

  
20 21
    /* XXX: GNU C vectors are more suitable */
21 22
    uint32_t ilevel[PXA2XX_GPIO_BANKS];
......
28 29
    uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
29 30

  
30 31
    uint32_t prev_level[PXA2XX_GPIO_BANKS];
31
    struct {
32
        gpio_handler_t fn;
33
        void *opaque;
34
    } handler[PXA2XX_GPIO_BANKS * 32];
35

  
36
    void (*read_notify)(void *opaque);
37
    void *opaque;
32
    qemu_irq handler[PXA2XX_GPIO_BANKS * 32];
33
    qemu_irq read_notify;
38 34
};
39 35

  
40 36
static struct {
......
86 82
}
87 83

  
88 84
/* Bitmap of pins used as standby and sleep wake-up sources.  */
89
const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
85
static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
90 86
    0x8003fe1b, 0x002001fc, 0xec080000, 0x0012007f,
91 87
};
92 88

  
93
void pxa2xx_gpio_set(struct pxa2xx_gpio_info_s *s, int line, int level)
89
static void pxa2xx_gpio_set(void *opaque, int line, int level)
94 90
{
91
    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
95 92
    int bank;
96 93
    uint32_t mask;
97 94

  
......
130 127
        for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
131 128
            bit = ffs(diff) - 1;
132 129
            line = bit + 32 * i;
133
            if (s->handler[line].fn)
134
                s->handler[line].fn(line, (level >> bit) & 1,
135
                                s->handler[line].opaque);
130
            qemu_set_irq(s->handler[line], (level >> bit) & 1);
136 131
        }
137 132

  
138 133
        s->prev_level[i] = level;
......
173 168
    case GPLR:		/* GPIO Pin-Level registers */
174 169
        ret = (s->olevel[bank] & s->dir[bank]) |
175 170
                (s->ilevel[bank] & ~s->dir[bank]);
176
        if (s->read_notify)
177
            s->read_notify(s->opaque);
171
        qemu_irq_raise(s->read_notify);
178 172
        return ret;
179 173

  
180 174
    case GEDR:		/* GPIO Edge Detect Status registers */
......
312 306
    s->pic = pic;
313 307
    s->lines = lines;
314 308
    s->cpu_env = env;
309
    s->in = qemu_allocate_irqs(pxa2xx_gpio_set, s, lines);
315 310

  
316 311
    iomemtype = cpu_register_io_memory(0, pxa2xx_gpio_readfn,
317 312
                    pxa2xx_gpio_writefn, s);
......
323 318
    return s;
324 319
}
325 320

  
326
void pxa2xx_gpio_handler_set(struct pxa2xx_gpio_info_s *s, int line,
327
                gpio_handler_t handler, void *opaque) {
321
qemu_irq *pxa2xx_gpio_in_get(struct pxa2xx_gpio_info_s *s)
322
{
323
    return s->in;
324
}
325

  
326
void pxa2xx_gpio_out_set(struct pxa2xx_gpio_info_s *s,
327
                int line, qemu_irq handler)
328
{
328 329
    if (line >= s->lines) {
329 330
        printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
330 331
        return;
331 332
    }
332 333

  
333
    s->handler[line].fn = handler;
334
    s->handler[line].opaque = opaque;
334
    s->handler[line] = handler;
335 335
}
336 336

  
337 337
/*
338 338
 * Registers a callback to notify on GPLR reads.  This normally
339 339
 * shouldn't be needed but it is used for the hack on Spitz machines.
340 340
 */
341
void pxa2xx_gpio_read_notifier(struct pxa2xx_gpio_info_s *s,
342
                void (*handler)(void *opaque), void *opaque) {
341
void pxa2xx_gpio_read_notifier(struct pxa2xx_gpio_info_s *s, qemu_irq handler)
342
{
343 343
    s->read_notify = handler;
344
    s->opaque = opaque;
345 344
}

Also available in: Unified diff