[POWERPC] PS3: Vuart rework
authorGeoff Levand <geoffrey.levand@am.sony.com>
Fri, 15 Jun 2007 22:01:06 +0000 (08:01 +1000)
committerPaul Mackerras <paulus@samba.org>
Thu, 28 Jun 2007 09:16:40 +0000 (19:16 +1000)
PS3 vuart updates to reflect the new PS3 unified device support.
 - Move vuart devices to the PS3 system bus.
 - Replace use of ps3_vuart_port_device with ps3_system_bus_device.
 - Make the PS3 vuart bus driver a loadable module.
 - Add remove() and shutdown() routines.
 - Move ps3_vuart_work into ps3_vuart_port_priv.tx_list.
 - Remove redundant spinlock ps3_vuart_work.lock.
 - No longer free ps3_vuart_port_device.priv on shutdown.
 - Cleanup Kconfig defs.
 - Export symbols needed for modular port drivers.
 - Arrange to use port numbers found in repository.
 - Fix bugs in ps3_vuart_read_async() and polled reading
 - Cleanup handling of shared interrupt with ps3_vuart_bus_interrupt_get()
   and ps3_vuart_bus_interrupt_put()
 - Add more comments to vuart.c.

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/platforms/ps3/Kconfig
arch/powerpc/platforms/ps3/interrupt.c
drivers/ps3/vuart.c
drivers/ps3/vuart.h
include/asm-powerpc/ps3.h

index 40f0008..b5122a7 100644 (file)
@@ -73,18 +73,12 @@ config PS3_USE_LPAR_ADDR
 
 config PS3_VUART
        depends on PPC_PS3
 
 config PS3_VUART
        depends on PPC_PS3
-       bool "PS3 Virtual UART support" if PS3_ADVANCED
-       default y
-       help
-         Include support for the PS3 Virtual UART.
-
-         This support is required for several system services
-         including the System Manager and AV Settings.  In
-         general, all users will say Y.
+       tristate
 
 config PS3_PS3AV
 
 config PS3_PS3AV
+       depends on PPC_PS3
        tristate "PS3 AV settings driver" if PS3_ADVANCED
        tristate "PS3 AV settings driver" if PS3_ADVANCED
-       depends on PS3_VUART
+       select PS3_VUART
        default y
        help
          Include support for the PS3 AV Settings driver.
        default y
        help
          Include support for the PS3 AV Settings driver.
@@ -93,13 +87,14 @@ config PS3_PS3AV
          general, all users will say Y or M.
 
 config PS3_SYS_MANAGER
          general, all users will say Y or M.
 
 config PS3_SYS_MANAGER
-       bool "PS3 System Manager driver" if PS3_ADVANCED
-       depends on PS3_VUART
-       default y
+       depends on PPC_PS3
+       tristate "PS3 System Manager driver" if PS3_ADVANCED
+       select PS3_VUART
+       default m
        help
          Include support for the PS3 System Manager.
 
          This support is required for system control.  In
        help
          Include support for the PS3 System Manager.
 
          This support is required for system control.  In
-         general, all users will say Y.
+         general, all users will say Y or M.
 
 endmenu
 
 endmenu
index 51141dc..99a0826 100644 (file)
@@ -564,6 +564,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
 
        return result;
 }
 
        return result;
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
 
 int ps3_vuart_irq_destroy(unsigned int virq)
 {
 
 int ps3_vuart_irq_destroy(unsigned int virq)
 {
@@ -583,6 +584,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
 
        return result;
 }
 
        return result;
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
 
 /**
  * ps3_spe_irq_setup - Setup an spe virq.
 
 /**
  * ps3_spe_irq_setup - Setup an spe virq.
index 5333fb2..bea25a1 100644 (file)
@@ -70,6 +70,34 @@ enum vuart_interrupt_mask {
        INTERRUPT_MASK_DISCONNECT = 4,
 };
 
        INTERRUPT_MASK_DISCONNECT = 4,
 };
 
+/**
+ * struct ps3_vuart_port_priv - private vuart device data.
+ */
+
+struct ps3_vuart_port_priv {
+       u64 interrupt_mask;
+
+       struct {
+               spinlock_t lock;
+               struct list_head head;
+       } tx_list;
+       struct {
+               struct ps3_vuart_work work;
+               unsigned long bytes_held;
+               spinlock_t lock;
+               struct list_head head;
+       } rx_list;
+       struct ps3_vuart_stats stats;
+};
+
+static struct ps3_vuart_port_priv *to_port_priv(
+       struct ps3_system_bus_device *dev)
+{
+       BUG_ON(!dev);
+       BUG_ON(!dev->driver_priv);
+       return (struct ps3_vuart_port_priv *)dev->driver_priv;
+}
+
 /**
  * struct ports_bmp - bitmap indicating ports needing service.
  *
 /**
  * struct ports_bmp - bitmap indicating ports needing service.
  *
@@ -89,23 +117,6 @@ static void __maybe_unused _dump_ports_bmp(
        pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
 }
 
        pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
 }
 
-static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id,
-       unsigned int *port_number)
-{
-       switch(match_id) {
-       case PS3_MATCH_ID_AV_SETTINGS:
-               *port_number = 0;
-               return 0;
-       case PS3_MATCH_ID_SYSTEM_MANAGER:
-               *port_number = 2;
-               return 0;
-       default:
-               WARN_ON(1);
-               *port_number = UINT_MAX;
-               return -EINVAL;
-       };
-}
-
 #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
 static void __maybe_unused _dump_port_params(unsigned int port_number,
        const char* func, int line)
 #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
 static void __maybe_unused _dump_port_params(unsigned int port_number,
        const char* func, int line)
@@ -144,14 +155,14 @@ struct vuart_triggers {
        unsigned long tx;
 };
 
        unsigned long tx;
 };
 
-int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
+int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev,
        struct vuart_triggers *trig)
 {
        int result;
        unsigned long size;
        unsigned long val;
 
        struct vuart_triggers *trig)
 {
        int result;
        unsigned long size;
        unsigned long val;
 
-       result = lv1_get_virtual_uart_param(dev->priv->port_number,
+       result = lv1_get_virtual_uart_param(dev->port_number,
                PARAM_TX_TRIGGER, &trig->tx);
 
        if (result) {
                PARAM_TX_TRIGGER, &trig->tx);
 
        if (result) {
@@ -160,7 +171,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
                return result;
        }
 
                return result;
        }
 
-       result = lv1_get_virtual_uart_param(dev->priv->port_number,
+       result = lv1_get_virtual_uart_param(dev->port_number,
                PARAM_RX_BUF_SIZE, &size);
 
        if (result) {
                PARAM_RX_BUF_SIZE, &size);
 
        if (result) {
@@ -169,7 +180,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
                return result;
        }
 
                return result;
        }
 
-       result = lv1_get_virtual_uart_param(dev->priv->port_number,
+       result = lv1_get_virtual_uart_param(dev->port_number,
                PARAM_RX_TRIGGER, &val);
 
        if (result) {
                PARAM_RX_TRIGGER, &val);
 
        if (result) {
@@ -186,13 +197,13 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
        return result;
 }
 
        return result;
 }
 
-int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
+int ps3_vuart_set_triggers(struct ps3_system_bus_device *dev, unsigned int tx,
        unsigned int rx)
 {
        int result;
        unsigned long size;
 
        unsigned int rx)
 {
        int result;
        unsigned long size;
 
-       result = lv1_set_virtual_uart_param(dev->priv->port_number,
+       result = lv1_set_virtual_uart_param(dev->port_number,
                PARAM_TX_TRIGGER, tx);
 
        if (result) {
                PARAM_TX_TRIGGER, tx);
 
        if (result) {
@@ -201,7 +212,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
                return result;
        }
 
                return result;
        }
 
-       result = lv1_get_virtual_uart_param(dev->priv->port_number,
+       result = lv1_get_virtual_uart_param(dev->port_number,
                PARAM_RX_BUF_SIZE, &size);
 
        if (result) {
                PARAM_RX_BUF_SIZE, &size);
 
        if (result) {
@@ -210,7 +221,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
                return result;
        }
 
                return result;
        }
 
-       result = lv1_set_virtual_uart_param(dev->priv->port_number,
+       result = lv1_set_virtual_uart_param(dev->port_number,
                PARAM_RX_TRIGGER, size - rx);
 
        if (result) {
                PARAM_RX_TRIGGER, size - rx);
 
        if (result) {
@@ -225,10 +236,12 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
        return result;
 }
 
        return result;
 }
 
-static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
+static int ps3_vuart_get_rx_bytes_waiting(struct ps3_system_bus_device *dev,
        u64 *bytes_waiting)
 {
        u64 *bytes_waiting)
 {
-       int result = lv1_get_virtual_uart_param(dev->priv->port_number,
+       int result;
+
+       result = lv1_get_virtual_uart_param(dev->port_number,
                PARAM_RX_BYTES, bytes_waiting);
 
        if (result)
                PARAM_RX_BYTES, bytes_waiting);
 
        if (result)
@@ -240,17 +253,24 @@ static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
        return result;
 }
 
        return result;
 }
 
-static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
+/**
+ * ps3_vuart_set_interrupt_mask - Enable/disable the port interrupt sources.
+ * @dev: The struct ps3_system_bus_device instance.
+ * @bmp: Logical OR of enum vuart_interrupt_mask values. A zero bit disables.
+ */
+
+static int ps3_vuart_set_interrupt_mask(struct ps3_system_bus_device *dev,
        unsigned long mask)
 {
        int result;
        unsigned long mask)
 {
        int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
 
        dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
 
 
        dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
 
-       dev->priv->interrupt_mask = mask;
+       priv->interrupt_mask = mask;
 
 
-       result = lv1_set_virtual_uart_param(dev->priv->port_number,
-               PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask);
+       result = lv1_set_virtual_uart_param(dev->port_number,
+               PARAM_INTERRUPT_MASK, priv->interrupt_mask);
 
        if (result)
                dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
 
        if (result)
                dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
@@ -259,79 +279,96 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
        return result;
 }
 
        return result;
 }
 
