aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-lpc32xx/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-lpc32xx/clock.c')
-rw-r--r--arch/arm/mach-lpc32xx/clock.c62
1 files changed, 21 insertions, 41 deletions
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index 1e027514096d..0e01bf44479c 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -82,6 +82,7 @@
82 * will also impact the individual peripheral rates. 82 * will also impact the individual peripheral rates.
83 */ 83 */
84 84
85#include <linux/export.h>
85#include <linux/kernel.h> 86#include <linux/kernel.h>
86#include <linux/list.h> 87#include <linux/list.h>
87#include <linux/errno.h> 88#include <linux/errno.h>
@@ -97,9 +98,10 @@
97#include "clock.h" 98#include "clock.h"
98#include "common.h" 99#include "common.h"
99 100
101static DEFINE_SPINLOCK(global_clkregs_lock);
102
100static struct clk clk_armpll; 103static struct clk clk_armpll;
101static struct clk clk_usbpll; 104static struct clk clk_usbpll;
102static DEFINE_MUTEX(clkm_lock);
103 105
104/* 106/*
105 * Post divider values for PLLs based on selected register value 107 * Post divider values for PLLs based on selected register value
@@ -127,7 +129,7 @@ static struct clk osc_32KHz = {
127static int local_pll397_enable(struct clk *clk, int enable) 129static int local_pll397_enable(struct clk *clk, int enable)
128{ 130{
129 u32 reg; 131 u32 reg;
130 unsigned long timeout = 1 + msecs_to_jiffies(10); 132 unsigned long timeout = jiffies + msecs_to_jiffies(10);
131 133
132 reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL); 134 reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL);
133 135
@@ -142,7 +144,7 @@ static int local_pll397_enable(struct clk *clk, int enable)
142 /* Wait for PLL397 lock */ 144 /* Wait for PLL397 lock */
143 while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & 145 while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
144 LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) && 146 LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) &&
145 (timeout > jiffies)) 147 time_before(jiffies, timeout))
146 cpu_relax(); 148 cpu_relax();
147 149
148 if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & 150 if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
@@ -156,7 +158,7 @@ static int local_pll397_enable(struct clk *clk, int enable)
156static int local_oscmain_enable(struct clk *clk, int enable) 158static int local_oscmain_enable(struct clk *clk, int enable)
157{ 159{
158 u32 reg; 160 u32 reg;
159 unsigned long timeout = 1 + msecs_to_jiffies(10); 161 unsigned long timeout = jiffies + msecs_to_jiffies(10);
160 162
161 reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL); 163 reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL);
162 164
@@ -171,7 +173,7 @@ static int local_oscmain_enable(struct clk *clk, int enable)
171 /* Wait for main oscillator to start */ 173 /* Wait for main oscillator to start */
172 while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & 174 while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
173 LPC32XX_CLKPWR_MOSC_DISABLE) != 0) && 175 LPC32XX_CLKPWR_MOSC_DISABLE) != 0) &&
174 (timeout > jiffies)) 176 time_before(jiffies, timeout))
175 cpu_relax(); 177 cpu_relax();
176 178
177 if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & 179 if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
@@ -383,7 +385,7 @@ static int local_usbpll_enable(struct clk *clk, int enable)
383{ 385{
384 u32 reg; 386 u32 reg;
385 int ret = -ENODEV; 387 int ret = -ENODEV;
386 unsigned long timeout = 1 + msecs_to_jiffies(10); 388 unsigned long timeout = jiffies + msecs_to_jiffies(10);
387 389
388 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); 390 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
389 391
@@ -396,7 +398,7 @@ static int local_usbpll_enable(struct clk *clk, int enable)
396 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); 398 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
397 399
398 /* Wait for PLL lock */ 400 /* Wait for PLL lock */
399 while ((timeout > jiffies) & (ret == -ENODEV)) { 401 while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
400 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); 402 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
401 if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) 403 if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
402 ret = 0; 404 ret = 0;
@@ -891,20 +893,8 @@ static struct clk clk_lcd = {
891 .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, 893 .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
892}; 894};
893 895
894static inline void clk_lock(void)
895{
896 mutex_lock(&clkm_lock);
897}
898
899static inline void clk_unlock(void)
900{
901 mutex_unlock(&clkm_lock);
902}
903
904static void local_clk_disable(struct clk *clk) 896static void local_clk_disable(struct clk *clk)
905{ 897{
906 WARN_ON(clk->usecount == 0);
907
908 /* Don't attempt to disable clock if it has no users */ 898 /* Don't attempt to disable clock if it has no users */
909 if (clk->usecount > 0) { 899 if (clk->usecount > 0) {
910 clk->usecount--; 900 clk->usecount--;
@@ -947,10 +937,11 @@ static int local_clk_enable(struct clk *clk)
947int clk_enable(struct clk *clk) 937int clk_enable(struct clk *clk)
948{ 938{
949 int ret; 939 int ret;
940 unsigned long flags;
950 941
951 clk_lock(); 942 spin_lock_irqsave(&global_clkregs_lock, flags);
952 ret = local_clk_enable(clk); 943 ret = local_clk_enable(clk);
953 clk_unlock(); 944 spin_unlock_irqrestore(&global_clkregs_lock, flags);
954 945
955 return ret; 946 return ret;
956} 947}
@@ -961,9 +952,11 @@ EXPORT_SYMBOL(clk_enable);
961 */ 952 */
962void clk_disable(struct clk *clk) 953void clk_disable(struct clk *clk)
963{ 954{
964 clk_lock(); 955 unsigned long flags;
956
957 spin_lock_irqsave(&global_clkregs_lock, flags);
965 local_clk_disable(clk); 958 local_clk_disable(clk);
966 clk_unlock(); 959 spin_unlock_irqrestore(&global_clkregs_lock, flags);
967} 960}
968EXPORT_SYMBOL(clk_disable); 961EXPORT_SYMBOL(clk_disable);
969 962
@@ -972,13 +965,7 @@ EXPORT_SYMBOL(clk_disable);
972 */ 965 */
973unsigned long clk_get_rate(struct clk *clk) 966unsigned long clk_get_rate(struct clk *clk)
974{ 967{
975 unsigned long rate; 968 return clk->get_rate(clk);
976
977 clk_lock();
978 rate = clk->get_rate(clk);
979 clk_unlock();
980
981 return rate;
982} 969}
983EXPORT_SYMBOL(clk_get_rate); 970EXPORT_SYMBOL(clk_get_rate);
984 971
@@ -994,11 +981,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
994 * the actual rate set as part of the peripheral dividers 981 * the actual rate set as part of the peripheral dividers
995 * instead of high level clock control 982 * instead of high level clock control
996 */ 983 */
997 if (clk->set_rate) { 984 if (clk->set_rate)
998 clk_lock();
999 ret = clk->set_rate(clk, rate); 985 ret = clk->set_rate(clk, rate);
1000 clk_unlock();
1001 }
1002 986
1003 return ret; 987 return ret;
1004} 988}
@@ -1009,15 +993,11 @@ EXPORT_SYMBOL(clk_set_rate);
1009 */ 993 */
1010long clk_round_rate(struct clk *clk, unsigned long rate) 994long clk_round_rate(struct clk *clk, unsigned long rate)
1011{ 995{
1012 clk_lock();
1013
1014 if (clk->round_rate) 996 if (clk->round_rate)
1015 rate = clk->round_rate(clk, rate); 997 rate = clk->round_rate(clk, rate);
1016 else 998 else
1017 rate = clk->get_rate(clk); 999 rate = clk->get_rate(clk);
1018 1000
1019 clk_unlock();
1020
1021 return rate; 1001 return rate;
1022} 1002}
1023EXPORT_SYMBOL(clk_round_rate); 1003EXPORT_SYMBOL(clk_round_rate);
@@ -1075,10 +1055,10 @@ static struct clk_lookup lookups[] = {
1075 _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1) 1055 _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1)
1076 _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan) 1056 _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan)
1077 _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand) 1057 _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
1078 _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0) 1058 _REGISTER_CLOCK(NULL, "i2s0_ck", clk_i2s0)
1079 _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1) 1059 _REGISTER_CLOCK(NULL, "i2s1_ck", clk_i2s1)
1080 _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc) 1060 _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc)
1081 _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc) 1061 _REGISTER_CLOCK("dev:mmc0", NULL, clk_mmc)
1082 _REGISTER_CLOCK("lpc-net.0", NULL, clk_net) 1062 _REGISTER_CLOCK("lpc-net.0", NULL, clk_net)
1083 _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd) 1063 _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd)
1084 _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd) 1064 _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd)