4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/interrupt.h>
26 #include <asm/lv1call.h>
27 #include <asm/bitops.h>
31 MODULE_AUTHOR("Sony Corporation");
32 MODULE_LICENSE("GPL v2");
33 MODULE_DESCRIPTION("ps3 vuart");
36 * vuart - An inter-partition data link service.
37 * port 0: PS3 AV Settings.
38 * port 2: PS3 System Manager.
40 * The vuart provides a bi-directional byte stream data link between logical
41 * partitions. Its primary role is as a communications link between the guest
42 * OS and the system policy module. The current HV does not support any
43 * connections other than those listed.
46 enum {PORT_COUNT
= 3,};
51 PARAM_INTERRUPT_MASK
= 2,
52 PARAM_RX_BUF_SIZE
= 3, /* read only */
53 PARAM_RX_BYTES
= 4, /* read only */
54 PARAM_TX_BUF_SIZE
= 5, /* read only */
55 PARAM_TX_BYTES
= 6, /* read only */
56 PARAM_INTERRUPT_STATUS
= 7, /* read only */
59 enum vuart_interrupt_bit
{
62 INTERRUPT_BIT_DISCONNECT
= 2,
65 enum vuart_interrupt_mask
{
66 INTERRUPT_MASK_TX
= 1,
67 INTERRUPT_MASK_RX
= 2,
68 INTERRUPT_MASK_DISCONNECT
= 4,
72 * struct ports_bmp - bitmap indicating ports needing service.
74 * A 256 bit read only bitmap indicating ports needing service. Do not write
75 * to these bits. Must not cross a page boundary.
81 } __attribute__ ((aligned (32)));
83 /* redefine dev_dbg to do a syntax check */
87 static inline int __attribute__ ((format (printf
, 2, 3))) dev_dbg(
88 const struct device
*_dev
, const char *fmt
, ...) {return 0;}
91 #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__)
92 static void __attribute__ ((unused
)) _dump_ports_bmp(
93 const struct ports_bmp
* bmp
, const char* func
, int line
)
95 pr_debug("%s:%d: ports_bmp: %016lxh\n", func
, line
, bmp
->status
);
98 static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id
,
99 unsigned int *port_number
)
102 case PS3_MATCH_ID_AV_SETTINGS
:
105 case PS3_MATCH_ID_SYSTEM_MANAGER
:
110 *port_number
= UINT_MAX
;
115 #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
116 static void __attribute__ ((unused
)) _dump_port_params(unsigned int port_number
,
117 const char* func
, int line
)
120 static const char *strings
[] = {
134 for (i
= 0; i
< ARRAY_SIZE(strings
); i
++) {
135 result
= lv1_get_virtual_uart_param(port_number
, i
, &value
);
138 pr_debug("%s:%d: port_%u: %s failed: %s\n", func
, line
,
139 port_number
, strings
[i
], ps3_result(result
));
142 pr_debug("%s:%d: port_%u: %s = %lxh\n",
143 func
, line
, port_number
, strings
[i
], value
);
148 struct vuart_triggers
{
153 int ps3_vuart_get_triggers(struct ps3_vuart_port_device
*dev
,
154 struct vuart_triggers
*trig
)
160 result
= lv1_get_virtual_uart_param(dev
->port_number
,
161 PARAM_TX_TRIGGER
, &trig
->tx
);
164 dev_dbg(&dev
->core
, "%s:%d: tx_trigger failed: %s\n",
165 __func__
, __LINE__
, ps3_result(result
));
169 result
= lv1_get_virtual_uart_param(dev
->port_number
,
170 PARAM_RX_BUF_SIZE
, &size
);
173 dev_dbg(&dev
->core
, "%s:%d: tx_buf_size failed: %s\n",
174 __func__
, __LINE__
, ps3_result(result
));
178 result
= lv1_get_virtual_uart_param(dev
->port_number
,
179 PARAM_RX_TRIGGER
, &val
);
182 dev_dbg(&dev
->core
, "%s:%d: rx_trigger failed: %s\n",
183 __func__
, __LINE__
, ps3_result(result
));
187 trig
->rx
= size
- val
;
189 dev_dbg(&dev
->core
, "%s:%d: tx %lxh, rx %lxh\n", __func__
, __LINE__
,
195 int ps3_vuart_set_triggers(struct ps3_vuart_port_device
*dev
, unsigned int tx
,
201 result
= lv1_set_virtual_uart_param(dev
->port_number
,
202 PARAM_TX_TRIGGER
, tx
);
205 dev_dbg(&dev
->core
, "%s:%d: tx_trigger failed: %s\n",
206 __func__
, __LINE__
, ps3_result(result
));
210 result
= lv1_get_virtual_uart_param(dev
->port_number
,
211 PARAM_RX_BUF_SIZE
, &size
);
214 dev_dbg(&dev
->core
, "%s:%d: tx_buf_size failed: %s\n",
215 __func__
, __LINE__
, ps3_result(result
));
219 result
= lv1_set_virtual_uart_param(dev
->port_number
,
220 PARAM_RX_TRIGGER
, size
- rx
);
223 dev_dbg(&dev
->core
, "%s:%d: rx_trigger failed: %s\n",
224 __func__
, __LINE__
, ps3_result(result
));
228 dev_dbg(&dev
->core
, "%s:%d: tx %xh, rx %xh\n", __func__
, __LINE__
,
234 static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device
*dev
,
235 unsigned long *bytes_waiting
)
237 int result
= lv1_get_virtual_uart_param(dev
->port_number
,
238 PARAM_RX_BYTES
, bytes_waiting
);
241 dev_dbg(&dev
->core
, "%s:%d: rx_bytes failed: %s\n",
242 __func__
, __LINE__
, ps3_result(result
));
244 dev_dbg(&dev
->core
, "%s:%d: %lxh\n", __func__
, __LINE__
,
249 static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device
*dev
,
254 dev_dbg(&dev
->core
, "%s:%d: %lxh\n", __func__
, __LINE__
, mask
);
256 dev
->interrupt_mask
= mask
;
258 result
= lv1_set_virtual_uart_param(dev
->port_number
,
259 PARAM_INTERRUPT_MASK
, dev
->interrupt_mask
);
262 dev_dbg(&dev
->core
, "%s:%d: interrupt_mask failed: %s\n",
263 __func__
, __LINE__
, ps3_result(result
));
268 static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device
*dev
,
269 unsigned long *status
)
271 int result
= lv1_get_virtual_uart_param(dev
->port_number
,
272 PARAM_INTERRUPT_STATUS
, status
);
275 dev_dbg(&dev
->core
, "%s:%d: interrupt_status failed: %s\n",
276 __func__
, __LINE__
, ps3_result(result
));
278 dev_dbg(&dev
->core
, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
279 __func__
, __LINE__
, dev
->interrupt_mask
, *status
,
280 dev
->interrupt_mask
& *status
);
285 int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device
*dev
)
287 return (dev
->interrupt_mask
& INTERRUPT_MASK_TX
) ? 0
288 : ps3_vuart_set_interrupt_mask(dev
, dev
->interrupt_mask
289 | INTERRUPT_MASK_TX
);
292 int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device
*dev
)
294 return (dev
->interrupt_mask
& INTERRUPT_MASK_RX
) ? 0
295 : ps3_vuart_set_interrupt_mask(dev
, dev
->interrupt_mask
296 | INTERRUPT_MASK_RX
);
299 int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device
*dev
)
301 return (dev
->interrupt_mask
& INTERRUPT_MASK_DISCONNECT
) ? 0
302 : ps3_vuart_set_interrupt_mask(dev
, dev
->interrupt_mask
303 | INTERRUPT_MASK_DISCONNECT
);
306 int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device
*dev
)
308 return (dev
->interrupt_mask
& INTERRUPT_MASK_TX
)
309 ? ps3_vuart_set_interrupt_mask(dev
, dev
->interrupt_mask
310 & ~INTERRUPT_MASK_TX
) : 0;
313 int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device
*dev
)
315 return (dev
->interrupt_mask
& INTERRUPT_MASK_RX
)
316 ? ps3_vuart_set_interrupt_mask(dev
, dev
->interrupt_mask
317 & ~INTERRUPT_MASK_RX
) : 0;
320 int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device
*dev
)
322 return (dev
->interrupt_mask
& INTERRUPT_MASK_DISCONNECT
)
323 ? ps3_vuart_set_interrupt_mask(dev
, dev
->interrupt_mask
324 & ~INTERRUPT_MASK_DISCONNECT
) : 0;
328 * ps3_vuart_raw_write - Low level write helper.
330 * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write.
333 static int ps3_vuart_raw_write(struct ps3_vuart_port_device
*dev
,
334 const void* buf
, unsigned int bytes
, unsigned long *bytes_written
)
338 dev_dbg(&dev
->core
, "%s:%d: %xh\n", __func__
, __LINE__
, bytes
);
340 result
= lv1_write_virtual_uart(dev
->port_number
,
341 ps3_mm_phys_to_lpar(__pa(buf
)), bytes
, bytes_written
);
344 dev_dbg(&dev
->core
, "%s:%d: lv1_write_virtual_uart failed: "
345 "%s\n", __func__
, __LINE__
, ps3_result(result
));
349 dev
->stats
.bytes_written
+= *bytes_written
;
351 dev_dbg(&dev
->core
, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__
,
352 __LINE__
, *bytes_written
, bytes
, dev
->stats
.bytes_written
);
358 * ps3_vuart_raw_read - Low level read helper.
360 * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read.
363 static int ps3_vuart_raw_read(struct ps3_vuart_port_device
*dev
, void* buf
,
364 unsigned int bytes
, unsigned long *bytes_read
)
368 dev_dbg(&dev
->core
, "%s:%d: %xh\n", __func__
, __LINE__
, bytes
);
370 result
= lv1_read_virtual_uart(dev
->port_number
,
371 ps3_mm_phys_to_lpar(__pa(buf
)), bytes
, bytes_read
);
374 dev_dbg(&dev
->core
, "%s:%d: lv1_read_virtual_uart failed: %s\n",
375 __func__
, __LINE__
, ps3_result(result
));
379 dev
->stats
.bytes_read
+= *bytes_read
;
381 dev_dbg(&dev
->core
, "%s:%d: read %lxh/%xh=>%lxh\n", __func__
, __LINE__
,
382 *bytes_read
, bytes
, dev
->stats
.bytes_read
);
388 * struct list_buffer - An element for a port device fifo buffer list.
392 struct list_head link
;
393 const unsigned char *head
;
394 const unsigned char *tail
;
395 unsigned long dbg_number
;
396 unsigned char data
[];
400 * ps3_vuart_write - the entry point for writing data to a port
402 * If the port is idle on entry as much of the incoming data is written to
403 * the port as the port will accept. Otherwise a list buffer is created
404 * and any remaning incoming data is copied to that buffer. The buffer is
405 * then enqueued for transmision via the transmit interrupt.
408 int ps3_vuart_write(struct ps3_vuart_port_device
*dev
, const void* buf
,
411 static unsigned long dbg_number
;
414 struct list_buffer
*lb
;
416 dev_dbg(&dev
->core
, "%s:%d: %u(%xh) bytes\n", __func__
, __LINE__
,
419 spin_lock_irqsave(&dev
->tx_list
.lock
, flags
);
421 if (list_empty(&dev
->tx_list
.head
)) {
422 unsigned long bytes_written
;
424 result
= ps3_vuart_raw_write(dev
, buf
, bytes
, &bytes_written
);
426 spin_unlock_irqrestore(&dev
->tx_list
.lock
, flags
);
430 "%s:%d: ps3_vuart_raw_write failed\n",
435 if (bytes_written
== bytes
) {
436 dev_dbg(&dev
->core
, "%s:%d: wrote %xh bytes\n",
437 __func__
, __LINE__
, bytes
);
441 bytes
-= bytes_written
;
442 buf
+= bytes_written
;
444 spin_unlock_irqrestore(&dev
->tx_list
.lock
, flags
);
446 lb
= kmalloc(sizeof(struct list_buffer
) + bytes
, GFP_KERNEL
);
452 memcpy(lb
->data
, buf
, bytes
);
454 lb
->tail
= lb
->data
+ bytes
;
455 lb
->dbg_number
= ++dbg_number
;
457 spin_lock_irqsave(&dev
->tx_list
.lock
, flags
);
458 list_add_tail(&lb
->link
, &dev
->tx_list
.head
);
459 ps3_vuart_enable_interrupt_tx(dev
);
460 spin_unlock_irqrestore(&dev
->tx_list
.lock
, flags
);
462 dev_dbg(&dev
->core
, "%s:%d: queued buf_%lu, %xh bytes\n",
463 __func__
, __LINE__
, lb
->dbg_number
, bytes
);
469 * ps3_vuart_read - the entry point for reading data from a port
471 * If enough bytes to satisfy the request are held in the buffer list those
472 * bytes are dequeued and copied to the caller's buffer. Emptied list buffers
473 * are retiered. If the request cannot be statified by bytes held in the list
474 * buffers -EAGAIN is returned.
477 int ps3_vuart_read(struct ps3_vuart_port_device
*dev
, void* buf
,
481 struct list_buffer
*lb
, *n
;
482 unsigned long bytes_read
;
484 dev_dbg(&dev
->core
, "%s:%d: %u(%xh) bytes\n", __func__
, __LINE__
,
487 spin_lock_irqsave(&dev
->rx_list
.lock
, flags
);
489 if (dev
->rx_list
.bytes_held
< bytes
) {
490 spin_unlock_irqrestore(&dev
->rx_list
.lock
, flags
);
491 dev_dbg(&dev
->core
, "%s:%d: starved for %lxh bytes\n",
492 __func__
, __LINE__
, bytes
- dev
->rx_list
.bytes_held
);
496 list_for_each_entry_safe(lb
, n
, &dev
->rx_list
.head
, link
) {
497 bytes_read
= min((unsigned int)(lb
->tail
- lb
->head
), bytes
);
499 memcpy(buf
, lb
->head
, bytes_read
);
502 dev
->rx_list
.bytes_held
-= bytes_read
;
504 if (bytes_read
< lb
->tail
- lb
->head
) {
505 lb
->head
+= bytes_read
;
506 spin_unlock_irqrestore(&dev
->rx_list
.lock
, flags
);
509 "%s:%d: dequeued buf_%lu, %lxh bytes\n",
510 __func__
, __LINE__
, lb
->dbg_number
, bytes_read
);
514 dev_dbg(&dev
->core
, "%s:%d free buf_%lu\n", __func__
, __LINE__
,
520 spin_unlock_irqrestore(&dev
->rx_list
.lock
, flags
);
522 dev_dbg(&dev
->core
, "%s:%d: dequeued buf_%lu, %xh bytes\n",
523 __func__
, __LINE__
, lb
->dbg_number
, bytes
);
529 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
531 * Services the transmit interrupt for the port. Writes as much data from the
532 * buffer list as the port will accept. Retires any emptied list buffers and
533 * adjusts the final list buffer state for a partial write.
536 static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device
*dev
)
540 struct list_buffer
*lb
, *n
;
541 unsigned long bytes_total
= 0;
543 dev_dbg(&dev
->core
, "%s:%d\n", __func__
, __LINE__
);
545 spin_lock_irqsave(&dev
->tx_list
.lock
, flags
);
547 list_for_each_entry_safe(lb
, n
, &dev
->tx_list
.head
, link
) {
549 unsigned long bytes_written
;
551 result
= ps3_vuart_raw_write(dev
, lb
->head
, lb
->tail
- lb
->head
,
556 "%s:%d: ps3_vuart_raw_write failed\n",
561 bytes_total
+= bytes_written
;
563 if (bytes_written
< lb
->tail
- lb
->head
) {
564 lb
->head
+= bytes_written
;
566 "%s:%d cleared buf_%lu, %lxh bytes\n",
567 __func__
, __LINE__
, lb
->dbg_number
,
572 dev_dbg(&dev
->core
, "%s:%d free buf_%lu\n", __func__
, __LINE__
,
579 ps3_vuart_disable_interrupt_tx(dev
);
581 spin_unlock_irqrestore(&dev
->tx_list
.lock
, flags
);
582 dev_dbg(&dev
->core
, "%s:%d wrote %lxh bytes total\n",
583 __func__
, __LINE__
, bytes_total
);
588 * ps3_vuart_handle_interrupt_rx - third stage receive interrupt handler
590 * Services the receive interrupt for the port. Creates a list buffer and
591 * copies all waiting port data to that buffer and enqueues the buffer in the
592 * buffer list. Buffer list data is dequeued via ps3_vuart_read.
595 static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device
*dev
)
597 static unsigned long dbg_number
;
600 struct list_buffer
*lb
;
603 dev_dbg(&dev
->core
, "%s:%d\n", __func__
, __LINE__
);
605 result
= ps3_vuart_get_rx_bytes_waiting(dev
, &bytes
);
612 /* add some extra space for recently arrived data */
616 lb
= kmalloc(sizeof(struct list_buffer
) + bytes
, GFP_ATOMIC
);
621 ps3_vuart_raw_read(dev
, lb
->data
, bytes
, &bytes
);
624 lb
->tail
= lb
->data
+ bytes
;
625 lb
->dbg_number
= ++dbg_number
;
627 spin_lock_irqsave(&dev
->rx_list
.lock
, flags
);
628 list_add_tail(&lb
->link
, &dev
->rx_list
.head
);
629 dev
->rx_list
.bytes_held
+= bytes
;
630 spin_unlock_irqrestore(&dev
->rx_list
.lock
, flags
);
632 dev_dbg(&dev
->core
, "%s:%d: queued buf_%lu, %lxh bytes\n",
633 __func__
, __LINE__
, lb
->dbg_number
, bytes
);
638 static int ps3_vuart_handle_interrupt_disconnect(
639 struct ps3_vuart_port_device
*dev
)
641 dev_dbg(&dev
->core
, "%s:%d\n", __func__
, __LINE__
);
642 BUG_ON("no support");
647 * ps3_vuart_handle_port_interrupt - second stage interrupt handler
649 * Services any pending interrupt types for the port. Passes control to the
650 * third stage type specific interrupt handler. Returns control to the first
651 * stage handler after one iteration.
654 static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device
*dev
)
657 unsigned long status
;
659 result
= ps3_vuart_get_interrupt_mask(dev
, &status
);
664 dev_dbg(&dev
->core
, "%s:%d: status: %lxh\n", __func__
, __LINE__
,
667 if (status
& INTERRUPT_MASK_DISCONNECT
) {
668 dev
->stats
.disconnect_interrupts
++;
669 result
= ps3_vuart_handle_interrupt_disconnect(dev
);
671 ps3_vuart_disable_interrupt_disconnect(dev
);
674 if (status
& INTERRUPT_MASK_TX
) {
675 dev
->stats
.tx_interrupts
++;
676 result
= ps3_vuart_handle_interrupt_tx(dev
);
678 ps3_vuart_disable_interrupt_tx(dev
);
681 if (status
& INTERRUPT_MASK_RX
) {
682 dev
->stats
.rx_interrupts
++;
683 result
= ps3_vuart_handle_interrupt_rx(dev
);
685 ps3_vuart_disable_interrupt_rx(dev
);
691 struct vuart_private
{
694 struct ps3_vuart_port_device
*devices
[PORT_COUNT
];
695 const struct ports_bmp bmp
;
699 * ps3_vuart_irq_handler - first stage interrupt handler
701 * Loops finding any interrupting port and its associated instance data.
702 * Passes control to the second stage port specific interrupt handler. Loops
703 * until all outstanding interrupts are serviced.
706 static irqreturn_t
ps3_vuart_irq_handler(int irq
, void *_private
)
708 struct vuart_private
*private;
711 private = (struct vuart_private
*)_private
;
716 dump_ports_bmp(&private->bmp
);
718 port
= (BITS_PER_LONG
- 1) - __ilog2(private->bmp
.status
);
720 if (port
== BITS_PER_LONG
)
723 BUG_ON(port
>= PORT_COUNT
);
724 BUG_ON(!private->devices
[port
]);
726 ps3_vuart_handle_port_interrupt(private->devices
[port
]);
732 static int ps3_vuart_match(struct device
*_dev
, struct device_driver
*_drv
)
735 struct ps3_vuart_port_driver
*drv
= to_ps3_vuart_port_driver(_drv
);
736 struct ps3_vuart_port_device
*dev
= to_ps3_vuart_port_device(_dev
);
738 result
= dev
->match_id
== drv
->match_id
;
740 dev_info(&dev
->core
, "%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__
,
741 __LINE__
, dev
->match_id
, dev
->core
.bus_id
, drv
->match_id
,
742 drv
->core
.name
, (result
? "match" : "miss"));
747 static struct vuart_private vuart_private
;
749 static int ps3_vuart_probe(struct device
*_dev
)
753 struct ps3_vuart_port_device
*dev
= to_ps3_vuart_port_device(_dev
);
754 struct ps3_vuart_port_driver
*drv
=
755 to_ps3_vuart_port_driver(_dev
->driver
);
757 dev_dbg(&dev
->core
, "%s:%d\n", __func__
, __LINE__
);
761 result
= ps3_vuart_match_id_to_port(dev
->match_id
, &dev
->port_number
);
764 dev_dbg(&dev
->core
, "%s:%d: unknown match_id (%d)\n",
765 __func__
, __LINE__
, dev
->match_id
);
770 if (vuart_private
.devices
[dev
->port_number
]) {
771 dev_dbg(&dev
->core
, "%s:%d: port busy (%d)\n", __func__
,
772 __LINE__
, dev
->port_number
);
777 vuart_private
.devices
[dev
->port_number
] = dev
;
779 INIT_LIST_HEAD(&dev
->tx_list
.head
);
780 spin_lock_init(&dev
->tx_list
.lock
);
781 INIT_LIST_HEAD(&dev
->rx_list
.head
);
782 spin_lock_init(&dev
->rx_list
.lock
);
784 vuart_private
.in_use
++;
785 if (vuart_private
.in_use
== 1) {
786 result
= ps3_alloc_vuart_irq((void*)&vuart_private
.bmp
.status
,
787 &vuart_private
.virq
);
791 "%s:%d: ps3_alloc_vuart_irq failed (%d)\n",
792 __func__
, __LINE__
, result
);
797 result
= request_irq(vuart_private
.virq
, ps3_vuart_irq_handler
,
798 IRQF_DISABLED
, "vuart", &vuart_private
);
801 dev_info(&dev
->core
, "%s:%d: request_irq failed (%d)\n",
802 __func__
, __LINE__
, result
);
803 goto fail_request_irq
;
807 ps3_vuart_set_interrupt_mask(dev
, INTERRUPT_MASK_RX
);
809 /* clear stale pending interrupts */
810 ps3_vuart_get_interrupt_mask(dev
, &tmp
);
812 ps3_vuart_set_triggers(dev
, 1, 1);
815 result
= drv
->probe(dev
);
818 dev_info(&dev
->core
, "%s:%d: no probe method\n", __func__
,
823 dev_dbg(&dev
->core
, "%s:%d: drv->probe failed\n",
832 vuart_private
.in_use
--;
833 if (!vuart_private
.in_use
) {
834 ps3_free_vuart_irq(vuart_private
.virq
);
835 vuart_private
.virq
= NO_IRQ
;
839 dev_dbg(&dev
->core
, "%s:%d failed\n", __func__
, __LINE__
);
843 static int ps3_vuart_remove(struct device
*_dev
)
845 struct ps3_vuart_port_device
*dev
= to_ps3_vuart_port_device(_dev
);
846 struct ps3_vuart_port_driver
*drv
=
847 to_ps3_vuart_port_driver(_dev
->driver
);
849 dev_dbg(&dev
->core
, "%s:%d: %s\n", __func__
, __LINE__
,
852 BUG_ON(vuart_private
.in_use
< 1);
857 dev_dbg(&dev
->core
, "%s:%d: %s no remove method\n", __func__
,
858 __LINE__
, dev
->core
.bus_id
);
860 vuart_private
.in_use
--;
862 if (!vuart_private
.in_use
) {
863 free_irq(vuart_private
.virq
, &vuart_private
);
864 ps3_free_vuart_irq(vuart_private
.virq
);
865 vuart_private
.virq
= NO_IRQ
;
871 * ps3_vuart - The vuart instance.
873 * The vuart is managed as a bus that port devices connect to.
876 struct bus_type ps3_vuart
= {
878 .match
= ps3_vuart_match
,
879 .probe
= ps3_vuart_probe
,
880 .remove
= ps3_vuart_remove
,
883 int __init
ps3_vuart_init(void)
887 pr_debug("%s:%d:\n", __func__
, __LINE__
);
888 result
= bus_register(&ps3_vuart
);
893 void __exit
ps3_vuart_exit(void)
895 pr_debug("%s:%d:\n", __func__
, __LINE__
);
896 bus_unregister(&ps3_vuart
);
899 core_initcall(ps3_vuart_init
);
900 module_exit(ps3_vuart_exit
);
903 * ps3_vuart_port_release_device - Remove a vuart port device.
906 static void ps3_vuart_port_release_device(struct device
*_dev
)
908 struct ps3_vuart_port_device
*dev
= to_ps3_vuart_port_device(_dev
);
910 memset(dev
, 0xad, sizeof(struct ps3_vuart_port_device
));
916 * ps3_vuart_port_device_register - Add a vuart port device.
919 int ps3_vuart_port_device_register(struct ps3_vuart_port_device
*dev
)
922 static unsigned int dev_count
= 1;
924 dev
->core
.parent
= NULL
;
925 dev
->core
.bus
= &ps3_vuart
;
926 dev
->core
.release
= ps3_vuart_port_release_device
;
928 snprintf(dev
->core
.bus_id
, sizeof(dev
->core
.bus_id
), "vuart_%02x",
931 dev_dbg(&dev
->core
, "%s:%d register\n", __func__
, __LINE__
);
933 result
= device_register(&dev
->core
);
938 EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register
);
941 * ps3_vuart_port_driver_register - Add a vuart port device driver.
944 int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver
*drv
)
948 pr_debug("%s:%d: (%s)\n", __func__
, __LINE__
, drv
->core
.name
);
949 drv
->core
.bus
= &ps3_vuart
;
950 result
= driver_register(&drv
->core
);
954 EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register
);
957 * ps3_vuart_port_driver_unregister - Remove a vuart port device driver.
960 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver
*drv
)
962 driver_unregister(&drv
->core
);
965 EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister
);