qemu/hw/timer/pxa2xx_timer.c
<<
>>
Prefs
   1/*
   2 * Intel XScale PXA255/270 OS Timers.
   3 *
   4 * Copyright (c) 2006 Openedhand Ltd.
   5 * Copyright (c) 2006 Thorsten Zitterell
   6 *
   7 * This code is licensed under the GPL.
   8 */
   9
  10#include "qemu/osdep.h"
  11#include "hw/irq.h"
  12#include "hw/qdev-properties.h"
  13#include "qemu/timer.h"
  14#include "sysemu/runstate.h"
  15#include "hw/arm/pxa.h"
  16#include "hw/sysbus.h"
  17#include "migration/vmstate.h"
  18#include "qemu/log.h"
  19#include "qemu/module.h"
  20#include "qom/object.h"
  21
  22#define OSMR0   0x00
  23#define OSMR1   0x04
  24#define OSMR2   0x08
  25#define OSMR3   0x0c
  26#define OSMR4   0x80
  27#define OSMR5   0x84
  28#define OSMR6   0x88
  29#define OSMR7   0x8c
  30#define OSMR8   0x90
  31#define OSMR9   0x94
  32#define OSMR10  0x98
  33#define OSMR11  0x9c
  34#define OSCR    0x10    /* OS Timer Count */
  35#define OSCR4   0x40
  36#define OSCR5   0x44
  37#define OSCR6   0x48
  38#define OSCR7   0x4c
  39#define OSCR8   0x50
  40#define OSCR9   0x54
  41#define OSCR10  0x58
  42#define OSCR11  0x5c
  43#define OSSR    0x14    /* Timer status register */
  44#define OWER    0x18
  45#define OIER    0x1c    /* Interrupt enable register  3-0 to E3-E0 */
  46#define OMCR4   0xc0    /* OS Match Control registers */
  47#define OMCR5   0xc4
  48#define OMCR6   0xc8
  49#define OMCR7   0xcc
  50#define OMCR8   0xd0
  51#define OMCR9   0xd4
  52#define OMCR10  0xd8
  53#define OMCR11  0xdc
  54#define OSNR    0x20
  55
  56#define PXA25X_FREQ     3686400 /* 3.6864 MHz */
  57#define PXA27X_FREQ     3250000 /* 3.25 MHz */
  58
  59static int pxa2xx_timer4_freq[8] = {
  60    [0] = 0,
  61    [1] = 32768,
  62    [2] = 1000,
  63    [3] = 1,
  64    [4] = 1000000,
  65    /* [5] is the "Externally supplied clock".  Assign if necessary.  */
  66    [5 ... 7] = 0,
  67};
  68
  69#define TYPE_PXA2XX_TIMER "pxa2xx-timer"
  70OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxTimerInfo, PXA2XX_TIMER)
  71
  72
  73typedef struct {
  74    uint32_t value;
  75    qemu_irq irq;
  76    QEMUTimer *qtimer;
  77    int num;
  78    PXA2xxTimerInfo *info;
  79} PXA2xxTimer0;
  80
  81typedef struct {
  82    PXA2xxTimer0 tm;
  83    int32_t oldclock;
  84    int32_t clock;
  85    uint64_t lastload;
  86    uint32_t freq;
  87    uint32_t control;
  88} PXA2xxTimer4;
  89
  90struct PXA2xxTimerInfo {
  91    SysBusDevice parent_obj;
  92
  93    MemoryRegion iomem;
  94    uint32_t flags;
  95
  96    int32_t clock;
  97    int32_t oldclock;
  98    uint64_t lastload;
  99    uint32_t freq;
 100    PXA2xxTimer0 timer[4];
 101    uint32_t events;
 102    uint32_t irq_enabled;
 103    uint32_t reset3;
 104    uint32_t snapshot;
 105
 106    qemu_irq irq4;
 107    PXA2xxTimer4 tm4[8];
 108};
 109
 110#define PXA2XX_TIMER_HAVE_TM4   0
 111
 112static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
 113{
 114    return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4);
 115}
 116
 117static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
 118{
 119    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
 120    int i;
 121    uint32_t now_vm;
 122    uint64_t new_qemu;
 123
 124    now_vm = s->clock +
 125            muldiv64(now_qemu - s->lastload, s->freq, NANOSECONDS_PER_SECOND);
 126
 127    for (i = 0; i < 4; i ++) {
 128        new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
 129                        NANOSECONDS_PER_SECOND, s->freq);
 130        timer_mod(s->timer[i].qtimer, new_qemu);
 131    }
 132}
 133
 134static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
 135{
 136    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
 137    uint32_t now_vm;
 138    uint64_t new_qemu;
 139    static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
 140    int counter;
 141
 142    assert(n < ARRAY_SIZE(counters));
 143    if (s->tm4[n].control & (1 << 7))
 144        counter = n;
 145    else
 146        counter = counters[n];
 147
 148    if (!s->tm4[counter].freq) {
 149        timer_del(s->tm4[n].tm.qtimer);
 150        return;
 151    }
 152
 153    now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
 154                    s->tm4[counter].lastload,
 155                    s->tm4[counter].freq, NANOSECONDS_PER_SECOND);
 156
 157    new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
 158                    NANOSECONDS_PER_SECOND, s->tm4[counter].freq);
 159    timer_mod(s->tm4[n].tm.qtimer, new_qemu);
 160}
 161
 162static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
 163                                  unsigned size)
 164{
 165    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
 166    int tm = 0;
 167
 168    switch (offset) {
 169    case OSMR3:  tm ++;
 170        /* fall through */
 171    case OSMR2:  tm ++;
 172        /* fall through */
 173    case OSMR1:  tm ++;
 174        /* fall through */
 175    case OSMR0:
 176        return s->timer[tm].value;
 177    case OSMR11: tm ++;
 178        /* fall through */
 179    case OSMR10: tm ++;
 180        /* fall through */
 181    case OSMR9:  tm ++;
 182        /* fall through */
 183    case OSMR8:  tm ++;
 184        /* fall through */
 185    case OSMR7:  tm ++;
 186        /* fall through */
 187    case OSMR6:  tm ++;
 188        /* fall through */
 189    case OSMR5:  tm ++;
 190        /* fall through */
 191    case OSMR4:
 192        if (!pxa2xx_timer_has_tm4(s))
 193            goto badreg;
 194        return s->tm4[tm].tm.value;
 195    case OSCR:
 196        return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
 197                        s->lastload, s->freq, NANOSECONDS_PER_SECOND);
 198    case OSCR11: tm ++;
 199        /* fall through */
 200    case OSCR10: tm ++;
 201        /* fall through */
 202    case OSCR9:  tm ++;
 203        /* fall through */
 204    case OSCR8:  tm ++;
 205        /* fall through */
 206    case OSCR7:  tm ++;
 207        /* fall through */
 208    case OSCR6:  tm ++;
 209        /* fall through */
 210    case OSCR5:  tm ++;
 211        /* fall through */
 212    case OSCR4:
 213        if (!pxa2xx_timer_has_tm4(s))
 214            goto badreg;
 215
 216        if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
 217            if (s->tm4[tm - 1].freq)
 218                s->snapshot = s->tm4[tm - 1].clock + muldiv64(
 219                                qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
 220                                s->tm4[tm - 1].lastload,
 221                                s->tm4[tm - 1].freq, NANOSECONDS_PER_SECOND);
 222            else
 223                s->snapshot = s->tm4[tm - 1].clock;
 224        }
 225
 226        if (!s->tm4[tm].freq)
 227            return s->tm4[tm].clock;
 228        return s->tm4[tm].clock +
 229            muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
 230                     s->tm4[tm].lastload, s->tm4[tm].freq,
 231                     NANOSECONDS_PER_SECOND);
 232    case OIER:
 233        return s->irq_enabled;
 234    case OSSR:  /* Status register */
 235        return s->events;
 236    case OWER:
 237        return s->reset3;
 238    case OMCR11: tm ++;
 239        /* fall through */
 240    case OMCR10: tm ++;
 241        /* fall through */
 242    case OMCR9:  tm ++;
 243        /* fall through */
 244    case OMCR8:  tm ++;
 245        /* fall through */
 246    case OMCR7:  tm ++;
 247        /* fall through */
 248    case OMCR6:  tm ++;
 249        /* fall through */
 250    case OMCR5:  tm ++;
 251        /* fall through */
 252    case OMCR4:
 253        if (!pxa2xx_timer_has_tm4(s))
 254            goto badreg;
 255        return s->tm4[tm].control;
 256    case OSNR:
 257        return s->snapshot;
 258    default:
 259        qemu_log_mask(LOG_UNIMP,
 260                      "%s: unknown register 0x%02" HWADDR_PRIx "\n",
 261                      __func__, offset);
 262        break;
 263    badreg:
 264        qemu_log_mask(LOG_GUEST_ERROR,
 265                      "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
 266                      __func__, offset);
 267    }
 268
 269    return 0;
 270}
 271
 272static void pxa2xx_timer_write(void *opaque, hwaddr offset,
 273                               uint64_t value, unsigned size)
 274{
 275    int i, tm = 0;
 276    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
 277
 278    switch (offset) {
 279    case OSMR3:  tm ++;
 280        /* fall through */
 281    case OSMR2:  tm ++;
 282        /* fall through */
 283    case OSMR1:  tm ++;
 284        /* fall through */
 285    case OSMR0:
 286        s->timer[tm].value = value;
 287        pxa2xx_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 288        break;
 289    case OSMR11: tm ++;
 290        /* fall through */
 291    case OSMR10: tm ++;
 292        /* fall through */
 293    case OSMR9:  tm ++;
 294        /* fall through */
 295    case OSMR8:  tm ++;
 296        /* fall through */
 297    case OSMR7:  tm ++;
 298        /* fall through */
 299    case OSMR6:  tm ++;
 300        /* fall through */
 301    case OSMR5:  tm ++;
 302        /* fall through */
 303    case OSMR4:
 304        if (!pxa2xx_timer_has_tm4(s))
 305            goto badreg;
 306        s->tm4[tm].tm.value = value;
 307        pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
 308        break;
 309    case OSCR:
 310        s->oldclock = s->clock;
 311        s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 312        s->clock = value;
 313        pxa2xx_timer_update(s, s->lastload);
 314        break;
 315    case OSCR11: tm ++;
 316        /* fall through */
 317    case OSCR10: tm ++;
 318        /* fall through */
 319    case OSCR9:  tm ++;
 320        /* fall through */
 321    case OSCR8:  tm ++;
 322        /* fall through */
 323    case OSCR7:  tm ++;
 324        /* fall through */
 325    case OSCR6:  tm ++;
 326        /* fall through */
 327    case OSCR5:  tm ++;
 328        /* fall through */
 329    case OSCR4:
 330        if (!pxa2xx_timer_has_tm4(s))
 331            goto badreg;
 332        s->tm4[tm].oldclock = s->tm4[tm].clock;
 333        s->tm4[tm].lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 334        s->tm4[tm].clock = value;
 335        pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
 336        break;
 337    case OIER:
 338        s->irq_enabled = value & 0xfff;
 339        break;
 340    case OSSR:  /* Status register */
 341        value &= s->events;
 342        s->events &= ~value;
 343        for (i = 0; i < 4; i ++, value >>= 1)
 344            if (value & 1)
 345                qemu_irq_lower(s->timer[i].irq);
 346        if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value)
 347            qemu_irq_lower(s->irq4);
 348        break;
 349    case OWER:  /* XXX: Reset on OSMR3 match? */
 350        s->reset3 = value;
 351        break;
 352    case OMCR7:  tm ++;
 353        /* fall through */
 354    case OMCR6:  tm ++;
 355        /* fall through */
 356    case OMCR5:  tm ++;
 357        /* fall through */
 358    case OMCR4:
 359        if (!pxa2xx_timer_has_tm4(s))
 360            goto badreg;
 361        s->tm4[tm].control = value & 0x0ff;
 362        /* XXX Stop if running (shouldn't happen) */
 363        if ((value & (1 << 7)) || tm == 0)
 364            s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
 365        else {
 366            s->tm4[tm].freq = 0;
 367            pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
 368        }
 369        break;
 370    case OMCR11: tm ++;
 371        /* fall through */
 372    case OMCR10: tm ++;
 373        /* fall through */
 374    case OMCR9:  tm ++;
 375        /* fall through */
 376    case OMCR8:  tm += 4;
 377        if (!pxa2xx_timer_has_tm4(s))
 378            goto badreg;
 379        s->tm4[tm].control = value & 0x3ff;
 380        /* XXX Stop if running (shouldn't happen) */
 381        if ((value & (1 << 7)) || !(tm & 1))
 382            s->tm4[tm].freq =
 383                    pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
 384        else {
 385            s->tm4[tm].freq = 0;
 386            pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
 387        }
 388        break;
 389    default:
 390        qemu_log_mask(LOG_UNIMP,
 391                      "%s: unknown register 0x%02" HWADDR_PRIx " "
 392                      "(value 0x%08" PRIx64 ")\n",  __func__, offset, value);
 393        break;
 394    badreg:
 395        qemu_log_mask(LOG_GUEST_ERROR,
 396                      "%s: incorrect register 0x%02" HWADDR_PRIx " "
 397                      "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
 398    }
 399}
 400
 401static const MemoryRegionOps pxa2xx_timer_ops = {
 402    .read = pxa2xx_timer_read,
 403    .write = pxa2xx_timer_write,
 404    .endianness = DEVICE_NATIVE_ENDIAN,
 405};
 406
 407static void pxa2xx_timer_tick(void *opaque)
 408{
 409    PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
 410    PXA2xxTimerInfo *i = t->info;
 411
 412    if (i->irq_enabled & (1 << t->num)) {
 413        i->events |= 1 << t->num;
 414        qemu_irq_raise(t->irq);
 415    }
 416
 417    if (t->num == 3)
 418        if (i->reset3 & 1) {
 419            i->reset3 = 0;
 420            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 421        }
 422}
 423
 424static void pxa2xx_timer_tick4(void *opaque)
 425{
 426    PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
 427    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
 428
 429    pxa2xx_timer_tick(&t->tm);
 430    if (t->control & (1 << 3))
 431        t->clock = 0;
 432    if (t->control & (1 << 6))
 433        pxa2xx_timer_update4(i, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), t->tm.num - 4);
 434    if (i->events & 0xff0)
 435        qemu_irq_raise(i->irq4);
 436}
 437
 438static int pxa25x_timer_post_load(void *opaque, int version_id)
 439{
 440    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
 441    int64_t now;
 442    int i;
 443
 444    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 445    pxa2xx_timer_update(s, now);
 446
 447    if (pxa2xx_timer_has_tm4(s))
 448        for (i = 0; i < 8; i ++)
 449            pxa2xx_timer_update4(s, now, i);
 450
 451    return 0;
 452}
 453
 454static void pxa2xx_timer_init(Object *obj)
 455{
 456    PXA2xxTimerInfo *s = PXA2XX_TIMER(obj);
 457    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
 458
 459    s->irq_enabled = 0;
 460    s->oldclock = 0;
 461    s->clock = 0;
 462    s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 463    s->reset3 = 0;
 464
 465    memory_region_init_io(&s->iomem, obj, &pxa2xx_timer_ops, s,
 466                          "pxa2xx-timer", 0x00001000);
 467    sysbus_init_mmio(dev, &s->iomem);
 468}
 469
 470static void pxa2xx_timer_realize(DeviceState *dev, Error **errp)
 471{
 472    PXA2xxTimerInfo *s = PXA2XX_TIMER(dev);
 473    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 474    int i;
 475
 476    for (i = 0; i < 4; i ++) {
 477        s->timer[i].value = 0;
 478        sysbus_init_irq(sbd, &s->timer[i].irq);
 479        s->timer[i].info = s;
 480        s->timer[i].num = i;
 481        s->timer[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
 482                                          pxa2xx_timer_tick, &s->timer[i]);
 483    }
 484
 485    if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
 486        sysbus_init_irq(sbd, &s->irq4);
 487
 488        for (i = 0; i < 8; i ++) {
 489            s->tm4[i].tm.value = 0;
 490            s->tm4[i].tm.info = s;
 491            s->tm4[i].tm.num = i + 4;
 492            s->tm4[i].freq = 0;
 493            s->tm4[i].control = 0x0;
 494            s->tm4[i].tm.qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
 495                                               pxa2xx_timer_tick4, &s->tm4[i]);
 496        }
 497    }
 498}
 499
 500static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
 501    .name = "pxa2xx_timer0",
 502    .version_id = 2,
 503    .minimum_version_id = 2,
 504    .fields = (VMStateField[]) {
 505        VMSTATE_UINT32(value, PXA2xxTimer0),
 506        VMSTATE_END_OF_LIST(),
 507    },
 508};
 509
 510static const VMStateDescription vmstate_pxa2xx_timer4_regs = {
 511    .name = "pxa2xx_timer4",
 512    .version_id = 1,
 513    .minimum_version_id = 1,
 514    .fields = (VMStateField[]) {
 515        VMSTATE_STRUCT(tm, PXA2xxTimer4, 1,
 516                        vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
 517        VMSTATE_INT32(oldclock, PXA2xxTimer4),
 518        VMSTATE_INT32(clock, PXA2xxTimer4),
 519        VMSTATE_UINT64(lastload, PXA2xxTimer4),
 520        VMSTATE_UINT32(freq, PXA2xxTimer4),
 521        VMSTATE_UINT32(control, PXA2xxTimer4),
 522        VMSTATE_END_OF_LIST(),
 523    },
 524};
 525
 526static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
 527{
 528    return pxa2xx_timer_has_tm4(opaque);
 529}
 530
 531static const VMStateDescription vmstate_pxa2xx_timer_regs = {
 532    .name = "pxa2xx_timer",
 533    .version_id = 1,
 534    .minimum_version_id = 1,
 535    .post_load = pxa25x_timer_post_load,
 536    .fields = (VMStateField[]) {
 537        VMSTATE_INT32(clock, PXA2xxTimerInfo),
 538        VMSTATE_INT32(oldclock, PXA2xxTimerInfo),
 539        VMSTATE_UINT64(lastload, PXA2xxTimerInfo),
 540        VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1,
 541                        vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
 542        VMSTATE_UINT32(events, PXA2xxTimerInfo),
 543        VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo),
 544        VMSTATE_UINT32(reset3, PXA2xxTimerInfo),
 545        VMSTATE_UINT32(snapshot, PXA2xxTimerInfo),
 546        VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8,
 547                        pxa2xx_timer_has_tm4_test, 0,
 548                        vmstate_pxa2xx_timer4_regs, PXA2xxTimer4),
 549        VMSTATE_END_OF_LIST(),
 550    }
 551};
 552
 553static Property pxa25x_timer_dev_properties[] = {
 554    DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
 555    DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
 556                    PXA2XX_TIMER_HAVE_TM4, false),
 557    DEFINE_PROP_END_OF_LIST(),
 558};
 559
 560static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
 561{
 562    DeviceClass *dc = DEVICE_CLASS(klass);
 563
 564    dc->desc = "PXA25x timer";
 565    device_class_set_props(dc, pxa25x_timer_dev_properties);
 566}
 567
 568static const TypeInfo pxa25x_timer_dev_info = {
 569    .name          = "pxa25x-timer",
 570    .parent        = TYPE_PXA2XX_TIMER,
 571    .instance_size = sizeof(PXA2xxTimerInfo),
 572    .class_init    = pxa25x_timer_dev_class_init,
 573};
 574
 575static Property pxa27x_timer_dev_properties[] = {
 576    DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
 577    DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
 578                    PXA2XX_TIMER_HAVE_TM4, true),
 579    DEFINE_PROP_END_OF_LIST(),
 580};
 581
 582static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
 583{
 584    DeviceClass *dc = DEVICE_CLASS(klass);
 585
 586    dc->desc = "PXA27x timer";
 587    device_class_set_props(dc, pxa27x_timer_dev_properties);
 588}
 589
 590static const TypeInfo pxa27x_timer_dev_info = {
 591    .name          = "pxa27x-timer",
 592    .parent        = TYPE_PXA2XX_TIMER,
 593    .instance_size = sizeof(PXA2xxTimerInfo),
 594    .class_init    = pxa27x_timer_dev_class_init,
 595};
 596
 597static void pxa2xx_timer_class_init(ObjectClass *oc, void *data)
 598{
 599    DeviceClass *dc = DEVICE_CLASS(oc);
 600
 601    dc->realize  = pxa2xx_timer_realize;
 602    dc->vmsd = &vmstate_pxa2xx_timer_regs;
 603}
 604
 605static const TypeInfo pxa2xx_timer_type_info = {
 606    .name          = TYPE_PXA2XX_TIMER,
 607    .parent        = TYPE_SYS_BUS_DEVICE,
 608    .instance_size = sizeof(PXA2xxTimerInfo),
 609    .instance_init = pxa2xx_timer_init,
 610    .abstract      = true,
 611    .class_init    = pxa2xx_timer_class_init,
 612};
 613
 614static void pxa2xx_timer_register_types(void)
 615{
 616    type_register_static(&pxa2xx_timer_type_info);
 617    type_register_static(&pxa25x_timer_dev_info);
 618    type_register_static(&pxa27x_timer_dev_info);
 619}
 620
 621type_init(pxa2xx_timer_register_types)
 622