-static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev,
+static int ps3_vuart_get_interrupt_status(struct ps3_system_bus_device *dev,
        unsigned long *status)
 {
        unsigned long *status)
 {
+       int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        u64 tmp;
        u64 tmp;
-       int result = lv1_get_virtual_uart_param(dev->priv->port_number,
+
+       result = lv1_get_virtual_uart_param(dev->port_number,
                PARAM_INTERRUPT_STATUS, &tmp);
 
        if (result)
                dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
                        __func__, __LINE__, ps3_result(result));
 
                PARAM_INTERRUPT_STATUS, &tmp);
 
        if (result)
                dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
                        __func__, __LINE__, ps3_result(result));
 
-       *status = tmp & dev->priv->interrupt_mask;
+       *status = tmp & priv->interrupt_mask;
 
        dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
 
        dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
-               __func__, __LINE__, dev->priv->interrupt_mask, tmp, *status);
+               __func__, __LINE__, priv->interrupt_mask, tmp, *status);
 
        return result;
 }
 
 
        return result;
 }
 
-int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev)
+int ps3_vuart_enable_interrupt_tx(struct ps3_system_bus_device *dev)
 {
 {
-       return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
-               : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+
+       return (priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
+               : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
                | INTERRUPT_MASK_TX);
 }
 
                | INTERRUPT_MASK_TX);
 }
 
-int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev)
+int ps3_vuart_enable_interrupt_rx(struct ps3_system_bus_device *dev)
 {
 {
-       return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
-               : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+
+       return (priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
+               : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
                | INTERRUPT_MASK_RX);
 }
 
                | INTERRUPT_MASK_RX);
 }
 
-int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
+int ps3_vuart_enable_interrupt_disconnect(struct ps3_system_bus_device *dev)
 {
 {
-       return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
-               : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+
+       return (priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
+               : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
                | INTERRUPT_MASK_DISCONNECT);
 }
 
                | INTERRUPT_MASK_DISCONNECT);
 }
 
-int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev)
+int ps3_vuart_disable_interrupt_tx(struct ps3_system_bus_device *dev)
 {
 {
-       return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX)
-               ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+
+       return (priv->interrupt_mask & INTERRUPT_MASK_TX)
+               ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
                & ~INTERRUPT_MASK_TX) : 0;
 }
 
                & ~INTERRUPT_MASK_TX) : 0;
 }
 
-int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev)
+int ps3_vuart_disable_interrupt_rx(struct ps3_system_bus_device *dev)
 {
 {
-       return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX)
-               ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+
+       return (priv->interrupt_mask & INTERRUPT_MASK_RX)
+               ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
                & ~INTERRUPT_MASK_RX) : 0;
 }
 
                & ~INTERRUPT_MASK_RX) : 0;
 }
 
-int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
+int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev)
 {
 {
-       return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
-               ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+
+       return (priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
+               ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
                & ~INTERRUPT_MASK_DISCONNECT) : 0;
 }
 
 /**
  * ps3_vuart_raw_write - Low level write helper.
                & ~INTERRUPT_MASK_DISCONNECT) : 0;
 }
 
 /**
  * ps3_vuart_raw_write - Low level write helper.
+ * @dev: The struct ps3_system_bus_device instance.
  *
  * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write.
  */
 
  *
  * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write.
  */
 
-static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
+static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev,
        const void* buf, unsigned int bytes, unsigned long *bytes_written)
 {
        int result;
        const void* buf, unsigned int bytes, unsigned long *bytes_written)
 {
        int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
 
 
-       result = lv1_write_virtual_uart(dev->priv->port_number,
+       result = lv1_write_virtual_uart(dev->port_number,
                ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
 
        if (result) {
                ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
 
        if (result) {
@@ -340,28 +377,30 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
                return result;
        }
 
                return result;
        }
 
-       dev->priv->stats.bytes_written += *bytes_written;
+       priv->stats.bytes_written += *bytes_written;
 
        dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
 
        dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
-               *bytes_written, bytes, dev->priv->stats.bytes_written);
+               *bytes_written, bytes, priv->stats.bytes_written);
 
        return result;
 }
 
 /**
  * ps3_vuart_raw_read - Low level read helper.
 
        return result;
 }
 
 /**
  * ps3_vuart_raw_read - Low level read helper.
+ * @dev: The struct ps3_system_bus_device instance.
  *
  * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read.
  */
 
  *
  * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read.
  */
 
