diff --git a/hw/omap.c b/hw/omap.c index 9c0e570aea..f8c2073da9 100644 --- a/hw/omap.c +++ b/hw/omap.c @@ -2882,7 +2882,9 @@ static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr) case 0x24: /* GPIO_INT */ ret = s->ints; - s->ints &= ~s->mask; + s->ints &= s->mask; + if (ret) + qemu_irq_lower(s->irq); return ret; case 0x28: /* KBD_MASKIT */ diff --git a/hw/omap.h b/hw/omap.h index 1ebb87aebc..70888698c7 100644 --- a/hw/omap.h +++ b/hw/omap.h @@ -470,6 +470,7 @@ struct omap_mmc_s; struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, qemu_irq irq, qemu_irq dma[], omap_clk clk); void omap_mmc_reset(struct omap_mmc_s *s); +void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover); # define cpu_is_omap310(cpu) (cpu->mpu_model == omap310) # define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510) diff --git a/hw/omap_mmc.c b/hw/omap_mmc.c index aa77660f28..008318db36 100644 --- a/hw/omap_mmc.c +++ b/hw/omap_mmc.c @@ -25,6 +25,7 @@ struct omap_mmc_s { target_phys_addr_t base; qemu_irq irq; qemu_irq *dma; + qemu_irq handler[2]; omap_clk clk; SDState *card; uint16_t last_cmd; @@ -506,6 +507,22 @@ void omap_mmc_reset(struct omap_mmc_s *host) host->transfer = 0; } +static void omap_mmc_ro_cb(void *opaque, int level) +{ + struct omap_mmc_s *s = (struct omap_mmc_s *) opaque; + + if (s->handler[0]) + qemu_set_irq(s->handler[0], level); +} + +static void omap_mmc_cover_cb(void *opaque, int level) +{ + struct omap_mmc_s *s = (struct omap_mmc_s *) opaque; + + if (s->handler[1]) + qemu_set_irq(s->handler[1], level); +} + struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, qemu_irq irq, qemu_irq dma[], omap_clk clk) { @@ -525,7 +542,13 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, /* Instantiate the storage */ s->card = sd_init(sd_bdrv); + sd_set_cb(s->card, s, omap_mmc_ro_cb, omap_mmc_cover_cb); + return s; } -/* TODO: insertion and read-only handlers */ +void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover) +{ + s->handler[0] = ro; + s->handler[1] = cover; +} diff --git a/hw/palm.c b/hw/palm.c index ead9cfd453..ba7e47f9f5 100644 --- a/hw/palm.c +++ b/hw/palm.c @@ -57,6 +57,24 @@ static CPUWriteMemoryFunc *static_writefn[] = { }; /* Palm Tunsgten|E support */ + +/* Shared GPIOs */ +#define PALMTE_USBDETECT_GPIO 0 +#define PALMTE_USB_OR_DC_GPIO 1 +#define PALMTE_TSC_GPIO 4 +#define PALMTE_PINTDAV_GPIO 6 +#define PALMTE_MMC_WP_GPIO 8 +#define PALMTE_MMC_POWER_GPIO 9 +#define PALMTE_HDQ_GPIO 11 +#define PALMTE_HEADPHONES_GPIO 14 +#define PALMTE_SPEAKER_GPIO 15 +/* MPU private GPIOs */ +#define PALMTE_DC_GPIO 2 +#define PALMTE_MMC_SWITCH_GPIO 4 +#define PALMTE_MMC1_GPIO 6 +#define PALMTE_MMC2_GPIO 7 +#define PALMTE_MMC3_GPIO 11 + static void palmte_microwire_setup(struct omap_mpu_state_s *cpu) { } @@ -90,6 +108,14 @@ static void palmte_button_event(void *opaque, int keycode) !(keycode & 0x80)); } +static void palmte_mmc_cover(void *opaque, int line, int level) +{ + struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque; + + qemu_set_irq(omap_mpuio_in_get(cpu->mpuio)[PALMTE_MMC_SWITCH_GPIO], + !level); +} + static void palmte_init(int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, @@ -132,6 +158,9 @@ static void palmte_init(int ram_size, int vga_ram_size, int boot_device, qemu_add_kbd_event_handler(palmte_button_event, cpu); + omap_mmc_handlers(cpu->mmc, 0, + qemu_allocate_irqs(palmte_mmc_cover, cpu, 1)[0]); + /* Setup initial (reset) machine state */ if (nb_option_roms) { rom_size = get_image_size(option_rom[0]);