@@ -460,8 +460,6 @@ static int mlxreg_lc_power_on_off(struct mlxreg_lc *mlxreg_lc, u8 action)
460460 u32 regval ;
461461 int err ;
462462
463- mutex_lock (& mlxreg_lc -> lock );
464-
465463 err = regmap_read (mlxreg_lc -> par_regmap , mlxreg_lc -> data -> reg_pwr , & regval );
466464 if (err )
467465 goto regmap_read_fail ;
@@ -474,7 +472,6 @@ static int mlxreg_lc_power_on_off(struct mlxreg_lc *mlxreg_lc, u8 action)
474472 err = regmap_write (mlxreg_lc -> par_regmap , mlxreg_lc -> data -> reg_pwr , regval );
475473
476474regmap_read_fail :
477- mutex_unlock (& mlxreg_lc -> lock );
478475 return err ;
479476}
480477
@@ -491,8 +488,6 @@ static int mlxreg_lc_enable_disable(struct mlxreg_lc *mlxreg_lc, bool action)
491488 * line card which is already has been enabled. Disabling does not affect the disabled line
492489 * card.
493490 */
494- mutex_lock (& mlxreg_lc -> lock );
495-
496491 err = regmap_read (mlxreg_lc -> par_regmap , mlxreg_lc -> data -> reg_ena , & regval );
497492 if (err )
498493 goto regmap_read_fail ;
@@ -505,7 +500,6 @@ static int mlxreg_lc_enable_disable(struct mlxreg_lc *mlxreg_lc, bool action)
505500 err = regmap_write (mlxreg_lc -> par_regmap , mlxreg_lc -> data -> reg_ena , regval );
506501
507502regmap_read_fail :
508- mutex_unlock (& mlxreg_lc -> lock );
509503 return err ;
510504}
511505
@@ -537,6 +531,15 @@ mlxreg_lc_sn4800_c16_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
537531
538532static void
539533mlxreg_lc_state_update (struct mlxreg_lc * mlxreg_lc , enum mlxreg_lc_state state , u8 action )
534+ {
535+ if (action )
536+ mlxreg_lc -> state |= state ;
537+ else
538+ mlxreg_lc -> state &= ~state ;
539+ }
540+
541+ static void
542+ mlxreg_lc_state_update_locked (struct mlxreg_lc * mlxreg_lc , enum mlxreg_lc_state state , u8 action )
540543{
541544 mutex_lock (& mlxreg_lc -> lock );
542545
@@ -560,8 +563,11 @@ static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind,
560563 dev_info (mlxreg_lc -> dev , "linecard#%d state %d event kind %d action %d\n" ,
561564 mlxreg_lc -> data -> slot , mlxreg_lc -> state , kind , action );
562565
563- if (!(mlxreg_lc -> state & MLXREG_LC_INITIALIZED ))
566+ mutex_lock (& mlxreg_lc -> lock );
567+ if (!(mlxreg_lc -> state & MLXREG_LC_INITIALIZED )) {
568+ mutex_unlock (& mlxreg_lc -> lock );
564569 return 0 ;
570+ }
565571
566572 switch (kind ) {
567573 case MLXREG_HOTPLUG_LC_SYNCED :
@@ -574,7 +580,7 @@ static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind,
574580 if (!(mlxreg_lc -> state & MLXREG_LC_POWERED ) && action ) {
575581 err = mlxreg_lc_power_on_off (mlxreg_lc , 1 );
576582 if (err )
577- return err ;
583+ goto mlxreg_lc_power_on_off_fail ;
578584 }
579585 /* In case line card is configured - enable it. */
580586 if (mlxreg_lc -> state & MLXREG_LC_CONFIGURED && action )
@@ -588,12 +594,13 @@ static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind,
588594 /* In case line card is configured - enable it. */
589595 if (mlxreg_lc -> state & MLXREG_LC_CONFIGURED )
590596 err = mlxreg_lc_enable_disable (mlxreg_lc , 1 );
597+ mutex_unlock (& mlxreg_lc -> lock );
591598 return err ;
592599 }
593600 err = mlxreg_lc_create_static_devices (mlxreg_lc , mlxreg_lc -> main_devs ,
594601 mlxreg_lc -> main_devs_num );
595602 if (err )
596- return err ;
603+ goto mlxreg_lc_create_static_devices_fail ;
597604
598605 /* In case line card is already in ready state - enable it. */
599606 if (mlxreg_lc -> state & MLXREG_LC_CONFIGURED )
@@ -620,6 +627,10 @@ static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind,
620627 break ;
621628 }
622629
630+ mlxreg_lc_power_on_off_fail :
631+ mlxreg_lc_create_static_devices_fail :
632+ mutex_unlock (& mlxreg_lc -> lock );
633+
623634 return err ;
624635}
625636
@@ -665,7 +676,7 @@ static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent,
665676 if (err )
666677 goto mlxreg_lc_create_static_devices_failed ;
667678
668- mlxreg_lc_state_update (mlxreg_lc , MLXREG_LC_POWERED , 1 );
679+ mlxreg_lc_state_update_locked (mlxreg_lc , MLXREG_LC_POWERED , 1 );
669680 }
670681
671682 /* Verify if line card is synchronized. */
@@ -676,15 +687,15 @@ static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent,
676687 /* Power on line card if necessary. */
677688 if (regval & mlxreg_lc -> data -> mask ) {
678689 mlxreg_lc -> state |= MLXREG_LC_SYNCED ;
679- mlxreg_lc_state_update (mlxreg_lc , MLXREG_LC_SYNCED , 1 );
690+ mlxreg_lc_state_update_locked (mlxreg_lc , MLXREG_LC_SYNCED , 1 );
680691 if (mlxreg_lc -> state & ~MLXREG_LC_POWERED ) {
681692 err = mlxreg_lc_power_on_off (mlxreg_lc , 1 );
682693 if (err )
683694 goto mlxreg_lc_regmap_power_on_off_fail ;
684695 }
685696 }
686697
687- mlxreg_lc_state_update (mlxreg_lc , MLXREG_LC_INITIALIZED , 1 );
698+ mlxreg_lc_state_update_locked (mlxreg_lc , MLXREG_LC_INITIALIZED , 1 );
688699
689700 return 0 ;
690701
@@ -904,6 +915,8 @@ static int mlxreg_lc_remove(struct platform_device *pdev)
904915 struct mlxreg_core_data * data = dev_get_platdata (& pdev -> dev );
905916 struct mlxreg_lc * mlxreg_lc = platform_get_drvdata (pdev );
906917
918+ mlxreg_lc_state_update_locked (mlxreg_lc , MLXREG_LC_INITIALIZED , 0 );
919+
907920 /*
908921 * Probing and removing are invoked by hotplug events raised upon line card insertion and
909922 * removing. If probing procedure fails all data is cleared. However, hotplug event still
0 commit comments