-static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
+static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void *buf,
        unsigned int bytes, unsigned long *bytes_read)
 {
        int result;
        unsigned int bytes, unsigned long *bytes_read)
 {
        int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
 
        dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
 
 
        dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
 
-       result = lv1_read_virtual_uart(dev->priv->port_number,
+       result = lv1_read_virtual_uart(dev->port_number,
                ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
 
        if (result) {
                ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
 
        if (result) {
@@ -370,25 +409,27 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
                return result;
        }
 
                return result;
        }
 
-       dev->priv->stats.bytes_read += *bytes_read;
+       priv->stats.bytes_read += *bytes_read;
 
        dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
 
        dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
-               *bytes_read, bytes, dev->priv->stats.bytes_read);
+               *bytes_read, bytes, priv->stats.bytes_read);
 
        return result;
 }
 
 /**
  * ps3_vuart_clear_rx_bytes - Discard bytes received.
 
        return result;
 }
 
 /**
  * ps3_vuart_clear_rx_bytes - Discard bytes received.
+ * @dev: The struct ps3_system_bus_device instance.
  * @bytes: Max byte count to discard, zero = all pending.
  *
  * Used to clear pending rx interrupt source.  Will not block.
  */
 
  * @bytes: Max byte count to discard, zero = all pending.
  *
  * Used to clear pending rx interrupt source.  Will not block.
  */
 
-void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
+void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev,
        unsigned int bytes)
 {
        int result;
        unsigned int bytes)
 {
        int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        u64 bytes_waiting;
        void* tmp;
 
        u64 bytes_waiting;
        void* tmp;
 
@@ -418,8 +459,9 @@ void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
 
        /* Don't include these bytes in the stats. */
 
 
        /* Don't include these bytes in the stats. */
 
-       dev->priv->stats.bytes_read -= bytes_waiting;
+       priv->stats.bytes_read -= bytes_waiting;
 }
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_clear_rx_bytes);
 
 /**
  * struct list_buffer - An element for a port device fifo buffer list.
 
 /**
  * struct list_buffer - An element for a port device fifo buffer list.
@@ -435,6 +477,7 @@ struct list_buffer {
 
 /**
  * ps3_vuart_write - the entry point for writing data to a port
 
 /**
  * ps3_vuart_write - the entry point for writing data to a port
+ * @dev: The struct ps3_system_bus_device instance.
  *
  * If the port is idle on entry as much of the incoming data is written to
  * the port as the port will accept.  Otherwise a list buffer is created
  *
  * If the port is idle on entry as much of the incoming data is written to
  * the port as the port will accept.  Otherwise a list buffer is created
@@ -442,25 +485,26 @@ struct list_buffer {
  * then enqueued for transmision via the transmit interrupt.
  */
 
  * then enqueued for transmision via the transmit interrupt.
  */
 
-int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
+int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf,
        unsigned int bytes)
 {
        static unsigned long dbg_number;
        int result;
        unsigned int bytes)
 {
        static unsigned long dbg_number;
        int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        unsigned long flags;
        struct list_buffer *lb;
 
        dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
                bytes, bytes);
 
        unsigned long flags;
        struct list_buffer *lb;
 
        dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
                bytes, bytes);
 
-       spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
+       spin_lock_irqsave(&priv->tx_list.lock, flags);
 
 
-       if (list_empty(&dev->priv->tx_list.head)) {
+       if (list_empty(&priv->tx_list.head)) {
                unsigned long bytes_written;
 
                result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
 
                unsigned long bytes_written;
 
                result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
 
-               spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
+               spin_unlock_irqrestore(&priv->tx_list.lock, flags);
 
                if (result) {
                        dev_dbg(&dev->core,
 
                if (result) {
                        dev_dbg(&dev->core,
@@ -478,7 +522,7 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
                bytes -= bytes_written;
                buf += bytes_written;
        } else
                bytes -= bytes_written;
                buf += bytes_written;
        } else
-               spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
+               spin_unlock_irqrestore(&priv->tx_list.lock, flags);
 
        lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
 
 
        lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
 
@@ -491,29 +535,86 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
        lb->tail = lb->data + bytes;
        lb->dbg_number = ++dbg_number;
 
        lb->tail = lb->data + bytes;
        lb->dbg_number = ++dbg_number;
 
-       spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
-       list_add_tail(&lb->link, &dev->priv->tx_list.head);
+       spin_lock_irqsave(&priv->tx_list.lock, flags);
+       list_add_tail(&lb->link, &priv->tx_list.head);
        ps3_vuart_enable_interrupt_tx(dev);
        ps3_vuart_enable_interrupt_tx(dev);
-       spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
+       spin_unlock_irqrestore(&priv->tx_list.lock, flags);
 
        dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
                __func__, __LINE__, lb->dbg_number, bytes);
 
        return 0;
 }
 
        dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
                __func__, __LINE__, lb->dbg_number, bytes);
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_write);
+
+/**
+ * ps3_vuart_queue_rx_bytes - Queue waiting bytes into the buffer list.
+ * @dev: The struct ps3_system_bus_device instance.
+ * @bytes_queued: Number of bytes queued to the buffer list.
+ *
+ * Must be called with priv->rx_list.lock held.
+ */
+
+static int ps3_vuart_queue_rx_bytes(struct ps3_system_bus_device *dev,
+       u64 *bytes_queued)
+{
+       static unsigned long dbg_number;
+       int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+       struct list_buffer *lb;
+       u64 bytes;
+
+       *bytes_queued = 0;
+
+       result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes);
+       BUG_ON(result);
+
+       if (result)
+               return -EIO;
+
+       if (!bytes)
+               return 0;
+
+       /* Add some extra space for recently arrived data. */
+
+       bytes += 128;
+
+       lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC);
+
+       if (!lb)
+               return -ENOMEM;
+
+       ps3_vuart_raw_read(dev, lb->data, bytes, &bytes);
+
+       lb->head = lb->data;
+       lb->tail = lb->data + bytes;
+       lb->dbg_number = ++dbg_number;
+
+       list_add_tail(&lb->link, &priv->rx_list.head);
+       priv->rx_list.bytes_held += bytes;
+
+       dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
+               __func__, __LINE__, lb->dbg_number, bytes);
+
+       *bytes_queued = bytes;
+
+       return 0;
+}
 
 /**
 
 /**
- * ps3_vuart_read - the entry point for reading data from a port
+ * ps3_vuart_read - The entry point for reading data from a port.
  *
  *
- * If enough bytes to satisfy the request are held in the buffer list those
- * bytes are dequeued and copied to the caller's buffer.  Emptied list buffers
- * are retiered.  If the request cannot be statified by bytes held in the list
- * buffers -EAGAIN is returned.
+ * Queue data waiting at the port, and if enough bytes to satisfy the request
+ * are held in the buffer list those bytes are dequeued and copied to the
+ * caller's buffer.  Emptied list buffers are retiered.  If the request cannot
+ * be statified by bytes held in the list buffers -EAGAIN is returned.
  */
 
  */
 
