@@ -235,6 +235,7 @@ static struct omap_hwmod_soc_ops soc_ops;
235
235
236
236
/* omap_hwmod_list contains all registered struct omap_hwmods */
237
237
static LIST_HEAD (omap_hwmod_list );
238
+ static DEFINE_MUTEX (list_lock );
238
239
239
240
/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
240
241
static struct omap_hwmod * mpu_oh ;
@@ -2624,7 +2625,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
2624
2625
* that the copy process would be relatively complex due to the large number
2625
2626
* of substructures.
2626
2627
*/
2627
- static int __init _register (struct omap_hwmod * oh )
2628
+ static int _register (struct omap_hwmod * oh )
2628
2629
{
2629
2630
if (!oh || !oh -> name || !oh -> class || !oh -> class -> name ||
2630
2631
(oh -> _state != _HWMOD_STATE_UNKNOWN ))
@@ -2663,7 +2664,7 @@ static int __init _register(struct omap_hwmod *oh)
2663
2664
* locking in this code. Changes to this assumption will require
2664
2665
* additional locking. Returns 0.
2665
2666
*/
2666
- static int __init _add_link (struct omap_hwmod_ocp_if * oi )
2667
+ static int _add_link (struct omap_hwmod_ocp_if * oi )
2667
2668
{
2668
2669
pr_debug ("omap_hwmod: %s -> %s: adding link\n" , oi -> master -> name ,
2669
2670
oi -> slave -> name );
@@ -3444,6 +3445,9 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
3444
3445
{
3445
3446
struct omap_hwmod_class_sysconfig * sysc ;
3446
3447
struct omap_hwmod_class * class = NULL ;
3448
+ struct omap_hwmod_ocp_if * oi = NULL ;
3449
+ struct clockdomain * clkdm = NULL ;
3450
+ struct clk * clk = NULL ;
3447
3451
void __iomem * regs = NULL ;
3448
3452
unsigned long flags ;
3449
3453
@@ -3476,13 +3480,62 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
3476
3480
return - ENOMEM ;
3477
3481
}
3478
3482
3483
+ if (list_empty (& oh -> slave_ports )) {
3484
+ oi = kcalloc (1 , sizeof (* oi ), GFP_KERNEL );
3485
+ if (!oi )
3486
+ return - ENOMEM ;
3487
+
3488
+ /*
3489
+ * Note that we assume interconnect interface clocks will be
3490
+ * managed by the interconnect driver for OCPIF_SWSUP_IDLE case
3491
+ * on omap24xx and omap3.
3492
+ */
3493
+ oi -> slave = oh ;
3494
+ oi -> user = OCP_USER_MPU | OCP_USER_SDMA ;
3495
+ }
3496
+
3497
+ if (!oh -> _clk ) {
3498
+ struct clk_hw_omap * hwclk ;
3499
+
3500
+ clk = of_clk_get_by_name (dev -> of_node , "fck" );
3501
+ if (!IS_ERR (clk ))
3502
+ clk_prepare (clk );
3503
+ else
3504
+ clk = NULL ;
3505
+
3506
+ /*
3507
+ * Populate clockdomain based on dts clock. It is needed for
3508
+ * clkdm_deny_idle() and clkdm_allow_idle() until we have have
3509
+ * interconnect driver and reset driver capable of blocking
3510
+ * clockdomain idle during reset, enable and idle.
3511
+ */
3512
+ if (clk ) {
3513
+ hwclk = to_clk_hw_omap (__clk_get_hw (clk ));
3514
+ if (hwclk && hwclk -> clkdm_name )
3515
+ clkdm = clkdm_lookup (hwclk -> clkdm_name );
3516
+ }
3517
+
3518
+ /*
3519
+ * Note that we assume interconnect driver manages the clocks
3520
+ * and do not need to populate oh->_clk for dynamically
3521
+ * allocated modules.
3522
+ */
3523
+ clk_unprepare (clk );
3524
+ clk_put (clk );
3525
+ }
3526
+
3479
3527
spin_lock_irqsave (& oh -> _lock , flags );
3480
3528
if (regs )
3481
3529
oh -> _mpu_rt_va = regs ;
3482
3530
if (class )
3483
3531
oh -> class = class ;
3484
3532
oh -> class -> sysc = sysc ;
3533
+ if (oi )
3534
+ _add_link (oi );
3535
+ if (clkdm )
3536
+ oh -> clkdm = clkdm ;
3485
3537
oh -> _state = _HWMOD_STATE_INITIALIZED ;
3538
+ oh -> _postsetup_state = _HWMOD_STATE_DEFAULT ;
3486
3539
_setup (oh , NULL );
3487
3540
spin_unlock_irqrestore (& oh -> _lock , flags );
3488
3541
@@ -3509,8 +3562,29 @@ int omap_hwmod_init_module(struct device *dev,
3509
3562
return - EINVAL ;
3510
3563
3511
3564
oh = _lookup (data -> name );
3512
- if (!oh )
3513
- return - ENODEV ;
3565
+ if (!oh ) {
3566
+ oh = kzalloc (sizeof (* oh ), GFP_KERNEL );
3567
+ if (!oh )
3568
+ return - ENOMEM ;
3569
+
3570
+ oh -> name = data -> name ;
3571
+ oh -> _state = _HWMOD_STATE_UNKNOWN ;
3572
+ lockdep_register_key (& oh -> hwmod_key );
3573
+
3574
+ /* Unused, can be handled by PRM driver handling resets */
3575
+ oh -> prcm .omap4 .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT ;
3576
+
3577
+ oh -> class = kzalloc (sizeof (* oh -> class ), GFP_KERNEL );
3578
+ if (!oh -> class ) {
3579
+ kfree (oh );
3580
+ return - ENOMEM ;
3581
+ }
3582
+
3583
+ oh -> class -> name = data -> name ;
3584
+ mutex_lock (& list_lock );
3585
+ error = _register (oh );
3586
+ mutex_unlock (& list_lock );
3587
+ }
3514
3588
3515
3589
cookie -> data = oh ;
3516
3590
0 commit comments