/*
 * TI OMAP processors GPIO emulation.
 *
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
 * Copyright (C) 2007-2009 Nokia Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "hw/hw.h"
#include "hw/arm/omap.h"
#include "hw/sysbus.h"

struct omap_gpio_s {
    qemu_irq irq;
    qemu_irq handler[16];

    uint16_t inputs;
    uint16_t outputs;
    uint16_t dir;
    uint16_t edge;
    uint16_t mask;
    uint16_t ints;
    uint16_t pins;
};

#define TYPE_OMAP1_GPIO "omap-gpio"
#define OMAP1_GPIO(obj) \
    OBJECT_CHECK(struct omap_gpif_s, (obj), TYPE_OMAP1_GPIO)

struct omap_gpif_s {
    SysBusDevice parent_obj;

    MemoryRegion iomem;
    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_gpif_s *) opaque)->omap1;
    uint16_t prev = s->inputs;

    if (level)
        s->inputs |= 1 << line;
    else
        s->inputs &= ~(1 << line);

    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
                    (1 << line) & s->dir & ~s->mask) {
        s->ints |= 1 << line;
        qemu_irq_raise(s->irq);
    }
}

static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
                               unsigned size)
{
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
    int offset = addr & OMAP_MPUI_REG_MASK;

    if (size != 2) {
        return omap_badwidth_read16(opaque, addr);
    }

    switch (offset) {
    case 0x00:	/* DATA_INPUT */
        return s->inputs & s->pins;

    case 0x04:	/* DATA_OUTPUT */
        return s->outputs;

    case 0x08:	/* DIRECTION_CONTROL */
        return s->dir;

    case 0x0c:	/* INTERRUPT_CONTROL */
        return s->edge;

    case 0x10:	/* INTERRUPT_MASK */
        return s->mask;

    case 0x14:	/* INTERRUPT_STATUS */
        return s->ints;

    case 0x18:	/* PIN_CONTROL (not in OMAP310) */
        OMAP_BAD_REG(addr);
        return s->pins;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap_gpio_write(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
{
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
    int offset = addr & OMAP_MPUI_REG_MASK;
    uint16_t diff;
    int ln;

    if (size != 2) {
        return omap_badwidth_write16(opaque, addr, value);
    }

    switch (offset) {
    case 0x00:	/* DATA_INPUT */
        OMAP_RO_REG(addr);
        return;

    case 0x04:	/* DATA_OUTPUT */
        diff = (s->outputs ^ value) & ~s->dir;
        s->outputs = value;
        while ((ln = ffs(diff))) {
            ln --;
            if (s->handler[ln])
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
            diff &= ~(1 << ln);
        }
        break;

    case 0x08:	/* DIRECTION_CONTROL */
        diff = s->outputs & (s->dir ^ value);
        s->dir = value;

        value = s->outputs & ~s->dir;
        while ((ln = ffs(diff))) {
            ln --;
            if (s->handler[ln])
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
            diff &= ~(1 << ln);
        }
        break;

    case 0x0c:	/* INTERRUPT_CONTROL */
        s->edge = value;
        break;

    case 0x10:	/* INTERRUPT_MASK */
        s->mask = value;
        break;

    case 0x14:	/* INTERRUPT_STATUS */
        s->ints &= ~value;
        if (!s->ints)
            qemu_irq_lower(s->irq);
        break;

    case 0x18:	/* PIN_CONTROL (not in OMAP310 TRM) */
        OMAP_BAD_REG(addr);
        s->pins = value;
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

/* *Some* sources say the memory region is 32-bit.  */
static const MemoryRegionOps omap_gpio_ops = {
    .read = omap_gpio_read,
    .write = omap_gpio_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void omap_gpio_reset(struct omap_gpio_s *s)
{
    s->inputs = 0;
    s->outputs = ~0;
    s->dir = ~0;
    s->edge = ~0;
    s->mask = ~0;
    s->ints = 0;
    s->pins = ~0;
}

struct omap2_gpio_s {
    qemu_irq irq[2];
    qemu_irq wkup;
    qemu_irq *handler;
    MemoryRegion iomem;

    uint8_t revision;
    uint8_t config[2];
    uint32_t inputs;
    uint32_t outputs;
    uint32_t dir;
    uint32_t level[2];
    uint32_t edge[2];
    uint32_t mask[2];
    uint32_t wumask;
    uint32_t ints[2];
    uint32_t debounce;
    uint8_t delay;
};

#define TYPE_OMAP2_GPIO "omap2-gpio"
#define OMAP2_GPIO(obj) \
    OBJECT_CHECK(struct omap2_gpif_s, (obj), TYPE_OMAP2_GPIO)

struct omap2_gpif_s {
    SysBusDevice parent_obj;

    MemoryRegion iomem;
    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)
{
    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
}

static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
{
    if (!(s->config[0] & (1 << 2)))			/* ENAWAKEUP */
        return;
    if (!(s->config[0] & (3 << 3)))			/* Force Idle */
        return;
    if (!(s->wumask & (1 << line)))
        return;

    qemu_irq_raise(s->wkup);
}

static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
                uint32_t diff)
{
    int ln;

    s->outputs ^= diff;
    diff &= ~s->dir;
    while ((ln = ffs(diff))) {
        ln --;
        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
        diff &= ~(1 << ln);
    }
}

static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
{
    s->ints[line] |= s->dir &
            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
    omap2_gpio_module_int_update(s, line);
}

static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
{
    s->ints[0] |= 1 << line;
    omap2_gpio_module_int_update(s, 0);
    s->ints[1] |= 1 << line;
    omap2_gpio_module_int_update(s, 1);
    omap2_gpio_module_wake(s, line);
}

static void omap2_gpio_set(void *opaque, int line, int level)
{
    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);
        s->inputs |= 1 << line;
    } else {
        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
            omap2_gpio_module_int(s, line);
        s->inputs &= ~(1 << line);
    }
}

static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
{
    s->config[0] = 0;
    s->config[1] = 2;
    s->ints[0] = 0;
    s->ints[1] = 0;
    s->mask[0] = 0;
    s->mask[1] = 0;
    s->wumask = 0;
    s->dir = ~0;
    s->level[0] = 0;
    s->level[1] = 0;
    s->edge[0] = 0;
    s->edge[1] = 0;
    s->debounce = 0;
    s->delay = 0;
}

static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
{
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;

    switch (addr) {
    case 0x00:	/* GPIO_REVISION */
        return s->revision;

    case 0x10:	/* GPIO_SYSCONFIG */
        return s->config[0];

    case 0x14:	/* GPIO_SYSSTATUS */
        return 0x01;

    case 0x18:	/* GPIO_IRQSTATUS1 */
        return s->ints[0];

    case 0x1c:	/* GPIO_IRQENABLE1 */
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
    case 0x64:	/* GPIO_SETIRQENABLE1 */
        return s->mask[0];

    case 0x20:	/* GPIO_WAKEUPENABLE */
    case 0x80:	/* GPIO_CLEARWKUENA */
    case 0x84:	/* GPIO_SETWKUENA */
        return s->wumask;

    case 0x28:	/* GPIO_IRQSTATUS2 */
        return s->ints[1];

    case 0x2c:	/* GPIO_IRQENABLE2 */
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
        return s->mask[1];

    case 0x30:	/* GPIO_CTRL */
        return s->config[1];

    case 0x34:	/* GPIO_OE */
        return s->dir;

    case 0x38:	/* GPIO_DATAIN */
        return s->inputs;

    case 0x3c:	/* GPIO_DATAOUT */
    case 0x90:	/* GPIO_CLEARDATAOUT */
    case 0x94:	/* GPIO_SETDATAOUT */
        return s->outputs;

    case 0x40:	/* GPIO_LEVELDETECT0 */
        return s->level[0];

    case 0x44:	/* GPIO_LEVELDETECT1 */
        return s->level[1];

    case 0x48:	/* GPIO_RISINGDETECT */
        return s->edge[0];

    case 0x4c:	/* GPIO_FALLINGDETECT */
        return s->edge[1];

    case 0x50:	/* GPIO_DEBOUNCENABLE */
        return s->debounce;

    case 0x54:	/* GPIO_DEBOUNCINGTIME */
        return s->delay;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap2_gpio_module_write(void *opaque, hwaddr addr,
                uint32_t value)
{
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
    uint32_t diff;
    int ln;

    switch (addr) {
    case 0x00:	/* GPIO_REVISION */
    case 0x14:	/* GPIO_SYSSTATUS */
    case 0x38:	/* GPIO_DATAIN */
        OMAP_RO_REG(addr);
        break;

    case 0x10:	/* GPIO_SYSCONFIG */
        if (((value >> 3) & 3) == 3)
            fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
        if (value & 2)
            omap2_gpio_module_reset(s);
        s->config[0] = value & 0x1d;
        break;

    case 0x18:	/* GPIO_IRQSTATUS1 */
        if (s->ints[0] & value) {
            s->ints[0] &= ~value;
            omap2_gpio_module_level_update(s, 0);
        }
        break;

    case 0x1c:	/* GPIO_IRQENABLE1 */
        s->mask[0] = value;
        omap2_gpio_module_int_update(s, 0);
        break;

    case 0x20:	/* GPIO_WAKEUPENABLE */
        s->wumask = value;
        break;

    case 0x28:	/* GPIO_IRQSTATUS2 */
        if (s->ints[1] & value) {
            s->ints[1] &= ~value;
            omap2_gpio_module_level_update(s, 1);
        }
        break;

    case 0x2c:	/* GPIO_IRQENABLE2 */
        s->mask[1] = value;
        omap2_gpio_module_int_update(s, 1);
        break;

    case 0x30:	/* GPIO_CTRL */
        s->config[1] = value & 7;
        break;

    case 0x34:	/* GPIO_OE */
        diff = s->outputs & (s->dir ^ value);
        s->dir = value;

        value = s->outputs & ~s->dir;
        while ((ln = ffs(diff))) {
            diff &= ~(1 <<-- ln);
            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
        }

        omap2_gpio_module_level_update(s, 0);
        omap2_gpio_module_level_update(s, 1);
        break;

    case 0x3c:	/* GPIO_DATAOUT */
        omap2_gpio_module_out_update(s, s->outputs ^ value);
        break;

    case 0x40:	/* GPIO_LEVELDETECT0 */
        s->level[0] = value;
        omap2_gpio_module_level_update(s, 0);
        omap2_gpio_module_level_update(s, 1);
        break;

    case 0x44:	/* GPIO_LEVELDETECT1 */
        s->level[1] = value;
        omap2_gpio_module_level_update(s, 0);
        omap2_gpio_module_level_update(s, 1);
        break;

    case 0x48:	/* GPIO_RISINGDETECT */
        s->edge[0] = value;
        break;

    case 0x4c:	/* GPIO_FALLINGDETECT */
        s->edge[1] = value;
        break;

    case 0x50:	/* GPIO_DEBOUNCENABLE */
        s->debounce = value;
        break;

    case 0x54:	/* GPIO_DEBOUNCINGTIME */
        s->delay = value;
        break;

    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
        s->mask[0] &= ~value;
        omap2_gpio_module_int_update(s, 0);
        break;

    case 0x64:	/* GPIO_SETIRQENABLE1 */
        s->mask[0] |= value;
        omap2_gpio_module_int_update(s, 0);
        break;

    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
        s->mask[1] &= ~value;
        omap2_gpio_module_int_update(s, 1);
        break;

    case 0x74:	/* GPIO_SETIREQNEABLE2 */
        s->mask[1] |= value;
        omap2_gpio_module_int_update(s, 1);
        break;

    case 0x80:	/* GPIO_CLEARWKUENA */
        s->wumask &= ~value;
        break;

    case 0x84:	/* GPIO_SETWKUENA */
        s->wumask |= value;
        break;

    case 0x90:	/* GPIO_CLEARDATAOUT */
        omap2_gpio_module_out_update(s, s->outputs & value);
        break;

    case 0x94:	/* GPIO_SETDATAOUT */
        omap2_gpio_module_out_update(s, ~s->outputs & value);
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

static uint32_t omap2_gpio_module_readp(void *opaque, hwaddr addr)
{
    return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3);
}

static void omap2_gpio_module_writep(void *opaque, hwaddr addr,
                uint32_t value)
{
    uint32_t cur = 0;
    uint32_t mask = 0xffff;

    switch (addr & ~3) {
    case 0x00:	/* GPIO_REVISION */
    case 0x14:	/* GPIO_SYSSTATUS */
    case 0x38:	/* GPIO_DATAIN */
        OMAP_RO_REG(addr);
        break;

    case 0x10:	/* GPIO_SYSCONFIG */
    case 0x1c:	/* GPIO_IRQENABLE1 */
    case 0x20:	/* GPIO_WAKEUPENABLE */
    case 0x2c:	/* GPIO_IRQENABLE2 */
    case 0x30:	/* GPIO_CTRL */
    case 0x34:	/* GPIO_OE */
    case 0x3c:	/* GPIO_DATAOUT */
    case 0x40:	/* GPIO_LEVELDETECT0 */
    case 0x44:	/* GPIO_LEVELDETECT1 */
    case 0x48:	/* GPIO_RISINGDETECT */
    case 0x4c:	/* GPIO_FALLINGDETECT */
    case 0x50:	/* GPIO_DEBOUNCENABLE */
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
        cur = omap2_gpio_module_read(opaque, addr & ~3) &
                ~(mask << ((addr & 3) << 3));

        /* Fall through.  */
    case 0x18:	/* GPIO_IRQSTATUS1 */
    case 0x28:	/* GPIO_IRQSTATUS2 */
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
    case 0x64:	/* GPIO_SETIRQENABLE1 */
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
    case 0x80:	/* GPIO_CLEARWKUENA */
    case 0x84:	/* GPIO_SETWKUENA */
    case 0x90:	/* GPIO_CLEARDATAOUT */
    case 0x94:	/* GPIO_SETDATAOUT */
        value <<= (addr & 3) << 3;
        omap2_gpio_module_write(opaque, addr, cur | value);
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

static const MemoryRegionOps omap2_gpio_module_ops = {
    .old_mmio = {
        .read = {
            omap2_gpio_module_readp,
            omap2_gpio_module_readp,
            omap2_gpio_module_read,
        },
        .write = {
            omap2_gpio_module_writep,
            omap2_gpio_module_writep,
            omap2_gpio_module_write,
        },
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void omap_gpif_reset(DeviceState *dev)
{
    struct omap_gpif_s *s = OMAP1_GPIO(dev);

    omap_gpio_reset(&s->omap1);
}

static void omap2_gpif_reset(DeviceState *dev)
{
    struct omap2_gpif_s *s = OMAP2_GPIO(dev);
    int i;

    for (i = 0; i < s->modulecount; i++) {
        omap2_gpio_module_reset(&s->modules[i]);
    }
    s->autoidle = 0;
    s->gpo = 0;
}

static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
                                    unsigned size)
{
    struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;

    switch (addr) {
    case 0x00:	/* IPGENERICOCPSPL_REVISION */
        return 0x18;

    case 0x10:	/* IPGENERICOCPSPL_SYSCONFIG */
        return s->autoidle;

    case 0x14:	/* IPGENERICOCPSPL_SYSSTATUS */
        return 0x01;

    case 0x18:	/* IPGENERICOCPSPL_IRQSTATUS */
        return 0x00;

    case 0x40:	/* IPGENERICOCPSPL_GPO */
        return s->gpo;

    case 0x50:	/* IPGENERICOCPSPL_GPI */
        return 0x00;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap2_gpif_top_write(void *opaque, hwaddr addr,
                                 uint64_t value, unsigned size)
{
    struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;

    switch (addr) {
    case 0x00:	/* IPGENERICOCPSPL_REVISION */
    case 0x14:	/* IPGENERICOCPSPL_SYSSTATUS */
    case 0x18:	/* IPGENERICOCPSPL_IRQSTATUS */
    case 0x50:	/* IPGENERICOCPSPL_GPI */
        OMAP_RO_REG(addr);
        break;

    case 0x10:	/* IPGENERICOCPSPL_SYSCONFIG */
        if (value & (1 << 1))					/* SOFTRESET */
            omap2_gpif_reset(DEVICE(s));
        s->autoidle = value & 1;
        break;

    case 0x40:	/* IPGENERICOCPSPL_GPO */
        s->gpo = value & 1;
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

static const MemoryRegionOps omap2_gpif_top_ops = {
    .read = omap2_gpif_top_read,
    .write = omap2_gpif_top_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static int omap_gpio_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    struct omap_gpif_s *s = OMAP1_GPIO(dev);

    if (!s->clk) {
        hw_error("omap-gpio: clk not connected\n");
    }
    qdev_init_gpio_in(dev, omap_gpio_set, 16);
    qdev_init_gpio_out(dev, s->omap1.handler, 16);
    sysbus_init_irq(sbd, &s->omap1.irq);
    memory_region_init_io(&s->iomem, OBJECT(s), &omap_gpio_ops, &s->omap1,
                          "omap.gpio", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    return 0;
}

static int omap2_gpio_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    struct omap2_gpif_s *s = OMAP2_GPIO(dev);
    int i;

    if (!s->iclk) {
        hw_error("omap2-gpio: iclk not connected\n");
    }
    if (s->mpu_model < omap3430) {
        s->modulecount = (s->mpu_model < omap2430) ? 4 : 5;
        memory_region_init_io(&s->iomem, OBJECT(s), &omap2_gpif_top_ops, s,
                              "omap2.gpio", 0x1000);
        sysbus_init_mmio(sbd, &s->iomem);
    } else {
        s->modulecount = 6;
    }
    s->modules = g_malloc0(s->modulecount * sizeof(struct omap2_gpio_s));
    s->handler = g_malloc0(s->modulecount * 32 * sizeof(qemu_irq));
    qdev_init_gpio_in(dev, omap2_gpio_set, s->modulecount * 32);
    qdev_init_gpio_out(dev, 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(sbd, &m->irq[0]); /* mpu irq */
        sysbus_init_irq(sbd, &m->irq[1]); /* dsp irq */
        sysbus_init_irq(sbd, &m->wkup);
        memory_region_init_io(&m->iomem, OBJECT(s), &omap2_gpio_module_ops, m,
                              "omap.gpio-module", 0x1000);
        sysbus_init_mmio(sbd, &m->iomem);
    }
    return 0;
}

/* 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 Property omap_gpio_properties[] = {
    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 void omap_gpio_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = omap_gpio_init;
    dc->reset = omap_gpif_reset;
    dc->props = omap_gpio_properties;
    /* Reason: pointer property "clk" */
    dc->cannot_instantiate_with_device_add_yet = true;
}

static const TypeInfo omap_gpio_info = {
    .name          = TYPE_OMAP1_GPIO,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(struct omap_gpif_s),
    .class_init    = omap_gpio_class_init,
};

static Property omap2_gpio_properties[] = {
    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 omap2_gpio_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = omap2_gpio_init;
    dc->reset = omap2_gpif_reset;
    dc->props = omap2_gpio_properties;
    /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
    dc->cannot_instantiate_with_device_add_yet = true;
}

static const TypeInfo omap2_gpio_info = {
    .name          = TYPE_OMAP2_GPIO,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(struct omap2_gpif_s),
    .class_init    = omap2_gpio_class_init,
};

static void omap_gpio_register_types(void)
{
    type_register_static(&omap_gpio_info);
    type_register_static(&omap2_gpio_info);
}

type_init(omap_gpio_register_types)