-int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
+int ps3_vuart_read(struct ps3_system_bus_device *dev, void *buf,
        unsigned int bytes)
 {
        unsigned int bytes)
 {
+       int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        unsigned long flags;
        struct list_buffer *lb, *n;
        unsigned long bytes_read;
        unsigned long flags;
        struct list_buffer *lb, *n;
        unsigned long bytes_read;
@@ -521,30 +622,37 @@ int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
        dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
                bytes, bytes);
 
        dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
                bytes, bytes);
 
-       spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
+       spin_lock_irqsave(&priv->rx_list.lock, flags);
 
 
-       if (dev->priv->rx_list.bytes_held < bytes) {
-               spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
-               dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
-                       __func__, __LINE__,
-                       bytes - dev->priv->rx_list.bytes_held);
-               return -EAGAIN;
+       /* Queue rx bytes here for polled reads. */
+
+       while (priv->rx_list.bytes_held < bytes) {
+               u64 tmp;
+
+               result = ps3_vuart_queue_rx_bytes(dev, &tmp);
+               if (result || !tmp) {
+                       dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
+                               __func__, __LINE__,
+                               bytes - priv->rx_list.bytes_held);
+                       spin_unlock_irqrestore(&priv->rx_list.lock, flags);
+                       return -EAGAIN;
+               }
        }
 
        }
 
-       list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) {
+       list_for_each_entry_safe(lb, n, &priv->rx_list.head, link) {
                bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
 
                memcpy(buf, lb->head, bytes_read);
                buf += bytes_read;
                bytes -= bytes_read;
                bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
 
                memcpy(buf, lb->head, bytes_read);
                buf += bytes_read;
                bytes -= bytes_read;
-               dev->priv->rx_list.bytes_held -= bytes_read;
+               priv->rx_list.bytes_held -= bytes_read;
 
                if (bytes_read < lb->tail - lb->head) {
                        lb->head += bytes_read;
                        dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
                                "bytes\n", __func__, __LINE__, lb->dbg_number,
                                bytes_read);
 
                if (bytes_read < lb->tail - lb->head) {
                        lb->head += bytes_read;
                        dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
                                "bytes\n", __func__, __LINE__, lb->dbg_number,
                                bytes_read);
-                       spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
+                       spin_unlock_irqrestore(&priv->rx_list.lock, flags);
                        return 0;
                }
 
                        return 0;
                }
 
@@ -556,16 +664,32 @@ int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
                kfree(lb);
        }
 
                kfree(lb);
        }
 
-       spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
+       spin_unlock_irqrestore(&priv->rx_list.lock, flags);
        return 0;
 }
        return 0;
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_read);
 
 
-int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
-       unsigned int bytes)
+/**
+ * ps3_vuart_work - Asynchronous read handler.
+ */
+
+static void ps3_vuart_work(struct work_struct *work)
+{
+       struct ps3_system_bus_device *dev =
+               ps3_vuart_work_to_system_bus_dev(work);
+       struct ps3_vuart_port_driver *drv =
+               ps3_system_bus_dev_to_vuart_drv(dev);
+
+       BUG_ON(!drv);
+       drv->work(dev);
+}
+
+int ps3_vuart_read_async(struct ps3_system_bus_device *dev, unsigned int bytes)
 {
 {
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        unsigned long flags;
 
        unsigned long flags;
 
-       if(dev->priv->work.trigger) {
+       if (priv->rx_list.work.trigger) {
                dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n",
                        __func__, __LINE__);
                return -EAGAIN;
                dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n",
                        __func__, __LINE__);
                return -EAGAIN;
@@ -573,30 +697,32 @@ int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
 
        BUG_ON(!bytes);
 
 
        BUG_ON(!bytes);
 
-       PREPARE_WORK(&dev->priv->work.work, func);
+       PREPARE_WORK(&priv->rx_list.work.work, ps3_vuart_work);
 
 
-       spin_lock_irqsave(&dev->priv->work.lock, flags);
-       if(dev->priv->rx_list.bytes_held >= bytes) {
+       spin_lock_irqsave(&priv->rx_list.lock, flags);
+       if (priv->rx_list.bytes_held >= bytes) {
                dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n",
                        __func__, __LINE__, bytes);
                dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n",
                        __func__, __LINE__, bytes);
-               schedule_work(&dev->priv->work.work);
-               spin_unlock_irqrestore(&dev->priv->work.lock, flags);
+               schedule_work(&priv->rx_list.work.work);
+               spin_unlock_irqrestore(&priv->rx_list.lock, flags);
                return 0;
        }
 
                return 0;
        }
 
-       dev->priv->work.trigger = bytes;
-       spin_unlock_irqrestore(&dev->priv->work.lock, flags);
+       priv->rx_list.work.trigger = bytes;
+       spin_unlock_irqrestore(&priv->rx_list.lock, flags);
 
        dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__,
                __LINE__, bytes, bytes);
 
        return 0;
 }
 
        dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__,
                __LINE__, bytes, bytes);
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_read_async);
 
 
-void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev)
+void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev)
 {
 {
-       dev->priv->work.trigger = 0;
+       to_port_priv(dev)->rx_list.work.trigger = 0;
 }
 }
+EXPORT_SYMBOL_GPL(ps3_vuart_cancel_async);
 
 /**
  * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
 
 /**
  * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
@@ -606,18 +732,19 @@ void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev)
  * adjusts the final list buffer state for a partial write.
  */
 
  * adjusts the final list buffer state for a partial write.
  */
 
