pxa2xx_timer.c 17 KB

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