aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ps3/vuart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ps3/vuart.c')
-rw-r--r--drivers/ps3/vuart.c398
1 files changed, 267 insertions, 131 deletions
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index ef8fd4c30875..746298107d6f 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -21,8 +21,10 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
24#include <asm/ps3.h> 25#include <asm/ps3.h>
25 26
27#include <asm/firmware.h>
26#include <asm/lv1call.h> 28#include <asm/lv1call.h>
27#include <asm/bitops.h> 29#include <asm/bitops.h>
28 30
@@ -30,7 +32,7 @@
30 32
31MODULE_AUTHOR("Sony Corporation"); 33MODULE_AUTHOR("Sony Corporation");
32MODULE_LICENSE("GPL v2"); 34MODULE_LICENSE("GPL v2");
33MODULE_DESCRIPTION("ps3 vuart"); 35MODULE_DESCRIPTION("PS3 vuart");
34 36
35/** 37/**
36 * vuart - An inter-partition data link service. 38 * vuart - An inter-partition data link service.
@@ -157,7 +159,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
157 unsigned long size; 159 unsigned long size;
158 unsigned long val; 160 unsigned long val;
159 161
160 result = lv1_get_virtual_uart_param(dev->port_number, 162 result = lv1_get_virtual_uart_param(dev->priv->port_number,
161 PARAM_TX_TRIGGER, &trig->tx); 163 PARAM_TX_TRIGGER, &trig->tx);
162 164
163 if (result) { 165 if (result) {
@@ -166,7 +168,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
166 return result; 168 return result;
167 } 169 }
168 170
169 result = lv1_get_virtual_uart_param(dev->port_number, 171 result = lv1_get_virtual_uart_param(dev->priv->port_number,
170 PARAM_RX_BUF_SIZE, &size); 172 PARAM_RX_BUF_SIZE, &size);
171 173
172 if (result) { 174 if (result) {
@@ -175,7 +177,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
175 return result; 177 return result;
176 } 178 }
177 179
178 result = lv1_get_virtual_uart_param(dev->port_number, 180 result = lv1_get_virtual_uart_param(dev->priv->port_number,
179 PARAM_RX_TRIGGER, &val); 181 PARAM_RX_TRIGGER, &val);
180 182
181 if (result) { 183 if (result) {
@@ -198,7 +200,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
198 int result; 200 int result;
199 unsigned long size; 201 unsigned long size;
200 202
201 result = lv1_set_virtual_uart_param(dev->port_number, 203 result = lv1_set_virtual_uart_param(dev->priv->port_number,
202 PARAM_TX_TRIGGER, tx); 204 PARAM_TX_TRIGGER, tx);
203 205
204 if (result) { 206 if (result) {
@@ -207,7 +209,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
207 return result; 209 return result;
208 } 210 }
209 211
210 result = lv1_get_virtual_uart_param(dev->port_number, 212 result = lv1_get_virtual_uart_param(dev->priv->port_number,
211 PARAM_RX_BUF_SIZE, &size); 213 PARAM_RX_BUF_SIZE, &size);
212 214
213 if (result) { 215 if (result) {
@@ -216,7 +218,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
216 return result; 218 return result;
217 } 219 }
218 220
219 result = lv1_set_virtual_uart_param(dev->port_number, 221 result = lv1_set_virtual_uart_param(dev->priv->port_number,
220 PARAM_RX_TRIGGER, size - rx); 222 PARAM_RX_TRIGGER, size - rx);
221 223
222 if (result) { 224 if (result) {
@@ -232,9 +234,9 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
232} 234}
233 235
234static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev, 236static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
235 unsigned long *bytes_waiting) 237 u64 *bytes_waiting)
236{ 238{
237 int result = lv1_get_virtual_uart_param(dev->port_number, 239 int result = lv1_get_virtual_uart_param(dev->priv->port_number,
238 PARAM_RX_BYTES, bytes_waiting); 240 PARAM_RX_BYTES, bytes_waiting);
239 241
240 if (result) 242 if (result)
@@ -253,10 +255,10 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
253 255
254 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask); 256 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
255 257
256 dev->interrupt_mask = mask; 258 dev->priv->interrupt_mask = mask;
257 259
258 result = lv1_set_virtual_uart_param(dev->port_number, 260 result = lv1_set_virtual_uart_param(dev->priv->port_number,
259 PARAM_INTERRUPT_MASK, dev->interrupt_mask); 261 PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask);
260 262
261 if (result) 263 if (result)
262 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n", 264 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
@@ -265,62 +267,64 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
265 return result; 267 return result;
266} 268}
267 269
268static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device *dev, 270static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev,
269 unsigned long *status) 271 unsigned long *status)
270{ 272{
271 int result = lv1_get_virtual_uart_param(dev->port_number, 273 u64 tmp;
272 PARAM_INTERRUPT_STATUS, status); 274 int result = lv1_get_virtual_uart_param(dev->priv->port_number,
275 PARAM_INTERRUPT_STATUS, &tmp);
273 276
274 if (result) 277 if (result)
275 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n", 278 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
276 __func__, __LINE__, ps3_result(result)); 279 __func__, __LINE__, ps3_result(result));
277 280
281 *status = tmp & dev->priv->interrupt_mask;
282
278 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", 283 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
279 __func__, __LINE__, dev->interrupt_mask, *status, 284 __func__, __LINE__, dev->priv->interrupt_mask, tmp, *status);
280 dev->interrupt_mask & *status);
281 285
282 return result; 286 return result;
283} 287}
284 288
285int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev) 289int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev)
286{ 290{
287 return (dev->interrupt_mask & INTERRUPT_MASK_TX) ? 0 291 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
288 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 292 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
289 | INTERRUPT_MASK_TX); 293 | INTERRUPT_MASK_TX);
290} 294}
291 295
292int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev) 296int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev)
293{ 297{
294 return (dev->interrupt_mask & INTERRUPT_MASK_RX) ? 0 298 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
295 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 299 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
296 | INTERRUPT_MASK_RX); 300 | INTERRUPT_MASK_RX);
297} 301}
298 302
299int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 303int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
300{ 304{
301 return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 305 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
302 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 306 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
303 | INTERRUPT_MASK_DISCONNECT); 307 | INTERRUPT_MASK_DISCONNECT);
304} 308}
305 309
306int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev) 310int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev)
307{ 311{
308 return (dev->interrupt_mask & INTERRUPT_MASK_TX) 312 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX)
309 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 313 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
310 & ~INTERRUPT_MASK_TX) : 0; 314 & ~INTERRUPT_MASK_TX) : 0;
311} 315}
312 316
313int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev) 317int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev)
314{ 318{
315 return (dev->interrupt_mask & INTERRUPT_MASK_RX) 319 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX)
316 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 320 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
317 & ~INTERRUPT_MASK_RX) : 0; 321 & ~INTERRUPT_MASK_RX) : 0;
318} 322}
319 323
320int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 324int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
321{ 325{
322 return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) 326 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
323 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 327 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
324 & ~INTERRUPT_MASK_DISCONNECT) : 0; 328 & ~INTERRUPT_MASK_DISCONNECT) : 0;
325} 329}
326 330
@@ -335,9 +339,7 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
335{ 339{
336 int result; 340 int result;
337 341
338 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 342 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); 343 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
342 344
343 if (result) { 345 if (result) {
@@ -346,10 +348,10 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
346 return result; 348 return result;
347 } 349 }
348 350
349 dev->stats.bytes_written += *bytes_written; 351 dev->priv->stats.bytes_written += *bytes_written;
350 352
351 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, 353 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
352 __LINE__, *bytes_written, bytes, dev->stats.bytes_written); 354 *bytes_written, bytes, dev->priv->stats.bytes_written);
353 355
354 return result; 356 return result;
355} 357}
@@ -367,7 +369,7 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
367 369
368 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 370 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
369 371
370 result = lv1_read_virtual_uart(dev->port_number, 372 result = lv1_read_virtual_uart(dev->priv->port_number,
371 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read); 373 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
372 374
373 if (result) { 375 if (result) {
@@ -376,15 +378,58 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
376 return result; 378 return result;
377 } 379 }
378 380
379 dev->stats.bytes_read += *bytes_read; 381 dev->priv->stats.bytes_read += *bytes_read;
380 382
381 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, 383 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
382 *bytes_read, bytes, dev->stats.bytes_read); 384 *bytes_read, bytes, dev->priv->stats.bytes_read);
383 385
384 return result; 386 return result;
385} 387}
386 388
387/** 389/**
390 * ps3_vuart_clear_rx_bytes - Discard bytes received.
391 * @bytes: Max byte count to discard, zero = all pending.
392 *
393 * Used to clear pending rx interrupt source. Will not block.
394 */
395
396void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
397 unsigned int bytes)
398{
399 int result;
400 u64 bytes_waiting;
401 void* tmp;
402
403 result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting);
404
405 BUG_ON(result);
406
407 bytes = bytes ? min(bytes, (unsigned int)bytes_waiting) : bytes_waiting;
408
409 dev_dbg(&dev->core, "%s:%d: %u\n", __func__, __LINE__, bytes);
410
411 if (!bytes)
412 return;
413
414 /* Add some extra space for recently arrived data. */
415
416 bytes += 128;
417
418 tmp = kmalloc(bytes, GFP_KERNEL);
419
420 if (!tmp)
421 return;
422
423 ps3_vuart_raw_read(dev, tmp, bytes, &bytes_waiting);
424
425 kfree(tmp);
426
427 /* Don't include these bytes in the stats. */
428
429 dev->priv->stats.bytes_read -= bytes_waiting;
430}
431
432/**
388 * struct list_buffer - An element for a port device fifo buffer list. 433 * struct list_buffer - An element for a port device fifo buffer list.
389 */ 434 */
390 435
@@ -416,14 +461,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__, 461 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
417 bytes, bytes); 462 bytes, bytes);
418 463
419 spin_lock_irqsave(&dev->tx_list.lock, flags); 464 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
420 465
421 if (list_empty(&dev->tx_list.head)) { 466 if (list_empty(&dev->priv->tx_list.head)) {
422 unsigned long bytes_written; 467 unsigned long bytes_written;
423 468
424 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); 469 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
425 470
426 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 471 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
427 472
428 if (result) { 473 if (result) {
429 dev_dbg(&dev->core, 474 dev_dbg(&dev->core,
@@ -441,7 +486,7 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
441 bytes -= bytes_written; 486 bytes -= bytes_written;
442 buf += bytes_written; 487 buf += bytes_written;
443 } else 488 } else
444 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 489 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
445 490
446 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); 491 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
447 492
@@ -454,10 +499,10 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
454 lb->tail = lb->data + bytes; 499 lb->tail = lb->data + bytes;
455 lb->dbg_number = ++dbg_number; 500 lb->dbg_number = ++dbg_number;
456 501
457 spin_lock_irqsave(&dev->tx_list.lock, flags); 502 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
458 list_add_tail(&lb->link, &dev->tx_list.head); 503 list_add_tail(&lb->link, &dev->priv->tx_list.head);
459 ps3_vuart_enable_interrupt_tx(dev); 504 ps3_vuart_enable_interrupt_tx(dev);
460 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 505 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
461 506
462 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n", 507 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
463 __func__, __LINE__, lb->dbg_number, bytes); 508 __func__, __LINE__, lb->dbg_number, bytes);
@@ -484,47 +529,83 @@ 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__, 529 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
485 bytes, bytes); 530 bytes, bytes);
486 531
487 spin_lock_irqsave(&dev->rx_list.lock, flags); 532 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
488 533
489 if (dev->rx_list.bytes_held < bytes) { 534 if (dev->priv->rx_list.bytes_held < bytes) {
490 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 535 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
491 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", 536 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
492 __func__, __LINE__, bytes - dev->rx_list.bytes_held); 537 __func__, __LINE__,
538 bytes - dev->priv->rx_list.bytes_held);
493 return -EAGAIN; 539 return -EAGAIN;
494 } 540 }
495 541
496 list_for_each_entry_safe(lb, n, &dev->rx_list.head, link) { 542 list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) {
497 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes); 543 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
498 544
499 memcpy(buf, lb->head, bytes_read); 545 memcpy(buf, lb->head, bytes_read);
500 buf += bytes_read; 546 buf += bytes_read;
501 bytes -= bytes_read; 547 bytes -= bytes_read;
502 dev->rx_list.bytes_held -= bytes_read; 548 dev->priv->rx_list.bytes_held -= bytes_read;
503 549
504 if (bytes_read < lb->tail - lb->head) { 550 if (bytes_read < lb->tail - lb->head) {
505 lb->head += bytes_read; 551 lb->head += bytes_read;
506 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 552 dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
507 553 "bytes\n", __func__, __LINE__, lb->dbg_number,
508 dev_dbg(&dev->core, 554 bytes_read);
509 "%s:%d: dequeued buf_%lu, %lxh bytes\n", 555 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
510 __func__, __LINE__, lb->dbg_number, bytes_read);
511 return 0; 556 return 0;
512 } 557 }
513 558
514 dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__, 559 dev_dbg(&dev->core, "%s:%d: buf_%lu: free, dequeued %lxh "
515 lb->dbg_number); 560 "bytes\n", __func__, __LINE__, lb->dbg_number,
561 bytes_read);
516 562
517 list_del(&lb->link); 563 list_del(&lb->link);
518 kfree(lb); 564 kfree(lb);
519 } 565 }
520 spin_unlock_irqrestore(&dev->rx_list.lock, flags);
521 566
522 dev_dbg(&dev->core, "%s:%d: dequeued buf_%lu, %xh bytes\n", 567 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
523 __func__, __LINE__, lb->dbg_number, bytes); 568 return 0;
569}
570
571int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
572 unsigned int bytes)
573{
574 unsigned long flags;
575
576 if(dev->priv->work.trigger) {
577 dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n",
578 __func__, __LINE__);
579 return -EAGAIN;
580 }
581
582 BUG_ON(!bytes);
583
584 PREPARE_WORK(&dev->priv->work.work, func);
585
586 spin_lock_irqsave(&dev->priv->work.lock, flags);
587 if(dev->priv->rx_list.bytes_held >= bytes) {
588 dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n",
589 __func__, __LINE__, bytes);
590 schedule_work(&dev->priv->work.work);
591 spin_unlock_irqrestore(&dev->priv->work.lock, flags);
592 return 0;
593 }
594
595 dev->priv->work.trigger = bytes;
596 spin_unlock_irqrestore(&dev->priv->work.lock, flags);
597
598 dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__,
599 __LINE__, bytes, bytes);
524 600
525 return 0; 601 return 0;
526} 602}
527 603
604void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev)
605{
606 dev->priv->work.trigger = 0;
607}
608
528/** 609/**
529 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler 610 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
530 * 611 *
@@ -542,9 +623,9 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
542 623
543 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 624 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
544 625
545 spin_lock_irqsave(&dev->tx_list.lock, flags); 626 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
546 627
547 list_for_each_entry_safe(lb, n, &dev->tx_list.head, link) { 628 list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) {
548 629
549 unsigned long bytes_written; 630 unsigned long bytes_written;
550 631
@@ -578,7 +659,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
578 659
579 ps3_vuart_disable_interrupt_tx(dev); 660 ps3_vuart_disable_interrupt_tx(dev);
580port_full: 661port_full:
581 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 662 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
582 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n", 663 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
583 __func__, __LINE__, bytes_total); 664 __func__, __LINE__, bytes_total);
584 return result; 665 return result;
@@ -609,7 +690,7 @@ static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
609 690
610 BUG_ON(!bytes); 691 BUG_ON(!bytes);
611 692
612 /* add some extra space for recently arrived data */ 693 /* Add some extra space for recently arrived data. */
613 694
614 bytes += 128; 695 bytes += 128;
615 696
@@ -624,14 +705,23 @@ static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
624 lb->tail = lb->data + bytes; 705 lb->tail = lb->data + bytes;
625 lb->dbg_number = ++dbg_number; 706 lb->dbg_number = ++dbg_number;
626 707
627 spin_lock_irqsave(&dev->rx_list.lock, flags); 708 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
628 list_add_tail(&lb->link, &dev->rx_list.head); 709 list_add_tail(&lb->link, &dev->priv->rx_list.head);
629 dev->rx_list.bytes_held += bytes; 710 dev->priv->rx_list.bytes_held += bytes;
630 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 711 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
631 712
632 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %lxh bytes\n", 713 dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
633 __func__, __LINE__, lb->dbg_number, bytes); 714 __func__, __LINE__, lb->dbg_number, bytes);
634 715
716 spin_lock_irqsave(&dev->priv->work.lock, flags);
717 if(dev->priv->work.trigger
718 && dev->priv->rx_list.bytes_held >= dev->priv->work.trigger) {
719 dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n",
720 __func__, __LINE__, dev->priv->work.trigger);
721 dev->priv->work.trigger = 0;
722 schedule_work(&dev->priv->work.work);
723 }
724 spin_unlock_irqrestore(&dev->priv->work.lock, flags);
635 return 0; 725 return 0;
636} 726}
637 727
@@ -656,7 +746,7 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
656 int result; 746 int result;
657 unsigned long status; 747 unsigned long status;
658 748
659 result = ps3_vuart_get_interrupt_mask(dev, &status); 749 result = ps3_vuart_get_interrupt_status(dev, &status);
660 750
661 if (result) 751 if (result)
662 return result; 752 return result;
@@ -665,21 +755,21 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
665 status); 755 status);
666 756
667 if (status & INTERRUPT_MASK_DISCONNECT) { 757 if (status & INTERRUPT_MASK_DISCONNECT) {
668 dev->stats.disconnect_interrupts++; 758 dev->priv->stats.disconnect_interrupts++;
669 result = ps3_vuart_handle_interrupt_disconnect(dev); 759 result = ps3_vuart_handle_interrupt_disconnect(dev);
670 if (result) 760 if (result)
671 ps3_vuart_disable_interrupt_disconnect(dev); 761 ps3_vuart_disable_interrupt_disconnect(dev);
672 } 762 }
673 763
674 if (status & INTERRUPT_MASK_TX) { 764 if (status & INTERRUPT_MASK_TX) {
675 dev->stats.tx_interrupts++; 765 dev->priv->stats.tx_interrupts++;
676 result = ps3_vuart_handle_interrupt_tx(dev); 766 result = ps3_vuart_handle_interrupt_tx(dev);
677 if (result) 767 if (result)
678 ps3_vuart_disable_interrupt_tx(dev); 768 ps3_vuart_disable_interrupt_tx(dev);
679 } 769 }
680 770
681 if (status & INTERRUPT_MASK_RX) { 771 if (status & INTERRUPT_MASK_RX) {
682 dev->stats.rx_interrupts++; 772 dev->priv->stats.rx_interrupts++;
683 result = ps3_vuart_handle_interrupt_rx(dev); 773 result = ps3_vuart_handle_interrupt_rx(dev);
684 if (result) 774 if (result)
685 ps3_vuart_disable_interrupt_rx(dev); 775 ps3_vuart_disable_interrupt_rx(dev);
@@ -688,12 +778,13 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
688 return 0; 778 return 0;
689} 779}
690 780
691struct vuart_private { 781struct vuart_bus_priv {
692 unsigned int in_use; 782 const struct ports_bmp bmp;
693 unsigned int virq; 783 unsigned int virq;
784 struct semaphore probe_mutex;
785 int use_count;
694 struct ps3_vuart_port_device *devices[PORT_COUNT]; 786 struct ps3_vuart_port_device *devices[PORT_COUNT];
695 const struct ports_bmp bmp; 787} static vuart_bus_priv;
696};
697 788
698/** 789/**
699 * ps3_vuart_irq_handler - first stage interrupt handler 790 * ps3_vuart_irq_handler - first stage interrupt handler
@@ -705,25 +796,25 @@ struct vuart_private {
705 796
706static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private) 797static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
707{ 798{
708 struct vuart_private *private; 799 struct vuart_bus_priv *bus_priv;
709 800
710 BUG_ON(!_private); 801 BUG_ON(!_private);
711 private = (struct vuart_private *)_private; 802 bus_priv = (struct vuart_bus_priv *)_private;
712 803
713 while (1) { 804 while (1) {
714 unsigned int port; 805 unsigned int port;
715 806
716 dump_ports_bmp(&private->bmp); 807 dump_ports_bmp(&bus_priv->bmp);
717 808
718 port = (BITS_PER_LONG - 1) - __ilog2(private->bmp.status); 809 port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status);
719 810
720 if (port == BITS_PER_LONG) 811 if (port == BITS_PER_LONG)
721 break; 812 break;
722 813
723 BUG_ON(port >= PORT_COUNT); 814 BUG_ON(port >= PORT_COUNT);
724 BUG_ON(!private->devices[port]); 815 BUG_ON(!bus_priv->devices[port]);
725 816
726 ps3_vuart_handle_port_interrupt(private->devices[port]); 817 ps3_vuart_handle_port_interrupt(bus_priv->devices[port]);
727 } 818 }
728 819
729 return IRQ_HANDLED; 820 return IRQ_HANDLED;
@@ -744,12 +835,10 @@ static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv)
744 return result; 835 return result;
745} 836}
746 837
747static struct vuart_private vuart_private;
748
749static int ps3_vuart_probe(struct device *_dev) 838static int ps3_vuart_probe(struct device *_dev)
750{ 839{
751 int result; 840 int result;
752 unsigned long tmp; 841 unsigned int port_number;
753 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 842 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
754 struct ps3_vuart_port_driver *drv = 843 struct ps3_vuart_port_driver *drv =
755 to_ps3_vuart_port_driver(_dev->driver); 844 to_ps3_vuart_port_driver(_dev->driver);
@@ -758,7 +847,12 @@ static int ps3_vuart_probe(struct device *_dev)
758 847
759 BUG_ON(!drv); 848 BUG_ON(!drv);
760 849
761 result = ps3_vuart_match_id_to_port(dev->match_id, &dev->port_number); 850 down(&vuart_bus_priv.probe_mutex);
851
852 /* Setup vuart_bus_priv.devices[]. */
853
854 result = ps3_vuart_match_id_to_port(dev->match_id,
855 &port_number);
762 856
763 if (result) { 857 if (result) {
764 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n", 858 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n",
@@ -767,24 +861,41 @@ static int ps3_vuart_probe(struct device *_dev)
767 goto fail_match; 861 goto fail_match;
768 } 862 }
769 863
770 if (vuart_private.devices[dev->port_number]) { 864 if (vuart_bus_priv.devices[port_number]) {
771 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__, 865 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
772 __LINE__, dev->port_number); 866 __LINE__, port_number);
773 result = -EBUSY; 867 result = -EBUSY;
774 goto fail_match; 868 goto fail_match;
775 } 869 }
776 870
777 vuart_private.devices[dev->port_number] = dev; 871 vuart_bus_priv.devices[port_number] = dev;
872
873 /* Setup dev->priv. */
874
875 dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL);
876
877 if (!dev->priv) {
878 result = -ENOMEM;
879 goto fail_alloc;
880 }
778 881
779 INIT_LIST_HEAD(&dev->tx_list.head); 882 dev->priv->port_number = port_number;
780 spin_lock_init(&dev->tx_list.lock); 883
781 INIT_LIST_HEAD(&dev->rx_list.head); 884 INIT_LIST_HEAD(&dev->priv->tx_list.head);
782 spin_lock_init(&dev->rx_list.lock); 885 spin_lock_init(&dev->priv->tx_list.lock);
886
887 INIT_LIST_HEAD(&dev->priv->rx_list.head);
888 spin_lock_init(&dev->priv->rx_list.lock);
889
890 INIT_WORK(&dev->priv->work.work, NULL);
891 spin_lock_init(&dev->priv->work.lock);
892 dev->priv->work.trigger = 0;
893 dev->priv->work.dev = dev;
894
895 if (++vuart_bus_priv.use_count == 1) {
783 896
784 vuart_private.in_use++;
785 if (vuart_private.in_use == 1) {
786 result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY, 897 result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
787 (void*)&vuart_private.bmp.status, &vuart_private.virq); 898 (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
788 899
789 if (result) { 900 if (result) {
790 dev_dbg(&dev->core, 901 dev_dbg(&dev->core,
@@ -794,8 +905,8 @@ static int ps3_vuart_probe(struct device *_dev)
794 goto fail_alloc_irq; 905 goto fail_alloc_irq;
795 } 906 }
796 907
797 result = request_irq(vuart_private.virq, ps3_vuart_irq_handler, 908 result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
798 IRQF_DISABLED, "vuart", &vuart_private); 909 IRQF_DISABLED, "vuart", &vuart_bus_priv);
799 910
800 if (result) { 911 if (result) {
801 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n", 912 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
@@ -804,10 +915,11 @@ static int ps3_vuart_probe(struct device *_dev)
804 } 915 }
805 } 916 }
806 917
807 ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
808
809 /* clear stale pending interrupts */ 918 /* clear stale pending interrupts */
810 ps3_vuart_get_interrupt_mask(dev, &tmp); 919
920 ps3_vuart_clear_rx_bytes(dev, 0);
921
922 ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
811 923
812 ps3_vuart_set_triggers(dev, 1, 1); 924 ps3_vuart_set_triggers(dev, 1, 1);
813 925
@@ -822,20 +934,27 @@ static int ps3_vuart_probe(struct device *_dev)
822 if (result) { 934 if (result) {
823 dev_dbg(&dev->core, "%s:%d: drv->probe failed\n", 935 dev_dbg(&dev->core, "%s:%d: drv->probe failed\n",
824 __func__, __LINE__); 936 __func__, __LINE__);
937 down(&vuart_bus_priv.probe_mutex);
825 goto fail_probe; 938 goto fail_probe;
826 } 939 }
827 940
941 up(&vuart_bus_priv.probe_mutex);
942
828 return result; 943 return result;
829 944
830fail_probe: 945fail_probe:
946 ps3_vuart_set_interrupt_mask(dev, 0);
831fail_request_irq: 947fail_request_irq:
832 vuart_private.in_use--; 948 ps3_free_vuart_irq(vuart_bus_priv.virq);
833 if (!vuart_private.in_use) { 949 vuart_bus_priv.virq = NO_IRQ;
834 ps3_free_vuart_irq(vuart_private.virq);
835 vuart_private.virq = NO_IRQ;
836 }
837fail_alloc_irq: 950fail_alloc_irq:
951 --vuart_bus_priv.use_count;
952 kfree(dev->priv);
953 dev->priv = NULL;
954fail_alloc:
955 vuart_bus_priv.devices[port_number] = 0;
838fail_match: 956fail_match:
957 up(&vuart_bus_priv.probe_mutex);
839 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); 958 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
840 return result; 959 return result;
841} 960}
@@ -846,10 +965,12 @@ static int ps3_vuart_remove(struct device *_dev)
846 struct ps3_vuart_port_driver *drv = 965 struct ps3_vuart_port_driver *drv =
847 to_ps3_vuart_port_driver(_dev->driver); 966 to_ps3_vuart_port_driver(_dev->driver);
848 967
968 down(&vuart_bus_priv.probe_mutex);
969
849 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, 970 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
850 dev->core.bus_id); 971 dev->core.bus_id);
851 972
852 BUG_ON(vuart_private.in_use < 1); 973 BUG_ON(vuart_bus_priv.use_count < 1);
853 974
854 if (drv->remove) 975 if (drv->remove)
855 drv->remove(dev); 976 drv->remove(dev);
@@ -857,13 +978,19 @@ static int ps3_vuart_remove(struct device *_dev)
857 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__, 978 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
858 __LINE__, dev->core.bus_id); 979 __LINE__, dev->core.bus_id);
859 980
860 vuart_private.in_use--; 981 vuart_bus_priv.devices[dev->priv->port_number] = 0;
861 982
862 if (!vuart_private.in_use) { 983 if (--vuart_bus_priv.use_count == 0) {
863 free_irq(vuart_private.virq, &vuart_private); 984 BUG();
864 ps3_free_vuart_irq(vuart_private.virq); 985 free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
865 vuart_private.virq = NO_IRQ; 986 ps3_free_vuart_irq(vuart_bus_priv.virq);
987 vuart_bus_priv.virq = NO_IRQ;
866 } 988 }
989
990 kfree(dev->priv);
991 dev->priv = NULL;
992
993 up(&vuart_bus_priv.probe_mutex);
867 return 0; 994 return 0;
868} 995}
869 996
@@ -884,12 +1011,12 @@ static void ps3_vuart_shutdown(struct device *_dev)
884} 1011}
885 1012
886/** 1013/**
887 * ps3_vuart - The vuart instance. 1014 * ps3_vuart_bus - The vuart bus instance.
888 * 1015 *
889 * The vuart is managed as a bus that port devices connect to. 1016 * The vuart is managed as a bus that port devices connect to.
890 */ 1017 */
891 1018
892struct bus_type ps3_vuart = { 1019struct bus_type ps3_vuart_bus = {
893 .name = "ps3_vuart", 1020 .name = "ps3_vuart",
894 .match = ps3_vuart_match, 1021 .match = ps3_vuart_match,
895 .probe = ps3_vuart_probe, 1022 .probe = ps3_vuart_probe,
@@ -897,24 +1024,30 @@ struct bus_type ps3_vuart = {
897 .shutdown = ps3_vuart_shutdown, 1024 .shutdown = ps3_vuart_shutdown,
898}; 1025};
899 1026
900int __init ps3_vuart_init(void) 1027int __init ps3_vuart_bus_init(void)
901{ 1028{
902 int result; 1029 int result;
903 1030
904 pr_debug("%s:%d:\n", __func__, __LINE__); 1031 pr_debug("%s:%d:\n", __func__, __LINE__);
905 result = bus_register(&ps3_vuart); 1032
1033 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1034 return 0;
1035
1036 init_MUTEX(&vuart_bus_priv.probe_mutex);
1037 result = bus_register(&ps3_vuart_bus);
906 BUG_ON(result); 1038 BUG_ON(result);
1039
907 return result; 1040 return result;
908} 1041}
909 1042
910void __exit ps3_vuart_exit(void) 1043void __exit ps3_vuart_bus_exit(void)
911{ 1044{
912 pr_debug("%s:%d:\n", __func__, __LINE__); 1045 pr_debug("%s:%d:\n", __func__, __LINE__);
913 bus_unregister(&ps3_vuart); 1046 bus_unregister(&ps3_vuart_bus);
914} 1047}
915 1048
916core_initcall(ps3_vuart_init); 1049core_initcall(ps3_vuart_bus_init);
917module_exit(ps3_vuart_exit); 1050module_exit(ps3_vuart_bus_exit);
918 1051
919/** 1052/**
920 * ps3_vuart_port_release_device - Remove a vuart port device. 1053 * ps3_vuart_port_release_device - Remove a vuart port device.
@@ -922,11 +1055,14 @@ module_exit(ps3_vuart_exit);
922 1055
923static void ps3_vuart_port_release_device(struct device *_dev) 1056static void ps3_vuart_port_release_device(struct device *_dev)
924{ 1057{
925 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
926#if defined(DEBUG) 1058#if defined(DEBUG)
927 memset(dev, 0xad, sizeof(struct ps3_vuart_port_device)); 1059 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
1060
1061 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
1062
1063 BUG_ON(dev->priv && "forgot to free");
1064 memset(&dev->core, 0, sizeof(dev->core));
928#endif 1065#endif
929 kfree(dev);
930} 1066}
931 1067
932/** 1068/**
@@ -935,11 +1071,12 @@ static void ps3_vuart_port_release_device(struct device *_dev)
935 1071
936int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev) 1072int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
937{ 1073{
938 int result;
939 static unsigned int dev_count = 1; 1074 static unsigned int dev_count = 1;
940 1075
1076 BUG_ON(dev->priv && "forgot to free");
1077
941 dev->core.parent = NULL; 1078 dev->core.parent = NULL;
942 dev->core.bus = &ps3_vuart; 1079 dev->core.bus = &ps3_vuart_bus;
943 dev->core.release = ps3_vuart_port_release_device; 1080 dev->core.release = ps3_vuart_port_release_device;
944 1081
945 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", 1082 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x",
@@ -947,9 +1084,7 @@ int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
947 1084
948 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__); 1085 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__);
949 1086
950 result = device_register(&dev->core); 1087 return device_register(&dev->core);
951
952 return result;
953} 1088}
954 1089
955EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register); 1090EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register);
@@ -963,7 +1098,7 @@ int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv)
963 int result; 1098 int result;
964 1099
965 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); 1100 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
966 drv->core.bus = &ps3_vuart; 1101 drv->core.bus = &ps3_vuart_bus;
967 result = driver_register(&drv->core); 1102 result = driver_register(&drv->core);
968 return result; 1103 return result;
969} 1104}
@@ -976,6 +1111,7 @@ EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
976 1111
977void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv) 1112void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
978{ 1113{
1114 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
979 driver_unregister(&drv->core); 1115 driver_unregister(&drv->core);
980} 1116}
981 1117