-static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
+static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev)
 {
        int result = 0;
 {
        int result = 0;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        unsigned long flags;
        struct list_buffer *lb, *n;
        unsigned long bytes_total = 0;
 
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
        unsigned long flags;
        struct list_buffer *lb, *n;
        unsigned long bytes_total = 0;
 
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
-       spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
+       spin_lock_irqsave(&priv->tx_list.lock, flags);
 
 
-       list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) {
+       list_for_each_entry_safe(lb, n, &priv->tx_list.head, link) {
 
                unsigned long bytes_written;
 
 
                unsigned long bytes_written;
 
@@ -651,7 +778,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
 
        ps3_vuart_disable_interrupt_tx(dev);
 port_full:
 
        ps3_vuart_disable_interrupt_tx(dev);
 port_full:
-       spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
+       spin_unlock_irqrestore(&priv->tx_list.lock, flags);
        dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
                __func__, __LINE__, bytes_total);
        return result;
        dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
                __func__, __LINE__, bytes_total);
        return result;
@@ -665,60 +792,37 @@ port_full:
  * buffer list.  Buffer list data is dequeued via ps3_vuart_read.
  */
 
  * buffer list.  Buffer list data is dequeued via ps3_vuart_read.
  */
 
-static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
+static int ps3_vuart_handle_interrupt_rx(struct ps3_system_bus_device *dev)
 {
 {
-       static unsigned long dbg_number;
-       int result = 0;
+       int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        unsigned long flags;
        unsigned long flags;
-       struct list_buffer *lb;
-       unsigned long bytes;
+       u64 bytes;
 
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
 
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
-       result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes);
-
-       if (result)
-               return -EIO;
-
-       BUG_ON(!bytes);
-
-       /* Add some extra space for recently arrived data. */
-
-       bytes += 128;
-
-       lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC);
+       spin_lock_irqsave(&priv->rx_list.lock, flags);
+       result = ps3_vuart_queue_rx_bytes(dev, &bytes);
 
 
-       if (!lb)
-               return -ENOMEM;
-
-       ps3_vuart_raw_read(dev, lb->data, bytes, &bytes);
-
-       lb->head = lb->data;
-       lb->tail = lb->data + bytes;
-       lb->dbg_number = ++dbg_number;
-
-       spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
-       list_add_tail(&lb->link, &dev->priv->rx_list.head);
-       dev->priv->rx_list.bytes_held += bytes;
-       spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
-
-       dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
-               __func__, __LINE__, lb->dbg_number, bytes);
+       if (result) {
+               spin_unlock_irqrestore(&priv->rx_list.lock, flags);
+               return result;
+       }
 
 
-       spin_lock_irqsave(&dev->priv->work.lock, flags);
-       if(dev->priv->work.trigger
-               && dev->priv->rx_list.bytes_held >= dev->priv->work.trigger) {
+       if (priv->rx_list.work.trigger && priv->rx_list.bytes_held
+               >= priv->rx_list.work.trigger) {
                dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n",
                dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n",
-                       __func__, __LINE__, dev->priv->work.trigger);
-               dev->priv->work.trigger = 0;
-               schedule_work(&dev->priv->work.work);
+                       __func__, __LINE__, priv->rx_list.work.trigger);
+               priv->rx_list.work.trigger = 0;
+               schedule_work(&priv->rx_list.work.work);
        }
        }
-       spin_unlock_irqrestore(&dev->priv->work.lock, flags);
-       return 0;
+
+       spin_unlock_irqrestore(&priv->rx_list.lock, flags);
+       return result;
 }
 
 static int ps3_vuart_handle_interrupt_disconnect(
 }
 
 static int ps3_vuart_handle_interrupt_disconnect(
-       struct ps3_vuart_port_device *dev)
+       struct ps3_system_bus_device *dev)
 {
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
        BUG_ON("no support");
 {
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
        BUG_ON("no support");
@@ -733,9 +837,10 @@ static int ps3_vuart_handle_interrupt_disconnect(
  * stage handler after one iteration.
  */
 
  * stage handler after one iteration.
  */
 
-static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
+static int ps3_vuart_handle_port_interrupt(struct ps3_system_bus_device *dev)
 {
        int result;
 {
        int result;
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
        unsigned long status;
 
        result = ps3_vuart_get_interrupt_status(dev, &status);
        unsigned long status;
 
        result = ps3_vuart_get_interrupt_status(dev, &status);
@@ -747,21 +852,21 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
                status);
 
        if (status & INTERRUPT_MASK_DISCONNECT) {
                status);
 
        if (status & INTERRUPT_MASK_DISCONNECT) {
-               dev->priv->stats.disconnect_interrupts++;
+               priv->stats.disconnect_interrupts++;
                result = ps3_vuart_handle_interrupt_disconnect(dev);
                if (result)
                        ps3_vuart_disable_interrupt_disconnect(dev);
        }
 
        if (status & INTERRUPT_MASK_TX) {
                result = ps3_vuart_handle_interrupt_disconnect(dev);
                if (result)
                        ps3_vuart_disable_interrupt_disconnect(dev);
        }
 
        if (status & INTERRUPT_MASK_TX) {
-               dev->priv->stats.tx_interrupts++;
+               priv->stats.tx_interrupts++;
                result = ps3_vuart_handle_interrupt_tx(dev);
                if (result)
                        ps3_vuart_disable_interrupt_tx(dev);
        }
 
        if (status & INTERRUPT_MASK_RX) {
                result = ps3_vuart_handle_interrupt_tx(dev);
                if (result)
                        ps3_vuart_disable_interrupt_tx(dev);
        }
 
        if (status & INTERRUPT_MASK_RX) {
-               dev->priv->stats.rx_interrupts++;
+               priv->stats.rx_interrupts++;
                result = ps3_vuart_handle_interrupt_rx(dev);
                if (result)
                        ps3_vuart_disable_interrupt_rx(dev);
                result = ps3_vuart_handle_interrupt_rx(dev);
                if (result)
                        ps3_vuart_disable_interrupt_rx(dev);
@@ -771,11 +876,11 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
 }
 
 struct vuart_bus_priv {
 }
 
 struct vuart_bus_priv {
-       const struct ports_bmp bmp;
+       struct ports_bmp *bmp;
        unsigned int virq;
        struct semaphore probe_mutex;
        int use_count;
        unsigned int virq;
        struct semaphore probe_mutex;
        int use_count;
-       struct ps3_vuart_port_device *devices[PORT_COUNT];
+       struct ps3_system_bus_device *devices[PORT_COUNT];
 } static vuart_bus_priv;
 
 /**
 } static vuart_bus_priv;
 
 /**
@@ -788,17 +893,16 @@ struct vuart_bus_priv {
 
 static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
 {
 
 static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
 {
-       struct vuart_bus_priv *bus_priv;
+       struct vuart_bus_priv *bus_priv = _private;
 
 
-       BUG_ON(!_private);
-       bus_priv = (struct vuart_bus_priv *)_private;
+       BUG_ON(!bus_priv);
 
        while (1) {
                unsigned int port;
 
 
        while (1) {
                unsigned int port;
 
-               dump_ports_bmp(&bus_priv->bmp);
+               dump_ports_bmp(bus_priv->bmp);
 
 
-               port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status);
+               port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp->status);
 
                if (port == BITS_PER_LONG)
                        break;
 
                if (port == BITS_PER_LONG)
                        break;
@@ -812,100 +916,144 @@ static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
        return IRQ_HANDLED;
 }
 
        return IRQ_HANDLED;
 }
 
-static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv)
+static int ps3_vuart_bus_interrupt_get(void)
 {
        int result;
 {
        int result;
-       struct ps3_vuart_port_driver *drv = to_ps3_vuart_port_driver(_drv);
-       struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
 
 
-       result = dev->match_id == drv->match_id;
+       pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+       vuart_bus_priv.use_count++;
+
+       BUG_ON(vuart_bus_priv.use_count > 2);
+
+       if (vuart_bus_priv.use_count != 1) {
+               return 0;
+       }
+
+       BUG_ON(vuart_bus_priv.bmp);
+
+       vuart_bus_priv.bmp = kzalloc(sizeof(struct ports_bmp), GFP_KERNEL);
+
+       if (!vuart_bus_priv.bmp) {
+               pr_debug("%s:%d: kzalloc failed.\n", __func__, __LINE__);
+               result = -ENOMEM;
+               goto fail_bmp_malloc;
+       }
+
+       result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, vuart_bus_priv.bmp,
+               &vuart_bus_priv.virq);
+
+       if (result) {
+               pr_debug("%s:%d: ps3_vuart_irq_setup failed (%d)\n",
+                       __func__, __LINE__, result);
+               result = -EPERM;
+               goto fail_alloc_irq;
+       }
+
+       result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
+               IRQF_DISABLED, "vuart", &vuart_bus_priv);
 
 
-       dev_info(&dev->core, "%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__,
-               __LINE__, dev->match_id, dev->core.bus_id, drv->match_id,
-               drv->core.name, (result ? "match" : "miss"));
+       if (result) {
+               pr_debug("%s:%d: request_irq failed (%d)\n",
+                       __func__, __LINE__, result);
+               goto fail_request_irq;
+       }
 
 
+       pr_debug(" <- %s:%d: ok\n", __func__, __LINE__);
        return result;
        return result;
+
+fail_request_irq:
+       ps3_vuart_irq_destroy(vuart_bus_priv.virq);
+       vuart_bus_priv.virq = NO_IRQ;
+fail_alloc_irq:
+       kfree(vuart_bus_priv.bmp);
+       vuart_bus_priv.bmp = NULL;
+fail_bmp_malloc:
+       vuart_bus_priv.use_count--;
+       pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
+       return result;
+}
+
+static int ps3_vuart_bus_interrupt_put(void)
+{
+       pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+       vuart_bus_priv.use_count--;
+
+       BUG_ON(vuart_bus_priv.use_count < 0);
+
+       if (vuart_bus_priv.use_count != 0)
+               return 0;
+
+       free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
+
+       ps3_vuart_irq_destroy(vuart_bus_priv.virq);
+       vuart_bus_priv.virq = NO_IRQ;
+
+       kfree(vuart_bus_priv.bmp);
+       vuart_bus_priv.bmp = NULL;
+
+       pr_debug(" <- %s:%d\n", __func__, __LINE__);
+       return 0;
 }
 
 }
 
-static int ps3_vuart_probe(struct device *_dev)
+static int ps3_vuart_probe(struct ps3_system_bus_device *dev)
 {
        int result;
 {
        int result;
-       unsigned int port_number;
-       struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
-       struct ps3_vuart_port_driver *drv =
-               to_ps3_vuart_port_driver(_dev->driver);
+       struct ps3_vuart_port_driver *drv;
+       struct ps3_vuart_port_priv *priv = NULL;
 
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
 
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
+       drv = ps3_system_bus_dev_to_vuart_drv(dev);
+
+       dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,
+               drv->core.core.name);
+
        BUG_ON(!drv);
 
        BUG_ON(!drv);
 
-       down(&vuart_bus_priv.probe_mutex);
+       if (dev->port_number >= PORT_COUNT) {
+               BUG();
+               return -EINVAL;
+       }
 
 
-       /* Setup vuart_bus_priv.devices[]. */
+       down(&vuart_bus_priv.probe_mutex);
 
 
-       result = ps3_vuart_match_id_to_port(dev->match_id,
-               &port_number);
+       result = ps3_vuart_bus_interrupt_get();
 
 
-       if (result) {
-               dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n",
-                       __func__, __LINE__, dev->match_id);
-               result = -EINVAL;
-               goto fail_match;
-       }
+       if (result)
+               goto fail_setup_interrupt;
 
 
-       if (vuart_bus_priv.devices[port_number]) {
+       if (vuart_bus_priv.devices[dev->port_number]) {
                dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
                dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
-                       __LINE__, port_number);
+                       __LINE__, dev->port_number);
                result = -EBUSY;
                result = -EBUSY;
-               goto fail_match;
+               goto fail_busy;
        }
 
        }
 
-       vuart_bus_priv.devices[port_number] = dev;
+       vuart_bus_priv.devices[dev->port_number] = dev;
 
 
-       /* Setup dev->priv. */
+       /* Setup dev->driver_priv. */
 
 
-       dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL);
+       dev->driver_priv = kzalloc(sizeof(struct ps3_vuart_port_priv),
+               GFP_KERNEL);
 
 
-       if (!dev->priv) {
+       if (!dev->driver_priv) {
                result = -ENOMEM;
                result = -ENOMEM;
-               goto fail_alloc;
+               goto fail_dev_malloc;
        }
 
        }
 
