1ddd04b98SVaibhav Hiremath /* 2ddd04b98SVaibhav Hiremath * AM33XX PRM functions 3ddd04b98SVaibhav Hiremath * 4ddd04b98SVaibhav Hiremath * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ 5ddd04b98SVaibhav Hiremath * 6ddd04b98SVaibhav Hiremath * This program is free software; you can redistribute it and/or 7ddd04b98SVaibhav Hiremath * modify it under the terms of the GNU General Public License as 8ddd04b98SVaibhav Hiremath * published by the Free Software Foundation version 2. 9ddd04b98SVaibhav Hiremath * 10ddd04b98SVaibhav Hiremath * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11ddd04b98SVaibhav Hiremath * kind, whether express or implied; without even the implied warranty 12ddd04b98SVaibhav Hiremath * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13ddd04b98SVaibhav Hiremath * GNU General Public License for more details. 14ddd04b98SVaibhav Hiremath */ 15ddd04b98SVaibhav Hiremath 16ddd04b98SVaibhav Hiremath #include <linux/kernel.h> 17ddd04b98SVaibhav Hiremath #include <linux/types.h> 18ddd04b98SVaibhav Hiremath #include <linux/errno.h> 19ddd04b98SVaibhav Hiremath #include <linux/err.h> 20ddd04b98SVaibhav Hiremath #include <linux/io.h> 21ddd04b98SVaibhav Hiremath 2249815399SPaul Walmsley #include "powerdomain.h" 23ddd04b98SVaibhav Hiremath #include "prm33xx.h" 24ddd04b98SVaibhav Hiremath #include "prm-regbits-33xx.h" 25ddd04b98SVaibhav Hiremath 26ddd04b98SVaibhav Hiremath /* Read a register in a PRM instance */ 27ddd04b98SVaibhav Hiremath u32 am33xx_prm_read_reg(s16 inst, u16 idx) 28ddd04b98SVaibhav Hiremath { 29edfaf05cSVictor Kamensky return readl_relaxed(prm_base + inst + idx); 30ddd04b98SVaibhav Hiremath } 31ddd04b98SVaibhav Hiremath 32ddd04b98SVaibhav Hiremath /* Write into a register in a PRM instance */ 33ddd04b98SVaibhav Hiremath void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) 34ddd04b98SVaibhav Hiremath { 35edfaf05cSVictor Kamensky writel_relaxed(val, prm_base + inst + idx); 36ddd04b98SVaibhav Hiremath } 37ddd04b98SVaibhav Hiremath 38ddd04b98SVaibhav Hiremath /* Read-modify-write a register in PRM. Caller must lock */ 39ddd04b98SVaibhav Hiremath u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) 40ddd04b98SVaibhav Hiremath { 41ddd04b98SVaibhav Hiremath u32 v; 42ddd04b98SVaibhav Hiremath 43ddd04b98SVaibhav Hiremath v = am33xx_prm_read_reg(inst, idx); 44ddd04b98SVaibhav Hiremath v &= ~mask; 45ddd04b98SVaibhav Hiremath v |= bits; 46ddd04b98SVaibhav Hiremath am33xx_prm_write_reg(v, inst, idx); 47ddd04b98SVaibhav Hiremath 48ddd04b98SVaibhav Hiremath return v; 49ddd04b98SVaibhav Hiremath } 50ddd04b98SVaibhav Hiremath 51ddd04b98SVaibhav Hiremath /** 52ddd04b98SVaibhav Hiremath * am33xx_prm_is_hardreset_asserted - read the HW reset line state of 53ddd04b98SVaibhav Hiremath * submodules contained in the hwmod module 54ddd04b98SVaibhav Hiremath * @shift: register bit shift corresponding to the reset line to check 55ddd04b98SVaibhav Hiremath * @inst: CM instance register offset (*_INST macro) 56ddd04b98SVaibhav Hiremath * @rstctrl_offs: RM_RSTCTRL register address offset for this module 57ddd04b98SVaibhav Hiremath * 58ddd04b98SVaibhav Hiremath * Returns 1 if the (sub)module hardreset line is currently asserted, 59ddd04b98SVaibhav Hiremath * 0 if the (sub)module hardreset line is not currently asserted, or 60ddd04b98SVaibhav Hiremath * -EINVAL upon parameter error. 61ddd04b98SVaibhav Hiremath */ 62ddd04b98SVaibhav Hiremath int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) 63ddd04b98SVaibhav Hiremath { 64ddd04b98SVaibhav Hiremath u32 v; 65ddd04b98SVaibhav Hiremath 66ddd04b98SVaibhav Hiremath v = am33xx_prm_read_reg(inst, rstctrl_offs); 67ddd04b98SVaibhav Hiremath v &= 1 << shift; 68ddd04b98SVaibhav Hiremath v >>= shift; 69ddd04b98SVaibhav Hiremath 70ddd04b98SVaibhav Hiremath return v; 71ddd04b98SVaibhav Hiremath } 72ddd04b98SVaibhav Hiremath 73ddd04b98SVaibhav Hiremath /** 74ddd04b98SVaibhav Hiremath * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule 75ddd04b98SVaibhav Hiremath * @shift: register bit shift corresponding to the reset line to assert 76ddd04b98SVaibhav Hiremath * @inst: CM instance register offset (*_INST macro) 77ddd04b98SVaibhav Hiremath * @rstctrl_reg: RM_RSTCTRL register address for this module 78ddd04b98SVaibhav Hiremath * 79ddd04b98SVaibhav Hiremath * Some IPs like dsp, ipu or iva contain processors that require an HW 80ddd04b98SVaibhav Hiremath * reset line to be asserted / deasserted in order to fully enable the 81ddd04b98SVaibhav Hiremath * IP. These modules may have multiple hard-reset lines that reset 82ddd04b98SVaibhav Hiremath * different 'submodules' inside the IP block. This function will 83ddd04b98SVaibhav Hiremath * place the submodule into reset. Returns 0 upon success or -EINVAL 84ddd04b98SVaibhav Hiremath * upon an argument error. 85ddd04b98SVaibhav Hiremath */ 86ddd04b98SVaibhav Hiremath int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) 87ddd04b98SVaibhav Hiremath { 88ddd04b98SVaibhav Hiremath u32 mask = 1 << shift; 89ddd04b98SVaibhav Hiremath 90ddd04b98SVaibhav Hiremath am33xx_prm_rmw_reg_bits(mask, mask, inst, rstctrl_offs); 91ddd04b98SVaibhav Hiremath 92ddd04b98SVaibhav Hiremath return 0; 93ddd04b98SVaibhav Hiremath } 94ddd04b98SVaibhav Hiremath 95ddd04b98SVaibhav Hiremath /** 96ddd04b98SVaibhav Hiremath * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and 97ddd04b98SVaibhav Hiremath * wait 98ddd04b98SVaibhav Hiremath * @shift: register bit shift corresponding to the reset line to deassert 99ddd04b98SVaibhav Hiremath * @inst: CM instance register offset (*_INST macro) 100ddd04b98SVaibhav Hiremath * @rstctrl_reg: RM_RSTCTRL register address for this module 101ddd04b98SVaibhav Hiremath * @rstst_reg: RM_RSTST register address for this module 102ddd04b98SVaibhav Hiremath * 103ddd04b98SVaibhav Hiremath * Some IPs like dsp, ipu or iva contain processors that require an HW 104ddd04b98SVaibhav Hiremath * reset line to be asserted / deasserted in order to fully enable the 105ddd04b98SVaibhav Hiremath * IP. These modules may have multiple hard-reset lines that reset 106ddd04b98SVaibhav Hiremath * different 'submodules' inside the IP block. This function will 107ddd04b98SVaibhav Hiremath * take the submodule out of reset and wait until the PRCM indicates 108ddd04b98SVaibhav Hiremath * that the reset has completed before returning. Returns 0 upon success or 109ddd04b98SVaibhav Hiremath * -EINVAL upon an argument error, -EEXIST if the submodule was already out 110ddd04b98SVaibhav Hiremath * of reset, or -EBUSY if the submodule did not exit reset promptly. 111ddd04b98SVaibhav Hiremath */ 1123c06f1b8SVaibhav Bedia int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, 113ddd04b98SVaibhav Hiremath u16 rstctrl_offs, u16 rstst_offs) 114ddd04b98SVaibhav Hiremath { 115ddd04b98SVaibhav Hiremath int c; 1163c06f1b8SVaibhav Bedia u32 mask = 1 << st_shift; 117ddd04b98SVaibhav Hiremath 118ddd04b98SVaibhav Hiremath /* Check the current status to avoid de-asserting the line twice */ 119ddd04b98SVaibhav Hiremath if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) 120ddd04b98SVaibhav Hiremath return -EEXIST; 121ddd04b98SVaibhav Hiremath 122ddd04b98SVaibhav Hiremath /* Clear the reset status by writing 1 to the status bit */ 123ddd04b98SVaibhav Hiremath am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs); 124ddd04b98SVaibhav Hiremath 1253c06f1b8SVaibhav Bedia /* de-assert the reset control line */ 1263c06f1b8SVaibhav Bedia mask = 1 << shift; 1273c06f1b8SVaibhav Bedia 1283c06f1b8SVaibhav Bedia am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); 1293c06f1b8SVaibhav Bedia 1303c06f1b8SVaibhav Bedia /* wait the status to be set */ 1313c06f1b8SVaibhav Bedia omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst, 132ddd04b98SVaibhav Hiremath rstst_offs), 133ddd04b98SVaibhav Hiremath MAX_MODULE_HARDRESET_WAIT, c); 134ddd04b98SVaibhav Hiremath 135ddd04b98SVaibhav Hiremath return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; 136ddd04b98SVaibhav Hiremath } 13749815399SPaul Walmsley 13849815399SPaul Walmsley static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) 13949815399SPaul Walmsley { 14049815399SPaul Walmsley am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK, 14149815399SPaul Walmsley (pwrst << OMAP_POWERSTATE_SHIFT), 14249815399SPaul Walmsley pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 14349815399SPaul Walmsley return 0; 14449815399SPaul Walmsley } 14549815399SPaul Walmsley 14649815399SPaul Walmsley static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) 14749815399SPaul Walmsley { 14849815399SPaul Walmsley u32 v; 14949815399SPaul Walmsley 15049815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 15149815399SPaul Walmsley v &= OMAP_POWERSTATE_MASK; 15249815399SPaul Walmsley v >>= OMAP_POWERSTATE_SHIFT; 15349815399SPaul Walmsley 15449815399SPaul Walmsley return v; 15549815399SPaul Walmsley } 15649815399SPaul Walmsley 15749815399SPaul Walmsley static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm) 15849815399SPaul Walmsley { 15949815399SPaul Walmsley u32 v; 16049815399SPaul Walmsley 16149815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); 16249815399SPaul Walmsley v &= OMAP_POWERSTATEST_MASK; 16349815399SPaul Walmsley v >>= OMAP_POWERSTATEST_SHIFT; 16449815399SPaul Walmsley 16549815399SPaul Walmsley return v; 16649815399SPaul Walmsley } 16749815399SPaul Walmsley 16849815399SPaul Walmsley static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 16949815399SPaul Walmsley { 17049815399SPaul Walmsley u32 v; 17149815399SPaul Walmsley 17249815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); 17349815399SPaul Walmsley v &= AM33XX_LASTPOWERSTATEENTERED_MASK; 17449815399SPaul Walmsley v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT; 17549815399SPaul Walmsley 17649815399SPaul Walmsley return v; 17749815399SPaul Walmsley } 17849815399SPaul Walmsley 17949815399SPaul Walmsley static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) 18049815399SPaul Walmsley { 18149815399SPaul Walmsley am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK, 18249815399SPaul Walmsley (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT), 18349815399SPaul Walmsley pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 18449815399SPaul Walmsley return 0; 18549815399SPaul Walmsley } 18649815399SPaul Walmsley 18749815399SPaul Walmsley static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) 18849815399SPaul Walmsley { 18949815399SPaul Walmsley am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK, 19049815399SPaul Walmsley AM33XX_LASTPOWERSTATEENTERED_MASK, 19149815399SPaul Walmsley pwrdm->prcm_offs, pwrdm->pwrstst_offs); 19249815399SPaul Walmsley return 0; 19349815399SPaul Walmsley } 19449815399SPaul Walmsley 19549815399SPaul Walmsley static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) 19649815399SPaul Walmsley { 19749815399SPaul Walmsley u32 m; 19849815399SPaul Walmsley 19949815399SPaul Walmsley m = pwrdm->logicretstate_mask; 20049815399SPaul Walmsley if (!m) 20149815399SPaul Walmsley return -EINVAL; 20249815399SPaul Walmsley 20349815399SPaul Walmsley am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), 20449815399SPaul Walmsley pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 20549815399SPaul Walmsley 20649815399SPaul Walmsley return 0; 20749815399SPaul Walmsley } 20849815399SPaul Walmsley 20949815399SPaul Walmsley static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) 21049815399SPaul Walmsley { 21149815399SPaul Walmsley u32 v; 21249815399SPaul Walmsley 21349815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); 21449815399SPaul Walmsley v &= AM33XX_LOGICSTATEST_MASK; 21549815399SPaul Walmsley v >>= AM33XX_LOGICSTATEST_SHIFT; 21649815399SPaul Walmsley 21749815399SPaul Walmsley return v; 21849815399SPaul Walmsley } 21949815399SPaul Walmsley 22049815399SPaul Walmsley static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm) 22149815399SPaul Walmsley { 22249815399SPaul Walmsley u32 v, m; 22349815399SPaul Walmsley 22449815399SPaul Walmsley m = pwrdm->logicretstate_mask; 22549815399SPaul Walmsley if (!m) 22649815399SPaul Walmsley return -EINVAL; 22749815399SPaul Walmsley 22849815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 22949815399SPaul Walmsley v &= m; 23049815399SPaul Walmsley v >>= __ffs(m); 23149815399SPaul Walmsley 23249815399SPaul Walmsley return v; 23349815399SPaul Walmsley } 23449815399SPaul Walmsley 23549815399SPaul Walmsley static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, 23649815399SPaul Walmsley u8 pwrst) 23749815399SPaul Walmsley { 23849815399SPaul Walmsley u32 m; 23949815399SPaul Walmsley 24049815399SPaul Walmsley m = pwrdm->mem_on_mask[bank]; 24149815399SPaul Walmsley if (!m) 24249815399SPaul Walmsley return -EINVAL; 24349815399SPaul Walmsley 24449815399SPaul Walmsley am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), 24549815399SPaul Walmsley pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 24649815399SPaul Walmsley 24749815399SPaul Walmsley return 0; 24849815399SPaul Walmsley } 24949815399SPaul Walmsley 25049815399SPaul Walmsley static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, 25149815399SPaul Walmsley u8 pwrst) 25249815399SPaul Walmsley { 25349815399SPaul Walmsley u32 m; 25449815399SPaul Walmsley 25549815399SPaul Walmsley m = pwrdm->mem_ret_mask[bank]; 25649815399SPaul Walmsley if (!m) 25749815399SPaul Walmsley return -EINVAL; 25849815399SPaul Walmsley 25949815399SPaul Walmsley am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), 26049815399SPaul Walmsley pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 26149815399SPaul Walmsley 26249815399SPaul Walmsley return 0; 26349815399SPaul Walmsley } 26449815399SPaul Walmsley 26549815399SPaul Walmsley static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 26649815399SPaul Walmsley { 26749815399SPaul Walmsley u32 m, v; 26849815399SPaul Walmsley 26949815399SPaul Walmsley m = pwrdm->mem_pwrst_mask[bank]; 27049815399SPaul Walmsley if (!m) 27149815399SPaul Walmsley return -EINVAL; 27249815399SPaul Walmsley 27349815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); 27449815399SPaul Walmsley v &= m; 27549815399SPaul Walmsley v >>= __ffs(m); 27649815399SPaul Walmsley 27749815399SPaul Walmsley return v; 27849815399SPaul Walmsley } 27949815399SPaul Walmsley 28049815399SPaul Walmsley static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) 28149815399SPaul Walmsley { 28249815399SPaul Walmsley u32 m, v; 28349815399SPaul Walmsley 28449815399SPaul Walmsley m = pwrdm->mem_retst_mask[bank]; 28549815399SPaul Walmsley if (!m) 28649815399SPaul Walmsley return -EINVAL; 28749815399SPaul Walmsley 28849815399SPaul Walmsley v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); 28949815399SPaul Walmsley v &= m; 29049815399SPaul Walmsley v >>= __ffs(m); 29149815399SPaul Walmsley 29249815399SPaul Walmsley return v; 29349815399SPaul Walmsley } 29449815399SPaul Walmsley 29549815399SPaul Walmsley static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm) 29649815399SPaul Walmsley { 29749815399SPaul Walmsley u32 c = 0; 29849815399SPaul Walmsley 29949815399SPaul Walmsley /* 30049815399SPaul Walmsley * REVISIT: pwrdm_wait_transition() may be better implemented 30149815399SPaul Walmsley * via a callback and a periodic timer check -- how long do we expect 30249815399SPaul Walmsley * powerdomain transitions to take? 30349815399SPaul Walmsley */ 30449815399SPaul Walmsley 30549815399SPaul Walmsley /* XXX Is this udelay() value meaningful? */ 30649815399SPaul Walmsley while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs) 30749815399SPaul Walmsley & OMAP_INTRANSITION_MASK) && 30849815399SPaul Walmsley (c++ < PWRDM_TRANSITION_BAILOUT)) 30949815399SPaul Walmsley udelay(1); 31049815399SPaul Walmsley 31149815399SPaul Walmsley if (c > PWRDM_TRANSITION_BAILOUT) { 31249815399SPaul Walmsley pr_err("powerdomain: %s: waited too long to complete transition\n", 31349815399SPaul Walmsley pwrdm->name); 31449815399SPaul Walmsley return -EAGAIN; 31549815399SPaul Walmsley } 31649815399SPaul Walmsley 31749815399SPaul Walmsley pr_debug("powerdomain: completed transition in %d loops\n", c); 31849815399SPaul Walmsley 31949815399SPaul Walmsley return 0; 32049815399SPaul Walmsley } 32149815399SPaul Walmsley 32263b0420cSRajendra Nayak static int am33xx_check_vcvp(void) 32363b0420cSRajendra Nayak { 32463b0420cSRajendra Nayak /* No VC/VP on am33xx devices */ 32563b0420cSRajendra Nayak return 0; 32663b0420cSRajendra Nayak } 32763b0420cSRajendra Nayak 32849815399SPaul Walmsley struct pwrdm_ops am33xx_pwrdm_operations = { 32949815399SPaul Walmsley .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, 33049815399SPaul Walmsley .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, 33149815399SPaul Walmsley .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst, 33249815399SPaul Walmsley .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst, 33349815399SPaul Walmsley .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst, 33449815399SPaul Walmsley .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst, 33549815399SPaul Walmsley .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst, 33649815399SPaul Walmsley .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst, 33749815399SPaul Walmsley .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange, 33849815399SPaul Walmsley .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst, 33949815399SPaul Walmsley .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst, 34049815399SPaul Walmsley .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst, 34149815399SPaul Walmsley .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst, 34249815399SPaul Walmsley .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, 34363b0420cSRajendra Nayak .pwrdm_has_voltdm = am33xx_check_vcvp, 34449815399SPaul Walmsley }; 345d9bbe84fSTero Kristo 346d9bbe84fSTero Kristo static struct prm_ll_data am33xx_prm_ll_data; 347d9bbe84fSTero Kristo 348d9bbe84fSTero Kristo int __init am33xx_prm_init(void) 349d9bbe84fSTero Kristo { 350d9bbe84fSTero Kristo return prm_register(&am33xx_prm_ll_data); 351d9bbe84fSTero Kristo } 352d9bbe84fSTero Kristo 353d9bbe84fSTero Kristo static void __exit am33xx_prm_exit(void) 354d9bbe84fSTero Kristo { 355d9bbe84fSTero Kristo prm_unregister(&am33xx_prm_ll_data); 356d9bbe84fSTero Kristo } 357d9bbe84fSTero Kristo __exitcall(am33xx_prm_exit); 358