qemu/hw/gpio/omap_gpio.c
<<
>>
Prefs
   1/*
   2 * TI OMAP processors GPIO emulation.
   3 *
   4 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
   5 * Copyright (C) 2007-2009 Nokia Corporation
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 or
  10 * (at your option) version 3 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along
  18 * with this program; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu/osdep.h"
  22#include "hw/irq.h"
  23#include "hw/qdev-properties.h"
  24#include "hw/arm/omap.h"
  25#include "hw/sysbus.h"
  26#include "qemu/error-report.h"
  27#include "qemu/module.h"
  28#include "qapi/error.h"
  29
  30struct omap_gpio_s {
  31    qemu_irq irq;
  32    qemu_irq handler[16];
  33
  34    uint16_t inputs;
  35    uint16_t outputs;
  36    uint16_t dir;
  37    uint16_t edge;
  38    uint16_t mask;
  39    uint16_t ints;
  40    uint16_t pins;
  41};
  42
  43#define TYPE_OMAP1_GPIO "omap-gpio"
  44#define OMAP1_GPIO(obj) \
  45    OBJECT_CHECK(struct omap_gpif_s, (obj), TYPE_OMAP1_GPIO)
  46
  47struct omap_gpif_s {
  48    SysBusDevice parent_obj;
  49
  50    MemoryRegion iomem;
  51    int mpu_model;
  52    void *clk;
  53    struct omap_gpio_s omap1;
  54};
  55
  56/* General-Purpose I/O of OMAP1 */
  57static void omap_gpio_set(void *opaque, int line, int level)
  58{
  59    struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1;
  60    uint16_t prev = s->inputs;
  61
  62    if (level)
  63        s->inputs |= 1 << line;
  64    else
  65        s->inputs &= ~(1 << line);
  66
  67    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
  68                    (1 << line) & s->dir & ~s->mask) {
  69        s->ints |= 1 << line;
  70        qemu_irq_raise(s->irq);
  71    }
  72}
  73
  74static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
  75                               unsigned size)
  76{
  77    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
  78    int offset = addr & OMAP_MPUI_REG_MASK;
  79
  80    if (size != 2) {
  81        return omap_badwidth_read16(opaque, addr);
  82    }
  83
  84    switch (offset) {
  85    case 0x00:  /* DATA_INPUT */
  86        return s->inputs & s->pins;
  87
  88    case 0x04:  /* DATA_OUTPUT */
  89        return s->outputs;
  90
  91    case 0x08:  /* DIRECTION_CONTROL */
  92        return s->dir;
  93
  94    case 0x0c:  /* INTERRUPT_CONTROL */
  95        return s->edge;
  96
  97    case 0x10:  /* INTERRUPT_MASK */
  98        return s->mask;
  99
 100    case 0x14:  /* INTERRUPT_STATUS */
 101        return s->ints;
 102
 103    case 0x18:  /* PIN_CONTROL (not in OMAP310) */
 104        OMAP_BAD_REG(addr);
 105        return s->pins;
 106    }
 107
 108    OMAP_BAD_REG(addr);
 109    return 0;
 110}
 111
 112static void omap_gpio_write(void *opaque, hwaddr addr,
 113                            uint64_t value, unsigned size)
 114{
 115    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
 116    int offset = addr & OMAP_MPUI_REG_MASK;
 117    uint16_t diff;
 118    int ln;
 119
 120    if (size != 2) {
 121        omap_badwidth_write16(opaque, addr, value);
 122        return;
 123    }
 124
 125    switch (offset) {
 126    case 0x00:  /* DATA_INPUT */
 127        OMAP_RO_REG(addr);
 128        return;
 129
 130    case 0x04:  /* DATA_OUTPUT */
 131        diff = (s->outputs ^ value) & ~s->dir;
 132        s->outputs = value;
 133        while ((ln = ctz32(diff)) != 32) {
 134            if (s->handler[ln])
 135                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 136            diff &= ~(1 << ln);
 137        }
 138        break;
 139
 140    case 0x08:  /* DIRECTION_CONTROL */
 141        diff = s->outputs & (s->dir ^ value);
 142        s->dir = value;
 143
 144        value = s->outputs & ~s->dir;
 145        while ((ln = ctz32(diff)) != 32) {
 146            if (s->handler[ln])
 147                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 148            diff &= ~(1 << ln);
 149        }
 150        break;
 151
 152    case 0x0c:  /* INTERRUPT_CONTROL */
 153        s->edge = value;
 154        break;
 155
 156    case 0x10:  /* INTERRUPT_MASK */
 157        s->mask = value;
 158        break;
 159
 160    case 0x14:  /* INTERRUPT_STATUS */
 161        s->ints &= ~value;
 162        if (!s->ints)
 163            qemu_irq_lower(s->irq);
 164        break;
 165
 166    case 0x18:  /* PIN_CONTROL (not in OMAP310 TRM) */
 167        OMAP_BAD_REG(addr);
 168        s->pins = value;
 169        break;
 170
 171    default:
 172        OMAP_BAD_REG(addr);
 173        return;
 174    }
 175}
 176
 177/* *Some* sources say the memory region is 32-bit.  */
 178static const MemoryRegionOps omap_gpio_ops = {
 179    .read = omap_gpio_read,
 180    .write = omap_gpio_write,
 181    .endianness = DEVICE_NATIVE_ENDIAN,
 182};
 183
 184static void omap_gpio_reset(struct omap_gpio_s *s)
 185{
 186    s->inputs = 0;
 187    s->outputs = ~0;
 188    s->dir = ~0;
 189    s->edge = ~0;
 190    s->mask = ~0;
 191    s->ints = 0;
 192    s->pins = ~0;
 193}
 194
 195struct omap2_gpio_s {
 196    qemu_irq irq[2];
 197    qemu_irq wkup;
 198    qemu_irq *handler;
 199    MemoryRegion iomem;
 200
 201    uint8_t revision;
 202    uint8_t config[2];
 203    uint32_t inputs;
 204    uint32_t outputs;
 205    uint32_t dir;
 206    uint32_t level[2];
 207    uint32_t edge[2];
 208    uint32_t mask[2];
 209    uint32_t wumask;
 210    uint32_t ints[2];
 211    uint32_t debounce;
 212    uint8_t delay;
 213};
 214
 215#define TYPE_OMAP2_GPIO "omap2-gpio"
 216#define OMAP2_GPIO(obj) \
 217    OBJECT_CHECK(struct omap2_gpif_s, (obj), TYPE_OMAP2_GPIO)
 218
 219struct omap2_gpif_s {
 220    SysBusDevice parent_obj;
 221
 222    MemoryRegion iomem;
 223    int mpu_model;
 224    void *iclk;
 225    void *fclk[6];
 226    int modulecount;
 227    struct omap2_gpio_s *modules;
 228    qemu_irq *handler;
 229    int autoidle;
 230    int gpo;
 231};
 232
 233/* General-Purpose Interface of OMAP2/3 */
 234static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
 235                                                int line)
 236{
 237    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
 238}
 239
 240static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
 241{
 242    if (!(s->config[0] & (1 << 2)))                     /* ENAWAKEUP */
 243        return;
 244    if (!(s->config[0] & (3 << 3)))                     /* Force Idle */
 245        return;
 246    if (!(s->wumask & (1 << line)))
 247        return;
 248
 249    qemu_irq_raise(s->wkup);
 250}
 251
 252static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
 253                uint32_t diff)
 254{
 255    int ln;
 256
 257    s->outputs ^= diff;
 258    diff &= ~s->dir;
 259    while ((ln = ctz32(diff)) != 32) {
 260        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
 261        diff &= ~(1 << ln);
 262    }
 263}
 264
 265static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
 266{
 267    s->ints[line] |= s->dir &
 268            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
 269    omap2_gpio_module_int_update(s, line);
 270}
 271
 272static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
 273{
 274    s->ints[0] |= 1 << line;
 275    omap2_gpio_module_int_update(s, 0);
 276    s->ints[1] |= 1 << line;
 277    omap2_gpio_module_int_update(s, 1);
 278    omap2_gpio_module_wake(s, line);
 279}
 280
 281static void omap2_gpio_set(void *opaque, int line, int level)
 282{
 283    struct omap2_gpif_s *p = opaque;
 284    struct omap2_gpio_s *s = &p->modules[line >> 5];
 285
 286    line &= 31;
 287    if (level) {
 288        if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
 289            omap2_gpio_module_int(s, line);
 290        s->inputs |= 1 << line;
 291    } else {
 292        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
 293            omap2_gpio_module_int(s, line);
 294        s->inputs &= ~(1 << line);
 295    }
 296}
 297
 298static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
 299{
 300    s->config[0] = 0;
 301    s->config[1] = 2;
 302    s->ints[0] = 0;
 303    s->ints[1] = 0;
 304    s->mask[0] = 0;
 305    s->mask[1] = 0;
 306    s->wumask = 0;
 307    s->dir = ~0;
 308    s->level[0] = 0;
 309    s->level[1] = 0;
 310    s->edge[0] = 0;
 311    s->edge[1] = 0;
 312    s->debounce = 0;
 313    s->delay = 0;
 314}
 315
 316static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
 317{
 318    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
 319
 320    switch (addr) {
 321    case 0x00:  /* GPIO_REVISION */
 322        return s->revision;
 323
 324    case 0x10:  /* GPIO_SYSCONFIG */
 325        return s->config[0];
 326
 327    case 0x14:  /* GPIO_SYSSTATUS */
 328        return 0x01;
 329
 330    case 0x18:  /* GPIO_IRQSTATUS1 */
 331        return s->ints[0];
 332
 333    case 0x1c:  /* GPIO_IRQENABLE1 */
 334    case 0x60:  /* GPIO_CLEARIRQENABLE1 */
 335    case 0x64:  /* GPIO_SETIRQENABLE1 */
 336        return s->mask[0];
 337
 338    case 0x20:  /* GPIO_WAKEUPENABLE */
 339    case 0x80:  /* GPIO_CLEARWKUENA */
 340    case 0x84:  /* GPIO_SETWKUENA */
 341        return s->wumask;
 342
 343    case 0x28:  /* GPIO_IRQSTATUS2 */
 344        return s->ints[1];
 345
 346    case 0x2c:  /* GPIO_IRQENABLE2 */
 347    case 0x70:  /* GPIO_CLEARIRQENABLE2 */
 348    case 0x74:  /* GPIO_SETIREQNEABLE2 */
 349        return s->mask[1];
 350
 351    case 0x30:  /* GPIO_CTRL */
 352        return s->config[1];
 353
 354    case 0x34:  /* GPIO_OE */
 355        return s->dir;
 356
 357    case 0x38:  /* GPIO_DATAIN */
 358        return s->inputs;
 359
 360    case 0x3c:  /* GPIO_DATAOUT */
 361    case 0x90:  /* GPIO_CLEARDATAOUT */
 362    case 0x94:  /* GPIO_SETDATAOUT */
 363        return s->outputs;
 364
 365    case 0x40:  /* GPIO_LEVELDETECT0 */
 366        return s->level[0];
 367
 368    case 0x44:  /* GPIO_LEVELDETECT1 */
 369        return s->level[1];
 370
 371    case 0x48:  /* GPIO_RISINGDETECT */
 372        return s->edge[0];
 373
 374    case 0x4c:  /* GPIO_FALLINGDETECT */
 375        return s->edge[1];
 376
 377    case 0x50:  /* GPIO_DEBOUNCENABLE */
 378        return s->debounce;
 379
 380    case 0x54:  /* GPIO_DEBOUNCINGTIME */
 381        return s->delay;
 382    }
 383
 384    OMAP_BAD_REG(addr);
 385    return 0;
 386}
 387
 388static void omap2_gpio_module_write(void *opaque, hwaddr addr,
 389                uint32_t value)
 390{
 391    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
 392    uint32_t diff;
 393    int ln;
 394
 395    switch (addr) {
 396    case 0x00:  /* GPIO_REVISION */
 397    case 0x14:  /* GPIO_SYSSTATUS */
 398    case 0x38:  /* GPIO_DATAIN */
 399        OMAP_RO_REG(addr);
 400        break;
 401
 402    case 0x10:  /* GPIO_SYSCONFIG */
 403        if (((value >> 3) & 3) == 3)
 404            fprintf(stderr, "%s: bad IDLEMODE value\n", __func__);
 405        if (value & 2)
 406            omap2_gpio_module_reset(s);
 407        s->config[0] = value & 0x1d;
 408        break;
 409
 410    case 0x18:  /* GPIO_IRQSTATUS1 */
 411        if (s->ints[0] & value) {
 412            s->ints[0] &= ~value;
 413            omap2_gpio_module_level_update(s, 0);
 414        }
 415        break;
 416
 417    case 0x1c:  /* GPIO_IRQENABLE1 */
 418        s->mask[0] = value;
 419        omap2_gpio_module_int_update(s, 0);
 420        break;
 421
 422    case 0x20:  /* GPIO_WAKEUPENABLE */
 423        s->wumask = value;
 424        break;
 425
 426    case 0x28:  /* GPIO_IRQSTATUS2 */
 427        if (s->ints[1] & value) {
 428            s->ints[1] &= ~value;
 429            omap2_gpio_module_level_update(s, 1);
 430        }
 431        break;
 432
 433    case 0x2c:  /* GPIO_IRQENABLE2 */
 434        s->mask[1] = value;
 435        omap2_gpio_module_int_update(s, 1);
 436        break;
 437
 438    case 0x30:  /* GPIO_CTRL */
 439        s->config[1] = value & 7;
 440        break;
 441
 442    case 0x34:  /* GPIO_OE */
 443        diff = s->outputs & (s->dir ^ value);
 444        s->dir = value;
 445
 446        value = s->outputs & ~s->dir;
 447        while ((ln = ctz32(diff)) != 32) {
 448            diff &= ~(1 << ln);
 449            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 450        }
 451
 452        omap2_gpio_module_level_update(s, 0);
 453        omap2_gpio_module_level_update(s, 1);
 454        break;
 455
 456    case 0x3c:  /* GPIO_DATAOUT */
 457        omap2_gpio_module_out_update(s, s->outputs ^ value);
 458        break;
 459
 460    case 0x40:  /* GPIO_LEVELDETECT0 */
 461        s->level[0] = value;
 462        omap2_gpio_module_level_update(s, 0);
 463        omap2_gpio_module_level_update(s, 1);
 464        break;
 465
 466    case 0x44:  /* GPIO_LEVELDETECT1 */
 467        s->level[1] = value;
 468        omap2_gpio_module_level_update(s, 0);
 469        omap2_gpio_module_level_update(s, 1);
 470        break;
 471
 472    case 0x48:  /* GPIO_RISINGDETECT */
 473        s->edge[0] = value;
 474        break;
 475
 476    case 0x4c:  /* GPIO_FALLINGDETECT */
 477        s->edge[1] = value;
 478        break;
 479
 480    case 0x50:  /* GPIO_DEBOUNCENABLE */
 481        s->debounce = value;
 482        break;
 483
 484    case 0x54:  /* GPIO_DEBOUNCINGTIME */
 485        s->delay = value;
 486        break;
 487
 488    case 0x60:  /* GPIO_CLEARIRQENABLE1 */
 489        s->mask[0] &= ~value;
 490        omap2_gpio_module_int_update(s, 0);
 491        break;
 492
 493    case 0x64:  /* GPIO_SETIRQENABLE1 */
 494        s->mask[0] |= value;
 495        omap2_gpio_module_int_update(s, 0);
 496        break;
 497
 498    case 0x70:  /* GPIO_CLEARIRQENABLE2 */
 499        s->mask[1] &= ~value;
 500        omap2_gpio_module_int_update(s, 1);
 501        break;
 502
 503    case 0x74:  /* GPIO_SETIREQNEABLE2 */
 504        s->mask[1] |= value;
 505        omap2_gpio_module_int_update(s, 1);
 506        break;
 507
 508    case 0x80:  /* GPIO_CLEARWKUENA */
 509        s->wumask &= ~value;
 510        break;
 511
 512    case 0x84:  /* GPIO_SETWKUENA */
 513        s->wumask |= value;
 514        break;
 515
 516    case 0x90:  /* GPIO_CLEARDATAOUT */
 517        omap2_gpio_module_out_update(s, s->outputs & value);
 518        break;
 519
 520    case 0x94:  /* GPIO_SETDATAOUT */
 521        omap2_gpio_module_out_update(s, ~s->outputs & value);
 522        break;
 523
 524    default:
 525        OMAP_BAD_REG(addr);
 526        return;
 527    }
 528}
 529
 530static uint64_t omap2_gpio_module_readp(void *opaque, hwaddr addr,
 531                                        unsigned size)
 532{
 533    return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3);
 534}
 535
 536static void omap2_gpio_module_writep(void *opaque, hwaddr addr,
 537                                     uint64_t value, unsigned size)
 538{
 539    uint32_t cur = 0;
 540    uint32_t mask = 0xffff;
 541
 542    if (size == 4) {
 543        omap2_gpio_module_write(opaque, addr, value);
 544        return;
 545    }
 546
 547    switch (addr & ~3) {
 548    case 0x00:  /* GPIO_REVISION */
 549    case 0x14:  /* GPIO_SYSSTATUS */
 550    case 0x38:  /* GPIO_DATAIN */
 551        OMAP_RO_REG(addr);
 552        break;
 553
 554    case 0x10:  /* GPIO_SYSCONFIG */
 555    case 0x1c:  /* GPIO_IRQENABLE1 */
 556    case 0x20:  /* GPIO_WAKEUPENABLE */
 557    case 0x2c:  /* GPIO_IRQENABLE2 */
 558    case 0x30:  /* GPIO_CTRL */
 559    case 0x34:  /* GPIO_OE */
 560    case 0x3c:  /* GPIO_DATAOUT */
 561    case 0x40:  /* GPIO_LEVELDETECT0 */
 562    case 0x44:  /* GPIO_LEVELDETECT1 */
 563    case 0x48:  /* GPIO_RISINGDETECT */
 564    case 0x4c:  /* GPIO_FALLINGDETECT */
 565    case 0x50:  /* GPIO_DEBOUNCENABLE */
 566    case 0x54:  /* GPIO_DEBOUNCINGTIME */
 567        cur = omap2_gpio_module_read(opaque, addr & ~3) &
 568                ~(mask << ((addr & 3) << 3));
 569
 570        /* Fall through.  */
 571    case 0x18:  /* GPIO_IRQSTATUS1 */
 572    case 0x28:  /* GPIO_IRQSTATUS2 */
 573    case 0x60:  /* GPIO_CLEARIRQENABLE1 */
 574    case 0x64:  /* GPIO_SETIRQENABLE1 */
 575    case 0x70:  /* GPIO_CLEARIRQENABLE2 */
 576    case 0x74:  /* GPIO_SETIREQNEABLE2 */
 577    case 0x80:  /* GPIO_CLEARWKUENA */
 578    case 0x84:  /* GPIO_SETWKUENA */
 579    case 0x90:  /* GPIO_CLEARDATAOUT */
 580    case 0x94:  /* GPIO_SETDATAOUT */
 581        value <<= (addr & 3) << 3;
 582        omap2_gpio_module_write(opaque, addr, cur | value);
 583        break;
 584
 585    default:
 586        OMAP_BAD_REG(addr);
 587        return;
 588    }
 589}
 590
 591static const MemoryRegionOps omap2_gpio_module_ops = {
 592    .read = omap2_gpio_module_readp,
 593    .write = omap2_gpio_module_writep,
 594    .valid.min_access_size = 1,
 595    .valid.max_access_size = 4,
 596    .endianness = DEVICE_NATIVE_ENDIAN,
 597};
 598
 599static void omap_gpif_reset(DeviceState *dev)
 600{
 601    struct omap_gpif_s *s = OMAP1_GPIO(dev);
 602
 603    omap_gpio_reset(&s->omap1);
 604}
 605
 606static void omap2_gpif_reset(DeviceState *dev)
 607{
 608    struct omap2_gpif_s *s = OMAP2_GPIO(dev);
 609    int i;
 610
 611    for (i = 0; i < s->modulecount; i++) {
 612        omap2_gpio_module_reset(&s->modules[i]);
 613    }
 614    s->autoidle = 0;
 615    s->gpo = 0;
 616}
 617
 618static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
 619                                    unsigned size)
 620{
 621    struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
 622
 623    switch (addr) {
 624    case 0x00:  /* IPGENERICOCPSPL_REVISION */
 625        return 0x18;
 626
 627    case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
 628        return s->autoidle;
 629
 630    case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
 631        return 0x01;
 632
 633    case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
 634        return 0x00;
 635
 636    case 0x40:  /* IPGENERICOCPSPL_GPO */
 637        return s->gpo;
 638
 639    case 0x50:  /* IPGENERICOCPSPL_GPI */
 640        return 0x00;
 641    }
 642
 643    OMAP_BAD_REG(addr);
 644    return 0;
 645}
 646
 647static void omap2_gpif_top_write(void *opaque, hwaddr addr,
 648                                 uint64_t value, unsigned size)
 649{
 650    struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
 651
 652    switch (addr) {
 653    case 0x00:  /* IPGENERICOCPSPL_REVISION */
 654    case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
 655    case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
 656    case 0x50:  /* IPGENERICOCPSPL_GPI */
 657        OMAP_RO_REG(addr);
 658        break;
 659
 660    case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
 661        if (value & (1 << 1))                                   /* SOFTRESET */
 662            omap2_gpif_reset(DEVICE(s));
 663        s->autoidle = value & 1;
 664        break;
 665
 666    case 0x40:  /* IPGENERICOCPSPL_GPO */
 667        s->gpo = value & 1;
 668        break;
 669
 670    default:
 671        OMAP_BAD_REG(addr);
 672        return;
 673    }
 674}
 675
 676static const MemoryRegionOps omap2_gpif_top_ops = {
 677    .read = omap2_gpif_top_read,
 678    .write = omap2_gpif_top_write,
 679    .endianness = DEVICE_NATIVE_ENDIAN,
 680};
 681
 682static void omap_gpio_init(Object *obj)
 683{
 684    DeviceState *dev = DEVICE(obj);
 685    struct omap_gpif_s *s = OMAP1_GPIO(obj);
 686    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 687
 688    qdev_init_gpio_in(dev, omap_gpio_set, 16);
 689    qdev_init_gpio_out(dev, s->omap1.handler, 16);
 690    sysbus_init_irq(sbd, &s->omap1.irq);
 691    memory_region_init_io(&s->iomem, obj, &omap_gpio_ops, &s->omap1,
 692                          "omap.gpio", 0x1000);
 693    sysbus_init_mmio(sbd, &s->iomem);
 694}
 695
 696static void omap_gpio_realize(DeviceState *dev, Error **errp)
 697{
 698    struct omap_gpif_s *s = OMAP1_GPIO(dev);
 699
 700    if (!s->clk) {
 701        error_setg(errp, "omap-gpio: clk not connected");
 702    }
 703}
 704
 705static void omap2_gpio_realize(DeviceState *dev, Error **errp)
 706{
 707    struct omap2_gpif_s *s = OMAP2_GPIO(dev);
 708    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 709    int i;
 710
 711    if (!s->iclk) {
 712        error_setg(errp, "omap2-gpio: iclk not connected");
 713        return;
 714    }
 715
 716    s->modulecount = s->mpu_model < omap2430 ? 4
 717        : s->mpu_model < omap3430 ? 5
 718        : 6;
 719
 720    if (s->mpu_model < omap3430) {
 721        memory_region_init_io(&s->iomem, OBJECT(dev), &omap2_gpif_top_ops, s,
 722                              "omap2.gpio", 0x1000);
 723        sysbus_init_mmio(sbd, &s->iomem);
 724    }
 725
 726    s->modules = g_new0(struct omap2_gpio_s, s->modulecount);
 727    s->handler = g_new0(qemu_irq, s->modulecount * 32);
 728    qdev_init_gpio_in(dev, omap2_gpio_set, s->modulecount * 32);
 729    qdev_init_gpio_out(dev, s->handler, s->modulecount * 32);
 730
 731    for (i = 0; i < s->modulecount; i++) {
 732        struct omap2_gpio_s *m = &s->modules[i];
 733
 734        if (!s->fclk[i]) {
 735            error_setg(errp, "omap2-gpio: fclk%d not connected", i);
 736            return;
 737        }
 738
 739        m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25;
 740        m->handler = &s->handler[i * 32];
 741        sysbus_init_irq(sbd, &m->irq[0]); /* mpu irq */
 742        sysbus_init_irq(sbd, &m->irq[1]); /* dsp irq */
 743        sysbus_init_irq(sbd, &m->wkup);
 744        memory_region_init_io(&m->iomem, OBJECT(dev), &omap2_gpio_module_ops, m,
 745                              "omap.gpio-module", 0x1000);
 746        sysbus_init_mmio(sbd, &m->iomem);
 747    }
 748}
 749
 750/* Using qdev pointer properties for the clocks is not ideal.
 751 * qdev should support a generic means of defining a 'port' with
 752 * an arbitrary interface for connecting two devices. Then we
 753 * could reframe the omap clock API in terms of clock ports,
 754 * and get some type safety. For now the best qdev provides is
 755 * passing an arbitrary pointer.
 756 * (It's not possible to pass in the string which is the clock
 757 * name, because this device does not have the necessary information
 758 * (ie the struct omap_mpu_state_s*) to do the clockname to pointer
 759 * translation.)
 760 */
 761
 762static Property omap_gpio_properties[] = {
 763    DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
 764    DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
 765    DEFINE_PROP_END_OF_LIST(),
 766};
 767
 768static void omap_gpio_class_init(ObjectClass *klass, void *data)
 769{
 770    DeviceClass *dc = DEVICE_CLASS(klass);
 771
 772    dc->realize = omap_gpio_realize;
 773    dc->reset = omap_gpif_reset;
 774    dc->props = omap_gpio_properties;
 775    /* Reason: pointer property "clk" */
 776    dc->user_creatable = false;
 777}
 778
 779static const TypeInfo omap_gpio_info = {
 780    .name          = TYPE_OMAP1_GPIO,
 781    .parent        = TYPE_SYS_BUS_DEVICE,
 782    .instance_size = sizeof(struct omap_gpif_s),
 783    .instance_init = omap_gpio_init,
 784    .class_init    = omap_gpio_class_init,
 785};
 786
 787static Property omap2_gpio_properties[] = {
 788    DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
 789    DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
 790    DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
 791    DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
 792    DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
 793    DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
 794    DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
 795    DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
 796    DEFINE_PROP_END_OF_LIST(),
 797};
 798
 799static void omap2_gpio_class_init(ObjectClass *klass, void *data)
 800{
 801    DeviceClass *dc = DEVICE_CLASS(klass);
 802
 803    dc->realize = omap2_gpio_realize;
 804    dc->reset = omap2_gpif_reset;
 805    dc->props = omap2_gpio_properties;
 806    /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
 807    dc->user_creatable = false;
 808}
 809
 810static const TypeInfo omap2_gpio_info = {
 811    .name          = TYPE_OMAP2_GPIO,
 812    .parent        = TYPE_SYS_BUS_DEVICE,
 813    .instance_size = sizeof(struct omap2_gpif_s),
 814    .class_init    = omap2_gpio_class_init,
 815};
 816
 817static void omap_gpio_register_types(void)
 818{
 819    type_register_static(&omap_gpio_info);
 820    type_register_static(&omap2_gpio_info);
 821}
 822
 823type_init(omap_gpio_register_types)
 824