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 473015ac07bd..f55c772d1816 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;
@@ -926,20 +928,8 @@ static struct clk clk_lcd = {
926 .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, 928 .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
927}; 929};
928 930
929static inline void clk_lock(void)
930{
931 mutex_lock(&clkm_lock);
932}
933
934static inline void clk_unlock(void)
935{
936 mutex_unlock(&clkm_lock);
937}
938
939static void local_clk_disable(struct clk *clk) 931static void local_clk_disable(struct clk *clk)
940{ 932{
941 WARN_ON(clk->usecount == 0);
942
943 /* Don't attempt to disable clock if it has no users */ 933 /* Don't attempt to disable clock if it has no users */
944 if (clk->usecount > 0) { 934 if (clk->usecount > 0) {
945 clk->usecount--; 935 clk->usecount--;
@@ -982,10 +972,11 @@ static int local_clk_enable(struct clk *clk)
982int clk_enable(struct clk *clk) 972int clk_enable(struct clk *clk)
983{ 973{
984 int ret; 974 int ret;
975 unsigned long flags;
985 976
986 clk_lock(); 977 spin_lock_irqsave(&global_clkregs_lock, flags);
987 ret = local_clk_enable(clk); 978 ret = local_clk_enable(clk);
988 clk_unlock(); 979 spin_unlock_irqrestore(&global_clkregs_lock, flags);
989 980
990 return ret; 981 return ret;
991} 982}
@@ -996,9 +987,11 @@ EXPORT_SYMBOL(clk_enable);
996 */ 987 */
997void clk_disable(struct clk *clk) 988void clk_disable(struct clk *clk)
998{ 989{
999 clk_lock(); 990 unsigned long flags;
991
992 spin_lock_irqsave(&global_clkregs_lock, flags);
1000 local_clk_disable(clk); 993 local_clk_disable(clk);
1001 clk_unlock(); 994 spin_unlock_irqrestore(&global_clkregs_lock, flags);
1002} 995}
1003EXPORT_SYMBOL(clk_disable); 996EXPORT_SYMBOL(clk_disable);
1004 997
@@ -1007,13 +1000,7 @@ EXPORT_SYMBOL(clk_disable);
1007 */ 1000 */
1008unsigned long clk_get_rate(struct clk *clk) 1001unsigned long clk_get_rate(struct clk *clk)
1009{ 1002{
1010 unsigned long rate; 1003 return clk->get_rate(clk);
1011
1012 clk_lock();
1013 rate = clk->get_rate(clk);
1014 clk_unlock();
1015
1016 return rate;
1017} 1004}
1018EXPORT_SYMBOL(clk_get_rate); 1005EXPORT_SYMBOL(clk_get_rate);
1019 1006
@@ -1029,11 +1016,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
1029 * the actual rate set as part of the peripheral dividers 1016 * the actual rate set as part of the peripheral dividers
1030 * instead of high level clock control 1017 * instead of high level clock control
1031 */ 1018 */
1032 if (clk->set_rate) { 1019 if (clk->set_rate)
1033 clk_lock();
1034 ret = clk->set_rate(clk, rate); 1020 ret = clk->set_rate(clk, rate);
1035 clk_unlock();
1036 }
1037 1021
1038 return ret; 1022 return ret;
1039} 1023}
@@ -1044,15 +1028,11 @@ EXPORT_SYMBOL(clk_set_rate);
1044 */ 1028 */
1045long clk_round_rate(struct clk *clk, unsigned long rate) 1029long clk_round_rate(struct clk *clk, unsigned long rate)
1046{ 1030{
1047 clk_lock();
1048
1049 if (clk->round_rate) 1031 if (clk->round_rate)
1050 rate = clk->round_rate(clk, rate); 1032 rate = clk->round_rate(clk, rate);
1051 else 1033 else
1052 rate = clk->get_rate(clk); 1034 rate = clk->get_rate(clk);
1053 1035
1054 clk_unlock();
1055
1056 return rate; 1036 return rate;
1057} 1037}
1058EXPORT_SYMBOL(clk_round_rate); 1038EXPORT_SYMBOL(clk_round_rate);
@@ -1111,10 +1091,10 @@ static struct clk_lookup lookups[] = {
1111 _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan) 1091 _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan)
1112 _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand) 1092 _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
1113 _REGISTER_CLOCK("lpc32xx-adc", NULL, clk_adc) 1093 _REGISTER_CLOCK("lpc32xx-adc", NULL, clk_adc)
1114 _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0) 1094 _REGISTER_CLOCK(NULL, "i2s0_ck", clk_i2s0)
1115 _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1) 1095 _REGISTER_CLOCK(NULL, "i2s1_ck", clk_i2s1)
1116 _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc) 1096 _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc)
1117 _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc) 1097 _REGISTER_CLOCK("dev:mmc0", NULL, clk_mmc)
1118 _REGISTER_CLOCK("lpc-net.0", NULL, clk_net) 1098 _REGISTER_CLOCK("lpc-net.0", NULL, clk_net)
1119 _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd) 1099 _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd)
1120 _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd) 1100 _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd)