aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2017-12-21 11:17:40 -0500
committerArnd Bergmann <arnd@arndb.de>2017-12-21 11:17:40 -0500
commit4e34e2702d3f454593b5fd26e3c011cc5cb89106 (patch)
tree569945a2d44d3d1a5d74999061348304e3a6d21d
parentf44780378639c7ad095d1f494ad80a9455db65b7 (diff)
parentfdf3632938a646c13f7407f2f8c33ff81eed9c76 (diff)
Merge tag 'omap-for-v4.16/soc-signed' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc
Pull "SoC changes for omaps for v4.16 merge window" from Tony Lindgren: For most part this is a series from Tero Kristo to prepare things for using clkctrl clocks with DTS data. The other changes are to make few data structures const. * tag 'omap-for-v4.16/soc-signed' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: OMAP2+: CM: make cm_ll_data structures as const ARM: OMAP2+: CM: make some pointers and function arguments as const ARM: DM816x: hwmod_data: fix clockdomain name for sata hwmod ARM: OMAP2+: hwmod: calculate physical register address on am33xx ARM: AM33xx: CM: add support for getting physical address for a register ARM: OMAP2+: clockdomain: remove the obsolete clkdm_xlate_address API ARM: OMAP2+: hwmod: fix clkctrl address translation logic ARM: OMAP4: CMINST: add support for translating clkctrl addresses ARM: OMAP2+: CM: add support for getting phys address for a clkctrl register
-rw-r--r--arch/arm/mach-omap2/clockdomain.c8
-rw-r--r--arch/arm/mach-omap2/clockdomain.h2
-rw-r--r--arch/arm/mach-omap2/cm.h7
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c2
-rw-r--r--arch/arm/mach-omap2/cm33xx.c8
-rw-r--r--arch/arm/mach-omap2/cm3xxx.c2
-rw-r--r--arch/arm/mach-omap2/cm_common.c16
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c12
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c73
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_81xx_data.c2
10 files changed, 68 insertions, 64 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 518926410b62..b79b1ca9aee9 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -1224,14 +1224,6 @@ ccd_exit:
1224 return 0; 1224 return 0;
1225} 1225}
1226 1226
1227u32 clkdm_xlate_address(struct clockdomain *clkdm)
1228{
1229 if (arch_clkdm->clkdm_xlate_address)
1230 return arch_clkdm->clkdm_xlate_address(clkdm);
1231
1232 return 0;
1233}
1234
1235/** 1227/**
1236 * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm 1228 * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
1237 * @clkdm: struct clockdomain * 1229 * @clkdm: struct clockdomain *
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 827f01e2d0af..24667a5a9dc0 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -175,7 +175,6 @@ struct clkdm_ops {
175 void (*clkdm_deny_idle)(struct clockdomain *clkdm); 175 void (*clkdm_deny_idle)(struct clockdomain *clkdm);
176 int (*clkdm_clk_enable)(struct clockdomain *clkdm); 176 int (*clkdm_clk_enable)(struct clockdomain *clkdm);
177 int (*clkdm_clk_disable)(struct clockdomain *clkdm); 177 int (*clkdm_clk_disable)(struct clockdomain *clkdm);
178 u32 (*clkdm_xlate_address)(struct clockdomain *clkdm);
179}; 178};
180 179
181int clkdm_register_platform_funcs(struct clkdm_ops *co); 180int clkdm_register_platform_funcs(struct clkdm_ops *co);
@@ -214,7 +213,6 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
214int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); 213int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
215int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); 214int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
216int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); 215int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
217u32 clkdm_xlate_address(struct clockdomain *clkdm);
218 216
219extern void __init omap242x_clockdomains_init(void); 217extern void __init omap242x_clockdomains_init(void);
220extern void __init omap243x_clockdomains_init(void); 218extern void __init omap243x_clockdomains_init(void);
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index e833984cc85e..b19e83d53501 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -52,6 +52,7 @@ extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
52 * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl 52 * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl
53 * @module_enable: ptr to the SoC CM-specific module_enable impl 53 * @module_enable: ptr to the SoC CM-specific module_enable impl
54 * @module_disable: ptr to the SoC CM-specific module_disable impl 54 * @module_disable: ptr to the SoC CM-specific module_disable impl
55 * @xlate_clkctrl: ptr to the SoC CM-specific clkctrl xlate addr impl
55 */ 56 */
56struct cm_ll_data { 57struct cm_ll_data {
57 int (*split_idlest_reg)(struct clk_omap_reg *idlest_reg, s16 *prcm_inst, 58 int (*split_idlest_reg)(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
@@ -62,6 +63,7 @@ struct cm_ll_data {
62 u8 idlest_shift); 63 u8 idlest_shift);
63 void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); 64 void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
64 void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs); 65 void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs);
66 u32 (*xlate_clkctrl)(u8 part, u16 inst, u16 clkctrl_offs);
65}; 67};
66 68
67extern int cm_split_idlest_reg(struct clk_omap_reg *idlest_reg, s16 *prcm_inst, 69extern int cm_split_idlest_reg(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
@@ -72,8 +74,9 @@ int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg,
72 u8 idlest_shift); 74 u8 idlest_shift);
73int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); 75int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
74int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs); 76int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs);
75extern int cm_register(struct cm_ll_data *cld); 77u32 omap_cm_xlate_clkctrl(u8 part, u16 inst, u16 clkctrl_offs);
76extern int cm_unregister(struct cm_ll_data *cld); 78extern int cm_register(const struct cm_ll_data *cld);
79extern int cm_unregister(const struct cm_ll_data *cld);
77int omap_cm_init(void); 80int omap_cm_init(void);
78int omap2_cm_base_init(void); 81int omap2_cm_base_init(void);
79 82
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index cd90b4c6a06b..d5b87f42a96e 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -385,7 +385,7 @@ void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm)
385 * 385 *
386 */ 386 */
387 387
388static struct cm_ll_data omap2xxx_cm_ll_data = { 388static const struct cm_ll_data omap2xxx_cm_ll_data = {
389 .split_idlest_reg = &omap2xxx_cm_split_idlest_reg, 389 .split_idlest_reg = &omap2xxx_cm_split_idlest_reg,
390 .wait_module_ready = &omap2xxx_cm_wait_module_ready, 390 .wait_module_ready = &omap2xxx_cm_wait_module_ready,
391}; 391};
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index a9e08d89104e..1cc0247a2cb5 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -333,6 +333,11 @@ static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
333 return 0; 333 return 0;
334} 334}
335 335
336static u32 am33xx_cm_xlate_clkctrl(u8 part, u16 inst, u16 offset)
337{
338 return cm_base.pa + inst + offset;
339}
340
336struct clkdm_ops am33xx_clkdm_operations = { 341struct clkdm_ops am33xx_clkdm_operations = {
337 .clkdm_sleep = am33xx_clkdm_sleep, 342 .clkdm_sleep = am33xx_clkdm_sleep,
338 .clkdm_wakeup = am33xx_clkdm_wakeup, 343 .clkdm_wakeup = am33xx_clkdm_wakeup,
@@ -342,11 +347,12 @@ struct clkdm_ops am33xx_clkdm_operations = {
342 .clkdm_clk_disable = am33xx_clkdm_clk_disable, 347 .clkdm_clk_disable = am33xx_clkdm_clk_disable,
343}; 348};
344 349
345static struct cm_ll_data am33xx_cm_ll_data = { 350static const struct cm_ll_data am33xx_cm_ll_data = {
346 .wait_module_ready = &am33xx_cm_wait_module_ready, 351 .wait_module_ready = &am33xx_cm_wait_module_ready,
347 .wait_module_idle = &am33xx_cm_wait_module_idle, 352 .wait_module_idle = &am33xx_cm_wait_module_idle,
348 .module_enable = &am33xx_cm_module_enable, 353 .module_enable = &am33xx_cm_module_enable,
349 .module_disable = &am33xx_cm_module_disable, 354 .module_disable = &am33xx_cm_module_disable,
355 .xlate_clkctrl = &am33xx_cm_xlate_clkctrl,
350}; 356};
351 357
352int __init am33xx_cm_init(const struct omap_prcm_init_data *data) 358int __init am33xx_cm_init(const struct omap_prcm_init_data *data)
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 961bc478b9de..ec580fd094a6 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -662,7 +662,7 @@ void omap3_cm_save_scratchpad_contents(u32 *ptr)
662 * 662 *
663 */ 663 */
664 664
665static struct cm_ll_data omap3xxx_cm_ll_data = { 665static const struct cm_ll_data omap3xxx_cm_ll_data = {
666 .split_idlest_reg = &omap3xxx_cm_split_idlest_reg, 666 .split_idlest_reg = &omap3xxx_cm_split_idlest_reg,
667 .wait_module_ready = &omap3xxx_cm_wait_module_ready, 667 .wait_module_ready = &omap3xxx_cm_wait_module_ready,
668}; 668};
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
index 83c6fa74cc31..aff747ecad51 100644
--- a/arch/arm/mach-omap2/cm_common.c
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -29,7 +29,7 @@
29 * common CM functions 29 * common CM functions
30 */ 30 */
31static struct cm_ll_data null_cm_ll_data; 31static struct cm_ll_data null_cm_ll_data;
32static struct cm_ll_data *cm_ll_data = &null_cm_ll_data; 32static const struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
33 33
34/* cm_base: base virtual address of the CM IP block */ 34/* cm_base: base virtual address of the CM IP block */
35struct omap_domain_base cm_base; 35struct omap_domain_base cm_base;
@@ -178,6 +178,16 @@ int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
178 return 0; 178 return 0;
179} 179}
180 180
181u32 omap_cm_xlate_clkctrl(u8 part, u16 inst, u16 clkctrl_offs)
182{
183 if (!cm_ll_data->xlate_clkctrl) {
184 WARN_ONCE(1, "cm: %s: no low-level function defined\n",
185 __func__);
186 return 0;
187 }
188 return cm_ll_data->xlate_clkctrl(part, inst, clkctrl_offs);
189}
190
181/** 191/**
182 * cm_register - register per-SoC low-level data with the CM 192 * cm_register - register per-SoC low-level data with the CM
183 * @cld: low-level per-SoC OMAP CM data & function pointers to register 193 * @cld: low-level per-SoC OMAP CM data & function pointers to register
@@ -189,7 +199,7 @@ int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
189 * is NULL, or -EEXIST if cm_register() has already been called 199 * is NULL, or -EEXIST if cm_register() has already been called
190 * without an intervening cm_unregister(). 200 * without an intervening cm_unregister().
191 */ 201 */
192int cm_register(struct cm_ll_data *cld) 202int cm_register(const struct cm_ll_data *cld)
193{ 203{
194 if (!cld) 204 if (!cld)
195 return -EINVAL; 205 return -EINVAL;
@@ -213,7 +223,7 @@ int cm_register(struct cm_ll_data *cld)
213 * -EINVAL if @cld is NULL or if @cld does not match the struct 223 * -EINVAL if @cld is NULL or if @cld does not match the struct
214 * cm_ll_data * previously registered by cm_register(). 224 * cm_ll_data * previously registered by cm_register().
215 */ 225 */
216int cm_unregister(struct cm_ll_data *cld) 226int cm_unregister(const struct cm_ll_data *cld)
217{ 227{
218 if (!cld || cm_ll_data != cld) 228 if (!cld || cm_ll_data != cld)
219 return -EINVAL; 229 return -EINVAL;
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 8774e983bea1..7deefee49fc3 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -476,12 +476,9 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
476 return 0; 476 return 0;
477} 477}
478 478
479static u32 omap4_clkdm_xlate_address(struct clockdomain *clkdm) 479static u32 omap4_cminst_xlate_clkctrl(u8 part, u16 inst, u16 offset)
480{ 480{
481 u32 addr = _cm_bases[clkdm->prcm_partition].pa + clkdm->cm_inst + 481 return _cm_bases[part].pa + inst + offset;
482 clkdm->clkdm_offs;
483
484 return addr;
485} 482}
486 483
487struct clkdm_ops omap4_clkdm_operations = { 484struct clkdm_ops omap4_clkdm_operations = {
@@ -499,7 +496,6 @@ struct clkdm_ops omap4_clkdm_operations = {
499 .clkdm_deny_idle = omap4_clkdm_deny_idle, 496 .clkdm_deny_idle = omap4_clkdm_deny_idle,
500 .clkdm_clk_enable = omap4_clkdm_clk_enable, 497 .clkdm_clk_enable = omap4_clkdm_clk_enable,
501 .clkdm_clk_disable = omap4_clkdm_clk_disable, 498 .clkdm_clk_disable = omap4_clkdm_clk_disable,
502 .clkdm_xlate_address = omap4_clkdm_xlate_address,
503}; 499};
504 500
505struct clkdm_ops am43xx_clkdm_operations = { 501struct clkdm_ops am43xx_clkdm_operations = {
@@ -509,14 +505,14 @@ struct clkdm_ops am43xx_clkdm_operations = {
509 .clkdm_deny_idle = omap4_clkdm_deny_idle, 505 .clkdm_deny_idle = omap4_clkdm_deny_idle,
510 .clkdm_clk_enable = omap4_clkdm_clk_enable, 506 .clkdm_clk_enable = omap4_clkdm_clk_enable,
511 .clkdm_clk_disable = omap4_clkdm_clk_disable, 507 .clkdm_clk_disable = omap4_clkdm_clk_disable,
512 .clkdm_xlate_address = omap4_clkdm_xlate_address,
513}; 508};
514 509
515static struct cm_ll_data omap4xxx_cm_ll_data = { 510static const struct cm_ll_data omap4xxx_cm_ll_data = {
516 .wait_module_ready = &omap4_cminst_wait_module_ready, 511 .wait_module_ready = &omap4_cminst_wait_module_ready,
517 .wait_module_idle = &omap4_cminst_wait_module_idle, 512 .wait_module_idle = &omap4_cminst_wait_module_idle,
518 .module_enable = &omap4_cminst_module_enable, 513 .module_enable = &omap4_cminst_module_enable,
519 .module_disable = &omap4_cminst_module_disable, 514 .module_disable = &omap4_cminst_module_disable,
515 .xlate_clkctrl = &omap4_cminst_xlate_clkctrl,
520}; 516};
521 517
522int __init omap4_cm_init(const struct omap_prcm_init_data *data) 518int __init omap4_cm_init(const struct omap_prcm_init_data *data)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 104256a5f0f7..5eff27e4f24b 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -185,15 +185,15 @@
185/** 185/**
186 * struct clkctrl_provider - clkctrl provider mapping data 186 * struct clkctrl_provider - clkctrl provider mapping data
187 * @addr: base address for the provider 187 * @addr: base address for the provider
188 * @offset: base offset for the provider 188 * @size: size of the provider address space
189 * @clkdm: base clockdomain for provider 189 * @offset: offset of the provider from PRCM instance base
190 * @node: device node associated with the provider 190 * @node: device node associated with the provider
191 * @link: list link 191 * @link: list link
192 */ 192 */
193struct clkctrl_provider { 193struct clkctrl_provider {
194 u32 addr; 194 u32 addr;
195 u32 size;
195 u16 offset; 196 u16 offset;
196 struct clockdomain *clkdm;
197 struct device_node *node; 197 struct device_node *node;
198 struct list_head link; 198 struct list_head link;
199}; 199};
@@ -223,8 +223,7 @@ struct omap_hwmod_soc_ops {
223 void (*update_context_lost)(struct omap_hwmod *oh); 223 void (*update_context_lost)(struct omap_hwmod *oh);
224 int (*get_context_lost)(struct omap_hwmod *oh); 224 int (*get_context_lost)(struct omap_hwmod *oh);
225 int (*disable_direct_prcm)(struct omap_hwmod *oh); 225 int (*disable_direct_prcm)(struct omap_hwmod *oh);
226 u32 (*xlate_clkctrl)(struct omap_hwmod *oh, 226 u32 (*xlate_clkctrl)(struct omap_hwmod *oh);
227 struct clkctrl_provider *provider);
228}; 227};
229 228
230/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ 229/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -716,45 +715,28 @@ static const struct of_device_id ti_clkctrl_match_table[] __initconst = {
716 { } 715 { }
717}; 716};
718 717
719static int _match_clkdm(struct clockdomain *clkdm, void *user)
720{
721 struct clkctrl_provider *provider = user;
722
723 if (clkdm_xlate_address(clkdm) == provider->addr) {
724 pr_debug("%s: Matched clkdm %s for addr %x (%s)\n", __func__,
725 clkdm->name, provider->addr,
726 provider->node->parent->name);
727 provider->clkdm = clkdm;
728
729 return -1;
730 }
731
732 return 0;
733}
734
735static int _setup_clkctrl_provider(struct device_node *np) 718static int _setup_clkctrl_provider(struct device_node *np)
736{ 719{
737 const __be32 *addrp; 720 const __be32 *addrp;
738 struct clkctrl_provider *provider; 721 struct clkctrl_provider *provider;
722 u64 size;
739 723
740 provider = memblock_virt_alloc(sizeof(*provider), 0); 724 provider = memblock_virt_alloc(sizeof(*provider), 0);
741 if (!provider) 725 if (!provider)
742 return -ENOMEM; 726 return -ENOMEM;
743 727
744 addrp = of_get_address(np, 0, NULL, NULL); 728 addrp = of_get_address(np, 0, &size, NULL);
745 provider->addr = (u32)of_translate_address(np, addrp); 729 provider->addr = (u32)of_translate_address(np, addrp);
746 provider->offset = provider->addr & 0xff; 730 addrp = of_get_address(np->parent, 0, NULL, NULL);
731 provider->offset = provider->addr -
732 (u32)of_translate_address(np->parent, addrp);
747 provider->addr &= ~0xff; 733 provider->addr &= ~0xff;
734 provider->size = size | 0xff;
748 provider->node = np; 735 provider->node = np;
749 736
750 clkdm_for_each(_match_clkdm, provider); 737 pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name,
751 738 provider->addr, provider->addr + provider->size,
752 if (!provider->clkdm) { 739 provider->offset);
753 pr_err("%s: nothing matched for node %s (%x)\n",
754 __func__, np->parent->name, provider->addr);
755 memblock_free_early(__pa(provider), sizeof(*provider));
756 return -EINVAL;
757 }
758 740
759 list_add(&provider->link, &clkctrl_providers); 741 list_add(&provider->link, &clkctrl_providers);
760 742
@@ -775,32 +757,48 @@ static int _init_clkctrl_providers(void)
775 return ret; 757 return ret;
776} 758}
777 759
778static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh, 760static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh)
779 struct clkctrl_provider *provider)
780{ 761{
781 return oh->prcm.omap4.clkctrl_offs - 762 if (!oh->prcm.omap4.modulemode)
782 provider->offset - provider->clkdm->clkdm_offs; 763 return 0;
764
765 return omap_cm_xlate_clkctrl(oh->clkdm->prcm_partition,
766 oh->clkdm->cm_inst,
767 oh->prcm.omap4.clkctrl_offs);
783} 768}
784 769
785static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh) 770static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
786{ 771{
787 struct clkctrl_provider *provider; 772 struct clkctrl_provider *provider;
788 struct clk *clk; 773 struct clk *clk;
774 u32 addr;
789 775
790 if (!soc_ops.xlate_clkctrl) 776 if (!soc_ops.xlate_clkctrl)
791 return NULL; 777 return NULL;
792 778
779 addr = soc_ops.xlate_clkctrl(oh);
780 if (!addr)
781 return NULL;
782
783 pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
784
793 list_for_each_entry(provider, &clkctrl_providers, link) { 785 list_for_each_entry(provider, &clkctrl_providers, link) {
794 if (provider->clkdm == oh->clkdm) { 786 if (provider->addr <= addr &&
787 provider->addr + provider->size >= addr) {
795 struct of_phandle_args clkspec; 788 struct of_phandle_args clkspec;
796 789
797 clkspec.np = provider->node; 790 clkspec.np = provider->node;
798 clkspec.args_count = 2; 791 clkspec.args_count = 2;
799 clkspec.args[0] = soc_ops.xlate_clkctrl(oh, provider); 792 clkspec.args[0] = addr - provider->addr -
793 provider->offset;
800 clkspec.args[1] = 0; 794 clkspec.args[1] = 0;
801 795
802 clk = of_clk_get_from_provider(&clkspec); 796 clk = of_clk_get_from_provider(&clkspec);
803 797
798 pr_debug("%s: %s got %p (offset=%x, provider=%s)\n",
799 __func__, oh->name, clk, clkspec.args[0],
800 provider->node->parent->name);
801
804 return clk; 802 return clk;
805 } 803 }
806 } 804 }
@@ -3521,6 +3519,7 @@ void __init omap_hwmod_init(void)
3521 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; 3519 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
3522 soc_ops.init_clkdm = _init_clkdm; 3520 soc_ops.init_clkdm = _init_clkdm;
3523 soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; 3521 soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
3522 soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl;
3524 } else { 3523 } else {
3525 WARN(1, "omap_hwmod: unknown SoC type\n"); 3524 WARN(1, "omap_hwmod: unknown SoC type\n");
3526 } 3525 }
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index 77a515b11ec2..84f118280a0e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -988,7 +988,7 @@ static struct omap_hwmod_class dm81xx_sata_hwmod_class = {
988 988
989static struct omap_hwmod dm81xx_sata_hwmod = { 989static struct omap_hwmod dm81xx_sata_hwmod = {
990 .name = "sata", 990 .name = "sata",
991 .clkdm_name = "default_sata_clkdm", 991 .clkdm_name = "default_clkdm",
992 .flags = HWMOD_NO_IDLEST, 992 .flags = HWMOD_NO_IDLEST,
993 .prcm = { 993 .prcm = {
994 .omap4 = { 994 .omap4 = {