-       dev->priv->port_number = port_number;
-
-       INIT_LIST_HEAD(&dev->priv->tx_list.head);
-       spin_lock_init(&dev->priv->tx_list.lock);
+       priv = to_port_priv(dev);
 
 
-       INIT_LIST_HEAD(&dev->priv->rx_list.head);
-       spin_lock_init(&dev->priv->rx_list.lock);
+       INIT_LIST_HEAD(&priv->tx_list.head);
+       spin_lock_init(&priv->tx_list.lock);
 
 
-       INIT_WORK(&dev->priv->work.work, NULL);
-       spin_lock_init(&dev->priv->work.lock);
-       dev->priv->work.trigger = 0;
-       dev->priv->work.dev = dev;
+       INIT_LIST_HEAD(&priv->rx_list.head);
+       spin_lock_init(&priv->rx_list.lock);
 
 
-       if (++vuart_bus_priv.use_count == 1) {
-
-               result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY,
-                       (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
-
-               if (result) {
-                       dev_dbg(&dev->core,
-                               "%s:%d: ps3_vuart_irq_setup failed (%d)\n",
-                               __func__, __LINE__, result);
-                       result = -EPERM;
-                       goto fail_alloc_irq;
-               }
-
-               result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
-                       IRQF_DISABLED, "vuart", &vuart_bus_priv);
-
-               if (result) {
-                       dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
-                               __func__, __LINE__, result);
-                       goto fail_request_irq;
-               }
-       }
+       INIT_WORK(&priv->rx_list.work.work, NULL);
+       priv->rx_list.work.trigger = 0;
+       priv->rx_list.work.dev = dev;
 
        /* clear stale pending interrupts */
 
 
        /* clear stale pending interrupts */
 
@@ -936,150 +1084,158 @@ static int ps3_vuart_probe(struct device *_dev)
 
 fail_probe:
        ps3_vuart_set_interrupt_mask(dev, 0);
 
 fail_probe:
        ps3_vuart_set_interrupt_mask(dev, 0);
