hw/omap_gpio.c: Convert to qdev

Convert the OMAP GPIO module to qdev.

Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
This commit is contained in:
Juha Riihimäki 2011-07-29 16:35:17 +01:00 committed by Andrzej Zaborowski
parent 0a34f96690
commit 77831c204f
6 changed files with 219 additions and 174 deletions

View File

@ -134,9 +134,9 @@ static void n800_mmc_cs_cb(void *opaque, int line, int level)
static void n8x0_gpio_setup(struct n800_s *s)
{
qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);
qdev_connect_gpio_out(s->cpu->gpio, N8X0_MMC_CS_GPIO, mmc_cs[0]);
qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
qemu_irq_lower(qdev_get_gpio_in(s->cpu->gpio, N800_BAT_COVER_GPIO));
}
#define MAEMO_CAL_HEADER(...) \
@ -168,8 +168,8 @@ static void n8x0_nand_setup(struct n800_s *s)
omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
onenand_base_unmap,
(s->nand = onenand_init(0xec4800, 1,
omap2_gpio_in_get(s->cpu->gpif,
N8X0_ONENAND_GPIO)[0])));
qdev_get_gpio_in(s->cpu->gpio,
N8X0_ONENAND_GPIO))));
otp_region = onenand_raw_otp(s->nand);
memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
@ -180,7 +180,7 @@ static void n8x0_nand_setup(struct n800_s *s)
static void n8x0_i2c_setup(struct n800_s *s)
{
DeviceState *dev;
qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
qemu_irq tmp_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TMP105_GPIO);
/* Attach the CPU on one end of our I2C bus. */
s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
@ -249,8 +249,8 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
/* XXX: are the three pins inverted inside the chip between the
* tsc and the cpu (N4111)? */
qemu_irq penirq = NULL; /* NC */
qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
qemu_irq kbirq = qdev_get_gpio_in(s->cpu->gpio, N800_TSC_KP_IRQ_GPIO);
qemu_irq dav = qdev_get_gpio_in(s->cpu->gpio, N800_TSC_TS_GPIO);
s->ts.chip = tsc2301_init(penirq, kbirq, dav);
s->ts.opaque = s->ts.chip->opaque;
@ -269,7 +269,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
static void n810_tsc_setup(struct n800_s *s)
{
qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];
qemu_irq pintdav = qdev_get_gpio_in(s->cpu->gpio, N810_TSC_TS_GPIO);
s->ts.opaque = tsc2005_init(pintdav);
s->ts.txrx = tsc2005_txrx;
@ -361,7 +361,7 @@ static int n810_keys[0x80] = {
static void n810_kbd_setup(struct n800_s *s)
{
qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];
qemu_irq kbd_irq = qdev_get_gpio_in(s->cpu->gpio, N810_KEYBOARD_GPIO);
DeviceState *dev;
int i;
@ -726,15 +726,15 @@ static void n8x0_dss_setup(struct n800_s *s)
static void n8x0_cbus_setup(struct n800_s *s)
{
qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
qemu_irq dat_out = qdev_get_gpio_in(s->cpu->gpio, N8X0_CBUS_DAT_GPIO);
qemu_irq retu_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_RETU_GPIO);
qemu_irq tahvo_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TAHVO_GPIO);
CBus *cbus = cbus_init(dat_out);
omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
@ -743,12 +743,11 @@ static void n8x0_cbus_setup(struct n800_s *s)
static void n8x0_uart_setup(struct n800_s *s)
{
CharDriverState *radio = uart_hci_init(
omap2_gpio_in_get(s->cpu->gpif,
N8X0_BT_HOST_WKUP_GPIO)[0]);
qdev_get_gpio_in(s->cpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_RESET_GPIO,
qdev_connect_gpio_out(s->cpu->gpio, N8X0_BT_RESET_GPIO,
csrhci_pins_get(radio)[csrhci_pin_reset]);
omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_WKUP_GPIO,
qdev_connect_gpio_out(s->cpu->gpio, N8X0_BT_WKUP_GPIO,
csrhci_pins_get(radio)[csrhci_pin_wakeup]);
omap_uart_attach(s->cpu->uart[BT_UART], radio);
@ -763,7 +762,7 @@ static void n8x0_usb_power_cb(void *opaque, int line, int level)
static void n8x0_usb_setup(struct n800_s *s)
{
qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
qemu_irq tusb_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO);
qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
TUSBState *tusb = tusb6010_init(tusb_irq);
@ -774,7 +773,7 @@ static void n8x0_usb_setup(struct n800_s *s)
tusb6010_sync_io(tusb), NULL, NULL, tusb);
s->usb = tusb;
omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
}
/* Setup done before the main bootloader starts by some early setup code
@ -1020,7 +1019,7 @@ static void n8x0_boot_init(void *opaque)
/* If the machine has a slided keyboard, open it */
if (s->kbd)
qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N810_SLIDE_GPIO)[0]);
qemu_irq_raise(qdev_get_gpio_in(s->cpu->gpio, N810_SLIDE_GPIO));
}
#define OMAP_TAG_NOKIA_BT 0x4e01

