aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2007-02-13 20:37:28 -0500
committerPaul Mackerras <paulus@samba.org>2007-02-15 22:00:19 -0500
commit75c86e7422751c5be3caaf448d802839ec685725 (patch)
tree9372526aa0722b9d1bac8341025873cb9e545999
parent724339d76d9407cd1a8ad32a9c1fdf64840cc51b (diff)
[POWERPC] PS3: Vuart cleanups
Cleanups for the PS3 vuart driver. - Hide driver private data from external interface with new structure ps3_vuart_port_priv. - Fix masking bug in ps3_vuart_get_interrupt_status(). - Add new helper routine ps3_vuart_clear_rx_bytes() to flush rx buffer. - Add new variable probe_mutex to serialize probe and destroy routines. - Rename some symbols. - Add platform check in ps3_vuart_bus_init(). Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--drivers/ps3/vuart.c347
-rw-r--r--drivers/ps3/vuart.h30
-rw-r--r--include/asm-powerpc/ps3.h22
3 files changed, 247 insertions, 152 deletions
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index ef8fd4c30875..90b3d1ca5172 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <asm/ps3.h> 24#include <asm/ps3.h>
25 25
26#include <asm/firmware.h>
26#include <asm/lv1call.h> 27#include <asm/lv1call.h>
27#include <asm/bitops.h> 28#include <asm/bitops.h>
28 29
@@ -30,7 +31,7 @@
30 31
31MODULE_AUTHOR("Sony Corporation"); 32MODULE_AUTHOR("Sony Corporation");
32MODULE_LICENSE("GPL v2"); 33MODULE_LICENSE("GPL v2");
33MODULE_DESCRIPTION("ps3 vuart"); 34MODULE_DESCRIPTION("PS3 vuart");
34 35
35/** 36/**
36 * vuart - An inter-partition data link service. 37 * vuart - An inter-partition data link service.
@@ -157,7 +158,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
157 unsigned long size; 158 unsigned long size;
158 unsigned long val; 159 unsigned long val;
159 160
160 result = lv1_get_virtual_uart_param(dev->port_number, 161 result = lv1_get_virtual_uart_param(dev->priv->port_number,
161 PARAM_TX_TRIGGER, &trig->tx); 162 PARAM_TX_TRIGGER, &trig->tx);
162 163
163 if (result) { 164 if (result) {
@@ -166,7 +167,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
166 return result; 167 return result;
167 } 168 }
168 169
169 result = lv1_get_virtual_uart_param(dev->port_number, 170 result = lv1_get_virtual_uart_param(dev->priv->port_number,
170 PARAM_RX_BUF_SIZE, &size); 171 PARAM_RX_BUF_SIZE, &size);
171 172
172 if (result) { 173 if (result) {
@@ -175,7 +176,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
175 return result; 176 return result;
176 } 177 }
177 178
178 result = lv1_get_virtual_uart_param(dev->port_number, 179 result = lv1_get_virtual_uart_param(dev->priv->port_number,
179 PARAM_RX_TRIGGER, &val); 180 PARAM_RX_TRIGGER, &val);
180 181
181 if (result) { 182 if (result) {
@@ -198,7 +199,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
198 int result; 199 int result;
199 unsigned long size; 200 unsigned long size;
200 201
201 result = lv1_set_virtual_uart_param(dev->port_number, 202 result = lv1_set_virtual_uart_param(dev->priv->port_number,
202 PARAM_TX_TRIGGER, tx); 203 PARAM_TX_TRIGGER, tx);
203 204
204 if (result) { 205 if (result) {
@@ -207,7 +208,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
207 return result; 208 return result;
208 } 209 }
209 210
210 result = lv1_get_virtual_uart_param(dev->port_number, 211 result = lv1_get_virtual_uart_param(dev->priv->port_number,
211 PARAM_RX_BUF_SIZE, &size); 212 PARAM_RX_BUF_SIZE, &size);
212 213
213 if (result) { 214 if (result) {
@@ -216,7 +217,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
216 return result; 217 return result;
217 } 218 }
218 219
219 result = lv1_set_virtual_uart_param(dev->port_number, 220 result = lv1_set_virtual_uart_param(dev->priv->port_number,
220 PARAM_RX_TRIGGER, size - rx); 221 PARAM_RX_TRIGGER, size - rx);
221 222
222 if (result) { 223 if (result) {
@@ -232,9 +233,9 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
232} 233}
233 234
234static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev, 235static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
235 unsigned long *bytes_waiting) 236 u64 *bytes_waiting)
236{ 237{
237 int result = lv1_get_virtual_uart_param(dev->port_number, 238 int result = lv1_get_virtual_uart_param(dev->priv->port_number,
238 PARAM_RX_BYTES, bytes_waiting); 239 PARAM_RX_BYTES, bytes_waiting);
239 240
240 if (result) 241 if (result)
@@ -253,10 +254,10 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
253 254
254 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask); 255 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
255 256
256 dev->interrupt_mask = mask; 257 dev->priv->interrupt_mask = mask;
257 258
258 result = lv1_set_virtual_uart_param(dev->port_number, 259 result = lv1_set_virtual_uart_param(dev->priv->port_number,
259 PARAM_INTERRUPT_MASK, dev->interrupt_mask); 260 PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask);
260 261
261 if (result) 262 if (result)
262 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n", 263 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
@@ -265,62 +266,64 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
265 return result; 266 return result;
266} 267}
267 268
268static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device *dev, 269static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev,
269 unsigned long *status) 270 unsigned long *status)
270{ 271{
271 int result = lv1_get_virtual_uart_param(dev->port_number, 272 u64 tmp;
272 PARAM_INTERRUPT_STATUS, status); 273 int result = lv1_get_virtual_uart_param(dev->priv->port_number,
274 PARAM_INTERRUPT_STATUS, &tmp);
273 275
274 if (result) 276 if (result)
275 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n", 277 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
276 __func__, __LINE__, ps3_result(result)); 278 __func__, __LINE__, ps3_result(result));
277 279
280 *status = tmp & dev->priv->interrupt_mask;
281
278 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", 282 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
279 __func__, __LINE__, dev->interrupt_mask, *status, 283 __func__, __LINE__, dev->priv->interrupt_mask, tmp, *status);
280 dev->interrupt_mask & *status);
281 284
282 return result; 285 return result;
283} 286}
284 287
285int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev) 288int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev)
286{ 289{
287 return (dev->interrupt_mask & INTERRUPT_MASK_TX) ? 0 290 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
288 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 291 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
289 | INTERRUPT_MASK_TX); 292 | INTERRUPT_MASK_TX);
290} 293}
291 294
292int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev) 295int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev)
293{ 296{
294 return (dev->interrupt_mask & INTERRUPT_MASK_RX) ? 0 297 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
295 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 298 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
296 | INTERRUPT_MASK_RX); 299 | INTERRUPT_MASK_RX);
297} 300}
298 301
299int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 302int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
300{ 303{
301 return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 304 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
302 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 305 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
303 | INTERRUPT_MASK_DISCONNECT); 306 | INTERRUPT_MASK_DISCONNECT);
304} 307}
305 308
306int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev) 309int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev)
307{ 310{
308 return (dev->interrupt_mask & INTERRUPT_MASK_TX) 311 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX)
309 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 312 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
310 & ~INTERRUPT_MASK_TX) : 0; 313 & ~INTERRUPT_MASK_TX) : 0;
311} 314}
312 315
313int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev) 316int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev)
314{ 317{
315 return (dev->interrupt_mask & INTERRUPT_MASK_RX) 318 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX)
316 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 319 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
317 & ~INTERRUPT_MASK_RX) : 0; 320 & ~INTERRUPT_MASK_RX) : 0;
318} 321}
319 322
320int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 323int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
321{ 324{
322 return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) 325 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
323 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 326 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
324 & ~INTERRUPT_MASK_DISCONNECT) : 0; 327 & ~INTERRUPT_MASK_DISCONNECT) : 0;
325} 328}
326 329
@@ -335,9 +338,7 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
335{ 338{
336 int result; 339 int result;
337 340
338 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 341 result = lv1_write_virtual_uart(dev->priv->port_number,
339
340 result = lv1_write_virtual_uart(dev->port_number,
341 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written); 342 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
342 343
343 if (result) { 344 if (result) {
@@ -346,10 +347,10 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
346 return result; 347 return result;
347 } 348 }
348 349
349 dev->stats.bytes_written += *bytes_written; 350 dev->priv->stats.bytes_written += *bytes_written;
350 351
351 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, 352 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
352 __LINE__, *bytes_written, bytes, dev->stats.bytes_written); 353 *bytes_written, bytes, dev->priv->stats.bytes_written);
353 354
354 return result; 355 return result;
355} 356}
@@ -367,7 +368,7 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
367 368
368 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 369 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
369 370
370 result = lv1_read_virtual_uart(dev->port_number, 371 result = lv1_read_virtual_uart(dev->priv->port_number,
371 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read); 372 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
372 373
373 if (result) { 374 if (result) {
@@ -376,15 +377,58 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
376 return result; 377 return result;
377 } 378 }
378 379
379 dev->stats.bytes_read += *bytes_read; 380 dev->priv->stats.bytes_read += *bytes_read;
380 381
381 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, 382 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
382 *bytes_read, bytes, dev->stats.bytes_read); 383 *bytes_read, bytes, dev->priv->stats.bytes_read);
383 384
384 return result; 385 return result;
385} 386}
386 387
387/** 388/**
389 * ps3_vuart_clear_rx_bytes - Discard bytes received.
390 * @bytes: Max byte count to discard, zero = all pending.
391 *
392 * Used to clear pending rx interrupt source. Will not block.
393 */
394
395void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
396 unsigned int bytes)
397{
398 int result;
399 u64 bytes_waiting;
400 void* tmp;
401
402 result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting);
403
404 BUG_ON(result);
405
406 bytes = bytes ? min(bytes, (unsigned int)bytes_waiting) : bytes_waiting;
407
408 dev_dbg(&dev->core, "%s:%d: %u\n", __func__, __LINE__, bytes);
409
410 if (!bytes)
411 return;
412
413 /* Add some extra space for recently arrived data. */
414
415 bytes += 128;
416
417 tmp = kmalloc(bytes, GFP_KERNEL);
418
419 if (!tmp)
420 return;
421
422 ps3_vuart_raw_read(dev, tmp, bytes, &bytes_waiting);
423
424 kfree(tmp);
425
426 /* Don't include these bytes in the stats. */
427
428 dev->priv->stats.bytes_read -= bytes_waiting;
429}
430
431/**
388 * struct list_buffer - An element for a port device fifo buffer list. 432 * struct list_buffer - An element for a port device fifo buffer list.
389 */ 433 */
390 434
@@ -416,14 +460,14 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
416 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 460 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
417 bytes, bytes); 461 bytes, bytes);
418 462
419 spin_lock_irqsave(&dev->tx_list.lock, flags); 463 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
420 464
421 if (list_empty(&dev->tx_list.head)) { 465 if (list_empty(&dev->priv->tx_list.head)) {
422 unsigned long bytes_written; 466 unsigned long bytes_written;
423 467
424 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); 468 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
425 469
426 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 470 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
427 471
428 if (result) { 472 if (result) {
429 dev_dbg(&dev->core, 473 dev_dbg(&dev->core,
@@ -441,7 +485,7 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
441 bytes -= bytes_written; 485 bytes -= bytes_written;
442 buf += bytes_written; 486 buf += bytes_written;
443 } else 487 } else
444 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 488 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
445 489
446 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); 490 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
447 491
@@ -454,10 +498,10 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
454 lb->tail = lb->data + bytes; 498 lb->tail = lb->data + bytes;
455 lb->dbg_number = ++dbg_number; 499 lb->dbg_number = ++dbg_number;
456 500
457 spin_lock_irqsave(&dev->tx_list.lock, flags); 501 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
458 list_add_tail(&lb->link, &dev->tx_list.head); 502 list_add_tail(&lb->link, &dev->priv->tx_list.head);
459 ps3_vuart_enable_interrupt_tx(dev); 503 ps3_vuart_enable_interrupt_tx(dev);
460 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 504 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
461 505
462 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n", 506 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
463 __func__, __LINE__, lb->dbg_number, bytes); 507 __func__, __LINE__, lb->dbg_number, bytes);
@@ -484,44 +528,42 @@ int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
484 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 528 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
485 bytes, bytes); 529 bytes, bytes);
486 530
487 spin_lock_irqsave(&dev->rx_list.lock, flags); 531 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
488 532
489 if (dev->rx_list.bytes_held < bytes) { 533 if (dev->priv->rx_list.bytes_held < bytes) {
490 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 534 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
491 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", 535 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
492 __func__, __LINE__, bytes - dev->rx_list.bytes_held); 536 __func__, __LINE__,
537 bytes - dev->priv->rx_list.bytes_held);
493 return -EAGAIN; 538 return -EAGAIN;
494 } 539 }
495 540
496 list_for_each_entry_safe(lb, n, &dev->rx_list.head, link) { 541 list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) {
497 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes); 542 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
498 543
499 memcpy(buf, lb->head, bytes_read); 544 memcpy(buf, lb->head, bytes_read);
500 buf += bytes_read; 545 buf += bytes_read;
501 bytes -= bytes_read; 546 bytes -= bytes_read;
502 dev->rx_list.bytes_held -= bytes_read; 547 dev->priv->rx_list.bytes_held -= bytes_read;
503 548
504 if (bytes_read < lb->tail - lb->head) { 549 if (bytes_read < lb->tail - lb->head) {
505 lb->head += bytes_read; 550 lb->head += bytes_read;
506 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 551 dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
507 552 "bytes\n", __func__, __LINE__, lb->dbg_number,
508 dev_dbg(&dev->core, 553 bytes_read);
509 "%s:%d: dequeued buf_%lu, %lxh bytes\n", 554 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
510 __func__, __LINE__, lb->dbg_number, bytes_read);
511 return 0; 555 return 0;
512 } 556 }
513 557
514 dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__, 558 dev_dbg(&dev->core, "%s:%d: buf_%lu: free, dequeued %lxh "
515 lb->dbg_number); 559 "bytes\n", __func__, __LINE__, lb->dbg_number,
560 bytes_read);
516 561
517 list_del(&lb->link); 562 list_del(&lb->link);
518 kfree(lb); 563 kfree(lb);
519 } 564 }
520 spin_unlock_irqrestore(&dev->rx_list.lock, flags);
521
522 dev_dbg(&dev->core, "%s:%d: dequeued buf_%lu, %xh bytes\n",
523 __func__, __LINE__, lb->dbg_number, bytes);
524 565
566 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
525 return 0; 567 return 0;
526} 568}
527 569
@@ -542,9 +584,9 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
542 584
543 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 585 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
544 586
545 spin_lock_irqsave(&dev->tx_list.lock, flags); 587 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
546 588
547 list_for_each_entry_safe(lb, n, &dev->tx_list.head, link) { 589 list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) {
548 590
549 unsigned long bytes_written; 591 unsigned long bytes_written;
550 592
@@ -578,7 +620,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
578 620
579 ps3_vuart_disable_interrupt_tx(dev); 621 ps3_vuart_disable_interrupt_tx(dev);
580port_full: 622port_full:
581 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 623 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
582 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n", 624 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
583 __func__, __LINE__, bytes_total); 625 __func__, __LINE__, bytes_total);
584 return result; 626 return result;
@@ -609,7 +651,7 @@ static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
609 651
610 BUG_ON(!bytes); 652 BUG_ON(!bytes);
611 653
612 /* add some extra space for recently arrived data */ 654 /* Add some extra space for recently arrived data. */
613 655
614 bytes += 128; 656 bytes += 128;
615 657
@@ -624,12 +666,12 @@ static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
624 lb->tail = lb->data + bytes; 666 lb->tail = lb->data + bytes;
625 lb->dbg_number = ++dbg_number; 667 lb->dbg_number = ++dbg_number;
626 668
627 spin_lock_irqsave(&dev->rx_list.lock, flags); 669 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
628 list_add_tail(&lb->link, &dev->rx_list.head); 670 list_add_tail(&lb->link, &dev->priv->rx_list.head);
629 dev->rx_list.bytes_held += bytes; 671 dev->priv->rx_list.bytes_held += bytes;
630 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 672 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
631 673
632 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %lxh bytes\n", 674 dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
633 __func__, __LINE__, lb->dbg_number, bytes); 675 __func__, __LINE__, lb->dbg_number, bytes);
634 676
635 return 0; 677 return 0;
@@ -656,7 +698,7 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
656 int result; 698 int result;
657 unsigned long status; 699 unsigned long status;
658 700
659 result = ps3_vuart_get_interrupt_mask(dev, &status); 701 result = ps3_vuart_get_interrupt_status(dev, &status);
660 702
661 if (result) 703 if (result)
662 return result; 704 return result;
@@ -665,21 +707,21 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
665 status); 707 status);
666 708
667 if (status & INTERRUPT_MASK_DISCONNECT) { 709 if (status & INTERRUPT_MASK_DISCONNECT) {
668 dev->stats.disconnect_interrupts++; 710 dev->priv->stats.disconnect_interrupts++;
669 result = ps3_vuart_handle_interrupt_disconnect(dev); 711 result = ps3_vuart_handle_interrupt_disconnect(dev);
670 if (result) 712 if (result)
671 ps3_vuart_disable_interrupt_disconnect(dev); 713 ps3_vuart_disable_interrupt_disconnect(dev);
672 } 714 }
673 715
674 if (status & INTERRUPT_MASK_TX) { 716 if (status & INTERRUPT_MASK_TX) {
675 dev->stats.tx_interrupts++; 717 dev->priv->stats.tx_interrupts++;
676 result = ps3_vuart_handle_interrupt_tx(dev); 718 result = ps3_vuart_handle_interrupt_tx(dev);
677 if (result) 719 if (result)
678 ps3_vuart_disable_interrupt_tx(dev); 720 ps3_vuart_disable_interrupt_tx(dev);
679 } 721 }
680 722
681 if (status & INTERRUPT_MASK_RX) { 723 if (status & INTERRUPT_MASK_RX) {
682 dev->stats.rx_interrupts++; 724 dev->priv->stats.rx_interrupts++;
683 result = ps3_vuart_handle_interrupt_rx(dev); 725 result = ps3_vuart_handle_interrupt_rx(dev);
684 if (result) 726 if (result)
685 ps3_vuart_disable_interrupt_rx(dev); 727 ps3_vuart_disable_interrupt_rx(dev);
@@ -688,12 +730,13 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
688 return 0; 730 return 0;
689} 731}
690 732
691struct vuart_private { 733struct vuart_bus_priv {
692 unsigned int in_use; 734 const struct ports_bmp bmp;
693 unsigned int virq; 735 unsigned int virq;
736 struct semaphore probe_mutex;
737 int use_count;
694 struct ps3_vuart_port_device *devices[PORT_COUNT]; 738 struct ps3_vuart_port_device *devices[PORT_COUNT];
695 const struct ports_bmp bmp; 739} static vuart_bus_priv;
696};
697 740
698/** 741/**
699 * ps3_vuart_irq_handler - first stage interrupt handler 742 * ps3_vuart_irq_handler - first stage interrupt handler
@@ -705,25 +748,25 @@ struct vuart_private {
705 748
706static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private) 749static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
707{ 750{
708 struct vuart_private *private; 751 struct vuart_bus_priv *bus_priv;
709 752
710 BUG_ON(!_private); 753 BUG_ON(!_private);
711 private = (struct vuart_private *)_private; 754 bus_priv = (struct vuart_bus_priv *)_private;
712 755
713 while (1) { 756 while (1) {
714 unsigned int port; 757 unsigned int port;
715 758
716 dump_ports_bmp(&private->bmp); 759 dump_ports_bmp(&bus_priv->bmp);
717 760
718 port = (BITS_PER_LONG - 1) - __ilog2(private->bmp.status); 761 port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status);
719 762
720 if (port == BITS_PER_LONG) 763 if (port == BITS_PER_LONG)
721 break; 764 break;
722 765
723 BUG_ON(port >= PORT_COUNT); 766 BUG_ON(port >= PORT_COUNT);
724 BUG_ON(!private->devices[port]); 767 BUG_ON(!bus_priv->devices[port]);
725 768
726 ps3_vuart_handle_port_interrupt(private->devices[port]); 769 ps3_vuart_handle_port_interrupt(bus_priv->devices[port]);
727 } 770 }
728 771
729 return IRQ_HANDLED; 772 return IRQ_HANDLED;
@@ -744,12 +787,10 @@ static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv)
744 return result; 787 return result;
745} 788}
746 789
747static struct vuart_private vuart_private;
748
749static int ps3_vuart_probe(struct device *_dev) 790static int ps3_vuart_probe(struct device *_dev)
750{ 791{
751 int result; 792 int result;
752 unsigned long tmp; 793 unsigned int port_number;
753 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 794 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
754 struct ps3_vuart_port_driver *drv = 795 struct ps3_vuart_port_driver *drv =
755 to_ps3_vuart_port_driver(_dev->driver); 796 to_ps3_vuart_port_driver(_dev->driver);
@@ -758,7 +799,12 @@ static int ps3_vuart_probe(struct device *_dev)
758 799
759 BUG_ON(!drv); 800 BUG_ON(!drv);
760 801
761 result = ps3_vuart_match_id_to_port(dev->match_id, &dev->port_number); 802 down(&vuart_bus_priv.probe_mutex);
803
804 /* Setup vuart_bus_priv.devices[]. */
805
806 result = ps3_vuart_match_id_to_port(dev->match_id,
807 &port_number);
762 808
763 if (result) { 809 if (result) {
764 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n", 810 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n",
@@ -767,24 +813,36 @@ static int ps3_vuart_probe(struct device *_dev)
767 goto fail_match; 813 goto fail_match;
768 } 814 }
769 815
770 if (vuart_private.devices[dev->port_number]) { 816 if (vuart_bus_priv.devices[port_number]) {
771 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__, 817 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
772 __LINE__, dev->port_number); 818 __LINE__, port_number);
773 result = -EBUSY; 819 result = -EBUSY;
774 goto fail_match; 820 goto fail_match;
775 } 821 }
776 822
777 vuart_private.devices[dev->port_number] = dev; 823 vuart_bus_priv.devices[port_number] = dev;
824
825 /* Setup dev->priv. */
826
827 dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL);
828
829 if (!dev->priv) {
830 result = -ENOMEM;
831 goto fail_alloc;
832 }
833
834 dev->priv->port_number = port_number;
778 835
779 INIT_LIST_HEAD(&dev->tx_list.head); 836 INIT_LIST_HEAD(&dev->priv->tx_list.head);
780 spin_lock_init(&dev->tx_list.lock); 837 spin_lock_init(&dev->priv->tx_list.lock);
781 INIT_LIST_HEAD(&dev->rx_list.head); 838
782 spin_lock_init(&dev->rx_list.lock); 839 INIT_LIST_HEAD(&dev->priv->rx_list.head);
840 spin_lock_init(&dev->priv->rx_list.lock);
841
842 if (++vuart_bus_priv.use_count == 1) {
783 843
784 vuart_private.in_use++;
785 if (vuart_private.in_use == 1) {
786 result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY, 844 result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
787 (void*)&vuart_private.bmp.status, &vuart_private.virq); 845 (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
788 846
789 if (result) { 847 if (result) {
790 dev_dbg(&dev->core, 848 dev_dbg(&dev->core,
@@ -794,8 +852,8 @@ static int ps3_vuart_probe(struct device *_dev)
794 goto fail_alloc_irq; 852 goto fail_alloc_irq;
795 } 853 }
796 854
797 result = request_irq(vuart_private.virq, ps3_vuart_irq_handler, 855 result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
798 IRQF_DISABLED, "vuart", &vuart_private); 856 IRQF_DISABLED, "vuart", &vuart_bus_priv);
799 857
800 if (result) { 858 if (result) {
801 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n", 859 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
@@ -804,10 +862,11 @@ static int ps3_vuart_probe(struct device *_dev)
804 } 862 }
805 } 863 }
806 864
807 ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
808
809 /* clear stale pending interrupts */ 865 /* clear stale pending interrupts */
810 ps3_vuart_get_interrupt_mask(dev, &tmp); 866
867 ps3_vuart_clear_rx_bytes(dev, 0);
868
869 ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
811 870
812 ps3_vuart_set_triggers(dev, 1, 1); 871 ps3_vuart_set_triggers(dev, 1, 1);
813 872
@@ -822,20 +881,27 @@ static int ps3_vuart_probe(struct device *_dev)
822 if (result) { 881 if (result) {
823 dev_dbg(&dev->core, "%s:%d: drv->probe failed\n", 882 dev_dbg(&dev->core, "%s:%d: drv->probe failed\n",
824 __func__, __LINE__); 883 __func__, __LINE__);
884 down(&vuart_bus_priv.probe_mutex);
825 goto fail_probe; 885 goto fail_probe;
826 } 886 }
827 887
888 up(&vuart_bus_priv.probe_mutex);
889
828 return result; 890 return result;
829 891
830fail_probe: 892fail_probe:
893 ps3_vuart_set_interrupt_mask(dev, 0);
831fail_request_irq: 894fail_request_irq:
832 vuart_private.in_use--; 895 ps3_free_vuart_irq(vuart_bus_priv.virq);
833 if (!vuart_private.in_use) { 896 vuart_bus_priv.virq = NO_IRQ;
834 ps3_free_vuart_irq(vuart_private.virq);
835 vuart_private.virq = NO_IRQ;
836 }
837fail_alloc_irq: 897fail_alloc_irq:
898 --vuart_bus_priv.use_count;
899 kfree(dev->priv);
900 dev->priv = NULL;
901fail_alloc:
902 vuart_bus_priv.devices[port_number] = 0;
838fail_match: 903fail_match:
904 up(&vuart_bus_priv.probe_mutex);
839 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); 905 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
840 return result; 906 return result;
841} 907}
@@ -846,10 +912,12 @@ static int ps3_vuart_remove(struct device *_dev)
846 struct ps3_vuart_port_driver *drv = 912 struct ps3_vuart_port_driver *drv =
847 to_ps3_vuart_port_driver(_dev->driver); 913 to_ps3_vuart_port_driver(_dev->driver);
848 914
915 down(&vuart_bus_priv.probe_mutex);
916
849 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, 917 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
850 dev->core.bus_id); 918 dev->core.bus_id);
851 919
852 BUG_ON(vuart_private.in_use < 1); 920 BUG_ON(vuart_bus_priv.use_count < 1);
853 921
854 if (drv->remove) 922 if (drv->remove)
855 drv->remove(dev); 923 drv->remove(dev);
@@ -857,13 +925,19 @@ static int ps3_vuart_remove(struct device *_dev)
857 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__, 925 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
858 __LINE__, dev->core.bus_id); 926 __LINE__, dev->core.bus_id);
859 927
860 vuart_private.in_use--; 928 vuart_bus_priv.devices[dev->priv->port_number] = 0;
861 929
862 if (!vuart_private.in_use) { 930 if (--vuart_bus_priv.use_count == 0) {
863 free_irq(vuart_private.virq, &vuart_private); 931 BUG();
864 ps3_free_vuart_irq(vuart_private.virq); 932 free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
865 vuart_private.virq = NO_IRQ; 933 ps3_free_vuart_irq(vuart_bus_priv.virq);
934 vuart_bus_priv.virq = NO_IRQ;
866 } 935 }
936
937 kfree(dev->priv);
938 dev->priv = NULL;
939
940 up(&vuart_bus_priv.probe_mutex);
867 return 0; 941 return 0;
868} 942}
869 943
@@ -884,12 +958,12 @@ static void ps3_vuart_shutdown(struct device *_dev)
884} 958}
885 959
886/** 960/**
887 * ps3_vuart - The vuart instance. 961 * ps3_vuart_bus - The vuart bus instance.
888 * 962 *
889 * The vuart is managed as a bus that port devices connect to. 963 * The vuart is managed as a bus that port devices connect to.
890 */ 964 */
891 965
892struct bus_type ps3_vuart = { 966struct bus_type ps3_vuart_bus = {
893 .name = "ps3_vuart", 967 .name = "ps3_vuart",
894 .match = ps3_vuart_match, 968 .match = ps3_vuart_match,
895 .probe = ps3_vuart_probe, 969 .probe = ps3_vuart_probe,
@@ -897,24 +971,30 @@ struct bus_type ps3_vuart = {
897 .shutdown = ps3_vuart_shutdown, 971 .shutdown = ps3_vuart_shutdown,
898}; 972};
899 973
900int __init ps3_vuart_init(void) 974int __init ps3_vuart_bus_init(void)
901{ 975{
902 int result; 976 int result;
903 977
904 pr_debug("%s:%d:\n", __func__, __LINE__); 978 pr_debug("%s:%d:\n", __func__, __LINE__);
905 result = bus_register(&ps3_vuart); 979
980 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
981 return 0;
982
983 init_MUTEX(&vuart_bus_priv.probe_mutex);
984 result = bus_register(&ps3_vuart_bus);
906 BUG_ON(result); 985 BUG_ON(result);
986
907 return result; 987 return result;
908} 988}
909 989
910void __exit ps3_vuart_exit(void) 990void __exit ps3_vuart_bus_exit(void)
911{ 991{
912 pr_debug("%s:%d:\n", __func__, __LINE__); 992 pr_debug("%s:%d:\n", __func__, __LINE__);
913 bus_unregister(&ps3_vuart); 993 bus_unregister(&ps3_vuart_bus);
914} 994}
915 995
916core_initcall(ps3_vuart_init); 996core_initcall(ps3_vuart_bus_init);
917module_exit(ps3_vuart_exit); 997module_exit(ps3_vuart_bus_exit);
918 998
919/** 999/**
920 * ps3_vuart_port_release_device - Remove a vuart port device. 1000 * ps3_vuart_port_release_device - Remove a vuart port device.
@@ -922,11 +1002,14 @@ module_exit(ps3_vuart_exit);
922 1002
923static void ps3_vuart_port_release_device(struct device *_dev) 1003static void ps3_vuart_port_release_device(struct device *_dev)
924{ 1004{
925 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
926#if defined(DEBUG) 1005#if defined(DEBUG)
927 memset(dev, 0xad, sizeof(struct ps3_vuart_port_device)); 1006 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
1007
1008 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
1009
1010 BUG_ON(dev->priv && "forgot to free");
1011 memset(&dev->core, 0, sizeof(dev->core));
928#endif 1012#endif
929 kfree(dev);
930} 1013}
931 1014
932/** 1015/**
@@ -935,11 +1018,12 @@ static void ps3_vuart_port_release_device(struct device *_dev)
935 1018
936int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev) 1019int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
937{ 1020{
938 int result;
939 static unsigned int dev_count = 1; 1021 static unsigned int dev_count = 1;
940 1022
1023 BUG_ON(dev->priv && "forgot to free");
1024
941 dev->core.parent = NULL; 1025 dev->core.parent = NULL;
942 dev->core.bus = &ps3_vuart; 1026 dev->core.bus = &ps3_vuart_bus;
943 dev->core.release = ps3_vuart_port_release_device; 1027 dev->core.release = ps3_vuart_port_release_device;
944 1028
945 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", 1029 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x",
@@ -947,9 +1031,7 @@ int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
947 1031
948 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__); 1032 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__);
949 1033
950 result = device_register(&dev->core); 1034 return device_register(&dev->core);
951
952 return result;
953} 1035}
954 1036
955EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register); 1037EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register);
@@ -963,7 +1045,7 @@ int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv)
963 int result; 1045 int result;
964 1046
965 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); 1047 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
966 drv->core.bus = &ps3_vuart; 1048 drv->core.bus = &ps3_vuart_bus;
967 result = driver_register(&drv->core); 1049 result = driver_register(&drv->core);
968 return result; 1050 return result;
969} 1051}
@@ -976,6 +1058,7 @@ EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
976 1058
977void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv) 1059void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
978{ 1060{
1061 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
979 driver_unregister(&drv->core); 1062 driver_unregister(&drv->core);
980} 1063}
981 1064
diff --git a/drivers/ps3/vuart.h b/drivers/ps3/vuart.h
index 2cbf728a3a0b..34b360da9ff9 100644
--- a/drivers/ps3/vuart.h
+++ b/drivers/ps3/vuart.h
@@ -21,6 +21,36 @@
21#if !defined(_PS3_VUART_H) 21#if !defined(_PS3_VUART_H)
22#define _PS3_VUART_H 22#define _PS3_VUART_H
23 23
24#include <asm/ps3.h>
25
26struct ps3_vuart_stats {
27 unsigned long bytes_written;
28 unsigned long bytes_read;
29 unsigned long tx_interrupts;
30 unsigned long rx_interrupts;
31 unsigned long disconnect_interrupts;
32};
33
34/**
35 * struct ps3_vuart_port_priv - private vuart device data.
36 */
37
38struct ps3_vuart_port_priv {
39 unsigned int port_number;
40 u64 interrupt_mask;
41
42 struct {
43 spinlock_t lock;
44 struct list_head head;
45 } tx_list;
46 struct {
47 unsigned long bytes_held;
48 spinlock_t lock;
49 struct list_head head;
50 } rx_list;
51 struct ps3_vuart_stats stats;
52};
53
24/** 54/**
25 * struct ps3_vuart_port_driver - a driver for a device on a vuart port 55 * struct ps3_vuart_port_driver - a driver for a device on a vuart port
26 */ 56 */
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index e5982ad46576..a39d92f9022b 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -355,13 +355,7 @@ extern struct bus_type ps3_system_bus_type;
355 355
356/* vuart routines */ 356/* vuart routines */
357 357
358struct ps3_vuart_stats { 358struct ps3_vuart_port_priv;
359 unsigned long bytes_written;
360 unsigned long bytes_read;
361 unsigned long tx_interrupts;
362 unsigned long rx_interrupts;
363 unsigned long disconnect_interrupts;
364};
365 359
366/** 360/**
367 * struct ps3_vuart_port_device - a device on a vuart port 361 * struct ps3_vuart_port_device - a device on a vuart port
@@ -370,20 +364,8 @@ struct ps3_vuart_stats {
370struct ps3_vuart_port_device { 364struct ps3_vuart_port_device {
371 enum ps3_match_id match_id; 365 enum ps3_match_id match_id;
372 struct device core; 366 struct device core;
367 struct ps3_vuart_port_priv* priv; /* private driver variables */
373 368
374 /* private driver variables */
375 unsigned int port_number;
376 u64 interrupt_mask;
377 struct {
378 spinlock_t lock;
379 struct list_head head;
380 } tx_list;
381 struct {
382 unsigned long bytes_held;
383 spinlock_t lock;
384 struct list_head head;
385 } rx_list;
386 struct ps3_vuart_stats stats;
387}; 369};
388 370
389int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev); 371int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev);