add flash locking code
[oweals/openwrt.git] / target / linux / ar71xx / files / arch / mips / ar71xx / ar71xx.c
1 /*
2  *  AR71xx SoC routines
3  *
4  *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6  *
7  *  This program is free software; you can redistribute it and/or modify it
8  *  under the terms of the GNU General Public License version 2 as published
9  *  by the Free Software Foundation.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/mutex.h>
16
17 #include <asm/mach-ar71xx/ar71xx.h>
18
19 static DEFINE_MUTEX(ar71xx_flash_mutex);
20 static int ar71xx_flash_lock_enabled;
21
22 void __iomem *ar71xx_ddr_base;
23 EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
24
25 void __iomem *ar71xx_pll_base;
26 EXPORT_SYMBOL_GPL(ar71xx_pll_base);
27
28 void __iomem *ar71xx_reset_base;
29 EXPORT_SYMBOL_GPL(ar71xx_reset_base);
30
31 void __iomem *ar71xx_gpio_base;
32 EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
33
34 void __iomem *ar71xx_usb_ctrl_base;
35 EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
36
37 void ar71xx_device_stop(u32 mask)
38 {
39         unsigned long flags;
40         u32 t;
41
42         switch (ar71xx_soc) {
43         case AR71XX_SOC_AR7130:
44         case AR71XX_SOC_AR7141:
45         case AR71XX_SOC_AR7161:
46                 local_irq_save(flags);
47                 t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
48                 ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
49                 local_irq_restore(flags);
50                 break;
51
52         case AR71XX_SOC_AR9130:
53         case AR71XX_SOC_AR9132:
54                 local_irq_save(flags);
55                 t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
56                 ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
57                 local_irq_restore(flags);
58                 break;
59
60         default:
61                 BUG();
62         }
63 }
64 EXPORT_SYMBOL_GPL(ar71xx_device_stop);
65
66 void ar71xx_device_start(u32 mask)
67 {
68         unsigned long flags;
69         u32 t;
70
71         switch (ar71xx_soc) {
72         case AR71XX_SOC_AR7130:
73         case AR71XX_SOC_AR7141:
74         case AR71XX_SOC_AR7161:
75                 local_irq_save(flags);
76                 t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
77                 ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
78                 local_irq_restore(flags);
79                 break;
80
81         case AR71XX_SOC_AR9130:
82         case AR71XX_SOC_AR9132:
83                 local_irq_save(flags);
84                 t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
85                 ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
86                 local_irq_restore(flags);
87                 break;
88
89         default:
90                 BUG();
91         }
92 }
93 EXPORT_SYMBOL_GPL(ar71xx_device_start);
94
95 void ar71xx_ddr_flush(u32 reg)
96 {
97         ar71xx_ddr_wr(reg, 1);
98         while ((ar71xx_ddr_rr(reg) & 0x1));
99
100         ar71xx_ddr_wr(reg, 1);
101         while ((ar71xx_ddr_rr(reg) & 0x1));
102 }
103 EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
104
105 void  __init ar71xx_flash_lock_enable(void)
106 {
107         ar71xx_flash_lock_enabled = 1;
108 }
109
110 void ar71xx_flash_acquire(void)
111 {
112         if (ar71xx_flash_lock_enabled)
113                 mutex_lock(&ar71xx_flash_mutex);
114 }
115 EXPORT_SYMBOL_GPL(ar71xx_flash_acquire);
116
117 void ar71xx_flash_release(void)
118 {
119         if (ar71xx_flash_lock_enabled)
120                 mutex_unlock(&ar71xx_flash_mutex);
121 }
122 EXPORT_SYMBOL_GPL(ar71xx_flash_release);