diff options
Diffstat (limited to 'arch/arm/mach-tegra/apbio.c')
-rw-r--r-- | arch/arm/mach-tegra/apbio.c | 118 |
1 files changed, 1 insertions, 117 deletions
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c index 643a37809a15..b5015d0f1912 100644 --- a/arch/arm/mach-tegra/apbio.c +++ b/arch/arm/mach-tegra/apbio.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #include "apbio.h" | 29 | #include "apbio.h" |
30 | 30 | ||
31 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) || defined(CONFIG_TEGRA20_APB_DMA) | 31 | #if defined(CONFIG_TEGRA20_APB_DMA) |
32 | static DEFINE_MUTEX(tegra_apb_dma_lock); | 32 | static DEFINE_MUTEX(tegra_apb_dma_lock); |
33 | static u32 *tegra_apb_bb; | 33 | static u32 *tegra_apb_bb; |
34 | static dma_addr_t tegra_apb_bb_phys; | 34 | static dma_addr_t tegra_apb_bb_phys; |
@@ -37,121 +37,6 @@ static DECLARE_COMPLETION(tegra_apb_wait); | |||
37 | static u32 tegra_apb_readl_direct(unsigned long offset); | 37 | static u32 tegra_apb_readl_direct(unsigned long offset); |
38 | static void tegra_apb_writel_direct(u32 value, unsigned long offset); | 38 | static void tegra_apb_writel_direct(u32 value, unsigned long offset); |
39 | 39 | ||
40 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
41 | static struct tegra_dma_channel *tegra_apb_dma; | ||
42 | |||
43 | bool tegra_apb_init(void) | ||
44 | { | ||
45 | struct tegra_dma_channel *ch; | ||
46 | |||
47 | mutex_lock(&tegra_apb_dma_lock); | ||
48 | |||
49 | /* Check to see if we raced to setup */ | ||
50 | if (tegra_apb_dma) | ||
51 | goto out; | ||
52 | |||
53 | ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT | | ||
54 | TEGRA_DMA_SHARED); | ||
55 | |||
56 | if (!ch) | ||
57 | goto out_fail; | ||
58 | |||
59 | tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32), | ||
60 | &tegra_apb_bb_phys, GFP_KERNEL); | ||
61 | if (!tegra_apb_bb) { | ||
62 | pr_err("%s: can not allocate bounce buffer\n", __func__); | ||
63 | tegra_dma_free_channel(ch); | ||
64 | goto out_fail; | ||
65 | } | ||
66 | |||
67 | tegra_apb_dma = ch; | ||
68 | out: | ||
69 | mutex_unlock(&tegra_apb_dma_lock); | ||
70 | return true; | ||
71 | |||
72 | out_fail: | ||
73 | mutex_unlock(&tegra_apb_dma_lock); | ||
74 | return false; | ||
75 | } | ||
76 | |||
77 | static void apb_dma_complete(struct tegra_dma_req *req) | ||
78 | { | ||
79 | complete(&tegra_apb_wait); | ||
80 | } | ||
81 | |||
82 | static u32 tegra_apb_readl_using_dma(unsigned long offset) | ||
83 | { | ||
84 | struct tegra_dma_req req; | ||
85 | int ret; | ||
86 | |||
87 | if (!tegra_apb_dma && !tegra_apb_init()) | ||
88 | return tegra_apb_readl_direct(offset); | ||
89 | |||
90 | mutex_lock(&tegra_apb_dma_lock); | ||
91 | req.complete = apb_dma_complete; | ||
92 | req.to_memory = 1; | ||
93 | req.dest_addr = tegra_apb_bb_phys; | ||
94 | req.dest_bus_width = 32; | ||
95 | req.dest_wrap = 1; | ||
96 | req.source_addr = offset; | ||
97 | req.source_bus_width = 32; | ||
98 | req.source_wrap = 4; | ||
99 | req.req_sel = TEGRA_DMA_REQ_SEL_CNTR; | ||
100 | req.size = 4; | ||
101 | |||
102 | INIT_COMPLETION(tegra_apb_wait); | ||
103 | |||
104 | tegra_dma_enqueue_req(tegra_apb_dma, &req); | ||
105 | |||
106 | ret = wait_for_completion_timeout(&tegra_apb_wait, | ||
107 | msecs_to_jiffies(50)); | ||
108 | |||
109 | if (WARN(ret == 0, "apb read dma timed out")) { | ||
110 | tegra_dma_dequeue_req(tegra_apb_dma, &req); | ||
111 | *(u32 *)tegra_apb_bb = 0; | ||
112 | } | ||
113 | |||
114 | mutex_unlock(&tegra_apb_dma_lock); | ||
115 | return *((u32 *)tegra_apb_bb); | ||
116 | } | ||
117 | |||
118 | static void tegra_apb_writel_using_dma(u32 value, unsigned long offset) | ||
119 | { | ||
120 | struct tegra_dma_req req; | ||
121 | int ret; | ||
122 | |||
123 | if (!tegra_apb_dma && !tegra_apb_init()) { | ||
124 | tegra_apb_writel_direct(value, offset); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | mutex_lock(&tegra_apb_dma_lock); | ||
129 | *((u32 *)tegra_apb_bb) = value; | ||
130 | req.complete = apb_dma_complete; | ||
131 | req.to_memory = 0; | ||
132 | req.dest_addr = offset; | ||
133 | req.dest_wrap = 4; | ||
134 | req.dest_bus_width = 32; | ||
135 | req.source_addr = tegra_apb_bb_phys; | ||
136 | req.source_bus_width = 32; | ||
137 | req.source_wrap = 1; | ||
138 | req.req_sel = TEGRA_DMA_REQ_SEL_CNTR; | ||
139 | req.size = 4; | ||
140 | |||
141 | INIT_COMPLETION(tegra_apb_wait); | ||
142 | |||
143 | tegra_dma_enqueue_req(tegra_apb_dma, &req); | ||
144 | |||
145 | ret = wait_for_completion_timeout(&tegra_apb_wait, | ||
146 | msecs_to_jiffies(50)); | ||
147 | |||
148 | if (WARN(ret == 0, "apb write dma timed out")) | ||
149 | tegra_dma_dequeue_req(tegra_apb_dma, &req); | ||
150 | |||
151 | mutex_unlock(&tegra_apb_dma_lock); | ||
152 | } | ||
153 | |||
154 | #else | ||
155 | static struct dma_chan *tegra_apb_dma_chan; | 40 | static struct dma_chan *tegra_apb_dma_chan; |
156 | static struct dma_slave_config dma_sconfig; | 41 | static struct dma_slave_config dma_sconfig; |
157 | 42 | ||
@@ -279,7 +164,6 @@ static void tegra_apb_writel_using_dma(u32 value, unsigned long offset) | |||
279 | pr_err("error in writing offset 0x%08lx using dma\n", offset); | 164 | pr_err("error in writing offset 0x%08lx using dma\n", offset); |
280 | mutex_unlock(&tegra_apb_dma_lock); | 165 | mutex_unlock(&tegra_apb_dma_lock); |
281 | } | 166 | } |
282 | #endif | ||
283 | #else | 167 | #else |
284 | #define tegra_apb_readl_using_dma tegra_apb_readl_direct | 168 | #define tegra_apb_readl_using_dma tegra_apb_readl_direct |
285 | #define tegra_apb_writel_using_dma tegra_apb_writel_direct | 169 | #define tegra_apb_writel_using_dma tegra_apb_writel_direct |