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