-fail_request_irq:
-       ps3_vuart_irq_destroy(vuart_bus_priv.virq);
-       vuart_bus_priv.virq = NO_IRQ;
-fail_alloc_irq:
-       --vuart_bus_priv.use_count;
-       kfree(dev->priv);
-       dev->priv = NULL;
-fail_alloc:
-       vuart_bus_priv.devices[port_number] = NULL;
-fail_match:
+       kfree(dev->driver_priv);
+       dev->driver_priv = NULL;
+fail_dev_malloc:
+       vuart_bus_priv.devices[dev->port_number] = NULL;
+fail_busy:
+       ps3_vuart_bus_interrupt_put();
+fail_setup_interrupt:
        up(&vuart_bus_priv.probe_mutex);
        up(&vuart_bus_priv.probe_mutex);
-       dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
+       dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__);
        return result;
 }
 
        return result;
 }
 
-static int ps3_vuart_remove(struct device *_dev)
+/**
+ * ps3_vuart_cleanup - common cleanup helper.
+ * @dev: The struct ps3_system_bus_device instance.
+ *
+ * Cleans interrupts and HV resources.  Must be called with
+ * vuart_bus_priv.probe_mutex held.  Used by ps3_vuart_remove and
+ * ps3_vuart_shutdown.  After this call, polled reading will still work.
+ */
+
+static int ps3_vuart_cleanup(struct ps3_system_bus_device *dev)
 {
 {
-       struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
-       struct ps3_vuart_port_driver *drv =
-               to_ps3_vuart_port_driver(_dev->driver);
+       dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+       ps3_vuart_cancel_async(dev);
+       ps3_vuart_set_interrupt_mask(dev, 0);
+       ps3_vuart_bus_interrupt_put();
+       return 0;
+}
+
+/**
+ * ps3_vuart_remove - Completely clean the device instance.
+ * @dev: The struct ps3_system_bus_device instance.
+ *
+ * Cleans all memory, interrupts and HV resources.  After this call the
+ * device can no longer be used.
+ */
+
+static int ps3_vuart_remove(struct ps3_system_bus_device *dev)
+{
+       struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+       struct ps3_vuart_port_driver *drv;
+
+       BUG_ON(!dev);
 
        down(&vuart_bus_priv.probe_mutex);
 
 
        down(&vuart_bus_priv.probe_mutex);
 
-       dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
-               dev->core.bus_id);
+       dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
+               dev->match_id);
 
 
-       BUG_ON(vuart_bus_priv.use_count < 1);
+       if (!dev->core.driver) {
+               dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
+                       __LINE__);
+               up(&vuart_bus_priv.probe_mutex);
+               return 0;
+       }
 
 
-       if (drv->remove)
-               drv->remove(dev);
-       else
-               dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
-                       __LINE__, dev->core.bus_id);
+       drv = ps3_system_bus_dev_to_vuart_drv(dev);
 
 
-       vuart_bus_priv.devices[dev->priv->port_number] = NULL;
+       BUG_ON(!drv);
 
 
-       if (--vuart_bus_priv.use_count == 0) {
+       if (drv->remove) {
+               drv->remove(dev);
+       } else {
+               dev_dbg(&dev->core, "%s:%d: no remove method\n", __func__,
+               __LINE__);
                BUG();
                BUG();
-               free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
-               ps3_vuart_irq_destroy(vuart_bus_priv.virq);
-               vuart_bus_priv.virq = NO_IRQ;
        }
 
        }
 
-       kfree(dev->priv);
-       dev->priv = NULL;
+       ps3_vuart_cleanup(dev);
+
+       vuart_bus_priv.devices[dev->port_number] = NULL;
+       kfree(priv);
+       priv = NULL;
 
 
+       dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
        up(&vuart_bus_priv.probe_mutex);
        return 0;
 }
 
        up(&vuart_bus_priv.probe_mutex);
        return 0;
 }
 
-static void ps3_vuart_shutdown(struct device *_dev)
-{
-       struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
-       struct ps3_vuart_port_driver *drv =
-               to_ps3_vuart_port_driver(_dev->driver);
-
-       dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
-               dev->core.bus_id);
-
-       if (drv->shutdown)
-               drv->shutdown(dev);
-       else
-               dev_dbg(&dev->core, "%s:%d: %s no shutdown method\n", __func__,
-                       __LINE__, dev->core.bus_id);
-}
-
 /**
 /**
- * ps3_vuart_bus - The vuart bus instance.
+ * ps3_vuart_shutdown - Cleans interrupts and HV resources.
+ * @dev: The struct ps3_system_bus_device instance.
  *
  *
- * The vuart is managed as a bus that port devices connect to.
+ * Cleans interrupts and HV resources.  After this call the
+ * device can still be used in polling mode.  This behavior required
+ * by sys-manager to be able to complete the device power operation
+ * sequence.
  */
 
  */
 
-struct bus_type ps3_vuart_bus = {
-        .name = "ps3_vuart",
-       .match = ps3_vuart_match,
-       .probe = ps3_vuart_probe,
-       .remove = ps3_vuart_remove,
-       .shutdown = ps3_vuart_shutdown,
-};
-
-int __init ps3_vuart_bus_init(void)
+static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev)
 {
 {
-       int result;
+       struct ps3_vuart_port_driver *drv;
 
 
-       pr_debug("%s:%d:\n", __func__, __LINE__);
+       BUG_ON(!dev);
 
 
-       if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
-               return -ENODEV;
+       down(&vuart_bus_priv.probe_mutex);
 
 
-       init_MUTEX(&vuart_bus_priv.probe_mutex);
-       result = bus_register(&ps3_vuart_bus);
-       BUG_ON(result);
+       dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
+               dev->match_id);
 
 
-       return result;
-}
+       if (!dev->core.driver) {
+               dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
+                       __LINE__);
+               up(&vuart_bus_priv.probe_mutex);
+               return 0;
+       }
 
 
-void __exit ps3_vuart_bus_exit(void)
-{
-       pr_debug("%s:%d:\n", __func__, __LINE__);
-       bus_unregister(&ps3_vuart_bus);
-}
+       drv = ps3_system_bus_dev_to_vuart_drv(dev);
 
 
-core_initcall(ps3_vuart_bus_init);
-module_exit(ps3_vuart_bus_exit);
+       BUG_ON(!drv);
 
 
-/**
- * ps3_vuart_port_release_device - Remove a vuart port device.
- */
+       if (drv->shutdown)
+               drv->shutdown(dev);
+       else if (drv->remove) {
+               dev_dbg(&dev->core, "%s:%d: no shutdown, calling remove\n",
+                       __func__, __LINE__);
+               drv->remove(dev);
+       } else {
+               dev_dbg(&dev->core, "%s:%d: no shutdown method\n", __func__,
+                       __LINE__);
+               BUG();
+       }
 
 
-static void ps3_vuart_port_release_device(struct device *_dev)
-{
-#if defined(DEBUG)
-       struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
+       ps3_vuart_cleanup(dev);
 
 
-       dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+       dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
 
 
-       BUG_ON(dev->priv && "forgot to free");
-       memset(&dev->core, 0, sizeof(dev->core));
-#endif
+       up(&vuart_bus_priv.probe_mutex);
+       return 0;
 }
 
 }
 
