aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/gxio
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/gxio')
-rw-r--r--arch/tile/gxio/Kconfig28
-rw-r--r--arch/tile/gxio/Makefile9
-rw-r--r--arch/tile/gxio/dma_queue.c176
-rw-r--r--arch/tile/gxio/iorpc_globals.c89
-rw-r--r--arch/tile/gxio/iorpc_mpipe.c529
-rw-r--r--arch/tile/gxio/iorpc_mpipe_info.c85
-rw-r--r--arch/tile/gxio/iorpc_trio.c327
-rw-r--r--arch/tile/gxio/iorpc_usb_host.c99
-rw-r--r--arch/tile/gxio/kiorpc.c61
-rw-r--r--arch/tile/gxio/mpipe.c545
-rw-r--r--arch/tile/gxio/trio.c49
-rw-r--r--arch/tile/gxio/usb_host.c91
12 files changed, 2088 insertions, 0 deletions
diff --git a/arch/tile/gxio/Kconfig b/arch/tile/gxio/Kconfig
new file mode 100644
index 000000000000..d221f8d6de8b
--- /dev/null
+++ b/arch/tile/gxio/Kconfig
@@ -0,0 +1,28 @@
1# Support direct access to TILE-Gx hardware from user space, via the
2# gxio library, or from kernel space, via kernel IORPC support.
3config TILE_GXIO
4 bool
5 depends on TILEGX
6
7# Support direct access to the common I/O DMA facility within the
8# TILE-Gx mPIPE and Trio hardware from kernel space.
9config TILE_GXIO_DMA
10 bool
11 select TILE_GXIO
12
13# Support direct access to the TILE-Gx mPIPE hardware from kernel space.
14config TILE_GXIO_MPIPE
15 bool
16 select TILE_GXIO
17 select TILE_GXIO_DMA
18
19# Support direct access to the TILE-Gx TRIO hardware from kernel space.
20config TILE_GXIO_TRIO
21 bool
22 select TILE_GXIO
23 select TILE_GXIO_DMA
24
25# Support direct access to the TILE-Gx USB hardware from kernel space.
26config TILE_GXIO_USB_HOST
27 bool
28 select TILE_GXIO
diff --git a/arch/tile/gxio/Makefile b/arch/tile/gxio/Makefile
new file mode 100644
index 000000000000..8684bcaa74ea
--- /dev/null
+++ b/arch/tile/gxio/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the Tile-Gx device access support.
3#
4
5obj-$(CONFIG_TILE_GXIO) += iorpc_globals.o kiorpc.o
6obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o
7obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o
8obj-$(CONFIG_TILE_GXIO_TRIO) += trio.o iorpc_trio.o
9obj-$(CONFIG_TILE_GXIO_USB_HOST) += usb_host.o iorpc_usb_host.o
diff --git a/arch/tile/gxio/dma_queue.c b/arch/tile/gxio/dma_queue.c
new file mode 100644
index 000000000000..baa60357f8ba
--- /dev/null
+++ b/arch/tile/gxio/dma_queue.c
@@ -0,0 +1,176 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/io.h>
16#include <linux/atomic.h>
17#include <linux/module.h>
18#include <gxio/dma_queue.h>
19
20/* Wait for a memory read to complete. */
21#define wait_for_value(val) \
22 __asm__ __volatile__("move %0, %0" :: "r"(val))
23
24/* The index is in the low 16. */
25#define DMA_QUEUE_INDEX_MASK ((1 << 16) - 1)
26
27/*
28 * The hardware descriptor-ring type.
29 * This matches the types used by mpipe (MPIPE_EDMA_POST_REGION_VAL_t)
30 * and trio (TRIO_PUSH_DMA_REGION_VAL_t or TRIO_PULL_DMA_REGION_VAL_t).
31 * See those types for more documentation on the individual fields.
32 */
33typedef union {
34 struct {
35#ifndef __BIG_ENDIAN__
36 uint64_t ring_idx:16;
37 uint64_t count:16;
38 uint64_t gen:1;
39 uint64_t __reserved:31;
40#else
41 uint64_t __reserved:31;
42 uint64_t gen:1;
43 uint64_t count:16;
44 uint64_t ring_idx:16;
45#endif
46 };
47 uint64_t word;
48} __gxio_ring_t;
49
50void __gxio_dma_queue_init(__gxio_dma_queue_t *dma_queue,
51 void *post_region_addr, unsigned int num_entries)
52{
53 /*
54 * Limit 65536 entry rings to 65535 credits because we only have a
55 * 16 bit completion counter.
56 */
57 int64_t credits = (num_entries < 65536) ? num_entries : 65535;
58
59 memset(dma_queue, 0, sizeof(*dma_queue));
60
61 dma_queue->post_region_addr = post_region_addr;
62 dma_queue->hw_complete_count = 0;
63 dma_queue->credits_and_next_index = credits << DMA_QUEUE_CREDIT_SHIFT;
64}
65
66EXPORT_SYMBOL_GPL(__gxio_dma_queue_init);
67
68void __gxio_dma_queue_update_credits(__gxio_dma_queue_t *dma_queue)
69{
70 __gxio_ring_t val;
71 uint64_t count;
72 uint64_t delta;
73 uint64_t new_count;
74
75 /*
76 * Read the 64-bit completion count without touching the cache, so
77 * we later avoid having to evict any sharers of this cache line
78 * when we update it below.
79 */
80 uint64_t orig_hw_complete_count =
81 cmpxchg(&dma_queue->hw_complete_count,
82 -1, -1);
83
84 /* Make sure the load completes before we access the hardware. */
85 wait_for_value(orig_hw_complete_count);
86
87 /* Read the 16-bit count of how many packets it has completed. */
88 val.word = __gxio_mmio_read(dma_queue->post_region_addr);
89 count = val.count;
90
91 /*
92 * Calculate the number of completions since we last updated the
93 * 64-bit counter. It's safe to ignore the high bits because the
94 * maximum credit value is 65535.
95 */
96 delta = (count - orig_hw_complete_count) & 0xffff;
97 if (delta == 0)
98 return;
99
100 /*
101 * Try to write back the count, advanced by delta. If we race with
102 * another thread, this might fail, in which case we return
103 * immediately on the assumption that some credits are (or at least
104 * were) available.
105 */
106 new_count = orig_hw_complete_count + delta;
107 if (cmpxchg(&dma_queue->hw_complete_count,
108 orig_hw_complete_count,
109 new_count) != orig_hw_complete_count)
110 return;
111
112 /*
113 * We succeeded in advancing the completion count; add back the
114 * corresponding number of egress credits.
115 */
116 __insn_fetchadd(&dma_queue->credits_and_next_index,
117 (delta << DMA_QUEUE_CREDIT_SHIFT));
118}
119
120EXPORT_SYMBOL_GPL(__gxio_dma_queue_update_credits);
121
122/*
123 * A separate 'blocked' method for put() so that backtraces and
124 * profiles will clearly indicate that we're wasting time spinning on
125 * egress availability rather than actually posting commands.
126 */
127int64_t __gxio_dma_queue_wait_for_credits(__gxio_dma_queue_t *dma_queue,
128 int64_t modifier)
129{
130 int backoff = 16;
131 int64_t old;
132
133 do {
134 int i;
135 /* Back off to avoid spamming memory networks. */
136 for (i = backoff; i > 0; i--)
137 __insn_mfspr(SPR_PASS);
138
139 /* Check credits again. */
140 __gxio_dma_queue_update_credits(dma_queue);
141 old = __insn_fetchaddgez(&dma_queue->credits_and_next_index,
142 modifier);
143
144 /* Calculate bounded exponential backoff for next iteration. */
145 if (backoff < 256)
146 backoff *= 2;
147 } while (old + modifier < 0);
148
149 return old;
150}
151
152EXPORT_SYMBOL_GPL(__gxio_dma_queue_wait_for_credits);
153
154int64_t __gxio_dma_queue_reserve_aux(__gxio_dma_queue_t *dma_queue,
155 unsigned int num, int wait)
156{
157 return __gxio_dma_queue_reserve(dma_queue, num, wait != 0, true);
158}
159
160EXPORT_SYMBOL_GPL(__gxio_dma_queue_reserve_aux);
161
162int __gxio_dma_queue_is_complete(__gxio_dma_queue_t *dma_queue,
163 int64_t completion_slot, int update)
164{
165 if (update) {
166 if (ACCESS_ONCE(dma_queue->hw_complete_count) >
167 completion_slot)
168 return 1;
169
170 __gxio_dma_queue_update_credits(dma_queue);
171 }
172
173 return ACCESS_ONCE(dma_queue->hw_complete_count) > completion_slot;
174}
175
176EXPORT_SYMBOL_GPL(__gxio_dma_queue_is_complete);
diff --git a/arch/tile/gxio/iorpc_globals.c b/arch/tile/gxio/iorpc_globals.c
new file mode 100644
index 000000000000..e178e90805a2
--- /dev/null
+++ b/arch/tile/gxio/iorpc_globals.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/* This file is machine-generated; DO NOT EDIT! */
16#include "gxio/iorpc_globals.h"
17
18struct arm_pollfd_param {
19 union iorpc_pollfd pollfd;
20};
21
22int __iorpc_arm_pollfd(int fd, int pollfd_cookie)
23{
24 struct arm_pollfd_param temp;
25 struct arm_pollfd_param *params = &temp;
26
27 params->pollfd.kernel.cookie = pollfd_cookie;
28
29 return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
30 IORPC_OP_ARM_POLLFD);
31}
32
33EXPORT_SYMBOL(__iorpc_arm_pollfd);
34
35struct close_pollfd_param {
36 union iorpc_pollfd pollfd;
37};
38
39int __iorpc_close_pollfd(int fd, int pollfd_cookie)
40{
41 struct close_pollfd_param temp;
42 struct close_pollfd_param *params = &temp;
43
44 params->pollfd.kernel.cookie = pollfd_cookie;
45
46 return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
47 IORPC_OP_CLOSE_POLLFD);
48}
49
50EXPORT_SYMBOL(__iorpc_close_pollfd);
51
52struct get_mmio_base_param {
53 HV_PTE base;
54};
55
56int __iorpc_get_mmio_base(int fd, HV_PTE *base)
57{
58 int __result;
59 struct get_mmio_base_param temp;
60 struct get_mmio_base_param *params = &temp;
61
62 __result =
63 hv_dev_pread(fd, 0, (HV_VirtAddr) params, sizeof(*params),
64 IORPC_OP_GET_MMIO_BASE);
65 *base = params->base;
66
67 return __result;
68}
69
70EXPORT_SYMBOL(__iorpc_get_mmio_base);
71
72struct check_mmio_offset_param {
73 unsigned long offset;
74 unsigned long size;
75};
76
77int __iorpc_check_mmio_offset(int fd, unsigned long offset, unsigned long size)
78{
79 struct check_mmio_offset_param temp;
80 struct check_mmio_offset_param *params = &temp;
81
82 params->offset = offset;
83 params->size = size;
84
85 return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
86 IORPC_OP_CHECK_MMIO_OFFSET);
87}
88
89EXPORT_SYMBOL(__iorpc_check_mmio_offset);
diff --git a/arch/tile/gxio/iorpc_mpipe.c b/arch/tile/gxio/iorpc_mpipe.c
new file mode 100644
index 000000000000..31b87bf8c027
--- /dev/null
+++ b/arch/tile/gxio/iorpc_mpipe.c
@@ -0,0 +1,529 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/* This file is machine-generated; DO NOT EDIT! */
16#include "gxio/iorpc_mpipe.h"
17
18struct alloc_buffer_stacks_param {
19 unsigned int count;
20 unsigned int first;
21 unsigned int flags;
22};
23
24int gxio_mpipe_alloc_buffer_stacks(gxio_mpipe_context_t * context,
25 unsigned int count, unsigned int first,
26 unsigned int flags)
27{
28 struct alloc_buffer_stacks_param temp;
29 struct alloc_buffer_stacks_param *params = &temp;
30
31 params->count = count;
32 params->first = first;
33 params->flags = flags;
34
35 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
36 sizeof(*params),
37 GXIO_MPIPE_OP_ALLOC_BUFFER_STACKS);
38}
39
40EXPORT_SYMBOL(gxio_mpipe_alloc_buffer_stacks);
41
42struct init_buffer_stack_aux_param {
43 union iorpc_mem_buffer buffer;
44 unsigned int stack;
45 unsigned int buffer_size_enum;
46};
47
48int gxio_mpipe_init_buffer_stack_aux(gxio_mpipe_context_t * context,
49 void *mem_va, size_t mem_size,
50 unsigned int mem_flags, unsigned int stack,
51 unsigned int buffer_size_enum)
52{
53 int __result;
54 unsigned long long __cpa;
55 pte_t __pte;
56 struct init_buffer_stack_aux_param temp;
57 struct init_buffer_stack_aux_param *params = &temp;
58
59 __result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
60 if (__result != 0)
61 return __result;
62 params->buffer.kernel.cpa = __cpa;
63 params->buffer.kernel.size = mem_size;
64 params->buffer.kernel.pte = __pte;
65 params->buffer.kernel.flags = mem_flags;
66 params->stack = stack;
67 params->buffer_size_enum = buffer_size_enum;
68
69 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
70 sizeof(*params),
71 GXIO_MPIPE_OP_INIT_BUFFER_STACK_AUX);
72}
73
74EXPORT_SYMBOL(gxio_mpipe_init_buffer_stack_aux);
75
76
77struct alloc_notif_rings_param {
78 unsigned int count;
79 unsigned int first;
80 unsigned int flags;
81};
82
83int gxio_mpipe_alloc_notif_rings(gxio_mpipe_context_t * context,
84 unsigned int count, unsigned int first,
85 unsigned int flags)
86{
87 struct alloc_notif_rings_param temp;
88 struct alloc_notif_rings_param *params = &temp;
89
90 params->count = count;
91 params->first = first;
92 params->flags = flags;
93
94 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
95 sizeof(*params), GXIO_MPIPE_OP_ALLOC_NOTIF_RINGS);
96}
97
98EXPORT_SYMBOL(gxio_mpipe_alloc_notif_rings);
99
100struct init_notif_ring_aux_param {
101 union iorpc_mem_buffer buffer;
102 unsigned int ring;
103};
104
105int gxio_mpipe_init_notif_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
106 size_t mem_size, unsigned int mem_flags,
107 unsigned int ring)
108{
109 int __result;
110 unsigned long long __cpa;
111 pte_t __pte;
112 struct init_notif_ring_aux_param temp;
113 struct init_notif_ring_aux_param *params = &temp;
114
115 __result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
116 if (__result != 0)
117 return __result;
118 params->buffer.kernel.cpa = __cpa;
119 params->buffer.kernel.size = mem_size;
120 params->buffer.kernel.pte = __pte;
121 params->buffer.kernel.flags = mem_flags;
122 params->ring = ring;
123
124 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
125 sizeof(*params),
126 GXIO_MPIPE_OP_INIT_NOTIF_RING_AUX);
127}
128
129EXPORT_SYMBOL(gxio_mpipe_init_notif_ring_aux);
130
131struct request_notif_ring_interrupt_param {
132 union iorpc_interrupt interrupt;
133 unsigned int ring;
134};
135
136int gxio_mpipe_request_notif_ring_interrupt(gxio_mpipe_context_t * context,
137 int inter_x, int inter_y,
138 int inter_ipi, int inter_event,
139 unsigned int ring)
140{
141 struct request_notif_ring_interrupt_param temp;
142 struct request_notif_ring_interrupt_param *params = &temp;
143
144 params->interrupt.kernel.x = inter_x;
145 params->interrupt.kernel.y = inter_y;
146 params->interrupt.kernel.ipi = inter_ipi;
147 params->interrupt.kernel.event = inter_event;
148 params->ring = ring;
149
150 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
151 sizeof(*params),
152 GXIO_MPIPE_OP_REQUEST_NOTIF_RING_INTERRUPT);
153}
154
155EXPORT_SYMBOL(gxio_mpipe_request_notif_ring_interrupt);
156
157struct enable_notif_ring_interrupt_param {
158 unsigned int ring;
159};
160
161int gxio_mpipe_enable_notif_ring_interrupt(gxio_mpipe_context_t * context,
162 unsigned int ring)
163{
164 struct enable_notif_ring_interrupt_param temp;
165 struct enable_notif_ring_interrupt_param *params = &temp;
166
167 params->ring = ring;
168
169 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
170 sizeof(*params),
171 GXIO_MPIPE_OP_ENABLE_NOTIF_RING_INTERRUPT);
172}
173
174EXPORT_SYMBOL(gxio_mpipe_enable_notif_ring_interrupt);
175
176struct alloc_notif_groups_param {
177 unsigned int count;
178 unsigned int first;
179 unsigned int flags;
180};
181
182int gxio_mpipe_alloc_notif_groups(gxio_mpipe_context_t * context,
183 unsigned int count, unsigned int first,
184 unsigned int flags)
185{
186 struct alloc_notif_groups_param temp;
187 struct alloc_notif_groups_param *params = &temp;
188
189 params->count = count;
190 params->first = first;
191 params->flags = flags;
192
193 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
194 sizeof(*params), GXIO_MPIPE_OP_ALLOC_NOTIF_GROUPS);
195}
196
197EXPORT_SYMBOL(gxio_mpipe_alloc_notif_groups);
198
199struct init_notif_group_param {
200 unsigned int group;
201 gxio_mpipe_notif_group_bits_t bits;
202};
203
204int gxio_mpipe_init_notif_group(gxio_mpipe_context_t * context,
205 unsigned int group,
206 gxio_mpipe_notif_group_bits_t bits)
207{
208 struct init_notif_group_param temp;
209 struct init_notif_group_param *params = &temp;
210
211 params->group = group;
212 params->bits = bits;
213
214 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
215 sizeof(*params), GXIO_MPIPE_OP_INIT_NOTIF_GROUP);
216}
217
218EXPORT_SYMBOL(gxio_mpipe_init_notif_group);
219
220struct alloc_buckets_param {
221 unsigned int count;
222 unsigned int first;
223 unsigned int flags;
224};
225
226int gxio_mpipe_alloc_buckets(gxio_mpipe_context_t * context, unsigned int count,
227 unsigned int first, unsigned int flags)
228{
229 struct alloc_buckets_param temp;
230 struct alloc_buckets_param *params = &temp;
231
232 params->count = count;
233 params->first = first;
234 params->flags = flags;
235
236 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
237 sizeof(*params), GXIO_MPIPE_OP_ALLOC_BUCKETS);
238}
239
240EXPORT_SYMBOL(gxio_mpipe_alloc_buckets);
241
242struct init_bucket_param {
243 unsigned int bucket;
244 MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info;
245};
246
247int gxio_mpipe_init_bucket(gxio_mpipe_context_t * context, unsigned int bucket,
248 MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info)
249{
250 struct init_bucket_param temp;
251 struct init_bucket_param *params = &temp;
252
253 params->bucket = bucket;
254 params->bucket_info = bucket_info;
255
256 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
257 sizeof(*params), GXIO_MPIPE_OP_INIT_BUCKET);
258}
259
260EXPORT_SYMBOL(gxio_mpipe_init_bucket);
261
262struct alloc_edma_rings_param {
263 unsigned int count;
264 unsigned int first;
265 unsigned int flags;
266};
267
268int gxio_mpipe_alloc_edma_rings(gxio_mpipe_context_t * context,
269 unsigned int count, unsigned int first,
270 unsigned int flags)
271{
272 struct alloc_edma_rings_param temp;
273 struct alloc_edma_rings_param *params = &temp;
274
275 params->count = count;
276 params->first = first;
277 params->flags = flags;
278
279 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
280 sizeof(*params), GXIO_MPIPE_OP_ALLOC_EDMA_RINGS);
281}
282
283EXPORT_SYMBOL(gxio_mpipe_alloc_edma_rings);
284
285struct init_edma_ring_aux_param {
286 union iorpc_mem_buffer buffer;
287 unsigned int ring;
288 unsigned int channel;
289};
290
291int gxio_mpipe_init_edma_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
292 size_t mem_size, unsigned int mem_flags,
293 unsigned int ring, unsigned int channel)
294{
295 int __result;
296 unsigned long long __cpa;
297 pte_t __pte;
298 struct init_edma_ring_aux_param temp;
299 struct init_edma_ring_aux_param *params = &temp;
300
301 __result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
302 if (__result != 0)
303 return __result;
304 params->buffer.kernel.cpa = __cpa;
305 params->buffer.kernel.size = mem_size;
306 params->buffer.kernel.pte = __pte;
307 params->buffer.kernel.flags = mem_flags;
308 params->ring = ring;
309 params->channel = channel;
310
311 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
312 sizeof(*params), GXIO_MPIPE_OP_INIT_EDMA_RING_AUX);
313}
314
315EXPORT_SYMBOL(gxio_mpipe_init_edma_ring_aux);
316
317
318int gxio_mpipe_commit_rules(gxio_mpipe_context_t * context, const void *blob,
319 size_t blob_size)
320{
321 const void *params = blob;
322
323 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, blob_size,
324 GXIO_MPIPE_OP_COMMIT_RULES);
325}
326
327EXPORT_SYMBOL(gxio_mpipe_commit_rules);
328
329struct register_client_memory_param {
330 unsigned int iotlb;
331 HV_PTE pte;
332 unsigned int flags;
333};
334
335int gxio_mpipe_register_client_memory(gxio_mpipe_context_t * context,
336 unsigned int iotlb, HV_PTE pte,
337 unsigned int flags)
338{
339 struct register_client_memory_param temp;
340 struct register_client_memory_param *params = &temp;
341
342 params->iotlb = iotlb;
343 params->pte = pte;
344 params->flags = flags;
345
346 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
347 sizeof(*params),
348 GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY);
349}
350
351EXPORT_SYMBOL(gxio_mpipe_register_client_memory);
352
353struct link_open_aux_param {
354 _gxio_mpipe_link_name_t name;
355 unsigned int flags;
356};
357
358int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,
359 _gxio_mpipe_link_name_t name, unsigned int flags)
360{
361 struct link_open_aux_param temp;
362 struct link_open_aux_param *params = &temp;
363
364 params->name = name;
365 params->flags = flags;
366
367 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
368 sizeof(*params), GXIO_MPIPE_OP_LINK_OPEN_AUX);
369}
370
371EXPORT_SYMBOL(gxio_mpipe_link_open_aux);
372
373struct link_close_aux_param {
374 int mac;
375};
376
377int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac)
378{
379 struct link_close_aux_param temp;
380 struct link_close_aux_param *params = &temp;
381
382 params->mac = mac;
383
384 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
385 sizeof(*params), GXIO_MPIPE_OP_LINK_CLOSE_AUX);
386}
387
388EXPORT_SYMBOL(gxio_mpipe_link_close_aux);
389
390
391struct get_timestamp_aux_param {
392 uint64_t sec;
393 uint64_t nsec;
394 uint64_t cycles;
395};
396
397int gxio_mpipe_get_timestamp_aux(gxio_mpipe_context_t * context, uint64_t * sec,
398 uint64_t * nsec, uint64_t * cycles)
399{
400 int __result;
401 struct get_timestamp_aux_param temp;
402 struct get_timestamp_aux_param *params = &temp;
403
404 __result =
405 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
406 GXIO_MPIPE_OP_GET_TIMESTAMP_AUX);
407 *sec = params->sec;
408 *nsec = params->nsec;
409 *cycles = params->cycles;
410
411 return __result;
412}
413
414EXPORT_SYMBOL(gxio_mpipe_get_timestamp_aux);
415
416struct set_timestamp_aux_param {
417 uint64_t sec;
418 uint64_t nsec;
419 uint64_t cycles;
420};
421
422int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,
423 uint64_t nsec, uint64_t cycles)
424{
425 struct set_timestamp_aux_param temp;
426 struct set_timestamp_aux_param *params = &temp;
427
428 params->sec = sec;
429 params->nsec = nsec;
430 params->cycles = cycles;
431
432 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
433 sizeof(*params), GXIO_MPIPE_OP_SET_TIMESTAMP_AUX);
434}
435
436EXPORT_SYMBOL(gxio_mpipe_set_timestamp_aux);
437
438struct adjust_timestamp_aux_param {
439 int64_t nsec;
440};
441
442int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,
443 int64_t nsec)
444{
445 struct adjust_timestamp_aux_param temp;
446 struct adjust_timestamp_aux_param *params = &temp;
447
448 params->nsec = nsec;
449
450 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
451 sizeof(*params),
452 GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX);
453}
454
455EXPORT_SYMBOL(gxio_mpipe_adjust_timestamp_aux);
456
457struct arm_pollfd_param {
458 union iorpc_pollfd pollfd;
459};
460
461int gxio_mpipe_arm_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie)
462{
463 struct arm_pollfd_param temp;
464 struct arm_pollfd_param *params = &temp;
465
466 params->pollfd.kernel.cookie = pollfd_cookie;
467
468 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
469 sizeof(*params), GXIO_MPIPE_OP_ARM_POLLFD);
470}
471
472EXPORT_SYMBOL(gxio_mpipe_arm_pollfd);
473
474struct close_pollfd_param {
475 union iorpc_pollfd pollfd;
476};
477
478int gxio_mpipe_close_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie)
479{
480 struct close_pollfd_param temp;
481 struct close_pollfd_param *params = &temp;
482
483 params->pollfd.kernel.cookie = pollfd_cookie;
484
485 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
486 sizeof(*params), GXIO_MPIPE_OP_CLOSE_POLLFD);
487}
488
489EXPORT_SYMBOL(gxio_mpipe_close_pollfd);
490
491struct get_mmio_base_param {
492 HV_PTE base;
493};
494
495int gxio_mpipe_get_mmio_base(gxio_mpipe_context_t * context, HV_PTE *base)
496{
497 int __result;
498 struct get_mmio_base_param temp;
499 struct get_mmio_base_param *params = &temp;
500
501 __result =
502 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
503 GXIO_MPIPE_OP_GET_MMIO_BASE);
504 *base = params->base;
505
506 return __result;
507}
508
509EXPORT_SYMBOL(gxio_mpipe_get_mmio_base);
510
511struct check_mmio_offset_param {
512 unsigned long offset;
513 unsigned long size;
514};
515
516int gxio_mpipe_check_mmio_offset(gxio_mpipe_context_t * context,
517 unsigned long offset, unsigned long size)
518{
519 struct check_mmio_offset_param temp;
520 struct check_mmio_offset_param *params = &temp;
521
522 params->offset = offset;
523 params->size = size;
524
525 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
526 sizeof(*params), GXIO_MPIPE_OP_CHECK_MMIO_OFFSET);
527}
528
529EXPORT_SYMBOL(gxio_mpipe_check_mmio_offset);
diff --git a/arch/tile/gxio/iorpc_mpipe_info.c b/arch/tile/gxio/iorpc_mpipe_info.c
new file mode 100644
index 000000000000..d0254aa60cba
--- /dev/null
+++ b/arch/tile/gxio/iorpc_mpipe_info.c
@@ -0,0 +1,85 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/* This file is machine-generated; DO NOT EDIT! */
16#include "gxio/iorpc_mpipe_info.h"
17
18
19struct enumerate_aux_param {
20 _gxio_mpipe_link_name_t name;
21 _gxio_mpipe_link_mac_t mac;
22};
23
24int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
25 unsigned int idx,
26 _gxio_mpipe_link_name_t * name,
27 _gxio_mpipe_link_mac_t * mac)
28{
29 int __result;
30 struct enumerate_aux_param temp;
31 struct enumerate_aux_param *params = &temp;
32
33 __result =
34 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
35 (((uint64_t) idx << 32) |
36 GXIO_MPIPE_INFO_OP_ENUMERATE_AUX));
37 *name = params->name;
38 *mac = params->mac;
39
40 return __result;
41}
42
43EXPORT_SYMBOL(gxio_mpipe_info_enumerate_aux);
44
45struct get_mmio_base_param {
46 HV_PTE base;
47};
48
49int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
50 HV_PTE *base)
51{
52 int __result;
53 struct get_mmio_base_param temp;
54 struct get_mmio_base_param *params = &temp;
55
56 __result =
57 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
58 GXIO_MPIPE_INFO_OP_GET_MMIO_BASE);
59 *base = params->base;
60
61 return __result;
62}
63
64EXPORT_SYMBOL(gxio_mpipe_info_get_mmio_base);
65
66struct check_mmio_offset_param {
67 unsigned long offset;
68 unsigned long size;
69};
70
71int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
72 unsigned long offset, unsigned long size)
73{
74 struct check_mmio_offset_param temp;
75 struct check_mmio_offset_param *params = &temp;
76
77 params->offset = offset;
78 params->size = size;
79
80 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
81 sizeof(*params),
82 GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET);
83}
84
85EXPORT_SYMBOL(gxio_mpipe_info_check_mmio_offset);
diff --git a/arch/tile/gxio/iorpc_trio.c b/arch/tile/gxio/iorpc_trio.c
new file mode 100644
index 000000000000..cef4b2209cda
--- /dev/null
+++ b/arch/tile/gxio/iorpc_trio.c
@@ -0,0 +1,327 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/* This file is machine-generated; DO NOT EDIT! */
16#include "gxio/iorpc_trio.h"
17
18struct alloc_asids_param {
19 unsigned int count;
20 unsigned int first;
21 unsigned int flags;
22};
23
24int gxio_trio_alloc_asids(gxio_trio_context_t * context, unsigned int count,
25 unsigned int first, unsigned int flags)
26{
27 struct alloc_asids_param temp;
28 struct alloc_asids_param *params = &temp;
29
30 params->count = count;
31 params->first = first;
32 params->flags = flags;
33
34 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
35 sizeof(*params), GXIO_TRIO_OP_ALLOC_ASIDS);
36}
37
38EXPORT_SYMBOL(gxio_trio_alloc_asids);
39
40
41struct alloc_memory_maps_param {
42 unsigned int count;
43 unsigned int first;
44 unsigned int flags;
45};
46
47int gxio_trio_alloc_memory_maps(gxio_trio_context_t * context,
48 unsigned int count, unsigned int first,
49 unsigned int flags)
50{
51 struct alloc_memory_maps_param temp;
52 struct alloc_memory_maps_param *params = &temp;
53
54 params->count = count;
55 params->first = first;
56 params->flags = flags;
57
58 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
59 sizeof(*params), GXIO_TRIO_OP_ALLOC_MEMORY_MAPS);
60}
61
62EXPORT_SYMBOL(gxio_trio_alloc_memory_maps);
63
64
65struct alloc_pio_regions_param {
66 unsigned int count;
67 unsigned int first;
68 unsigned int flags;
69};
70
71int gxio_trio_alloc_pio_regions(gxio_trio_context_t * context,
72 unsigned int count, unsigned int first,
73 unsigned int flags)
74{
75 struct alloc_pio_regions_param temp;
76 struct alloc_pio_regions_param *params = &temp;
77
78 params->count = count;
79 params->first = first;
80 params->flags = flags;
81
82 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
83 sizeof(*params), GXIO_TRIO_OP_ALLOC_PIO_REGIONS);
84}
85
86EXPORT_SYMBOL(gxio_trio_alloc_pio_regions);
87
88struct init_pio_region_aux_param {
89 unsigned int pio_region;
90 unsigned int mac;
91 uint32_t bus_address_hi;
92 unsigned int flags;
93};
94
95int gxio_trio_init_pio_region_aux(gxio_trio_context_t * context,
96 unsigned int pio_region, unsigned int mac,
97 uint32_t bus_address_hi, unsigned int flags)
98{
99 struct init_pio_region_aux_param temp;
100 struct init_pio_region_aux_param *params = &temp;
101
102 params->pio_region = pio_region;
103 params->mac = mac;
104 params->bus_address_hi = bus_address_hi;
105 params->flags = flags;
106
107 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
108 sizeof(*params), GXIO_TRIO_OP_INIT_PIO_REGION_AUX);
109}
110
111EXPORT_SYMBOL(gxio_trio_init_pio_region_aux);
112
113
114struct init_memory_map_mmu_aux_param {
115 unsigned int map;
116 unsigned long va;
117 uint64_t size;
118 unsigned int asid;
119 unsigned int mac;
120 uint64_t bus_address;
121 unsigned int node;
122 unsigned int order_mode;
123};
124
125int gxio_trio_init_memory_map_mmu_aux(gxio_trio_context_t * context,
126 unsigned int map, unsigned long va,
127 uint64_t size, unsigned int asid,
128 unsigned int mac, uint64_t bus_address,
129 unsigned int node,
130 unsigned int order_mode)
131{
132 struct init_memory_map_mmu_aux_param temp;
133 struct init_memory_map_mmu_aux_param *params = &temp;
134
135 params->map = map;
136 params->va = va;
137 params->size = size;
138 params->asid = asid;
139 params->mac = mac;
140 params->bus_address = bus_address;
141 params->node = node;
142 params->order_mode = order_mode;
143
144 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
145 sizeof(*params),
146 GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX);
147}
148
149EXPORT_SYMBOL(gxio_trio_init_memory_map_mmu_aux);
150
151struct get_port_property_param {
152 struct pcie_trio_ports_property trio_ports;
153};
154
155int gxio_trio_get_port_property(gxio_trio_context_t * context,
156 struct pcie_trio_ports_property *trio_ports)
157{
158 int __result;
159 struct get_port_property_param temp;
160 struct get_port_property_param *params = &temp;
161
162 __result =
163 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
164 GXIO_TRIO_OP_GET_PORT_PROPERTY);
165 *trio_ports = params->trio_ports;
166
167 return __result;
168}
169
170EXPORT_SYMBOL(gxio_trio_get_port_property);
171
172struct config_legacy_intr_param {
173 union iorpc_interrupt interrupt;
174 unsigned int mac;
175 unsigned int intx;
176};
177
178int gxio_trio_config_legacy_intr(gxio_trio_context_t * context, int inter_x,
179 int inter_y, int inter_ipi, int inter_event,
180 unsigned int mac, unsigned int intx)
181{
182 struct config_legacy_intr_param temp;
183 struct config_legacy_intr_param *params = &temp;
184
185 params->interrupt.kernel.x = inter_x;
186 params->interrupt.kernel.y = inter_y;
187 params->interrupt.kernel.ipi = inter_ipi;
188 params->interrupt.kernel.event = inter_event;
189 params->mac = mac;
190 params->intx = intx;
191
192 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
193 sizeof(*params), GXIO_TRIO_OP_CONFIG_LEGACY_INTR);
194}
195
196EXPORT_SYMBOL(gxio_trio_config_legacy_intr);
197
198struct config_msi_intr_param {
199 union iorpc_interrupt interrupt;
200 unsigned int mac;
201 unsigned int mem_map;
202 uint64_t mem_map_base;
203 uint64_t mem_map_limit;
204 unsigned int asid;
205};
206
207int gxio_trio_config_msi_intr(gxio_trio_context_t * context, int inter_x,
208 int inter_y, int inter_ipi, int inter_event,
209 unsigned int mac, unsigned int mem_map,
210 uint64_t mem_map_base, uint64_t mem_map_limit,
211 unsigned int asid)
212{
213 struct config_msi_intr_param temp;
214 struct config_msi_intr_param *params = &temp;
215
216 params->interrupt.kernel.x = inter_x;
217 params->interrupt.kernel.y = inter_y;
218 params->interrupt.kernel.ipi = inter_ipi;
219 params->interrupt.kernel.event = inter_event;
220 params->mac = mac;
221 params->mem_map = mem_map;
222 params->mem_map_base = mem_map_base;
223 params->mem_map_limit = mem_map_limit;
224 params->asid = asid;
225
226 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
227 sizeof(*params), GXIO_TRIO_OP_CONFIG_MSI_INTR);
228}
229
230EXPORT_SYMBOL(gxio_trio_config_msi_intr);
231
232
233struct set_mps_mrs_param {
234 uint16_t mps;
235 uint16_t mrs;
236 unsigned int mac;
237};
238
239int gxio_trio_set_mps_mrs(gxio_trio_context_t * context, uint16_t mps,
240 uint16_t mrs, unsigned int mac)
241{
242 struct set_mps_mrs_param temp;
243 struct set_mps_mrs_param *params = &temp;
244
245 params->mps = mps;
246 params->mrs = mrs;
247 params->mac = mac;
248
249 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
250 sizeof(*params), GXIO_TRIO_OP_SET_MPS_MRS);
251}
252
253EXPORT_SYMBOL(gxio_trio_set_mps_mrs);
254
255struct force_rc_link_up_param {
256 unsigned int mac;
257};
258
259int gxio_trio_force_rc_link_up(gxio_trio_context_t * context, unsigned int mac)
260{
261 struct force_rc_link_up_param temp;
262 struct force_rc_link_up_param *params = &temp;
263
264 params->mac = mac;
265
266 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
267 sizeof(*params), GXIO_TRIO_OP_FORCE_RC_LINK_UP);
268}
269
270EXPORT_SYMBOL(gxio_trio_force_rc_link_up);
271
272struct force_ep_link_up_param {
273 unsigned int mac;
274};
275
276int gxio_trio_force_ep_link_up(gxio_trio_context_t * context, unsigned int mac)
277{
278 struct force_ep_link_up_param temp;
279 struct force_ep_link_up_param *params = &temp;
280
281 params->mac = mac;
282
283 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
284 sizeof(*params), GXIO_TRIO_OP_FORCE_EP_LINK_UP);
285}
286
287EXPORT_SYMBOL(gxio_trio_force_ep_link_up);
288
289struct get_mmio_base_param {
290 HV_PTE base;
291};
292
293int gxio_trio_get_mmio_base(gxio_trio_context_t * context, HV_PTE *base)
294{
295 int __result;
296 struct get_mmio_base_param temp;
297 struct get_mmio_base_param *params = &temp;
298
299 __result =
300 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
301 GXIO_TRIO_OP_GET_MMIO_BASE);
302 *base = params->base;
303
304 return __result;
305}
306
307EXPORT_SYMBOL(gxio_trio_get_mmio_base);
308
309struct check_mmio_offset_param {
310 unsigned long offset;
311 unsigned long size;
312};
313
314int gxio_trio_check_mmio_offset(gxio_trio_context_t * context,
315 unsigned long offset, unsigned long size)
316{
317 struct check_mmio_offset_param temp;
318 struct check_mmio_offset_param *params = &temp;
319
320 params->offset = offset;
321 params->size = size;
322
323 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
324 sizeof(*params), GXIO_TRIO_OP_CHECK_MMIO_OFFSET);
325}
326
327EXPORT_SYMBOL(gxio_trio_check_mmio_offset);
diff --git a/arch/tile/gxio/iorpc_usb_host.c b/arch/tile/gxio/iorpc_usb_host.c
new file mode 100644
index 000000000000..cf3c3cc12204
--- /dev/null
+++ b/arch/tile/gxio/iorpc_usb_host.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/* This file is machine-generated; DO NOT EDIT! */
16#include "gxio/iorpc_usb_host.h"
17
18struct cfg_interrupt_param {
19 union iorpc_interrupt interrupt;
20};
21
22int gxio_usb_host_cfg_interrupt(gxio_usb_host_context_t * context, int inter_x,
23 int inter_y, int inter_ipi, int inter_event)
24{
25 struct cfg_interrupt_param temp;
26 struct cfg_interrupt_param *params = &temp;
27
28 params->interrupt.kernel.x = inter_x;
29 params->interrupt.kernel.y = inter_y;
30 params->interrupt.kernel.ipi = inter_ipi;
31 params->interrupt.kernel.event = inter_event;
32
33 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
34 sizeof(*params), GXIO_USB_HOST_OP_CFG_INTERRUPT);
35}
36
37EXPORT_SYMBOL(gxio_usb_host_cfg_interrupt);
38
39struct register_client_memory_param {
40 HV_PTE pte;
41 unsigned int flags;
42};
43
44int gxio_usb_host_register_client_memory(gxio_usb_host_context_t * context,
45 HV_PTE pte, unsigned int flags)
46{
47 struct register_client_memory_param temp;
48 struct register_client_memory_param *params = &temp;
49
50 params->pte = pte;
51 params->flags = flags;
52
53 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
54 sizeof(*params),
55 GXIO_USB_HOST_OP_REGISTER_CLIENT_MEMORY);
56}
57
58EXPORT_SYMBOL(gxio_usb_host_register_client_memory);
59
60struct get_mmio_base_param {
61 HV_PTE base;
62};
63
64int gxio_usb_host_get_mmio_base(gxio_usb_host_context_t * context, HV_PTE *base)
65{
66 int __result;
67 struct get_mmio_base_param temp;
68 struct get_mmio_base_param *params = &temp;
69
70 __result =
71 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
72 GXIO_USB_HOST_OP_GET_MMIO_BASE);
73 *base = params->base;
74
75 return __result;
76}
77
78EXPORT_SYMBOL(gxio_usb_host_get_mmio_base);
79
80struct check_mmio_offset_param {
81 unsigned long offset;
82 unsigned long size;
83};
84
85int gxio_usb_host_check_mmio_offset(gxio_usb_host_context_t * context,
86 unsigned long offset, unsigned long size)
87{
88 struct check_mmio_offset_param temp;
89 struct check_mmio_offset_param *params = &temp;
90
91 params->offset = offset;
92 params->size = size;
93
94 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
95 sizeof(*params),
96 GXIO_USB_HOST_OP_CHECK_MMIO_OFFSET);
97}
98
99EXPORT_SYMBOL(gxio_usb_host_check_mmio_offset);
diff --git a/arch/tile/gxio/kiorpc.c b/arch/tile/gxio/kiorpc.c
new file mode 100644
index 000000000000..c8096aa5a3fc
--- /dev/null
+++ b/arch/tile/gxio/kiorpc.c
@@ -0,0 +1,61 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 *
14 * TILE-Gx IORPC support for kernel I/O drivers.
15 */
16
17#include <linux/mmzone.h>
18#include <linux/module.h>
19#include <linux/io.h>
20#include <gxio/iorpc_globals.h>
21#include <gxio/kiorpc.h>
22
23#ifdef DEBUG_IORPC
24#define TRACE(FMT, ...) pr_info(SIMPLE_MSG_LINE FMT, ## __VA_ARGS__)
25#else
26#define TRACE(...)
27#endif
28
29/* Create kernel-VA-space MMIO mapping for an on-chip IO device. */
30void __iomem *iorpc_ioremap(int hv_fd, resource_size_t offset,
31 unsigned long size)
32{
33 pgprot_t mmio_base, prot = { 0 };
34 unsigned long pfn;
35 int err;
36
37 /* Look up the shim's lotar and base PA. */
38 err = __iorpc_get_mmio_base(hv_fd, &mmio_base);
39 if (err) {
40 TRACE("get_mmio_base() failure: %d\n", err);
41 return NULL;
42 }
43
44 /* Make sure the HV driver approves of our offset and size. */
45 err = __iorpc_check_mmio_offset(hv_fd, offset, size);
46 if (err) {
47 TRACE("check_mmio_offset() failure: %d\n", err);
48 return NULL;
49 }
50
51 /*
52 * mmio_base contains a base pfn and homing coordinates. Turn
53 * it into an MMIO pgprot and offset pfn.
54 */
55 prot = hv_pte_set_lotar(prot, hv_pte_get_lotar(mmio_base));
56 pfn = pte_pfn(mmio_base) + PFN_DOWN(offset);
57
58 return ioremap_prot(PFN_PHYS(pfn), size, prot);
59}
60
61EXPORT_SYMBOL(iorpc_ioremap);
diff --git a/arch/tile/gxio/mpipe.c b/arch/tile/gxio/mpipe.c
new file mode 100644
index 000000000000..e71c63390acc
--- /dev/null
+++ b/arch/tile/gxio/mpipe.c
@@ -0,0 +1,545 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/*
16 * Implementation of mpipe gxio calls.
17 */
18
19#include <linux/errno.h>
20#include <linux/io.h>
21#include <linux/module.h>
22
23#include <gxio/iorpc_globals.h>
24#include <gxio/iorpc_mpipe.h>
25#include <gxio/iorpc_mpipe_info.h>
26#include <gxio/kiorpc.h>
27#include <gxio/mpipe.h>
28
29/* HACK: Avoid pointless "shadow" warnings. */
30#define link link_shadow
31
32int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)
33{
34 char file[32];
35
36 int fd;
37 int i;
38
39 snprintf(file, sizeof(file), "mpipe/%d/iorpc", mpipe_index);
40 fd = hv_dev_open((HV_VirtAddr) file, 0);
41 if (fd < 0) {
42 if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
43 return fd;
44 else
45 return -ENODEV;
46 }
47
48 context->fd = fd;
49
50 /* Map in the MMIO space. */
51 context->mmio_cfg_base = (void __force *)
52 iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET,
53 HV_MPIPE_CONFIG_MMIO_SIZE);
54 if (context->mmio_cfg_base == NULL)
55 goto cfg_failed;
56
57 context->mmio_fast_base = (void __force *)
58 iorpc_ioremap(fd, HV_MPIPE_FAST_MMIO_OFFSET,
59 HV_MPIPE_FAST_MMIO_SIZE);
60 if (context->mmio_fast_base == NULL)
61 goto fast_failed;
62
63 /* Initialize the stacks. */
64 for (i = 0; i < 8; i++)
65 context->__stacks.stacks[i] = 255;
66
67 return 0;
68
69 fast_failed:
70 iounmap((void __force __iomem *)(context->mmio_cfg_base));
71 cfg_failed:
72 hv_dev_close(context->fd);
73 return -ENODEV;
74}
75
76EXPORT_SYMBOL_GPL(gxio_mpipe_init);
77
78int gxio_mpipe_destroy(gxio_mpipe_context_t *context)
79{
80 iounmap((void __force __iomem *)(context->mmio_cfg_base));
81 iounmap((void __force __iomem *)(context->mmio_fast_base));
82 return hv_dev_close(context->fd);
83}
84
85EXPORT_SYMBOL_GPL(gxio_mpipe_destroy);
86
87static int16_t gxio_mpipe_buffer_sizes[8] =
88 { 128, 256, 512, 1024, 1664, 4096, 10368, 16384 };
89
90gxio_mpipe_buffer_size_enum_t gxio_mpipe_buffer_size_to_buffer_size_enum(size_t
91 size)
92{
93 int i;
94 for (i = 0; i < 7; i++)
95 if (size <= gxio_mpipe_buffer_sizes[i])
96 break;
97 return i;
98}
99
100EXPORT_SYMBOL_GPL(gxio_mpipe_buffer_size_to_buffer_size_enum);
101
102size_t gxio_mpipe_buffer_size_enum_to_buffer_size(gxio_mpipe_buffer_size_enum_t
103 buffer_size_enum)
104{
105 if (buffer_size_enum > 7)
106 buffer_size_enum = 7;
107
108 return gxio_mpipe_buffer_sizes[buffer_size_enum];
109}
110
111EXPORT_SYMBOL_GPL(gxio_mpipe_buffer_size_enum_to_buffer_size);
112
113size_t gxio_mpipe_calc_buffer_stack_bytes(unsigned long buffers)
114{
115 const int BUFFERS_PER_LINE = 12;
116
117 /* Count the number of cachlines. */
118 unsigned long lines =
119 (buffers + BUFFERS_PER_LINE - 1) / BUFFERS_PER_LINE;
120
121 /* Convert to bytes. */
122 return lines * CHIP_L2_LINE_SIZE();
123}
124
125EXPORT_SYMBOL_GPL(gxio_mpipe_calc_buffer_stack_bytes);
126
127int gxio_mpipe_init_buffer_stack(gxio_mpipe_context_t *context,
128 unsigned int stack,
129 gxio_mpipe_buffer_size_enum_t
130 buffer_size_enum, void *mem, size_t mem_size,
131 unsigned int mem_flags)
132{
133 int result;
134
135 memset(mem, 0, mem_size);
136
137 result = gxio_mpipe_init_buffer_stack_aux(context, mem, mem_size,
138 mem_flags, stack,
139 buffer_size_enum);
140 if (result < 0)
141 return result;
142
143 /* Save the stack. */
144 context->__stacks.stacks[buffer_size_enum] = stack;
145
146 return 0;
147}
148
149EXPORT_SYMBOL_GPL(gxio_mpipe_init_buffer_stack);
150
151int gxio_mpipe_init_notif_ring(gxio_mpipe_context_t *context,
152 unsigned int ring,
153 void *mem, size_t mem_size,
154 unsigned int mem_flags)
155{
156 return gxio_mpipe_init_notif_ring_aux(context, mem, mem_size,
157 mem_flags, ring);
158}
159
160EXPORT_SYMBOL_GPL(gxio_mpipe_init_notif_ring);
161
162int gxio_mpipe_init_notif_group_and_buckets(gxio_mpipe_context_t *context,
163 unsigned int group,
164 unsigned int ring,
165 unsigned int num_rings,
166 unsigned int bucket,
167 unsigned int num_buckets,
168 gxio_mpipe_bucket_mode_t mode)
169{
170 int i;
171 int result;
172
173 gxio_mpipe_bucket_info_t bucket_info = { {
174 .group = group,
175 .mode = mode,
176 }
177 };
178
179 gxio_mpipe_notif_group_bits_t bits = { {0} };
180
181 for (i = 0; i < num_rings; i++)
182 gxio_mpipe_notif_group_add_ring(&bits, ring + i);
183
184 result = gxio_mpipe_init_notif_group(context, group, bits);
185 if (result != 0)
186 return result;
187
188 for (i = 0; i < num_buckets; i++) {
189 bucket_info.notifring = ring + (i % num_rings);
190
191 result = gxio_mpipe_init_bucket(context, bucket + i,
192 bucket_info);
193 if (result != 0)
194 return result;
195 }
196
197 return 0;
198}
199
200EXPORT_SYMBOL_GPL(gxio_mpipe_init_notif_group_and_buckets);
201
202int gxio_mpipe_init_edma_ring(gxio_mpipe_context_t *context,
203 unsigned int ring, unsigned int channel,
204 void *mem, size_t mem_size,
205 unsigned int mem_flags)
206{
207 memset(mem, 0, mem_size);
208
209 return gxio_mpipe_init_edma_ring_aux(context, mem, mem_size, mem_flags,
210 ring, channel);
211}
212
213EXPORT_SYMBOL_GPL(gxio_mpipe_init_edma_ring);
214
215void gxio_mpipe_rules_init(gxio_mpipe_rules_t *rules,
216 gxio_mpipe_context_t *context)
217{
218 rules->context = context;
219 memset(&rules->list, 0, sizeof(rules->list));
220}
221
222EXPORT_SYMBOL_GPL(gxio_mpipe_rules_init);
223
224int gxio_mpipe_rules_begin(gxio_mpipe_rules_t *rules,
225 unsigned int bucket, unsigned int num_buckets,
226 gxio_mpipe_rules_stacks_t *stacks)
227{
228 int i;
229 int stack = 255;
230
231 gxio_mpipe_rules_list_t *list = &rules->list;
232
233 /* Current rule. */
234 gxio_mpipe_rules_rule_t *rule =
235 (gxio_mpipe_rules_rule_t *) (list->rules + list->head);
236
237 unsigned int head = list->tail;
238
239 /*
240 * Align next rule properly.
241 *Note that "dmacs_and_vlans" will also be aligned.
242 */
243 unsigned int pad = 0;
244 while (((head + pad) % __alignof__(gxio_mpipe_rules_rule_t)) != 0)
245 pad++;
246
247 /*
248 * Verify room.
249 * ISSUE: Mark rules as broken on error?
250 */
251 if (head + pad + sizeof(*rule) >= sizeof(list->rules))
252 return GXIO_MPIPE_ERR_RULES_FULL;
253
254 /* Verify num_buckets is a power of 2. */
255 if (__builtin_popcount(num_buckets) != 1)
256 return GXIO_MPIPE_ERR_RULES_INVALID;
257
258 /* Add padding to previous rule. */
259 rule->size += pad;
260
261 /* Start a new rule. */
262 list->head = head + pad;
263
264 rule = (gxio_mpipe_rules_rule_t *) (list->rules + list->head);
265
266 /* Default some values. */
267 rule->headroom = 2;
268 rule->tailroom = 0;
269 rule->capacity = 16384;
270
271 /* Save the bucket info. */
272 rule->bucket_mask = num_buckets - 1;
273 rule->bucket_first = bucket;
274
275 for (i = 8 - 1; i >= 0; i--) {
276 int maybe =
277 stacks ? stacks->stacks[i] : rules->context->__stacks.
278 stacks[i];
279 if (maybe != 255)
280 stack = maybe;
281 rule->stacks.stacks[i] = stack;
282 }
283
284 if (stack == 255)
285 return GXIO_MPIPE_ERR_RULES_INVALID;
286
287 /* NOTE: Only entries at the end of the array can be 255. */
288 for (i = 8 - 1; i > 0; i--) {
289 if (rule->stacks.stacks[i] == 255) {
290 rule->stacks.stacks[i] = stack;
291 rule->capacity =
292 gxio_mpipe_buffer_size_enum_to_buffer_size(i -
293 1);
294 }
295 }
296
297 rule->size = sizeof(*rule);
298 list->tail = list->head + rule->size;
299
300 return 0;
301}
302
303EXPORT_SYMBOL_GPL(gxio_mpipe_rules_begin);
304
305int gxio_mpipe_rules_add_channel(gxio_mpipe_rules_t *rules,
306 unsigned int channel)
307{
308 gxio_mpipe_rules_list_t *list = &rules->list;
309
310 gxio_mpipe_rules_rule_t *rule =
311 (gxio_mpipe_rules_rule_t *) (list->rules + list->head);
312
313 /* Verify channel. */
314 if (channel >= 32)
315 return GXIO_MPIPE_ERR_RULES_INVALID;
316
317 /* Verify begun. */
318 if (list->tail == 0)
319 return GXIO_MPIPE_ERR_RULES_EMPTY;
320
321 rule->channel_bits |= (1UL << channel);
322
323 return 0;
324}
325
326EXPORT_SYMBOL_GPL(gxio_mpipe_rules_add_channel);
327
328int gxio_mpipe_rules_set_headroom(gxio_mpipe_rules_t *rules, uint8_t headroom)
329{
330 gxio_mpipe_rules_list_t *list = &rules->list;
331
332 gxio_mpipe_rules_rule_t *rule =
333 (gxio_mpipe_rules_rule_t *) (list->rules + list->head);
334
335 /* Verify begun. */
336 if (list->tail == 0)
337 return GXIO_MPIPE_ERR_RULES_EMPTY;
338
339 rule->headroom = headroom;
340
341 return 0;
342}
343
344EXPORT_SYMBOL_GPL(gxio_mpipe_rules_set_headroom);
345
346int gxio_mpipe_rules_commit(gxio_mpipe_rules_t *rules)
347{
348 gxio_mpipe_rules_list_t *list = &rules->list;
349 unsigned int size =
350 offsetof(gxio_mpipe_rules_list_t, rules) + list->tail;
351 return gxio_mpipe_commit_rules(rules->context, list, size);
352}
353
354EXPORT_SYMBOL_GPL(gxio_mpipe_rules_commit);
355
356int gxio_mpipe_iqueue_init(gxio_mpipe_iqueue_t *iqueue,
357 gxio_mpipe_context_t *context,
358 unsigned int ring,
359 void *mem, size_t mem_size, unsigned int mem_flags)
360{
361 /* The init call below will verify that "mem_size" is legal. */
362 unsigned int num_entries = mem_size / sizeof(gxio_mpipe_idesc_t);
363
364 iqueue->context = context;
365 iqueue->idescs = (gxio_mpipe_idesc_t *)mem;
366 iqueue->ring = ring;
367 iqueue->num_entries = num_entries;
368 iqueue->mask_num_entries = num_entries - 1;
369 iqueue->log2_num_entries = __builtin_ctz(num_entries);
370 iqueue->head = 1;
371#ifdef __BIG_ENDIAN__
372 iqueue->swapped = 0;
373#endif
374
375 /* Initialize the "tail". */
376 __gxio_mmio_write(mem, iqueue->head);
377
378 return gxio_mpipe_init_notif_ring(context, ring, mem, mem_size,
379 mem_flags);
380}
381
382EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init);
383
384int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue,
385 gxio_mpipe_context_t *context,
386 unsigned int edma_ring_id,
387 unsigned int channel,
388 void *mem, unsigned int mem_size,
389 unsigned int mem_flags)
390{
391 /* The init call below will verify that "mem_size" is legal. */
392 unsigned int num_entries = mem_size / sizeof(gxio_mpipe_edesc_t);
393
394 /* Offset used to read number of completed commands. */
395 MPIPE_EDMA_POST_REGION_ADDR_t offset;
396
397 int result = gxio_mpipe_init_edma_ring(context, edma_ring_id, channel,
398 mem, mem_size, mem_flags);
399 if (result < 0)
400 return result;
401
402 memset(equeue, 0, sizeof(*equeue));
403
404 offset.word = 0;
405 offset.region =
406 MPIPE_MMIO_ADDR__REGION_VAL_EDMA -
407 MPIPE_MMIO_ADDR__REGION_VAL_IDMA;
408 offset.ring = edma_ring_id;
409
410 __gxio_dma_queue_init(&equeue->dma_queue,
411 context->mmio_fast_base + offset.word,
412 num_entries);
413 equeue->edescs = mem;
414 equeue->mask_num_entries = num_entries - 1;
415 equeue->log2_num_entries = __builtin_ctz(num_entries);
416
417 return 0;
418}
419
420EXPORT_SYMBOL_GPL(gxio_mpipe_equeue_init);
421
422int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,
423 const struct timespec *ts)
424{
425 cycles_t cycles = get_cycles();
426 return gxio_mpipe_set_timestamp_aux(context, (uint64_t)ts->tv_sec,
427 (uint64_t)ts->tv_nsec,
428 (uint64_t)cycles);
429}
430
431int gxio_mpipe_get_timestamp(gxio_mpipe_context_t *context,
432 struct timespec *ts)
433{
434 int ret;
435 cycles_t cycles_prev, cycles_now, clock_rate;
436 cycles_prev = get_cycles();
437 ret = gxio_mpipe_get_timestamp_aux(context, (uint64_t *)&ts->tv_sec,
438 (uint64_t *)&ts->tv_nsec,
439 (uint64_t *)&cycles_now);
440 if (ret < 0) {
441 return ret;
442 }
443
444 clock_rate = get_clock_rate();
445 ts->tv_nsec -= (cycles_now - cycles_prev) * 1000000000LL / clock_rate;
446 if (ts->tv_nsec < 0) {
447 ts->tv_nsec += 1000000000LL;
448 ts->tv_sec -= 1;
449 }
450 return ret;
451}
452
453int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, int64_t delta)
454{
455 return gxio_mpipe_adjust_timestamp_aux(context, delta);
456}
457
458/* Get our internal context used for link name access. This context is
459 * special in that it is not associated with an mPIPE service domain.
460 */
461static gxio_mpipe_context_t *_gxio_get_link_context(void)
462{
463 static gxio_mpipe_context_t context;
464 static gxio_mpipe_context_t *contextp;
465 static int tried_open = 0;
466 static DEFINE_MUTEX(mutex);
467
468 mutex_lock(&mutex);
469
470 if (!tried_open) {
471 int i = 0;
472 tried_open = 1;
473
474 /*
475 * "4" here is the maximum possible number of mPIPE shims; it's
476 * an exaggeration but we shouldn't ever go beyond 2 anyway.
477 */
478 for (i = 0; i < 4; i++) {
479 char file[80];
480
481 snprintf(file, sizeof(file), "mpipe/%d/iorpc_info", i);
482 context.fd = hv_dev_open((HV_VirtAddr) file, 0);
483 if (context.fd < 0)
484 continue;
485
486 contextp = &context;
487 break;
488 }
489 }
490
491 mutex_unlock(&mutex);
492
493 return contextp;
494}
495
496int gxio_mpipe_link_enumerate_mac(int idx, char *link_name, uint8_t *link_mac)
497{
498 int rv;
499 _gxio_mpipe_link_name_t name;
500 _gxio_mpipe_link_mac_t mac;
501
502 gxio_mpipe_context_t *context = _gxio_get_link_context();
503 if (!context)
504 return GXIO_ERR_NO_DEVICE;
505
506 rv = gxio_mpipe_info_enumerate_aux(context, idx, &name, &mac);
507 if (rv >= 0) {
508 strncpy(link_name, name.name, sizeof(name.name));
509 memcpy(link_mac, mac.mac, sizeof(mac.mac));
510 }
511
512 return rv;
513}
514
515EXPORT_SYMBOL_GPL(gxio_mpipe_link_enumerate_mac);
516
517int gxio_mpipe_link_open(gxio_mpipe_link_t *link,
518 gxio_mpipe_context_t *context, const char *link_name,
519 unsigned int flags)
520{
521 _gxio_mpipe_link_name_t name;
522 int rv;
523
524 strncpy(name.name, link_name, sizeof(name.name));
525 name.name[GXIO_MPIPE_LINK_NAME_LEN - 1] = '\0';
526
527 rv = gxio_mpipe_link_open_aux(context, name, flags);
528 if (rv < 0)
529 return rv;
530
531 link->context = context;
532 link->channel = rv >> 8;
533 link->mac = rv & 0xFF;
534
535 return 0;
536}
537
538EXPORT_SYMBOL_GPL(gxio_mpipe_link_open);
539
540int gxio_mpipe_link_close(gxio_mpipe_link_t *link)
541{
542 return gxio_mpipe_link_close_aux(link->context, link->mac);
543}
544
545EXPORT_SYMBOL_GPL(gxio_mpipe_link_close);
diff --git a/arch/tile/gxio/trio.c b/arch/tile/gxio/trio.c
new file mode 100644
index 000000000000..69f0b8df3ce3
--- /dev/null
+++ b/arch/tile/gxio/trio.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/*
16 * Implementation of trio gxio calls.
17 */
18
19#include <linux/errno.h>
20#include <linux/io.h>
21#include <linux/module.h>
22
23#include <gxio/trio.h>
24#include <gxio/iorpc_globals.h>
25#include <gxio/iorpc_trio.h>
26#include <gxio/kiorpc.h>
27
28int gxio_trio_init(gxio_trio_context_t *context, unsigned int trio_index)
29{
30 char file[32];
31 int fd;
32
33 snprintf(file, sizeof(file), "trio/%d/iorpc", trio_index);
34 fd = hv_dev_open((HV_VirtAddr) file, 0);
35 if (fd < 0) {
36 context->fd = -1;
37
38 if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
39 return fd;
40 else
41 return -ENODEV;
42 }
43
44 context->fd = fd;
45
46 return 0;
47}
48
49EXPORT_SYMBOL_GPL(gxio_trio_init);
diff --git a/arch/tile/gxio/usb_host.c b/arch/tile/gxio/usb_host.c
new file mode 100644
index 000000000000..66b002f54ecc
--- /dev/null
+++ b/arch/tile/gxio/usb_host.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/*
16 *
17 * Implementation of USB gxio calls.
18 */
19
20#include <linux/io.h>
21#include <linux/errno.h>
22#include <linux/module.h>
23
24#include <gxio/iorpc_globals.h>
25#include <gxio/iorpc_usb_host.h>
26#include <gxio/kiorpc.h>
27#include <gxio/usb_host.h>
28
29int gxio_usb_host_init(gxio_usb_host_context_t * context, int usb_index,
30 int is_ehci)
31{
32 char file[32];
33 int fd;
34
35 if (is_ehci)
36 snprintf(file, sizeof(file), "usb_host/%d/iorpc/ehci",
37 usb_index);
38 else
39 snprintf(file, sizeof(file), "usb_host/%d/iorpc/ohci",
40 usb_index);
41
42 fd = hv_dev_open((HV_VirtAddr) file, 0);
43 if (fd < 0) {
44 if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
45 return fd;
46 else
47 return -ENODEV;
48 }
49
50 context->fd = fd;
51
52 // Map in the MMIO space.
53 context->mmio_base =
54 (void __force *)iorpc_ioremap(fd, 0, HV_USB_HOST_MMIO_SIZE);
55
56 if (context->mmio_base == NULL) {
57 hv_dev_close(context->fd);
58 return -ENODEV;
59 }
60
61 return 0;
62}
63
64EXPORT_SYMBOL_GPL(gxio_usb_host_init);
65
66int gxio_usb_host_destroy(gxio_usb_host_context_t * context)
67{
68 iounmap((void __force __iomem *)(context->mmio_base));
69 hv_dev_close(context->fd);
70
71 context->mmio_base = NULL;
72 context->fd = -1;
73
74 return 0;
75}
76
77EXPORT_SYMBOL_GPL(gxio_usb_host_destroy);
78
79void *gxio_usb_host_get_reg_start(gxio_usb_host_context_t * context)
80{
81 return context->mmio_base;
82}
83
84EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_start);
85
86size_t gxio_usb_host_get_reg_len(gxio_usb_host_context_t * context)
87{
88 return HV_USB_HOST_MMIO_SIZE;
89}
90
91EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_len);