ARM: tegra11: clock: Update cbus operations
Alex Frid [Sat, 14 Jul 2012 06:07:58 +0000 (23:07 -0700)]
When several users request the same rate, select the slowest one
as the top user (instead of selecting in order of link list parsing).

Eliminate debugfs floor user from top user selection.

Prevent top user migration if it has the same dvfs table as the
slowest user on the same bus.

Change-Id: I9b0ba04d60b9408cc68a81e1cb59baee7f37fed8
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/117249
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bo Yan <byan@nvidia.com>

arch/arm/mach-tegra/tegra11_clocks.c

index 1372527..7471d3a 100644 (file)
@@ -4144,6 +4144,7 @@ static int tegra11_clk_cbus_update(struct clk *bus)
        struct clk *slow = NULL;
        struct clk *top = NULL;
 
+       unsigned long top_rate = 0;
        unsigned long rate = bus->min_rate;
        unsigned long ceiling = bus->max_rate;
 
@@ -4165,9 +4166,15 @@ static int tegra11_clk_cbus_update(struct clk *bus)
                                break;
                        case SHARED_FLOOR:
                        default:
-                               if (rate < request_rate) {
-                                       rate = request_rate;
-                                       top = c;
+                               rate = max(request_rate, rate);
+                               if (c->u.shared_bus_user.client) {
+                                       if (top_rate < request_rate) {
+                                               top_rate = request_rate;
+                                               top = c;
+                                       } else if ((top_rate == request_rate) &&
+                                               cbus_user_is_slower(c, top)) {
+                                               top = c;
+                                       }
                                }
                        }
                        if (c->u.shared_bus_user.client &&
@@ -4249,13 +4256,13 @@ static int tegra11_clk_cbus_migrate_users(struct clk *user)
        /* If top user is the slow one on its own (source) bus, do nothing */
        top_user = src_bus->u.cbus.top_user;
        BUG_ON(!top_user->u.shared_bus_user.client);
-       if (top_user == src_bus->u.cbus.slow_user)
+       if (!cbus_user_is_slower(src_bus->u.cbus.slow_user, top_user))
                return 0;
 
        /* If source bus top user is slower than all users on destination bus,
           move top user; otherwise move all users slower than the top one */
        if (!dst_bus->u.cbus.slow_user ||
-           cbus_user_is_slower(top_user, dst_bus->u.cbus.slow_user)) {
+           !cbus_user_is_slower(dst_bus->u.cbus.slow_user, top_user)) {
                cbus_move_enabled_user(top_user, dst_bus, src_bus);
        } else {
                list_for_each_safe(pos, n, &src_bus->shared_bus_list) {