diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/crunch.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/clock.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/core.c | 52 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 36 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/platform.h | 16 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/system.h | 12 |
6 files changed, 118 insertions, 35 deletions
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index 99995c2b2312..769abe15cf91 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c | |||
@@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread) | |||
31 | 31 | ||
32 | static int crunch_enabled(u32 devcfg) | 32 | static int crunch_enabled(u32 devcfg) |
33 | { | 33 | { |
34 | return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); | 34 | return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA); |
35 | } | 35 | } |
36 | 36 | ||
37 | static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | 37 | static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) |
@@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | |||
56 | break; | 56 | break; |
57 | 57 | ||
58 | case THREAD_NOTIFY_SWITCH: | 58 | case THREAD_NOTIFY_SWITCH: |
59 | devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | 59 | devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG); |
60 | if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { | 60 | if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { |
61 | devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; | 61 | /* |
62 | * We don't use ep93xx_syscon_swlocked_write() here | ||
63 | * because we are on the context switch path and | ||
64 | * preemption is already disabled. | ||
65 | */ | ||
66 | devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA; | ||
62 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 67 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); |
63 | __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); | 68 | __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG); |
64 | } | 69 | } |
65 | break; | 70 | break; |
66 | } | 71 | } |
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 6c4c1633ed12..c7642acfd022 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c | |||
@@ -50,20 +50,20 @@ static unsigned long get_uart_rate(struct clk *clk); | |||
50 | 50 | ||
51 | static struct clk clk_uart1 = { | 51 | static struct clk clk_uart1 = { |
52 | .sw_locked = 1, | 52 | .sw_locked = 1, |
53 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | 53 | .enable_reg = EP93XX_SYSCON_DEVCFG, |
54 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, | 54 | .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN, |
55 | .get_rate = get_uart_rate, | 55 | .get_rate = get_uart_rate, |
56 | }; | 56 | }; |
57 | static struct clk clk_uart2 = { | 57 | static struct clk clk_uart2 = { |
58 | .sw_locked = 1, | 58 | .sw_locked = 1, |
59 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | 59 | .enable_reg = EP93XX_SYSCON_DEVCFG, |
60 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, | 60 | .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN, |
61 | .get_rate = get_uart_rate, | 61 | .get_rate = get_uart_rate, |
62 | }; | 62 | }; |
63 | static struct clk clk_uart3 = { | 63 | static struct clk clk_uart3 = { |
64 | .sw_locked = 1, | 64 | .sw_locked = 1, |
65 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | 65 | .enable_reg = EP93XX_SYSCON_DEVCFG, |
66 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, | 66 | .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN, |
67 | .get_rate = get_uart_rate, | 67 | .get_rate = get_uart_rate, |
68 | }; | 68 | }; |
69 | static struct clk clk_pll1; | 69 | static struct clk clk_pll1; |
@@ -160,9 +160,11 @@ int clk_enable(struct clk *clk) | |||
160 | u32 value; | 160 | u32 value; |
161 | 161 | ||
162 | value = __raw_readl(clk->enable_reg); | 162 | value = __raw_readl(clk->enable_reg); |
163 | value |= clk->enable_mask; | ||
163 | if (clk->sw_locked) | 164 | if (clk->sw_locked) |
164 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 165 | ep93xx_syscon_swlocked_write(value, clk->enable_reg); |
165 | __raw_writel(value | clk->enable_mask, clk->enable_reg); | 166 | else |
167 | __raw_writel(value, clk->enable_reg); | ||
166 | } | 168 | } |
167 | 169 | ||
168 | return 0; | 170 | return 0; |
@@ -175,9 +177,11 @@ void clk_disable(struct clk *clk) | |||
175 | u32 value; | 177 | u32 value; |
176 | 178 | ||
177 | value = __raw_readl(clk->enable_reg); | 179 | value = __raw_readl(clk->enable_reg); |
180 | value &= ~clk->enable_mask; | ||
178 | if (clk->sw_locked) | 181 | if (clk->sw_locked) |
179 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 182 | ep93xx_syscon_swlocked_write(value, clk->enable_reg); |
180 | __raw_writel(value & ~clk->enable_mask, clk->enable_reg); | 183 | else |
184 | __raw_writel(value, clk->enable_reg); | ||
181 | } | 185 | } |
182 | } | 186 | } |
183 | EXPORT_SYMBOL(clk_disable); | 187 | EXPORT_SYMBOL(clk_disable); |
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 204dc5cbd0b8..9399d3af9906 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
@@ -385,6 +385,47 @@ void __init ep93xx_init_irq(void) | |||
385 | 385 | ||
386 | 386 | ||
387 | /************************************************************************* | 387 | /************************************************************************* |
388 | * EP93xx System Controller Software Locked register handling | ||
389 | *************************************************************************/ | ||
390 | |||
391 | /* | ||
392 | * syscon_swlock prevents anything else from writing to the syscon | ||
393 | * block while a software locked register is being written. | ||
394 | */ | ||
395 | static DEFINE_SPINLOCK(syscon_swlock); | ||
396 | |||
397 | void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg) | ||
398 | { | ||
399 | unsigned long flags; | ||
400 | |||
401 | spin_lock_irqsave(&syscon_swlock, flags); | ||
402 | |||
403 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
404 | __raw_writel(val, reg); | ||
405 | |||
406 | spin_unlock_irqrestore(&syscon_swlock, flags); | ||
407 | } | ||
408 | EXPORT_SYMBOL(ep93xx_syscon_swlocked_write); | ||
409 | |||
410 | void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) | ||
411 | { | ||
412 | unsigned long flags; | ||
413 | unsigned int val; | ||
414 | |||
415 | spin_lock_irqsave(&syscon_swlock, flags); | ||
416 | |||
417 | val = __raw_readl(EP93XX_SYSCON_DEVCFG); | ||
418 | val |= set_bits; | ||
419 | val &= ~clear_bits; | ||
420 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
421 | __raw_writel(val, EP93XX_SYSCON_DEVCFG); | ||
422 | |||
423 | spin_unlock_irqrestore(&syscon_swlock, flags); | ||
424 | } | ||
425 | EXPORT_SYMBOL(ep93xx_devcfg_set_clear); | ||
426 | |||
427 | |||
428 | /************************************************************************* | ||
388 | * EP93xx peripheral handling | 429 | * EP93xx peripheral handling |
389 | *************************************************************************/ | 430 | *************************************************************************/ |
390 | #define EP93XX_UART_MCR_OFFSET (0x0100) | 431 | #define EP93XX_UART_MCR_OFFSET (0x0100) |
@@ -550,15 +591,8 @@ extern void ep93xx_gpio_init(void); | |||
550 | 591 | ||
551 | void __init ep93xx_init_devices(void) | 592 | void __init ep93xx_init_devices(void) |
552 | { | 593 | { |
553 | unsigned int v; | 594 | /* Disallow access to MaverickCrunch initially */ |
554 | 595 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); | |
555 | /* | ||
556 | * Disallow access to MaverickCrunch initially. | ||
557 | */ | ||
558 | v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | ||
559 | v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; | ||
560 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
561 | __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG); | ||
562 | 596 | ||
563 | ep93xx_gpio_init(); | 597 | ep93xx_gpio_init(); |
564 | 598 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 49b256b3ddfc..087d22b8f351 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | |||
@@ -175,11 +175,37 @@ | |||
175 | #define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) | 175 | #define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) |
176 | #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) | 176 | #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) |
177 | #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) | 177 | #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) |
178 | #define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) | 178 | #define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80) |
179 | #define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) | 179 | #define EP93XX_SYSCON_DEVCFG_SWRST (1<<31) |
180 | #define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) | 180 | #define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30) |
181 | #define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) | 181 | #define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29) |
182 | #define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) | 182 | #define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28) |
183 | #define EP93XX_SYSCON_DEVCFG_GONK (1<<27) | ||
184 | #define EP93XX_SYSCON_DEVCFG_TONG (1<<26) | ||
185 | #define EP93XX_SYSCON_DEVCFG_MONG (1<<25) | ||
186 | #define EP93XX_SYSCON_DEVCFG_U3EN (1<<24) | ||
187 | #define EP93XX_SYSCON_DEVCFG_CPENA (1<<23) | ||
188 | #define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22) | ||
189 | #define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21) | ||
190 | #define EP93XX_SYSCON_DEVCFG_U2EN (1<<20) | ||
191 | #define EP93XX_SYSCON_DEVCFG_EXVC (1<<19) | ||
192 | #define EP93XX_SYSCON_DEVCFG_U1EN (1<<18) | ||
193 | #define EP93XX_SYSCON_DEVCFG_TIN (1<<17) | ||
194 | #define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15) | ||
195 | #define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14) | ||
196 | #define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13) | ||
197 | #define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12) | ||
198 | #define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11) | ||
199 | #define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10) | ||
200 | #define EP93XX_SYSCON_DEVCFG_PONG (1<<9) | ||
201 | #define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8) | ||
202 | #define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7) | ||
203 | #define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6) | ||
204 | #define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4) | ||
205 | #define EP93XX_SYSCON_DEVCFG_RAS (1<<3) | ||
206 | #define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2) | ||
207 | #define EP93XX_SYSCON_DEVCFG_KEYS (1<<1) | ||
208 | #define EP93XX_SYSCON_DEVCFG_SHENA (1<<0) | ||
183 | #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) | 209 | #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) |
184 | 210 | ||
185 | #define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) | 211 | #define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) |
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 05f0f4f2f3ce..fb5e59a3ea04 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h | |||
@@ -15,8 +15,24 @@ struct ep93xx_eth_data | |||
15 | void ep93xx_map_io(void); | 15 | void ep93xx_map_io(void); |
16 | void ep93xx_init_irq(void); | 16 | void ep93xx_init_irq(void); |
17 | void ep93xx_init_time(unsigned long); | 17 | void ep93xx_init_time(unsigned long); |
18 | |||
19 | /* EP93xx System Controller software locked register write */ | ||
20 | void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg); | ||
21 | void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits); | ||
22 | |||
23 | static inline void ep93xx_devcfg_set_bits(unsigned int bits) | ||
24 | { | ||
25 | ep93xx_devcfg_set_clear(bits, 0x00); | ||
26 | } | ||
27 | |||
28 | static inline void ep93xx_devcfg_clear_bits(unsigned int bits) | ||
29 | { | ||
30 | ep93xx_devcfg_set_clear(0x00, bits); | ||
31 | } | ||
32 | |||
18 | void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); | 33 | void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); |
19 | void ep93xx_register_i2c(struct i2c_board_info *devices, int num); | 34 | void ep93xx_register_i2c(struct i2c_board_info *devices, int num); |
35 | |||
20 | void ep93xx_init_devices(void); | 36 | void ep93xx_init_devices(void); |
21 | extern struct sys_timer ep93xx_timer; | 37 | extern struct sys_timer ep93xx_timer; |
22 | 38 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h index ed8f35e4f068..6d661fe9d66c 100644 --- a/arch/arm/mach-ep93xx/include/mach/system.h +++ b/arch/arm/mach-ep93xx/include/mach/system.h | |||
@@ -11,15 +11,13 @@ static inline void arch_idle(void) | |||
11 | 11 | ||
12 | static inline void arch_reset(char mode, const char *cmd) | 12 | static inline void arch_reset(char mode, const char *cmd) |
13 | { | 13 | { |
14 | u32 devicecfg; | ||
15 | |||
16 | local_irq_disable(); | 14 | local_irq_disable(); |
17 | 15 | ||
18 | devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | 16 | /* |
19 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 17 | * Set then clear the SWRST bit to initiate a software reset |
20 | __raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); | 18 | */ |
21 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 19 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST); |
22 | __raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); | 20 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST); |
23 | 21 | ||
24 | while (1) | 22 | while (1) |
25 | ; | 23 | ; |