diff options
author | Colin Cross <ccross@android.com> | 2011-02-21 19:44:07 -0500 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-02-22 14:25:07 -0500 |
commit | 1be3d0537516fa42825406b4bc1291b77ed62614 (patch) | |
tree | 4ade740dd278fd5e213bad3774f0df3721f6110c /arch/arm | |
parent | 421186e71000c067c2687baeffde62954a80cdcc (diff) |
ARM: tegra: clock: prevent accidental disables of cpu clock
Peripheral clocks that have no clock enable bit in the
enable registers have their clk_num set to 0. Bit 0
in the clock enable registers is the CPU clock.
Prevent disables on these peripheral clocks from
accidentally disabling the CPU clock.
Signed-off-by: Colin Cross <ccross@android.com>
Acked-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 73e112f12695..3015a2c64252 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c | |||
@@ -946,9 +946,14 @@ static void tegra2_periph_clk_init(struct clk *c) | |||
946 | } | 946 | } |
947 | 947 | ||
948 | c->state = ON; | 948 | c->state = ON; |
949 | |||
950 | if (!c->u.periph.clk_num) | ||
951 | return; | ||
952 | |||
949 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & | 953 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & |
950 | PERIPH_CLK_TO_ENB_BIT(c))) | 954 | PERIPH_CLK_TO_ENB_BIT(c))) |
951 | c->state = OFF; | 955 | c->state = OFF; |
956 | |||
952 | if (!(c->flags & PERIPH_NO_RESET)) | 957 | if (!(c->flags & PERIPH_NO_RESET)) |
953 | if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) & | 958 | if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) & |
954 | PERIPH_CLK_TO_ENB_BIT(c)) | 959 | PERIPH_CLK_TO_ENB_BIT(c)) |
@@ -962,6 +967,9 @@ static int tegra2_periph_clk_enable(struct clk *c) | |||
962 | int refcount; | 967 | int refcount; |
963 | pr_debug("%s on clock %s\n", __func__, c->name); | 968 | pr_debug("%s on clock %s\n", __func__, c->name); |
964 | 969 | ||
970 | if (!c->u.periph.clk_num) | ||
971 | return 0; | ||
972 | |||
965 | spin_lock_irqsave(&clock_register_lock, flags); | 973 | spin_lock_irqsave(&clock_register_lock, flags); |
966 | 974 | ||
967 | refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; | 975 | refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; |
@@ -994,6 +1002,9 @@ static void tegra2_periph_clk_disable(struct clk *c) | |||
994 | 1002 | ||
995 | pr_debug("%s on clock %s\n", __func__, c->name); | 1003 | pr_debug("%s on clock %s\n", __func__, c->name); |
996 | 1004 | ||
1005 | if (!c->u.periph.clk_num) | ||
1006 | return; | ||
1007 | |||
997 | spin_lock_irqsave(&clock_register_lock, flags); | 1008 | spin_lock_irqsave(&clock_register_lock, flags); |
998 | 1009 | ||
999 | if (c->refcnt) | 1010 | if (c->refcnt) |
@@ -1012,6 +1023,9 @@ static void tegra2_periph_clk_reset(struct clk *c, bool assert) | |||
1012 | 1023 | ||
1013 | pr_debug("%s %s on clock %s\n", __func__, | 1024 | pr_debug("%s %s on clock %s\n", __func__, |
1014 | assert ? "assert" : "deassert", c->name); | 1025 | assert ? "assert" : "deassert", c->name); |
1026 | |||
1027 | BUG_ON(!c->u.periph.clk_num); | ||
1028 | |||
1015 | if (!(c->flags & PERIPH_NO_RESET)) | 1029 | if (!(c->flags & PERIPH_NO_RESET)) |
1016 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | 1030 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), |
1017 | base + PERIPH_CLK_TO_ENB_SET_REG(c)); | 1031 | base + PERIPH_CLK_TO_ENB_SET_REG(c)); |
@@ -1182,6 +1196,10 @@ static void tegra2_clk_double_init(struct clk *c) | |||
1182 | c->mul = 2; | 1196 | c->mul = 2; |
1183 | c->div = 1; | 1197 | c->div = 1; |
1184 | c->state = ON; | 1198 | c->state = ON; |
1199 | |||
1200 | if (!c->u.periph.clk_num) | ||
1201 | return; | ||
1202 | |||
1185 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & | 1203 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & |
1186 | PERIPH_CLK_TO_ENB_BIT(c))) | 1204 | PERIPH_CLK_TO_ENB_BIT(c))) |
1187 | c->state = OFF; | 1205 | c->state = OFF; |
@@ -1269,6 +1287,9 @@ static void tegra2_cdev_clk_init(struct clk *c) | |||
1269 | /* We could un-tristate the cdev1 or cdev2 pingroup here; this is | 1287 | /* We could un-tristate the cdev1 or cdev2 pingroup here; this is |
1270 | * currently done in the pinmux code. */ | 1288 | * currently done in the pinmux code. */ |
1271 | c->state = ON; | 1289 | c->state = ON; |
1290 | |||
1291 | BUG_ON(!c->u.periph.clk_num); | ||
1292 | |||
1272 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & | 1293 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & |
1273 | PERIPH_CLK_TO_ENB_BIT(c))) | 1294 | PERIPH_CLK_TO_ENB_BIT(c))) |
1274 | c->state = OFF; | 1295 | c->state = OFF; |
@@ -1276,6 +1297,8 @@ static void tegra2_cdev_clk_init(struct clk *c) | |||
1276 | 1297 | ||
1277 | static int tegra2_cdev_clk_enable(struct clk *c) | 1298 | static int tegra2_cdev_clk_enable(struct clk *c) |
1278 | { | 1299 | { |
1300 | BUG_ON(!c->u.periph.clk_num); | ||
1301 | |||
1279 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | 1302 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), |
1280 | CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); | 1303 | CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); |
1281 | return 0; | 1304 | return 0; |
@@ -1283,6 +1306,8 @@ static int tegra2_cdev_clk_enable(struct clk *c) | |||
1283 | 1306 | ||
1284 | static void tegra2_cdev_clk_disable(struct clk *c) | 1307 | static void tegra2_cdev_clk_disable(struct clk *c) |
1285 | { | 1308 | { |
1309 | BUG_ON(!c->u.periph.clk_num); | ||
1310 | |||
1286 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | 1311 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), |
1287 | CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); | 1312 | CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); |
1288 | } | 1313 | } |