View File

@ -683,22 +683,6 @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
/* omap1 gpio module interface */
struct omap_gpio_s;
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
qemu_irq irq, omap_clk clk);
void omap_gpio_reset(struct omap_gpio_s *s);
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
/* omap2 gpio interface */
struct omap_gpif_s;
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules);
void omap_gpif_reset(struct omap_gpif_s *s);
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start);
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler);
struct uWireSlave {
uint16_t (*receive)(void *opaque);
void (*send)(void *opaque, uint16_t data);
@ -852,7 +836,7 @@ struct omap_mpu_state_s {
/* MPUI-TIPB peripherals */
struct omap_uart_s *uart[3];
struct omap_gpio_s *gpio;
DeviceState *gpio;
struct omap_mcbsp_s *mcbsp1;
struct omap_mcbsp_s *mcbsp3;
@ -950,8 +934,6 @@ struct omap_mpu_state_s {
struct omap_gpmc_s *gpmc;
struct omap_sysctl_s *sysc;
struct omap_gpif_s *gpif;
struct omap_mcspi_s *mcspi[2];
struct omap_dss_s *dss;

View File

@ -27,6 +27,7 @@
#include "pc.h"
#include "blockdev.h"
#include "range.h"
#include "sysbus.h"
/* Should signal the TCMI/GPMC */
uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
@ -3585,7 +3586,6 @@ static void omap1_mpu_reset(void *opaque)
omap_uart_reset(mpu->uart[2]);
omap_mmc_reset(mpu->mmc);
omap_mpuio_reset(mpu->mpuio);
omap_gpio_reset(mpu->gpio);
omap_uwire_reset(mpu->microwire);
omap_pwl_reset(mpu);
omap_pwt_reset(mpu);
@ -3845,8 +3845,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
s->wakeup, omap_findclk(s, "clk32-kHz"));
s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
omap_findclk(s, "arm_gpio_ck"));
s->gpio = qdev_create(NULL, "omap-gpio");
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
qdev_init_nofail(s->gpio);
sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
s->irq[0][OMAP_INT_GPIO_BANK1]);
sysbus_mmio_map(sysbus_from_qdev(s->gpio), 0, 0xfffce000);
s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));

View File

@ -27,6 +27,7 @@
#include "qemu-char.h"
#include "flash.h"
#include "soc_dma.h"
#include "sysbus.h"
#include "audio/audio.h"
/* Enhanced Audio Controller (CODEC only) */
@ -2203,7 +2204,6 @@ static void omap2_mpu_reset(void *opaque)
omap_uart_reset(mpu->uart[1]);
omap_uart_reset(mpu->uart[2]);
omap_mmc_reset(mpu->mmc);
omap_gpif_reset(mpu->gpif);
omap_mcspi_reset(mpu->mcspi[0]);
omap_mcspi_reset(mpu->mcspi[1]);
omap_i2c_reset(mpu->i2c[0]);
@ -2232,9 +2232,10 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
ram_addr_t sram_base, q2_base;
qemu_irq *cpu_irq;
qemu_irq dma_irqs[4];
omap_clk gpio_clks[4];
DriveInfo *dinfo;
int i;
SysBusDevice *busdev;
struct omap_target_agent_s *ta;
/* Core */
s->mpu_model = omap2420;
@ -2377,13 +2378,28 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
omap_findclk(s, "i2c2.fclk"),
omap_findclk(s, "i2c2.iclk"));
gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
&s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
s->gpio = qdev_create(NULL, "omap2-gpio");
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
if (s->mpu_model == omap2430) {
qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
}
qdev_init_nofail(s->gpio);
busdev = sysbus_from_qdev(s->gpio);
sysbus_connect_irq(busdev, 0, s->irq[0][OMAP_INT_24XX_GPIO_BANK1]);
sysbus_connect_irq(busdev, 3, s->irq[0][OMAP_INT_24XX_GPIO_BANK2]);
sysbus_connect_irq(busdev, 6, s->irq[0][OMAP_INT_24XX_GPIO_BANK3]);
sysbus_connect_irq(busdev, 9, s->irq[0][OMAP_INT_24XX_GPIO_BANK4]);
ta = omap_l4ta(s->l4, 3);
sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1));
sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0));
sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2));
sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4));
sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
s->sdrc = omap_sdrc_init(0x68009000);
s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);

