OPP: Protect `lazy_opp_tables` list with `opp_table_lock`
[linux-2.6-microblaze.git] / drivers / opp / of.c
index c740a90..ac2179d 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "opp.h"
 
-/* OPP tables with uninitialized required OPPs */
+/* OPP tables with uninitialized required OPPs, protected by opp_table_lock */
 static LIST_HEAD(lazy_opp_tables);
 
 /*
@@ -148,7 +148,10 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table)
 
        opp_table->required_opp_count = 0;
        opp_table->required_opp_tables = NULL;
+
+       mutex_lock(&opp_table_lock);
        list_del(&opp_table->lazy);
+       mutex_unlock(&opp_table_lock);
 }
 
 /*
@@ -197,8 +200,15 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
        }
 
        /* Let's do the linking later on */
-       if (lazy)
+       if (lazy) {
+               /*
+                * The OPP table is not held while allocating the table, take it
+                * now to avoid corruption to the lazy_opp_tables list.
+                */
+               mutex_lock(&opp_table_lock);
                list_add(&opp_table->lazy, &lazy_opp_tables);
+               mutex_unlock(&opp_table_lock);
+       }
        else
                _update_set_required_opps(opp_table);