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