View File

@ -20,10 +20,10 @@
#include "hw.h"
#include "omap.h"
/* General-Purpose I/O */
#include "sysbus.h"
struct omap_gpio_s {
qemu_irq irq;
qemu_irq *in;
qemu_irq handler[16];
uint16_t inputs;
@ -35,9 +35,17 @@ struct omap_gpio_s {
uint16_t pins;
};
struct omap_gpif_s {
SysBusDevice busdev;
int mpu_model;
void *clk;
struct omap_gpio_s omap1;
};
/* General-Purpose I/O of OMAP1 */
static void omap_gpio_set(void *opaque, int line, int level)
{
struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1;
uint16_t prev = s->inputs;
if (level)
@ -160,7 +168,7 @@ static CPUWriteMemoryFunc * const omap_gpio_writefn[] = {
omap_badwidth_write16,
};
void omap_gpio_reset(struct omap_gpio_s *s)
static void omap_gpio_reset(struct omap_gpio_s *s)
{
s->inputs = 0;
s->outputs = ~0;
@ -171,43 +179,12 @@ void omap_gpio_reset(struct omap_gpio_s *s)
s->pins = ~0;
}
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
qemu_irq irq, omap_clk clk)
{
int iomemtype;
struct omap_gpio_s *s = (struct omap_gpio_s *)
qemu_mallocz(sizeof(struct omap_gpio_s));
s->irq = irq;
s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
omap_gpio_reset(s);
iomemtype = cpu_register_io_memory(omap_gpio_readfn,
omap_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(base, 0x1000, iomemtype);
return s;
}
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
{
return s->in;
}
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
{
if (line >= 16 || line < 0)
hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
s->handler[line] = handler;
}
/* General-Purpose Interface of OMAP2 */
struct omap2_gpio_s {
qemu_irq irq[2];
qemu_irq wkup;
qemu_irq *in;
qemu_irq handler[32];
qemu_irq *handler;
uint8_t revision;
uint8_t config[2];
uint32_t inputs;
uint32_t outputs;
@ -221,8 +198,21 @@ struct omap2_gpio_s {
uint8_t delay;
};
struct omap2_gpif_s {
SysBusDevice busdev;
int mpu_model;
void *iclk;
void *fclk[6];
int modulecount;
struct omap2_gpio_s *modules;
qemu_irq *handler;
int autoidle;
int gpo;
};
/* General-Purpose Interface of OMAP2/3 */
static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
int line)
int line)
{
qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
}
@ -269,10 +259,12 @@ static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
omap2_gpio_module_wake(s, line);
}
static void omap2_gpio_module_set(void *opaque, int line, int level)
static void omap2_gpio_set(void *opaque, int line, int level)
{
struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
struct omap2_gpif_s *p = opaque;
struct omap2_gpio_s *s = &p->modules[line >> 5];
line &= 31;
if (level) {
if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
omap2_gpio_module_int(s, line);
@ -308,7 +300,7 @@ static uint32_t omap2_gpio_module_read(void *opaque, target_phys_addr_t addr)
switch (addr) {
case 0x00: /* GPIO_REVISION */
return 0x18;
return s->revision;
case 0x10: /* GPIO_SYSCONFIG */
return s->config[0];
@ -583,45 +575,28 @@ static CPUWriteMemoryFunc * const omap2_gpio_module_writefn[] = {
omap2_gpio_module_write,
};
static void omap2_gpio_module_init(struct omap2_gpio_s *s,
struct omap_target_agent_s *ta, int region,
qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
omap_clk fclk, omap_clk iclk)
static void omap_gpif_reset(DeviceState *dev)
{
int iomemtype;
s->irq[0] = mpu;
s->irq[1] = dsp;
s->wkup = wkup;
s->in = qemu_allocate_irqs(omap2_gpio_module_set, s, 32);
iomemtype = l4_register_io_memory(omap2_gpio_module_readfn,
omap2_gpio_module_writefn, s);
omap_l4_attach(ta, region, iomemtype);
struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s,
sysbus_from_qdev(dev));
omap_gpio_reset(&s->omap1);
}
struct omap_gpif_s {
struct omap2_gpio_s module[5];
int modules;
int autoidle;
int gpo;
};
void omap_gpif_reset(struct omap_gpif_s *s)
static void omap2_gpif_reset(DeviceState *dev)
{
int i;
for (i = 0; i < s->modules; i ++)
omap2_gpio_module_reset(s->module + i);
struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s,
sysbus_from_qdev(dev));
for (i = 0; i < s->modulecount; i++) {
omap2_gpio_module_reset(&s->modules[i]);
}
s->autoidle = 0;
s->gpo = 0;
}
static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
static uint32_t omap2_gpif_top_read(void *opaque, target_phys_addr_t addr)
{
struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
switch (addr) {
case 0x00: /* IPGENERICOCPSPL_REVISION */
@ -647,10 +622,10 @@ static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
return 0;
}
static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
static void omap2_gpif_top_write(void *opaque, target_phys_addr_t addr,
uint32_t value)
{
struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
switch (addr) {
case 0x00: /* IPGENERICOCPSPL_REVISION */
@ -662,7 +637,7 @@ static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
if (value & (1 << 1)) /* SOFTRESET */
omap_gpif_reset(s);
omap2_gpif_reset(&s->busdev.qdev);
s->autoidle = value & 1;
break;
@ -676,50 +651,119 @@ static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
}
}
static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
omap_gpif_top_read,
omap_gpif_top_read,
omap_gpif_top_read,
static CPUReadMemoryFunc * const omap2_gpif_top_readfn[] = {
omap2_gpif_top_read,
omap2_gpif_top_read,
omap2_gpif_top_read,
};
static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
omap_gpif_top_write,
omap_gpif_top_write,
omap_gpif_top_write,
static CPUWriteMemoryFunc * const omap2_gpif_top_writefn[] = {
omap2_gpif_top_write,
omap2_gpif_top_write,
omap2_gpif_top_write,
};
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
static int omap_gpio_init(SysBusDevice *dev)
{
int iomemtype, i;
struct omap_gpif_s *s = (struct omap_gpif_s *)
qemu_mallocz(sizeof(struct omap_gpif_s));
int region[4] = { 0, 2, 4, 5 };
s->modules = modules;
for (i = 0; i < modules; i ++)
omap2_gpio_module_init(s->module + i, ta, region[i],
irq[i], NULL, NULL, fclk[i], iclk);
omap_gpif_reset(s);
iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
omap_gpif_top_writefn, s);
omap_l4_attach(ta, 1, iomemtype);
return s;
struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, dev);
if (!s->clk) {
hw_error("omap-gpio: clk not connected\n");
}
qdev_init_gpio_in(&dev->qdev, omap_gpio_set, 16);
qdev_init_gpio_out(&dev->qdev, s->omap1.handler, 16);
sysbus_init_irq(dev, &s->omap1.irq);
sysbus_init_mmio(dev, 0x1000,
cpu_register_io_memory(omap_gpio_readfn,
omap_gpio_writefn,
&s->omap1,
DEVICE_NATIVE_ENDIAN));
return 0;
}
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
static int omap2_gpio_init(SysBusDevice *dev)
{
if (start >= s->modules * 32 || start < 0)
hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
return s->module[start >> 5].in + (start & 31);
int i;
struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, dev);
if (!s->iclk) {
hw_error("omap2-gpio: iclk not connected\n");
}
if (s->mpu_model < omap3430) {
s->modulecount = (s->mpu_model < omap2430) ? 4 : 5;
sysbus_init_mmio(dev, 0x1000,
cpu_register_io_memory(omap2_gpif_top_readfn,
omap2_gpif_top_writefn, s,
DEVICE_NATIVE_ENDIAN));
} else {
s->modulecount = 6;
}
s->modules = qemu_mallocz(s->modulecount * sizeof(struct omap2_gpio_s));
s->handler = qemu_mallocz(s->modulecount * 32 * sizeof(qemu_irq));
qdev_init_gpio_in(&dev->qdev, omap2_gpio_set, s->modulecount * 32);
qdev_init_gpio_out(&dev->qdev, s->handler, s->modulecount * 32);
for (i = 0; i < s->modulecount; i++) {
struct omap2_gpio_s *m = &s->modules[i];
if (!s->fclk[i]) {
hw_error("omap2-gpio: fclk%d not connected\n", i);
}
m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25;
m->handler = &s->handler[i * 32];
sysbus_init_irq(dev, &m->irq[0]); /* mpu irq */
sysbus_init_irq(dev, &m->irq[1]); /* dsp irq */
sysbus_init_irq(dev, &m->wkup);
sysbus_init_mmio(dev, 0x1000,
cpu_register_io_memory(omap2_gpio_module_readfn,
omap2_gpio_module_writefn,
m, DEVICE_NATIVE_ENDIAN));
}
return 0;
}
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
/* Using qdev pointer properties for the clocks is not ideal.
* qdev should support a generic means of defining a 'port' with
* an arbitrary interface for connecting two devices. Then we
* could reframe the omap clock API in terms of clock ports,
* and get some type safety. For now the best qdev provides is
* passing an arbitrary pointer.
* (It's not possible to pass in the string which is the clock
* name, because this device does not have the necessary information
* (ie the struct omap_mpu_state_s*) to do the clockname to pointer
* translation.)
*/
static SysBusDeviceInfo omap_gpio_info = {
.init = omap_gpio_init,
.qdev.name = "omap-gpio",
.qdev.size = sizeof(struct omap_gpif_s),
.qdev.reset = omap_gpif_reset,
.qdev.props = (Property[]) {
DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
DEFINE_PROP_END_OF_LIST()
}
};
static SysBusDeviceInfo omap2_gpio_info = {
.init = omap2_gpio_init,
.qdev.name = "omap2-gpio",
.qdev.size = sizeof(struct omap2_gpif_s),
.qdev.reset = omap2_gpif_reset,
.qdev.props = (Property[]) {
DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
DEFINE_PROP_END_OF_LIST()
}
};
static void omap_gpio_register_device(void)
{
if (line >= s->modules * 32 || line < 0)
hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
s->module[line >> 5].handler[line & 31] = handler;
sysbus_register_withprop(&omap_gpio_info);
sysbus_register_withprop(&omap2_gpio_info);
}
device_init(omap_gpio_register_device)

