prm_common.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. * OMAP2+ common Power & Reset Management (PRM) IP block functions
  3. *
  4. * Copyright (C) 2011 Texas Instruments, Inc.
  5. * Tero Kristo <t-kristo@ti.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. *
  12. * For historical purposes, the API used to configure the PRM
  13. * interrupt handler refers to it as the "PRCM interrupt." The
  14. * underlying registers are located in the PRM on OMAP3/4.
  15. *
  16. * XXX This code should eventually be moved to a PRM driver.
  17. */
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/init.h>
  21. #include <linux/io.h>
  22. #include <linux/irq.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/slab.h>
  25. #include <linux/of.h>
  26. #include <linux/of_address.h>
  27. #include <linux/clk-provider.h>
  28. #include <linux/clk/ti.h>
  29. #include "soc.h"
  30. #include "prm2xxx_3xxx.h"
  31. #include "prm2xxx.h"
  32. #include "prm3xxx.h"
  33. #include "prm44xx.h"
  34. #include "common.h"
  35. #include "clock.h"
  36. /*
  37. * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
  38. * XXX this is technically not needed, since
  39. * omap_prcm_register_chain_handler() could allocate this based on the
  40. * actual amount of memory needed for the SoC
  41. */
  42. #define OMAP_PRCM_MAX_NR_PENDING_REG 2
  43. /*
  44. * prcm_irq_chips: an array of all of the "generic IRQ chips" in use
  45. * by the PRCM interrupt handler code. There will be one 'chip' per
  46. * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have
  47. * one "chip" and OMAP4 will have two.)
  48. */
  49. static struct irq_chip_generic **prcm_irq_chips;
  50. /*
  51. * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code
  52. * is currently running on. Defined and passed by initialization code
  53. * that calls omap_prcm_register_chain_handler().
  54. */
  55. static struct omap_prcm_irq_setup *prcm_irq_setup;
  56. /* prm_base: base virtual address of the PRM IP block */
  57. void __iomem *prm_base;
  58. u16 prm_features;
  59. /*
  60. * prm_ll_data: function pointers to SoC-specific implementations of
  61. * common PRM functions
  62. */
  63. static struct prm_ll_data null_prm_ll_data;
  64. static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;
  65. /* Private functions */
  66. /*
  67. * Move priority events from events to priority_events array
  68. */
  69. static void omap_prcm_events_filter_priority(unsigned long *events,
  70. unsigned long *priority_events)
  71. {
  72. int i;
  73. for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
  74. priority_events[i] =
  75. events[i] & prcm_irq_setup->priority_mask[i];
  76. events[i] ^= priority_events[i];
  77. }
  78. }
  79. /*
  80. * PRCM Interrupt Handler
  81. *
  82. * This is a common handler for the OMAP PRCM interrupts. Pending
  83. * interrupts are detected by a call to prcm_pending_events and
  84. * dispatched accordingly. Clearing of the wakeup events should be
  85. * done by the SoC specific individual handlers.
  86. */
  87. static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
  88. {
  89. unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
  90. unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
  91. struct irq_chip *chip = irq_desc_get_chip(desc);
  92. unsigned int virtirq;
  93. int nr_irq = prcm_irq_setup->nr_regs * 32;
  94. /*
  95. * If we are suspended, mask all interrupts from PRCM level,
  96. * this does not ack them, and they will be pending until we
  97. * re-enable the interrupts, at which point the
  98. * omap_prcm_irq_handler will be executed again. The
  99. * _save_and_clear_irqen() function must ensure that the PRM
  100. * write to disable all IRQs has reached the PRM before
  101. * returning, or spurious PRCM interrupts may occur during
  102. * suspend.
  103. */
  104. if (prcm_irq_setup->suspended) {
  105. prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
  106. prcm_irq_setup->suspend_save_flag = true;
  107. }
  108. /*
  109. * Loop until all pending irqs are handled, since
  110. * generic_handle_irq() can cause new irqs to come
  111. */
  112. while (!prcm_irq_setup->suspended) {
  113. prcm_irq_setup->read_pending_irqs(pending);
  114. /* No bit set, then all IRQs are handled */
  115. if (find_first_bit(pending, nr_irq) >= nr_irq)
  116. break;
  117. omap_prcm_events_filter_priority(pending, priority_pending);
  118. /*
  119. * Loop on all currently pending irqs so that new irqs
  120. * cannot starve previously pending irqs
  121. */
  122. /* Serve priority events first */
  123. for_each_set_bit(virtirq, priority_pending, nr_irq)
  124. generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
  125. /* Serve normal events next */
  126. for_each_set_bit(virtirq, pending, nr_irq)
  127. generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
  128. }
  129. if (chip->irq_ack)
  130. chip->irq_ack(&desc->irq_data);
  131. if (chip->irq_eoi)
  132. chip->irq_eoi(&desc->irq_data);
  133. chip->irq_unmask(&desc->irq_data);
  134. prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */
  135. }
  136. /* Public functions */
  137. /**
  138. * omap_prcm_event_to_irq - given a PRCM event name, returns the
  139. * corresponding IRQ on which the handler should be registered
  140. * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
  141. *
  142. * Returns the Linux internal IRQ ID corresponding to @name upon success,
  143. * or -ENOENT upon failure.
  144. */
  145. int omap_prcm_event_to_irq(const char *name)
  146. {
  147. int i;
  148. if (!prcm_irq_setup || !name)
  149. return -ENOENT;
  150. for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
  151. if (!strcmp(prcm_irq_setup->irqs[i].name, name))
  152. return prcm_irq_setup->base_irq +
  153. prcm_irq_setup->irqs[i].offset;
  154. return -ENOENT;
  155. }
  156. /**
  157. * omap_prcm_irq_cleanup - reverses memory allocated and other steps
  158. * done by omap_prcm_register_chain_handler()
  159. *
  160. * No return value.
  161. */
  162. void omap_prcm_irq_cleanup(void)
  163. {
  164. unsigned int irq;
  165. int i;
  166. if (!prcm_irq_setup) {
  167. pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
  168. return;
  169. }
  170. if (prcm_irq_chips) {
  171. for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
  172. if (prcm_irq_chips[i])
  173. irq_remove_generic_chip(prcm_irq_chips[i],
  174. 0xffffffff, 0, 0);
  175. prcm_irq_chips[i] = NULL;
  176. }
  177. kfree(prcm_irq_chips);
  178. prcm_irq_chips = NULL;
  179. }
  180. kfree(prcm_irq_setup->saved_mask);
  181. prcm_irq_setup->saved_mask = NULL;
  182. kfree(prcm_irq_setup->priority_mask);
  183. prcm_irq_setup->priority_mask = NULL;
  184. if (prcm_irq_setup->xlate_irq)
  185. irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq);
  186. else
  187. irq = prcm_irq_setup->irq;
  188. irq_set_chained_handler(irq, NULL);
  189. if (prcm_irq_setup->base_irq > 0)
  190. irq_free_descs(prcm_irq_setup->base_irq,
  191. prcm_irq_setup->nr_regs * 32);
  192. prcm_irq_setup->base_irq = 0;
  193. }
  194. void omap_prcm_irq_prepare(void)
  195. {
  196. prcm_irq_setup->suspended = true;
  197. }
  198. void omap_prcm_irq_complete(void)
  199. {
  200. prcm_irq_setup->suspended = false;
  201. /* If we have not saved the masks, do not attempt to restore */
  202. if (!prcm_irq_setup->suspend_save_flag)
  203. return;
  204. prcm_irq_setup->suspend_save_flag = false;
  205. /*
  206. * Re-enable all masked PRCM irq sources, this causes the PRCM
  207. * interrupt to fire immediately if the events were masked
  208. * previously in the chain handler
  209. */
  210. prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
  211. }
  212. /**
  213. * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
  214. * handler based on provided parameters
  215. * @irq_setup: hardware data about the underlying PRM/PRCM
  216. *
  217. * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up
  218. * one generic IRQ chip per PRM interrupt status/enable register pair.
  219. * Returns 0 upon success, -EINVAL if called twice or if invalid
  220. * arguments are passed, or -ENOMEM on any other error.
  221. */
  222. int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
  223. {
  224. int nr_regs;
  225. u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
  226. int offset, i;
  227. struct irq_chip_generic *gc;
  228. struct irq_chip_type *ct;
  229. unsigned int irq;
  230. if (!irq_setup)
  231. return -EINVAL;
  232. nr_regs = irq_setup->nr_regs;
  233. if (prcm_irq_setup) {
  234. pr_err("PRCM: already initialized; won't reinitialize\n");
  235. return -EINVAL;
  236. }
  237. if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
  238. pr_err("PRCM: nr_regs too large\n");
  239. return -EINVAL;
  240. }
  241. prcm_irq_setup = irq_setup;
  242. prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
  243. prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
  244. prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
  245. GFP_KERNEL);
  246. if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
  247. !prcm_irq_setup->priority_mask) {
  248. pr_err("PRCM: kzalloc failed\n");
  249. goto err;
  250. }
  251. memset(mask, 0, sizeof(mask));
  252. for (i = 0; i < irq_setup->nr_irqs; i++) {
  253. offset = irq_setup->irqs[i].offset;
  254. mask[offset >> 5] |= 1 << (offset & 0x1f);
  255. if (irq_setup->irqs[i].priority)
  256. irq_setup->priority_mask[offset >> 5] |=
  257. 1 << (offset & 0x1f);
  258. }
  259. if (irq_setup->xlate_irq)
  260. irq = irq_setup->xlate_irq(irq_setup->irq);
  261. else
  262. irq = irq_setup->irq;
  263. irq_set_chained_handler(irq, omap_prcm_irq_handler);
  264. irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
  265. 0);
  266. if (irq_setup->base_irq < 0) {
  267. pr_err("PRCM: failed to allocate irq descs: %d\n",
  268. irq_setup->base_irq);
  269. goto err;
  270. }
  271. for (i = 0; i < irq_setup->nr_regs; i++) {
  272. gc = irq_alloc_generic_chip("PRCM", 1,
  273. irq_setup->base_irq + i * 32, prm_base,
  274. handle_level_irq);
  275. if (!gc) {
  276. pr_err("PRCM: failed to allocate generic chip\n");
  277. goto err;
  278. }
  279. ct = gc->chip_types;
  280. ct->chip.irq_ack = irq_gc_ack_set_bit;
  281. ct->chip.irq_mask = irq_gc_mask_clr_bit;
  282. ct->chip.irq_unmask = irq_gc_mask_set_bit;
  283. ct->regs.ack = irq_setup->ack + i * 4;
  284. ct->regs.mask = irq_setup->mask + i * 4;
  285. irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
  286. prcm_irq_chips[i] = gc;
  287. }
  288. if (of_have_populated_dt()) {
  289. int irq = omap_prcm_event_to_irq("io");
  290. omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain);
  291. }
  292. return 0;
  293. err:
  294. omap_prcm_irq_cleanup();
  295. return -ENOMEM;
  296. }
  297. /**
  298. * omap2_set_globals_prm - set the PRM base address (for early use)
  299. * @prm: PRM base virtual address
  300. *
  301. * XXX Will be replaced when the PRM/CM drivers are completed.
  302. */
  303. void __init omap2_set_globals_prm(void __iomem *prm)
  304. {
  305. prm_base = prm;
  306. }
  307. /**
  308. * prm_read_reset_sources - return the sources of the SoC's last reset
  309. *
  310. * Return a u32 bitmask representing the reset sources that caused the
  311. * SoC to reset. The low-level per-SoC functions called by this
  312. * function remap the SoC-specific reset source bits into an
  313. * OMAP-common set of reset source bits, defined in
  314. * arch/arm/mach-omap2/prm.h. Returns the standardized reset source
  315. * u32 bitmask from the hardware upon success, or returns (1 <<
  316. * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
  317. * function was registered.
  318. */
  319. u32 prm_read_reset_sources(void)
  320. {
  321. u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;
  322. if (prm_ll_data->read_reset_sources)
  323. ret = prm_ll_data->read_reset_sources();
  324. else
  325. WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);
  326. return ret;
  327. }
  328. /**
  329. * prm_was_any_context_lost_old - was device context lost? (old API)
  330. * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  331. * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  332. * @idx: CONTEXT register offset
  333. *
  334. * Return 1 if any bits were set in the *_CONTEXT_* register
  335. * identified by (@part, @inst, @idx), which means that some context
  336. * was lost for that module; otherwise, return 0. XXX Deprecated;
  337. * callers need to use a less-SoC-dependent way to identify hardware
  338. * IP blocks.
  339. */
  340. bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
  341. {
  342. bool ret = true;
  343. if (prm_ll_data->was_any_context_lost_old)
  344. ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
  345. else
  346. WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  347. __func__);
  348. return ret;
  349. }
  350. /**
  351. * prm_clear_context_lost_flags_old - clear context loss flags (old API)
  352. * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  353. * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  354. * @idx: CONTEXT register offset
  355. *
  356. * Clear hardware context loss bits for the module identified by
  357. * (@part, @inst, @idx). No return value. XXX Deprecated; callers
  358. * need to use a less-SoC-dependent way to identify hardware IP
  359. * blocks.
  360. */
  361. void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
  362. {
  363. if (prm_ll_data->clear_context_loss_flags_old)
  364. prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
  365. else
  366. WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  367. __func__);
  368. }
  369. /**
  370. * omap_prm_assert_hardreset - assert hardreset for an IP block
  371. * @shift: register bit shift corresponding to the reset line
  372. * @part: PRM partition
  373. * @prm_mod: PRM submodule base or instance offset
  374. * @offset: register offset
  375. *
  376. * Asserts a hardware reset line for an IP block.
  377. */
  378. int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset)
  379. {
  380. if (!prm_ll_data->assert_hardreset) {
  381. WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  382. __func__);
  383. return -EINVAL;
  384. }
  385. return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset);
  386. }
  387. /**
  388. * omap_prm_deassert_hardreset - deassert hardreset for an IP block
  389. * @shift: register bit shift corresponding to the reset line
  390. * @st_shift: reset status bit shift corresponding to the reset line
  391. * @part: PRM partition
  392. * @prm_mod: PRM submodule base or instance offset
  393. * @offset: register offset
  394. * @st_offset: status register offset
  395. *
  396. * Deasserts a hardware reset line for an IP block.
  397. */
  398. int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
  399. u16 offset, u16 st_offset)
  400. {
  401. if (!prm_ll_data->deassert_hardreset) {
  402. WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  403. __func__);
  404. return -EINVAL;
  405. }
  406. return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod,
  407. offset, st_offset);
  408. }
  409. /**
  410. * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block
  411. * @shift: register bit shift corresponding to the reset line
  412. * @part: PRM partition
  413. * @prm_mod: PRM submodule base or instance offset
  414. * @offset: register offset
  415. *
  416. * Checks if a hardware reset line for an IP block is enabled or not.
  417. */
  418. int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset)
  419. {
  420. if (!prm_ll_data->is_hardreset_asserted) {
  421. WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  422. __func__);
  423. return -EINVAL;
  424. }
  425. return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset);
  426. }
  427. /**
  428. * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
  429. *
  430. * Clear any previously-latched I/O wakeup events and ensure that the
  431. * I/O wakeup gates are aligned with the current mux settings.
  432. * Calls SoC specific I/O chain reconfigure function if available,
  433. * otherwise does nothing.
  434. */
  435. void omap_prm_reconfigure_io_chain(void)
  436. {
  437. if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain)
  438. return;
  439. prcm_irq_setup->reconfigure_io_chain();
  440. }
  441. /**
  442. * omap_prm_reset_system - trigger global SW reset
  443. *
  444. * Triggers SoC specific global warm reset to reboot the device.
  445. */
  446. void omap_prm_reset_system(void)
  447. {
  448. if (!prm_ll_data->reset_system) {
  449. WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  450. __func__);
  451. return;
  452. }
  453. prm_ll_data->reset_system();
  454. while (1)
  455. cpu_relax();
  456. }
  457. /**
  458. * prm_register - register per-SoC low-level data with the PRM
  459. * @pld: low-level per-SoC OMAP PRM data & function pointers to register
  460. *
  461. * Register per-SoC low-level OMAP PRM data and function pointers with
  462. * the OMAP PRM common interface. The caller must keep the data
  463. * pointed to by @pld valid until it calls prm_unregister() and
  464. * it returns successfully. Returns 0 upon success, -EINVAL if @pld
  465. * is NULL, or -EEXIST if prm_register() has already been called
  466. * without an intervening prm_unregister().
  467. */
  468. int prm_register(struct prm_ll_data *pld)
  469. {
  470. if (!pld)
  471. return -EINVAL;
  472. if (prm_ll_data != &null_prm_ll_data)
  473. return -EEXIST;
  474. prm_ll_data = pld;
  475. return 0;
  476. }
  477. /**
  478. * prm_unregister - unregister per-SoC low-level data & function pointers
  479. * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
  480. *
  481. * Unregister per-SoC low-level OMAP PRM data and function pointers
  482. * that were previously registered with prm_register(). The
  483. * caller may not destroy any of the data pointed to by @pld until
  484. * this function returns successfully. Returns 0 upon success, or
  485. * -EINVAL if @pld is NULL or if @pld does not match the struct
  486. * prm_ll_data * previously registered by prm_register().
  487. */
  488. int prm_unregister(struct prm_ll_data *pld)
  489. {
  490. if (!pld || prm_ll_data != pld)
  491. return -EINVAL;
  492. prm_ll_data = &null_prm_ll_data;
  493. return 0;
  494. }
  495. static const struct of_device_id omap_prcm_dt_match_table[] = {
  496. { .compatible = "ti,am3-prcm" },
  497. { .compatible = "ti,am3-scrm" },
  498. { .compatible = "ti,am4-prcm" },
  499. { .compatible = "ti,am4-scrm" },
  500. { .compatible = "ti,omap2-prcm" },
  501. { .compatible = "ti,omap2-scrm" },
  502. { .compatible = "ti,omap3-prm" },
  503. { .compatible = "ti,omap3-cm" },
  504. { .compatible = "ti,omap3-scrm" },
  505. { .compatible = "ti,omap4-cm1" },
  506. { .compatible = "ti,omap4-prm" },
  507. { .compatible = "ti,omap4-cm2" },
  508. { .compatible = "ti,omap4-scrm" },
  509. { .compatible = "ti,omap5-prm" },
  510. { .compatible = "ti,omap5-cm-core-aon" },
  511. { .compatible = "ti,omap5-scrm" },
  512. { .compatible = "ti,omap5-cm-core" },
  513. { .compatible = "ti,dra7-prm" },
  514. { .compatible = "ti,dra7-cm-core-aon" },
  515. { .compatible = "ti,dra7-cm-core" },
  516. { }
  517. };
  518. static struct clk_hw_omap memmap_dummy_ck = {
  519. .flags = MEMMAP_ADDRESSING,
  520. };
  521. static u32 prm_clk_readl(void __iomem *reg)
  522. {
  523. return omap2_clk_readl(&memmap_dummy_ck, reg);
  524. }
  525. static void prm_clk_writel(u32 val, void __iomem *reg)
  526. {
  527. omap2_clk_writel(val, &memmap_dummy_ck, reg);
  528. }
  529. static struct ti_clk_ll_ops omap_clk_ll_ops = {
  530. .clk_readl = prm_clk_readl,
  531. .clk_writel = prm_clk_writel,
  532. };
  533. int __init of_prcm_init(void)
  534. {
  535. struct device_node *np;
  536. void __iomem *mem;
  537. int memmap_index = 0;
  538. ti_clk_ll_ops = &omap_clk_ll_ops;
  539. for_each_matching_node(np, omap_prcm_dt_match_table) {
  540. mem = of_iomap(np, 0);
  541. clk_memmaps[memmap_index] = mem;
  542. ti_dt_clk_init_provider(np, memmap_index);
  543. memmap_index++;
  544. }
  545. return 0;
  546. }
  547. static int __init prm_late_init(void)
  548. {
  549. if (prm_ll_data->late_init)
  550. return prm_ll_data->late_init();
  551. return 0;
  552. }
  553. subsys_initcall(prm_late_init);