Revision 0919ac78 hw/omap_intc.c

b/hw/omap_intc.c
19 19
 */
20 20
#include "hw.h"
21 21
#include "omap.h"
22
#include "exec-memory.h"
22
#include "sysbus.h"
23 23

  
24 24
/* Interrupt Handlers */
25 25
struct omap_intr_handler_bank_s {
......
33 33
};
34 34

  
35 35
struct omap_intr_handler_s {
36
    SysBusDevice busdev;
36 37
    qemu_irq *pins;
37 38
    qemu_irq parent_intr[2];
38 39
    MemoryRegion mmio;
40
    void *iclk;
41
    void *fclk;
39 42
    unsigned char nbanks;
40 43
    int level_only;
44
    uint32_t size;
45

  
46
    uint8_t revision;
41 47

  
42 48
    /* state */
43 49
    uint32_t new_agr[2];
44 50
    int sir_intr[2];
45 51
    int autoidle;
46 52
    uint32_t mask;
47
    struct omap_intr_handler_bank_s bank[];
53
    struct omap_intr_handler_bank_s bank[3];
48 54
};
49 55

  
50
inline qemu_irq omap_inth_get_pin(struct omap_intr_handler_s *s, int n)
51
{
52
    return s->pins[n];
53
}
54

  
55 56
static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
56 57
{
57 58
    int i, j, sir_intr, p_intr, p, f;
......
325 326
    },
326 327
};
327 328

  
328
void omap_inth_reset(struct omap_intr_handler_s *s)
329
static void omap_inth_reset(DeviceState *dev)
329 330
{
331
    struct omap_intr_handler_s *s = FROM_SYSBUS(struct omap_intr_handler_s,
332
                                                sysbus_from_qdev(dev));
330 333
    int i;
331 334

  
332 335
    for (i = 0; i < s->nbanks; ++i){
......
353 356
    qemu_set_irq(s->parent_intr[1], 0);
354 357
}
355 358

  
356
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
357
                unsigned long size, unsigned char nbanks, qemu_irq **pins,
358
                qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
359
static int omap_intc_init(SysBusDevice *dev)
359 360
{
360
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
361
            g_malloc0(sizeof(struct omap_intr_handler_s) +
362
                            sizeof(struct omap_intr_handler_bank_s) * nbanks);
363

  
364
    s->parent_intr[0] = parent_irq;
365
    s->parent_intr[1] = parent_fiq;
366
    s->nbanks = nbanks;
367
    s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
368
    if (pins)
369
        *pins = s->pins;
370

  
371
    memory_region_init_io(&s->mmio, &omap_inth_mem_ops, s, "omap-intc", size);
372
    memory_region_add_subregion(get_system_memory(), base, &s->mmio);
373

  
374
    omap_inth_reset(s);
375

  
376
    return s;
361
    struct omap_intr_handler_s *s;
362
    s = FROM_SYSBUS(struct omap_intr_handler_s, dev);
363
    if (!s->iclk) {
364
        hw_error("omap-intc: clk not connected\n");
365
    }
366
    s->nbanks = 1;
367
    sysbus_init_irq(dev, &s->parent_intr[0]);
368
    sysbus_init_irq(dev, &s->parent_intr[1]);
369
    qdev_init_gpio_in(&dev->qdev, omap_set_intr, s->nbanks * 32);
370
    memory_region_init_io(&s->mmio, &omap_inth_mem_ops, s,
371
                          "omap-intc", s->size);
372
    sysbus_init_mmio_region(dev, &s->mmio);
373
    return 0;
377 374
}
378 375

  
376
static SysBusDeviceInfo omap_intc_info = {
377
    .init = omap_intc_init,
378
    .qdev.name = "omap-intc",
379
    .qdev.size = sizeof(struct omap_intr_handler_s),
380
    .qdev.reset = omap_inth_reset,
381
    .qdev.props = (Property[]) {
382
        DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
383
        DEFINE_PROP_PTR("clk", struct omap_intr_handler_s, iclk),
384
        DEFINE_PROP_END_OF_LIST()
385
    }
386
};
387

  
379 388
static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr,
380 389
                                unsigned size)
381 390
{
......
394 403

  
395 404
    switch (offset) {
396 405
    case 0x00:	/* INTC_REVISION */
397
        return 0x21;
406
        return s->revision;
398 407

  
399 408
    case 0x10:	/* INTC_SYSCONFIG */
400 409
        return (s->autoidle >> 2) & 1;
......
475 484
        s->autoidle &= 4;
476 485
        s->autoidle |= (value & 1) << 2;
477 486
        if (value & 2)						/* SOFTRESET */
478
            omap_inth_reset(s);
487
            omap_inth_reset(&s->busdev.qdev);
479 488
        return;
480 489

  
481 490
    case 0x48:	/* INTC_CONTROL */
......
568 577
    },
569 578
};
570 579

  
571
struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,
572
                int size, int nbanks, qemu_irq **pins,
573
                qemu_irq parent_irq, qemu_irq parent_fiq,
574
                omap_clk fclk, omap_clk iclk)
580
static int omap2_intc_init(SysBusDevice *dev)
575 581
{
576
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
577
            g_malloc0(sizeof(struct omap_intr_handler_s) +
578
                            sizeof(struct omap_intr_handler_bank_s) * nbanks);
579

  
580
    s->parent_intr[0] = parent_irq;
581
    s->parent_intr[1] = parent_fiq;
582
    s->nbanks = nbanks;
582
    struct omap_intr_handler_s *s;
583
    s = FROM_SYSBUS(struct omap_intr_handler_s, dev);
584
    if (!s->iclk) {
585
        hw_error("omap2-intc: iclk not connected\n");
586
    }
587
    if (!s->fclk) {
588
        hw_error("omap2-intc: fclk not connected\n");
589
    }
583 590
    s->level_only = 1;
584
    s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32);
585
    if (pins)
586
        *pins = s->pins;
587

  
588
    memory_region_init_io(&s->mmio, &omap2_inth_mem_ops, s, "omap2-intc", size);
589
    memory_region_add_subregion(get_system_memory(), base, &s->mmio);
591
    s->nbanks = 3;
592
    sysbus_init_irq(dev, &s->parent_intr[0]);
593
    sysbus_init_irq(dev, &s->parent_intr[1]);
594
    qdev_init_gpio_in(&dev->qdev, omap_set_intr_noedge, s->nbanks * 32);
595
    memory_region_init_io(&s->mmio, &omap2_inth_mem_ops, s,
596
                          "omap2-intc", 0x1000);
597
    sysbus_init_mmio_region(dev, &s->mmio);
598
    return 0;
599
}
590 600

  
591
    omap_inth_reset(s);
601
static SysBusDeviceInfo omap2_intc_info = {
602
    .init = omap2_intc_init,
603
    .qdev.name = "omap2-intc",
604
    .qdev.size = sizeof(struct omap_intr_handler_s),
605
    .qdev.reset = omap_inth_reset,
606
    .qdev.props = (Property[]) {
607
        DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
608
                          revision, 0x21),
609
        DEFINE_PROP_PTR("iclk", struct omap_intr_handler_s, iclk),
610
        DEFINE_PROP_PTR("fclk", struct omap_intr_handler_s, fclk),
611
        DEFINE_PROP_END_OF_LIST()
612
    }
613
};
592 614

  
593
    return s;
615
static void omap_intc_register_device(void)
616
{
617
    sysbus_register_withprop(&omap_intc_info);
618
    sysbus_register_withprop(&omap2_intc_info);
594 619
}
620

  
621
device_init(omap_intc_register_device)

Also available in: Unified diff