diff options
author | Zhang Wei <wei.zhang@freescale.com> | 2008-04-18 16:33:41 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-04-29 05:40:28 -0400 |
commit | ad1e9380b17addf112f89ce5a57d4d0bee129b7a (patch) | |
tree | 41bb74c91533f0a2f4a7bfbfb1036ba250cbf50b /arch/powerpc/sysdev | |
parent | 5a7b60ed8892756b137496b629f2e7c689fe6d8d (diff) |
[RAPIDIO] Add RapidIO multi mport support
The original RapidIO driver suppose there is only one mpc85xx RIO controller
in system. So, some data structures are defined as mpc85xx_rio global, such
as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them to mport's
private members. And you can define multi RIO OF-nodes in dts file for multi
RapidIO controller in one processor, such as PCI/PCI-Ex host controllers in
Freescale's silicon. And the mport operation function declaration should be
changed to know which RapidIO controller is target.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 395 |
1 files changed, 222 insertions, 173 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 659a5609d2db..80acc7940194 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -1,6 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Freescale MPC85xx/MPC86xx RapidIO support | 2 | * Freescale MPC85xx/MPC86xx RapidIO support |
3 | * | 3 | * |
4 | * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. | ||
5 | * Zhang Wei <wei.zhang@freescale.com> | ||
6 | * | ||
4 | * Copyright 2005 MontaVista Software, Inc. | 7 | * Copyright 2005 MontaVista Software, Inc. |
5 | * Matt Porter <mporter@kernel.crashing.org> | 8 | * Matt Porter <mporter@kernel.crashing.org> |
6 | * | 9 | * |
@@ -20,6 +23,11 @@ | |||
20 | 23 | ||
21 | #include <asm/io.h> | 24 | #include <asm/io.h> |
22 | 25 | ||
26 | /* RapidIO definition irq, which read from OF-tree */ | ||
27 | #define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq) | ||
28 | #define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq) | ||
29 | #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) | ||
30 | |||
23 | #define RIO_REGS_BASE (CCSRBAR + 0xc0000) | 31 | #define RIO_REGS_BASE (CCSRBAR + 0xc0000) |
24 | #define RIO_ATMU_REGS_OFFSET 0x10c00 | 32 | #define RIO_ATMU_REGS_OFFSET 0x10c00 |
25 | #define RIO_MSG_REGS_OFFSET 0x11000 | 33 | #define RIO_MSG_REGS_OFFSET 0x11000 |
@@ -112,20 +120,12 @@ struct rio_tx_desc { | |||
112 | u32 res4; | 120 | u32 res4; |
113 | }; | 121 | }; |
114 | 122 | ||
115 | static u32 regs_win; | 123 | struct rio_dbell_ring { |
116 | static struct rio_atmu_regs *atmu_regs; | ||
117 | static struct rio_atmu_regs *maint_atmu_regs; | ||
118 | static struct rio_atmu_regs *dbell_atmu_regs; | ||
119 | static u32 dbell_win; | ||
120 | static u32 maint_win; | ||
121 | static struct rio_msg_regs *msg_regs; | ||
122 | |||
123 | static struct rio_dbell_ring { | ||
124 | void *virt; | 124 | void *virt; |
125 | dma_addr_t phys; | 125 | dma_addr_t phys; |
126 | } dbell_ring; | 126 | }; |
127 | 127 | ||
128 | static struct rio_msg_tx_ring { | 128 | struct rio_msg_tx_ring { |
129 | void *virt; | 129 | void *virt; |
130 | dma_addr_t phys; | 130 | dma_addr_t phys; |
131 | void *virt_buffer[RIO_MAX_TX_RING_SIZE]; | 131 | void *virt_buffer[RIO_MAX_TX_RING_SIZE]; |
@@ -133,16 +133,32 @@ static struct rio_msg_tx_ring { | |||
133 | int tx_slot; | 133 | int tx_slot; |
134 | int size; | 134 | int size; |
135 | void *dev_id; | 135 | void *dev_id; |
136 | } msg_tx_ring; | 136 | }; |
137 | 137 | ||
138 | static struct rio_msg_rx_ring { | 138 | struct rio_msg_rx_ring { |
139 | void *virt; | 139 | void *virt; |
140 | dma_addr_t phys; | 140 | dma_addr_t phys; |
141 | void *virt_buffer[RIO_MAX_RX_RING_SIZE]; | 141 | void *virt_buffer[RIO_MAX_RX_RING_SIZE]; |
142 | int rx_slot; | 142 | int rx_slot; |
143 | int size; | 143 | int size; |
144 | void *dev_id; | 144 | void *dev_id; |
145 | } msg_rx_ring; | 145 | }; |
146 | |||
147 | struct rio_priv { | ||
148 | void __iomem *regs_win; | ||
149 | struct rio_atmu_regs __iomem *atmu_regs; | ||
150 | struct rio_atmu_regs __iomem *maint_atmu_regs; | ||
151 | struct rio_atmu_regs __iomem *dbell_atmu_regs; | ||
152 | void __iomem *dbell_win; | ||
153 | void __iomem *maint_win; | ||
154 | struct rio_msg_regs __iomem *msg_regs; | ||
155 | struct rio_dbell_ring dbell_ring; | ||
156 | struct rio_msg_tx_ring msg_tx_ring; | ||
157 | struct rio_msg_rx_ring msg_rx_ring; | ||
158 | int bellirq; | ||
159 | int txirq; | ||
160 | int rxirq; | ||
161 | }; | ||
146 | 162 | ||
147 | /** | 163 | /** |
148 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message | 164 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message |
@@ -153,12 +169,14 @@ static struct rio_msg_rx_ring { | |||
153 | * Sends a MPC85xx doorbell message. Returns %0 on success or | 169 | * Sends a MPC85xx doorbell message. Returns %0 on success or |
154 | * %-EINVAL on failure. | 170 | * %-EINVAL on failure. |
155 | */ | 171 | */ |
156 | static int fsl_rio_doorbell_send(int index, u16 destid, u16 data) | 172 | static int fsl_rio_doorbell_send(struct rio_mport *mport, |
173 | int index, u16 destid, u16 data) | ||
157 | { | 174 | { |
175 | struct rio_priv *priv = mport->priv; | ||
158 | pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", | 176 | pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", |
159 | index, destid, data); | 177 | index, destid, data); |
160 | out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22); | 178 | out_be32(&priv->dbell_atmu_regs->rowtar, destid << 22); |
161 | out_be16((void *)(dbell_win), data); | 179 | out_be16(priv->dbell_win, data); |
162 | 180 | ||
163 | return 0; | 181 | return 0; |
164 | } | 182 | } |
@@ -173,11 +191,13 @@ static int fsl_rio_doorbell_send(int index, u16 destid, u16 data) | |||
173 | * Generates a MPC85xx local configuration space read. Returns %0 on | 191 | * Generates a MPC85xx local configuration space read. Returns %0 on |
174 | * success or %-EINVAL on failure. | 192 | * success or %-EINVAL on failure. |
175 | */ | 193 | */ |
176 | static int fsl_local_config_read(int index, u32 offset, int len, u32 *data) | 194 | static int fsl_local_config_read(struct rio_mport *mport, |
195 | int index, u32 offset, int len, u32 *data) | ||
177 | { | 196 | { |
197 | struct rio_priv *priv = mport->priv; | ||
178 | pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index, | 198 | pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index, |
179 | offset); | 199 | offset); |
180 | *data = in_be32((void *)(regs_win + offset)); | 200 | *data = in_be32(priv->regs_win + offset); |
181 | 201 | ||
182 | return 0; | 202 | return 0; |
183 | } | 203 | } |
@@ -192,12 +212,14 @@ static int fsl_local_config_read(int index, u32 offset, int len, u32 *data) | |||
192 | * Generates a MPC85xx local configuration space write. Returns %0 on | 212 | * Generates a MPC85xx local configuration space write. Returns %0 on |
193 | * success or %-EINVAL on failure. | 213 | * success or %-EINVAL on failure. |
194 | */ | 214 | */ |
195 | static int fsl_local_config_write(int index, u32 offset, int len, u32 data) | 215 | static int fsl_local_config_write(struct rio_mport *mport, |
216 | int index, u32 offset, int len, u32 data) | ||
196 | { | 217 | { |
218 | struct rio_priv *priv = mport->priv; | ||
197 | pr_debug | 219 | pr_debug |
198 | ("fsl_local_config_write: index %d offset %8.8x data %8.8x\n", | 220 | ("fsl_local_config_write: index %d offset %8.8x data %8.8x\n", |
199 | index, offset, data); | 221 | index, offset, data); |
200 | out_be32((void *)(regs_win + offset), data); | 222 | out_be32(priv->regs_win + offset, data); |
201 | 223 | ||
202 | return 0; | 224 | return 0; |
203 | } | 225 | } |
@@ -215,18 +237,19 @@ static int fsl_local_config_write(int index, u32 offset, int len, u32 data) | |||
215 | * success or %-EINVAL on failure. | 237 | * success or %-EINVAL on failure. |
216 | */ | 238 | */ |
217 | static int | 239 | static int |
218 | fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len, | 240 | fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, |
219 | u32 * val) | 241 | u8 hopcount, u32 offset, int len, u32 *val) |
220 | { | 242 | { |
243 | struct rio_priv *priv = mport->priv; | ||
221 | u8 *data; | 244 | u8 *data; |
222 | 245 | ||
223 | pr_debug | 246 | pr_debug |
224 | ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", | 247 | ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", |
225 | index, destid, hopcount, offset, len); | 248 | index, destid, hopcount, offset, len); |
226 | out_be32((void *)&maint_atmu_regs->rowtar, | 249 | out_be32(&priv->maint_atmu_regs->rowtar, |
227 | (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); | 250 | (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); |
228 | 251 | ||
229 | data = (u8 *) maint_win + offset; | 252 | data = (u8 *) priv->maint_win + offset; |
230 | switch (len) { | 253 | switch (len) { |
231 | case 1: | 254 | case 1: |
232 | *val = in_8((u8 *) data); | 255 | *val = in_8((u8 *) data); |
@@ -255,17 +278,18 @@ fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len, | |||
255 | * success or %-EINVAL on failure. | 278 | * success or %-EINVAL on failure. |
256 | */ | 279 | */ |
257 | static int | 280 | static int |
258 | fsl_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset, | 281 | fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, |
259 | int len, u32 val) | 282 | u8 hopcount, u32 offset, int len, u32 val) |
260 | { | 283 | { |
284 | struct rio_priv *priv = mport->priv; | ||
261 | u8 *data; | 285 | u8 *data; |
262 | pr_debug | 286 | pr_debug |
263 | ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", | 287 | ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", |
264 | index, destid, hopcount, offset, len, val); | 288 | index, destid, hopcount, offset, len, val); |
265 | out_be32((void *)&maint_atmu_regs->rowtar, | 289 | out_be32(&priv->maint_atmu_regs->rowtar, |
266 | (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); | 290 | (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); |
267 | 291 | ||
268 | data = (u8 *) maint_win + offset; | 292 | data = (u8 *) priv->maint_win + offset; |
269 | switch (len) { | 293 | switch (len) { |
270 | case 1: | 294 | case 1: |
271 | out_8((u8 *) data, val); | 295 | out_8((u8 *) data, val); |
@@ -296,9 +320,10 @@ int | |||
296 | rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, | 320 | rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, |
297 | void *buffer, size_t len) | 321 | void *buffer, size_t len) |
298 | { | 322 | { |
323 | struct rio_priv *priv = mport->priv; | ||
299 | u32 omr; | 324 | u32 omr; |
300 | struct rio_tx_desc *desc = | 325 | struct rio_tx_desc *desc = (struct rio_tx_desc *)priv->msg_tx_ring.virt |
301 | (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot; | 326 | + priv->msg_tx_ring.tx_slot; |
302 | int ret = 0; | 327 | int ret = 0; |
303 | 328 | ||
304 | pr_debug | 329 | pr_debug |
@@ -311,11 +336,11 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, | |||
311 | } | 336 | } |
312 | 337 | ||
313 | /* Copy and clear rest of buffer */ | 338 | /* Copy and clear rest of buffer */ |
314 | memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len); | 339 | memcpy(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot], buffer, |
340 | len); | ||
315 | if (len < (RIO_MAX_MSG_SIZE - 4)) | 341 | if (len < (RIO_MAX_MSG_SIZE - 4)) |
316 | memset((void *)((u32) msg_tx_ring. | 342 | memset(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot] |
317 | virt_buffer[msg_tx_ring.tx_slot] + len), 0, | 343 | + len, 0, RIO_MAX_MSG_SIZE - len); |
318 | RIO_MAX_MSG_SIZE - len); | ||
319 | 344 | ||
320 | /* Set mbox field for message */ | 345 | /* Set mbox field for message */ |
321 | desc->dport = mbox & 0x3; | 346 | desc->dport = mbox & 0x3; |
@@ -327,15 +352,16 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, | |||
327 | desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len); | 352 | desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len); |
328 | 353 | ||
329 | /* Set snooping and source buffer address */ | 354 | /* Set snooping and source buffer address */ |
330 | desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot]; | 355 | desc->saddr = 0x00000004 |
356 | | priv->msg_tx_ring.phys_buffer[priv->msg_tx_ring.tx_slot]; | ||
331 | 357 | ||
332 | /* Increment enqueue pointer */ | 358 | /* Increment enqueue pointer */ |
333 | omr = in_be32((void *)&msg_regs->omr); | 359 | omr = in_be32(&priv->msg_regs->omr); |
334 | out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI); | 360 | out_be32(&priv->msg_regs->omr, omr | RIO_MSG_OMR_MUI); |
335 | 361 | ||
336 | /* Go to next descriptor */ | 362 | /* Go to next descriptor */ |
337 | if (++msg_tx_ring.tx_slot == msg_tx_ring.size) | 363 | if (++priv->msg_tx_ring.tx_slot == priv->msg_tx_ring.size) |
338 | msg_tx_ring.tx_slot = 0; | 364 | priv->msg_tx_ring.tx_slot = 0; |
339 | 365 | ||
340 | out: | 366 | out: |
341 | return ret; | 367 | return ret; |
@@ -356,28 +382,30 @@ fsl_rio_tx_handler(int irq, void *dev_instance) | |||
356 | { | 382 | { |
357 | int osr; | 383 | int osr; |
358 | struct rio_mport *port = (struct rio_mport *)dev_instance; | 384 | struct rio_mport *port = (struct rio_mport *)dev_instance; |
385 | struct rio_priv *priv = port->priv; | ||
359 | 386 | ||
360 | osr = in_be32((void *)&msg_regs->osr); | 387 | osr = in_be32(&priv->msg_regs->osr); |
361 | 388 | ||
362 | if (osr & RIO_MSG_OSR_TE) { | 389 | if (osr & RIO_MSG_OSR_TE) { |
363 | pr_info("RIO: outbound message transmission error\n"); | 390 | pr_info("RIO: outbound message transmission error\n"); |
364 | out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE); | 391 | out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_TE); |
365 | goto out; | 392 | goto out; |
366 | } | 393 | } |
367 | 394 | ||
368 | if (osr & RIO_MSG_OSR_QOI) { | 395 | if (osr & RIO_MSG_OSR_QOI) { |
369 | pr_info("RIO: outbound message queue overflow\n"); | 396 | pr_info("RIO: outbound message queue overflow\n"); |
370 | out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI); | 397 | out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_QOI); |
371 | goto out; | 398 | goto out; |
372 | } | 399 | } |
373 | 400 | ||
374 | if (osr & RIO_MSG_OSR_EOMI) { | 401 | if (osr & RIO_MSG_OSR_EOMI) { |
375 | u32 dqp = in_be32((void *)&msg_regs->odqdpar); | 402 | u32 dqp = in_be32(&priv->msg_regs->odqdpar); |
376 | int slot = (dqp - msg_tx_ring.phys) >> 5; | 403 | int slot = (dqp - priv->msg_tx_ring.phys) >> 5; |
377 | port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot); | 404 | port->outb_msg[0].mcback(port, priv->msg_tx_ring.dev_id, -1, |
405 | slot); | ||
378 | 406 | ||
379 | /* Ack the end-of-message interrupt */ | 407 | /* Ack the end-of-message interrupt */ |
380 | out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI); | 408 | out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_EOMI); |
381 | } | 409 | } |
382 | 410 | ||
383 | out: | 411 | out: |
@@ -398,6 +426,7 @@ fsl_rio_tx_handler(int irq, void *dev_instance) | |||
398 | int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) | 426 | int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) |
399 | { | 427 | { |
400 | int i, j, rc = 0; | 428 | int i, j, rc = 0; |
429 | struct rio_priv *priv = mport->priv; | ||
401 | 430 | ||
402 | if ((entries < RIO_MIN_TX_RING_SIZE) || | 431 | if ((entries < RIO_MIN_TX_RING_SIZE) || |
403 | (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) { | 432 | (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) { |
@@ -406,54 +435,53 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr | |||
406 | } | 435 | } |
407 | 436 | ||
408 | /* Initialize shadow copy ring */ | 437 | /* Initialize shadow copy ring */ |
409 | msg_tx_ring.dev_id = dev_id; | 438 | priv->msg_tx_ring.dev_id = dev_id; |
410 | msg_tx_ring.size = entries; | 439 | priv->msg_tx_ring.size = entries; |
411 | 440 | ||
412 | for (i = 0; i < msg_tx_ring.size; i++) { | 441 | for (i = 0; i < priv->msg_tx_ring.size; i++) { |
413 | if (! | 442 | priv->msg_tx_ring.virt_buffer[i] = |
414 | (msg_tx_ring.virt_buffer[i] = | 443 | dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE, |
415 | dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE, | 444 | &priv->msg_tx_ring.phys_buffer[i], GFP_KERNEL); |
416 | &msg_tx_ring.phys_buffer[i], | 445 | if (!priv->msg_tx_ring.virt_buffer[i]) { |
417 | GFP_KERNEL))) { | ||
418 | rc = -ENOMEM; | 446 | rc = -ENOMEM; |
419 | for (j = 0; j < msg_tx_ring.size; j++) | 447 | for (j = 0; j < priv->msg_tx_ring.size; j++) |
420 | if (msg_tx_ring.virt_buffer[j]) | 448 | if (priv->msg_tx_ring.virt_buffer[j]) |
421 | dma_free_coherent(NULL, | 449 | dma_free_coherent(NULL, |
422 | RIO_MSG_BUFFER_SIZE, | 450 | RIO_MSG_BUFFER_SIZE, |
423 | msg_tx_ring. | 451 | priv->msg_tx_ring. |
424 | virt_buffer[j], | 452 | virt_buffer[j], |
425 | msg_tx_ring. | 453 | priv->msg_tx_ring. |
426 | phys_buffer[j]); | 454 | phys_buffer[j]); |
427 | goto out; | 455 | goto out; |
428 | } | 456 | } |
429 | } | 457 | } |
430 | 458 | ||
431 | /* Initialize outbound message descriptor ring */ | 459 | /* Initialize outbound message descriptor ring */ |
432 | if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL, | 460 | priv->msg_tx_ring.virt = dma_alloc_coherent(NULL, |
433 | msg_tx_ring.size * | 461 | priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, |
434 | RIO_MSG_DESC_SIZE, | 462 | &priv->msg_tx_ring.phys, GFP_KERNEL); |
435 | &msg_tx_ring.phys, | 463 | if (!priv->msg_tx_ring.virt) { |
436 | GFP_KERNEL))) { | ||
437 | rc = -ENOMEM; | 464 | rc = -ENOMEM; |
438 | goto out_dma; | 465 | goto out_dma; |
439 | } | 466 | } |
440 | memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE); | 467 | memset(priv->msg_tx_ring.virt, 0, |
441 | msg_tx_ring.tx_slot = 0; | 468 | priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE); |
469 | priv->msg_tx_ring.tx_slot = 0; | ||
442 | 470 | ||
443 | /* Point dequeue/enqueue pointers at first entry in ring */ | 471 | /* Point dequeue/enqueue pointers at first entry in ring */ |
444 | out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys); | 472 | out_be32(&priv->msg_regs->odqdpar, priv->msg_tx_ring.phys); |
445 | out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys); | 473 | out_be32(&priv->msg_regs->odqepar, priv->msg_tx_ring.phys); |
446 | 474 | ||
447 | /* Configure for snooping */ | 475 | /* Configure for snooping */ |
448 | out_be32((void *)&msg_regs->osar, 0x00000004); | 476 | out_be32(&priv->msg_regs->osar, 0x00000004); |
449 | 477 | ||
450 | /* Clear interrupt status */ | 478 | /* Clear interrupt status */ |
451 | out_be32((void *)&msg_regs->osr, 0x000000b3); | 479 | out_be32(&priv->msg_regs->osr, 0x000000b3); |
452 | 480 | ||
453 | /* Hook up outbound message handler */ | 481 | /* Hook up outbound message handler */ |
454 | if ((rc = | 482 | rc = request_irq(IRQ_RIO_TX(mport), fsl_rio_tx_handler, 0, |
455 | request_irq(MPC85xx_IRQ_RIO_TX, fsl_rio_tx_handler, 0, | 483 | "msg_tx", (void *)mport); |
456 | "msg_tx", (void *)mport)) < 0) | 484 | if (rc < 0) |
457 | goto out_irq; | 485 | goto out_irq; |
458 | 486 | ||
459 | /* | 487 | /* |
@@ -463,28 +491,28 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr | |||
463 | * Chaining mode | 491 | * Chaining mode |
464 | * Disable | 492 | * Disable |
465 | */ | 493 | */ |
466 | out_be32((void *)&msg_regs->omr, 0x00100220); | 494 | out_be32(&priv->msg_regs->omr, 0x00100220); |
467 | 495 | ||
468 | /* Set number of entries */ | 496 | /* Set number of entries */ |
469 | out_be32((void *)&msg_regs->omr, | 497 | out_be32(&priv->msg_regs->omr, |
470 | in_be32((void *)&msg_regs->omr) | | 498 | in_be32(&priv->msg_regs->omr) | |
471 | ((get_bitmask_order(entries) - 2) << 12)); | 499 | ((get_bitmask_order(entries) - 2) << 12)); |
472 | 500 | ||
473 | /* Now enable the unit */ | 501 | /* Now enable the unit */ |
474 | out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1); | 502 | out_be32(&priv->msg_regs->omr, in_be32(&priv->msg_regs->omr) | 0x1); |
475 | 503 | ||
476 | out: | 504 | out: |
477 | return rc; | 505 | return rc; |
478 | 506 | ||
479 | out_irq: | 507 | out_irq: |
480 | dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, | 508 | dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, |
481 | msg_tx_ring.virt, msg_tx_ring.phys); | 509 | priv->msg_tx_ring.virt, priv->msg_tx_ring.phys); |
482 | 510 | ||
483 | out_dma: | 511 | out_dma: |
484 | for (i = 0; i < msg_tx_ring.size; i++) | 512 | for (i = 0; i < priv->msg_tx_ring.size; i++) |
485 | dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, | 513 | dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, |
486 | msg_tx_ring.virt_buffer[i], | 514 | priv->msg_tx_ring.virt_buffer[i], |
487 | msg_tx_ring.phys_buffer[i]); | 515 | priv->msg_tx_ring.phys_buffer[i]); |
488 | 516 | ||
489 | return rc; | 517 | return rc; |
490 | } | 518 | } |
@@ -499,15 +527,16 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr | |||
499 | */ | 527 | */ |
500 | void rio_close_outb_mbox(struct rio_mport *mport, int mbox) | 528 | void rio_close_outb_mbox(struct rio_mport *mport, int mbox) |
501 | { | 529 | { |
530 | struct rio_priv *priv = mport->priv; | ||
502 | /* Disable inbound message unit */ | 531 | /* Disable inbound message unit */ |
503 | out_be32((void *)&msg_regs->omr, 0); | 532 | out_be32(&priv->msg_regs->omr, 0); |
504 | 533 | ||
505 | /* Free ring */ | 534 | /* Free ring */ |
506 | dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, | 535 | dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, |
507 | msg_tx_ring.virt, msg_tx_ring.phys); | 536 | priv->msg_tx_ring.virt, priv->msg_tx_ring.phys); |
508 | 537 | ||
509 | /* Free interrupt */ | 538 | /* Free interrupt */ |
510 | free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport); | 539 | free_irq(IRQ_RIO_TX(mport), (void *)mport); |
511 | } | 540 | } |
512 | 541 | ||
513 | /** | 542 | /** |
@@ -523,12 +552,13 @@ fsl_rio_rx_handler(int irq, void *dev_instance) | |||
523 | { | 552 | { |
524 | int isr; | 553 | int isr; |
525 | struct rio_mport *port = (struct rio_mport *)dev_instance; | 554 | struct rio_mport *port = (struct rio_mport *)dev_instance; |
555 | struct rio_priv *priv = port->priv; | ||
526 | 556 | ||
527 | isr = in_be32((void *)&msg_regs->isr); | 557 | isr = in_be32(&priv->msg_regs->isr); |
528 | 558 | ||
529 | if (isr & RIO_MSG_ISR_TE) { | 559 | if (isr & RIO_MSG_ISR_TE) { |
530 | pr_info("RIO: inbound message reception error\n"); | 560 | pr_info("RIO: inbound message reception error\n"); |
531 | out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE); | 561 | out_be32((void *)&priv->msg_regs->isr, RIO_MSG_ISR_TE); |
532 | goto out; | 562 | goto out; |
533 | } | 563 | } |
534 | 564 | ||
@@ -540,10 +570,10 @@ fsl_rio_rx_handler(int irq, void *dev_instance) | |||
540 | * make the callback with an unknown/invalid mailbox number | 570 | * make the callback with an unknown/invalid mailbox number |
541 | * argument. | 571 | * argument. |
542 | */ | 572 | */ |
543 | port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1); | 573 | port->inb_msg[0].mcback(port, priv->msg_rx_ring.dev_id, -1, -1); |
544 | 574 | ||
545 | /* Ack the queueing interrupt */ | 575 | /* Ack the queueing interrupt */ |
546 | out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI); | 576 | out_be32(&priv->msg_regs->isr, RIO_MSG_ISR_DIQI); |
547 | } | 577 | } |
548 | 578 | ||
549 | out: | 579 | out: |
@@ -564,6 +594,7 @@ fsl_rio_rx_handler(int irq, void *dev_instance) | |||
564 | int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) | 594 | int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) |
565 | { | 595 | { |
566 | int i, rc = 0; | 596 | int i, rc = 0; |
597 | struct rio_priv *priv = mport->priv; | ||
567 | 598 | ||
568 | if ((entries < RIO_MIN_RX_RING_SIZE) || | 599 | if ((entries < RIO_MIN_RX_RING_SIZE) || |
569 | (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) { | 600 | (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) { |
@@ -572,36 +603,35 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri | |||
572 | } | 603 | } |
573 | 604 | ||
574 | /* Initialize client buffer ring */ | 605 | /* Initialize client buffer ring */ |
575 | msg_rx_ring.dev_id = dev_id; | 606 | priv->msg_rx_ring.dev_id = dev_id; |
576 | msg_rx_ring.size = entries; | 607 | priv->msg_rx_ring.size = entries; |
577 | msg_rx_ring.rx_slot = 0; | 608 | priv->msg_rx_ring.rx_slot = 0; |
578 | for (i = 0; i < msg_rx_ring.size; i++) | 609 | for (i = 0; i < priv->msg_rx_ring.size; i++) |
579 | msg_rx_ring.virt_buffer[i] = NULL; | 610 | priv->msg_rx_ring.virt_buffer[i] = NULL; |
580 | 611 | ||
581 | /* Initialize inbound message ring */ | 612 | /* Initialize inbound message ring */ |
582 | if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL, | 613 | priv->msg_rx_ring.virt = dma_alloc_coherent(NULL, |
583 | msg_rx_ring.size * | 614 | priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE, |
584 | RIO_MAX_MSG_SIZE, | 615 | &priv->msg_rx_ring.phys, GFP_KERNEL); |
585 | &msg_rx_ring.phys, | 616 | if (!priv->msg_rx_ring.virt) { |
586 | GFP_KERNEL))) { | ||
587 | rc = -ENOMEM; | 617 | rc = -ENOMEM; |
588 | goto out; | 618 | goto out; |
589 | } | 619 | } |
590 | 620 | ||
591 | /* Point dequeue/enqueue pointers at first entry in ring */ | 621 | /* Point dequeue/enqueue pointers at first entry in ring */ |
592 | out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys); | 622 | out_be32(&priv->msg_regs->ifqdpar, (u32) priv->msg_rx_ring.phys); |
593 | out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys); | 623 | out_be32(&priv->msg_regs->ifqepar, (u32) priv->msg_rx_ring.phys); |
594 | 624 | ||
595 | /* Clear interrupt status */ | 625 | /* Clear interrupt status */ |
596 | out_be32((void *)&msg_regs->isr, 0x00000091); | 626 | out_be32(&priv->msg_regs->isr, 0x00000091); |
597 | 627 | ||
598 | /* Hook up inbound message handler */ | 628 | /* Hook up inbound message handler */ |
599 | if ((rc = | 629 | rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0, |
600 | request_irq(MPC85xx_IRQ_RIO_RX, fsl_rio_rx_handler, 0, | 630 | "msg_rx", (void *)mport); |
601 | "msg_rx", (void *)mport)) < 0) { | 631 | if (rc < 0) { |
602 | dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, | 632 | dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, |
603 | msg_tx_ring.virt_buffer[i], | 633 | priv->msg_tx_ring.virt_buffer[i], |
604 | msg_tx_ring.phys_buffer[i]); | 634 | priv->msg_tx_ring.phys_buffer[i]); |
605 | goto out; | 635 | goto out; |
606 | } | 636 | } |
607 | 637 | ||
@@ -612,15 +642,13 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri | |||
612 | * Unmask all interrupt sources | 642 | * Unmask all interrupt sources |
613 | * Disable | 643 | * Disable |
614 | */ | 644 | */ |
615 | out_be32((void *)&msg_regs->imr, 0x001b0060); | 645 | out_be32(&priv->msg_regs->imr, 0x001b0060); |
616 | 646 | ||
617 | /* Set number of queue entries */ | 647 | /* Set number of queue entries */ |
618 | out_be32((void *)&msg_regs->imr, | 648 | setbits32(&priv->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12); |
619 | in_be32((void *)&msg_regs->imr) | | ||
620 | ((get_bitmask_order(entries) - 2) << 12)); | ||
621 | 649 | ||
622 | /* Now enable the unit */ | 650 | /* Now enable the unit */ |
623 | out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1); | 651 | setbits32(&priv->msg_regs->imr, 0x1); |
624 | 652 | ||
625 | out: | 653 | out: |
626 | return rc; | 654 | return rc; |
@@ -636,15 +664,16 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri | |||
636 | */ | 664 | */ |
637 | void rio_close_inb_mbox(struct rio_mport *mport, int mbox) | 665 | void rio_close_inb_mbox(struct rio_mport *mport, int mbox) |
638 | { | 666 | { |
667 | struct rio_priv *priv = mport->priv; | ||
639 | /* Disable inbound message unit */ | 668 | /* Disable inbound message unit */ |
640 | out_be32((void *)&msg_regs->imr, 0); | 669 | out_be32(&priv->msg_regs->imr, 0); |
641 | 670 | ||
642 | /* Free ring */ | 671 | /* Free ring */ |
643 | dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE, | 672 | dma_free_coherent(NULL, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE, |
644 | msg_rx_ring.virt, msg_rx_ring.phys); | 673 | priv->msg_rx_ring.virt, priv->msg_rx_ring.phys); |
645 | 674 | ||
646 | /* Free interrupt */ | 675 | /* Free interrupt */ |
647 | free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport); | 676 | free_irq(IRQ_RIO_RX(mport), (void *)mport); |
648 | } | 677 | } |
649 | 678 | ||
650 | /** | 679 | /** |
@@ -659,21 +688,22 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox) | |||
659 | int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) | 688 | int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) |
660 | { | 689 | { |
661 | int rc = 0; | 690 | int rc = 0; |
691 | struct rio_priv *priv = mport->priv; | ||
662 | 692 | ||
663 | pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n", | 693 | pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n", |
664 | msg_rx_ring.rx_slot); | 694 | priv->msg_rx_ring.rx_slot); |
665 | 695 | ||
666 | if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) { | 696 | if (priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot]) { |
667 | printk(KERN_ERR | 697 | printk(KERN_ERR |
668 | "RIO: error adding inbound buffer %d, buffer exists\n", | 698 | "RIO: error adding inbound buffer %d, buffer exists\n", |
669 | msg_rx_ring.rx_slot); | 699 | priv->msg_rx_ring.rx_slot); |
670 | rc = -EINVAL; | 700 | rc = -EINVAL; |
671 | goto out; | 701 | goto out; |
672 | } | 702 | } |
673 | 703 | ||
674 | msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf; | 704 | priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot] = buf; |
675 | if (++msg_rx_ring.rx_slot == msg_rx_ring.size) | 705 | if (++priv->msg_rx_ring.rx_slot == priv->msg_rx_ring.size) |
676 | msg_rx_ring.rx_slot = 0; | 706 | priv->msg_rx_ring.rx_slot = 0; |
677 | 707 | ||
678 | out: | 708 | out: |
679 | return rc; | 709 | return rc; |
@@ -691,20 +721,21 @@ EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer); | |||
691 | */ | 721 | */ |
692 | void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) | 722 | void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) |
693 | { | 723 | { |
694 | u32 imr; | 724 | struct rio_priv *priv = mport->priv; |
695 | u32 phys_buf, virt_buf; | 725 | u32 phys_buf, virt_buf; |
696 | void *buf = NULL; | 726 | void *buf = NULL; |
697 | int buf_idx; | 727 | int buf_idx; |
698 | 728 | ||
699 | phys_buf = in_be32((void *)&msg_regs->ifqdpar); | 729 | phys_buf = in_be32(&priv->msg_regs->ifqdpar); |
700 | 730 | ||
701 | /* If no more messages, then bail out */ | 731 | /* If no more messages, then bail out */ |
702 | if (phys_buf == in_be32((void *)&msg_regs->ifqepar)) | 732 | if (phys_buf == in_be32(&priv->msg_regs->ifqepar)) |
703 | goto out2; | 733 | goto out2; |
704 | 734 | ||
705 | virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys); | 735 | virt_buf = (u32) priv->msg_rx_ring.virt + (phys_buf |
706 | buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; | 736 | - priv->msg_rx_ring.phys); |
707 | buf = msg_rx_ring.virt_buffer[buf_idx]; | 737 | buf_idx = (phys_buf - priv->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; |
738 | buf = priv->msg_rx_ring.virt_buffer[buf_idx]; | ||
708 | 739 | ||
709 | if (!buf) { | 740 | if (!buf) { |
710 | printk(KERN_ERR | 741 | printk(KERN_ERR |
@@ -716,11 +747,10 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) | |||
716 | memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE); | 747 | memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE); |
717 | 748 | ||
718 | /* Clear the available buffer */ | 749 | /* Clear the available buffer */ |
719 | msg_rx_ring.virt_buffer[buf_idx] = NULL; | 750 | priv->msg_rx_ring.virt_buffer[buf_idx] = NULL; |
720 | 751 | ||
721 | out1: | 752 | out1: |
722 | imr = in_be32((void *)&msg_regs->imr); | 753 | setbits32(&priv->msg_regs->imr, RIO_MSG_IMR_MI); |
723 | out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI); | ||
724 | 754 | ||
725 | out2: | 755 | out2: |
726 | return buf; | 756 | return buf; |
@@ -741,27 +771,27 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
741 | { | 771 | { |
742 | int dsr; | 772 | int dsr; |
743 | struct rio_mport *port = (struct rio_mport *)dev_instance; | 773 | struct rio_mport *port = (struct rio_mport *)dev_instance; |
774 | struct rio_priv *priv = port->priv; | ||
744 | 775 | ||
745 | dsr = in_be32((void *)&msg_regs->dsr); | 776 | dsr = in_be32(&priv->msg_regs->dsr); |
746 | 777 | ||
747 | if (dsr & DOORBELL_DSR_TE) { | 778 | if (dsr & DOORBELL_DSR_TE) { |
748 | pr_info("RIO: doorbell reception error\n"); | 779 | pr_info("RIO: doorbell reception error\n"); |
749 | out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE); | 780 | out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_TE); |
750 | goto out; | 781 | goto out; |
751 | } | 782 | } |
752 | 783 | ||
753 | if (dsr & DOORBELL_DSR_QFI) { | 784 | if (dsr & DOORBELL_DSR_QFI) { |
754 | pr_info("RIO: doorbell queue full\n"); | 785 | pr_info("RIO: doorbell queue full\n"); |
755 | out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI); | 786 | out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI); |
756 | goto out; | 787 | goto out; |
757 | } | 788 | } |
758 | 789 | ||
759 | /* XXX Need to check/dispatch until queue empty */ | 790 | /* XXX Need to check/dispatch until queue empty */ |
760 | if (dsr & DOORBELL_DSR_DIQI) { | 791 | if (dsr & DOORBELL_DSR_DIQI) { |
761 | u32 dmsg = | 792 | u32 dmsg = |
762 | (u32) dbell_ring.virt + | 793 | (u32) priv->dbell_ring.virt + |
763 | (in_be32((void *)&msg_regs->dqdpar) & 0xfff); | 794 | (in_be32(&priv->msg_regs->dqdpar) & 0xfff); |
764 | u32 dmr; | ||
765 | struct rio_dbell *dbell; | 795 | struct rio_dbell *dbell; |
766 | int found = 0; | 796 | int found = 0; |
767 | 797 | ||
@@ -784,9 +814,8 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
784 | ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n", | 814 | ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n", |
785 | DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); | 815 | DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); |
786 | } | 816 | } |
787 | dmr = in_be32((void *)&msg_regs->dmr); | 817 | setbits32(&priv->msg_regs->dmr, DOORBELL_DMR_DI); |
788 | out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI); | 818 | out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_DIQI); |
789 | out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI); | ||
790 | } | 819 | } |
791 | 820 | ||
792 | out: | 821 | out: |
@@ -803,12 +832,13 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
803 | */ | 832 | */ |
804 | static int fsl_rio_doorbell_init(struct rio_mport *mport) | 833 | static int fsl_rio_doorbell_init(struct rio_mport *mport) |
805 | { | 834 | { |
835 | struct rio_priv *priv = mport->priv; | ||
806 | int rc = 0; | 836 | int rc = 0; |
807 | 837 | ||
808 | /* Map outbound doorbell window immediately after maintenance window */ | 838 | /* Map outbound doorbell window immediately after maintenance window */ |
809 | if (!(dbell_win = | 839 | priv->dbell_win = ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE, |
810 | (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE, | 840 | RIO_DBELL_WIN_SIZE); |
811 | RIO_DBELL_WIN_SIZE))) { | 841 | if (!priv->dbell_win) { |
812 | printk(KERN_ERR | 842 | printk(KERN_ERR |
813 | "RIO: unable to map outbound doorbell window\n"); | 843 | "RIO: unable to map outbound doorbell window\n"); |
814 | rc = -ENOMEM; | 844 | rc = -ENOMEM; |
@@ -816,37 +846,36 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport) | |||
816 | } | 846 | } |
817 | 847 | ||
818 | /* Initialize inbound doorbells */ | 848 | /* Initialize inbound doorbells */ |
819 | if (!(dbell_ring.virt = dma_alloc_coherent(NULL, | 849 | priv->dbell_ring.virt = dma_alloc_coherent(NULL, 512 * |
820 | 512 * DOORBELL_MESSAGE_SIZE, | 850 | DOORBELL_MESSAGE_SIZE, &priv->dbell_ring.phys, GFP_KERNEL); |
821 | &dbell_ring.phys, | 851 | if (!priv->dbell_ring.virt) { |
822 | GFP_KERNEL))) { | ||
823 | printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); | 852 | printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); |
824 | rc = -ENOMEM; | 853 | rc = -ENOMEM; |
825 | iounmap((void *)dbell_win); | 854 | iounmap(priv->dbell_win); |
826 | goto out; | 855 | goto out; |
827 | } | 856 | } |
828 | 857 | ||
829 | /* Point dequeue/enqueue pointers at first entry in ring */ | 858 | /* Point dequeue/enqueue pointers at first entry in ring */ |
830 | out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys); | 859 | out_be32(&priv->msg_regs->dqdpar, (u32) priv->dbell_ring.phys); |
831 | out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys); | 860 | out_be32(&priv->msg_regs->dqepar, (u32) priv->dbell_ring.phys); |
832 | 861 | ||
833 | /* Clear interrupt status */ | 862 | /* Clear interrupt status */ |
834 | out_be32((void *)&msg_regs->dsr, 0x00000091); | 863 | out_be32(&priv->msg_regs->dsr, 0x00000091); |
835 | 864 | ||
836 | /* Hook up doorbell handler */ | 865 | /* Hook up doorbell handler */ |
837 | if ((rc = | 866 | rc = request_irq(IRQ_RIO_BELL(mport), fsl_rio_dbell_handler, 0, |
838 | request_irq(MPC85xx_IRQ_RIO_BELL, fsl_rio_dbell_handler, 0, | 867 | "dbell_rx", (void *)mport); |
839 | "dbell_rx", (void *)mport) < 0)) { | 868 | if (rc < 0) { |
840 | iounmap((void *)dbell_win); | 869 | iounmap(priv->dbell_win); |
841 | dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE, | 870 | dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE, |
842 | dbell_ring.virt, dbell_ring.phys); | 871 | priv->dbell_ring.virt, priv->dbell_ring.phys); |
843 | printk(KERN_ERR | 872 | printk(KERN_ERR |
844 | "MPC85xx RIO: unable to request inbound doorbell irq"); | 873 | "MPC85xx RIO: unable to request inbound doorbell irq"); |
845 | goto out; | 874 | goto out; |
846 | } | 875 | } |
847 | 876 | ||
848 | /* Configure doorbells for snooping, 512 entries, and enable */ | 877 | /* Configure doorbells for snooping, 512 entries, and enable */ |
849 | out_be32((void *)&msg_regs->dmr, 0x00108161); | 878 | out_be32(&priv->msg_regs->dmr, 0x00108161); |
850 | 879 | ||
851 | out: | 880 | out: |
852 | return rc; | 881 | return rc; |
@@ -887,6 +916,8 @@ void fsl_rio_setup(int law_start, int law_size) | |||
887 | { | 916 | { |
888 | struct rio_ops *ops; | 917 | struct rio_ops *ops; |
889 | struct rio_mport *port; | 918 | struct rio_mport *port; |
919 | struct rio_priv *priv = NULL; | ||
920 | int rc; | ||
890 | 921 | ||
891 | ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); | 922 | ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); |
892 | ops->lcread = fsl_local_config_read; | 923 | ops->lcread = fsl_local_config_read; |
@@ -895,9 +926,17 @@ void fsl_rio_setup(int law_start, int law_size) | |||
895 | ops->cwrite = fsl_rio_config_write; | 926 | ops->cwrite = fsl_rio_config_write; |
896 | ops->dsend = fsl_rio_doorbell_send; | 927 | ops->dsend = fsl_rio_doorbell_send; |
897 | 928 | ||
898 | port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL); | 929 | port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); |
899 | port->id = 0; | 930 | port->id = 0; |
900 | port->index = 0; | 931 | port->index = 0; |
932 | |||
933 | priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL); | ||
934 | if (!priv) { | ||
935 | printk(KERN_ERR "Can't alloc memory for 'priv'\n"); | ||
936 | rc = -ENOMEM; | ||
937 | goto err; | ||
938 | } | ||
939 | |||
901 | INIT_LIST_HEAD(&port->dbells); | 940 | INIT_LIST_HEAD(&port->dbells); |
902 | port->iores.start = law_start; | 941 | port->iores.start = law_start; |
903 | port->iores.end = law_start + law_size; | 942 | port->iores.end = law_start + law_size; |
@@ -911,22 +950,32 @@ void fsl_rio_setup(int law_start, int law_size) | |||
911 | port->ops = ops; | 950 | port->ops = ops; |
912 | port->host_deviceid = fsl_rio_get_hdid(port->id); | 951 | port->host_deviceid = fsl_rio_get_hdid(port->id); |
913 | 952 | ||
953 | port->priv = priv; | ||
914 | rio_register_mport(port); | 954 | rio_register_mport(port); |
915 | 955 | ||
916 | regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000); | 956 | priv->regs_win = ioremap(RIO_REGS_BASE, 0x20000); |
917 | atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET); | 957 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win |
918 | maint_atmu_regs = atmu_regs + 1; | 958 | + RIO_ATMU_REGS_OFFSET); |
919 | dbell_atmu_regs = atmu_regs + 2; | 959 | priv->maint_atmu_regs = priv->atmu_regs + 1; |
920 | msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET); | 960 | priv->dbell_atmu_regs = priv->atmu_regs + 2; |
961 | priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win | ||
962 | + RIO_MSG_REGS_OFFSET); | ||
921 | 963 | ||
922 | /* Configure maintenance transaction window */ | 964 | /* Configure maintenance transaction window */ |
923 | out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000); | 965 | out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000); |
924 | out_be32((void *)&maint_atmu_regs->rowar, 0x80077015); | 966 | out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); |
925 | 967 | ||
926 | maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE); | 968 | priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE); |
927 | 969 | ||
928 | /* Configure outbound doorbell window */ | 970 | /* Configure outbound doorbell window */ |
929 | out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400); | 971 | out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400); |
930 | out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b); | 972 | out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b); |
931 | fsl_rio_doorbell_init(port); | 973 | fsl_rio_doorbell_init(port); |
974 | |||
975 | return; | ||
976 | err: | ||
977 | if (priv) | ||
978 | iounmap(priv->regs_win); | ||
979 | kfree(priv); | ||
980 | kfree(port); | ||
932 | } | 981 | } |