View File

@ -94,7 +94,7 @@ static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
{
uWireSlave *tsc;
tsc = tsc2102_init(omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO]);
tsc = tsc2102_init(qdev_get_gpio_in(cpu->gpio, PALMTE_PINTDAV_GPIO));
omap_uwire_attach(cpu->microwire, tsc, 0);
omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
@ -163,24 +163,24 @@ static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
qemu_irq *misc_gpio;
omap_mmc_handlers(cpu->mmc,
omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO],
qdev_get_gpio_in(cpu->gpio, PALMTE_MMC_WP_GPIO),
qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
[PALMTE_MMC_SWITCH_GPIO]));
misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
omap_gpio_out_set(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]);
omap_gpio_out_set(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]);
omap_gpio_out_set(cpu->gpio, 11, misc_gpio[2]);
omap_gpio_out_set(cpu->gpio, 12, misc_gpio[3]);
omap_gpio_out_set(cpu->gpio, 13, misc_gpio[4]);
omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]);
omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]);
qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]);
qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]);
qdev_connect_gpio_out(cpu->gpio, 11, misc_gpio[2]);
qdev_connect_gpio_out(cpu->gpio, 12, misc_gpio[3]);
qdev_connect_gpio_out(cpu->gpio, 13, misc_gpio[4]);
omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]);
omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]);
/* Reset some inputs to initial state. */
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USBDETECT_GPIO]);
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USB_OR_DC_GPIO]);
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[4]);
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_HEADPHONES_GPIO]);
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USBDETECT_GPIO));
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USB_OR_DC_GPIO));
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, 4));
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_HEADPHONES_GPIO));
qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);