-/**
- * ps3_vuart_port_device_register - Add a vuart port device.
- */
-
-int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
+static int __init ps3_vuart_bus_init(void)
 {
 {
-       static unsigned int dev_count = 1;
-
-       BUG_ON(dev->priv && "forgot to free");
+       pr_debug("%s:%d:\n", __func__, __LINE__);
 
 
-       dev->core.parent = NULL;
-       dev->core.bus = &ps3_vuart_bus;
-       dev->core.release = ps3_vuart_port_release_device;
+       if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+               return -ENODEV;
 
 
-       snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x",
-               dev_count++);
+       init_MUTEX(&vuart_bus_priv.probe_mutex);
 
 
-       dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__);
+       return 0;
+}
 
 
-       return device_register(&dev->core);
+static void __exit ps3_vuart_bus_exit(void)
+{
+       pr_debug("%s:%d:\n", __func__, __LINE__);
 }
 
 }
 
-EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register);
+core_initcall(ps3_vuart_bus_init);
+module_exit(ps3_vuart_bus_exit);
 
 /**
  * ps3_vuart_port_driver_register - Add a vuart port device driver.
 
 /**
  * ps3_vuart_port_driver_register - Add a vuart port device driver.
@@ -1089,12 +1245,18 @@ int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv)
 {
        int result;
 
 {
        int result;
 
-       pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
-       drv->core.bus = &ps3_vuart_bus;
-       result = driver_register(&drv->core);
+       pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.core.name);
+
+       BUG_ON(!drv->core.match_id);
+       BUG_ON(!drv->core.core.name);
+
+       drv->core.probe = ps3_vuart_probe;
+       drv->core.remove = ps3_vuart_remove;
+       drv->core.shutdown = ps3_vuart_shutdown;
+
+       result = ps3_system_bus_driver_register(&drv->core);
        return result;
 }
        return result;
 }
-
 EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
 
 /**
 EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
 
 /**
@@ -1103,8 +1265,7 @@ EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
 
 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
 {
 
 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
 {
-       pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
-       driver_unregister(&drv->core);
+       pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.core.name);
+       ps3_system_bus_driver_unregister(&drv->core);
 }
 }
-
 EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister);
 EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister);
index 1be992d..eb7f6d9 100644 (file)
@@ -34,29 +34,7 @@ struct ps3_vuart_stats {
 struct ps3_vuart_work {
        struct work_struct work;
        unsigned long trigger;
 struct ps3_vuart_work {
        struct work_struct work;
        unsigned long trigger;
-       spinlock_t lock;
-       struct ps3_vuart_port_device* dev; /* to convert work to device */
-};
-
-/**
- * struct ps3_vuart_port_priv - private vuart device data.
- */
-
-struct ps3_vuart_port_priv {
-       unsigned int port_number;
-       u64 interrupt_mask;
-
-       struct {
-               spinlock_t lock;
-               struct list_head head;
-       } tx_list;
-       struct {
-               unsigned long bytes_held;
-               spinlock_t lock;
-               struct list_head head;
-       } rx_list;
-       struct ps3_vuart_stats stats;
-       struct ps3_vuart_work work;
+       struct ps3_system_bus_device *dev; /* to convert work to device */
 };
 
 /**
 };
 
 /**
@@ -64,32 +42,30 @@ struct ps3_vuart_port_priv {
  */
 
 struct ps3_vuart_port_driver {
  */
 
 struct ps3_vuart_port_driver {
-       enum ps3_match_id match_id;
-       struct device_driver core;
-       int (*probe)(struct ps3_vuart_port_device *);
-       int (*remove)(struct ps3_vuart_port_device *);
-       void (*shutdown)(struct ps3_vuart_port_device *);
-       int (*tx_event)(struct ps3_vuart_port_device *dev);
-       int (*rx_event)(struct ps3_vuart_port_device *dev);
-       int (*disconnect_event)(struct ps3_vuart_port_device *dev);
-       /* int (*suspend)(struct ps3_vuart_port_device *, pm_message_t); */
-       /* int (*resume)(struct ps3_vuart_port_device *); */
+       struct ps3_system_bus_driver core;
+       int (*probe)(struct ps3_system_bus_device *);
+       int (*remove)(struct ps3_system_bus_device *);
+       void (*shutdown)(struct ps3_system_bus_device *);
+       void (*work)(struct ps3_system_bus_device *);
+       /* int (*tx_event)(struct ps3_system_bus_device *dev); */
+       /* int (*rx_event)(struct ps3_system_bus_device *dev); */
+       /* int (*disconnect_event)(struct ps3_system_bus_device *dev); */
+       /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
+       /* int (*resume)(struct ps3_system_bus_device *); */
 };
 
 int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv);
 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv);
 
 };
 
 int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv);
 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv);
 
-static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver(
-       struct device_driver *_drv)
-{
-       return container_of(_drv, struct ps3_vuart_port_driver, core);
-}
-static inline struct ps3_vuart_port_device *to_ps3_vuart_port_device(
-       struct device *_dev)
+static inline struct ps3_vuart_port_driver *
+       ps3_system_bus_dev_to_vuart_drv(struct ps3_system_bus_device *_dev)
 {
 {
-       return container_of(_dev, struct ps3_vuart_port_device, core);
+       struct ps3_system_bus_driver *sbd =
+               ps3_system_bus_dev_to_system_bus_drv(_dev);
+       BUG_ON(!sbd);
+       return container_of(sbd, struct ps3_vuart_port_driver, core);
 }
 }
-static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device(
+static inline struct ps3_system_bus_device *ps3_vuart_work_to_system_bus_dev(
        struct work_struct *_work)
 {
        struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work,
        struct work_struct *_work)
 {
        struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work,
@@ -97,14 +73,13 @@ static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device(
        return vw->dev;
 }
 
        return vw->dev;
 }
 
-int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
-       unsigned int bytes);
-int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
+int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf,
        unsigned int bytes);
        unsigned int bytes);
-int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
+int ps3_vuart_read(struct ps3_system_bus_device *dev, void *buf,
        unsigned int bytes);
        unsigned int bytes);
-void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev);
-void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
+int ps3_vuart_read_async(struct ps3_system_bus_device *dev, unsigned int bytes);
+void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev);
+void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev,
        unsigned int bytes);
 
 #endif
        unsigned int bytes);
 
 #endif
index 4f75390..433c38e 100644 (file)
@@ -407,23 +407,6 @@ static inline void *ps3_system_bus_get_driver_data(
 
 extern struct bus_type ps3_system_bus_type;
 
 
 extern struct bus_type ps3_system_bus_type;
 
-/* vuart routines */
-
-struct ps3_vuart_port_priv;
-
-/**
- * struct ps3_vuart_port_device - a device on a vuart port
- */
-
-struct ps3_vuart_port_device {
-       enum ps3_match_id match_id;
-       struct device core;
-       struct ps3_vuart_port_priv* priv; /* private driver variables */
-
-};
-
-int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev);
-
 /* system manager */
 
 #ifdef CONFIG_PS3_SYS_MANAGER
 /* system manager */
 
 #ifdef CONFIG_PS3_SYS_MANAGER