{
        int err;
 
+       atomic_set(&rdev->state, RIO_DEVICE_RUNNING);
        err = device_register(&rdev->dev);
        if (err)
                return err;
 /*
  * rio_del_device - removes a RIO device from the device model
  * @rdev: RIO device
+ * @state: device state to set during removal process
  *
  * Removes the RIO device to the kernel device list and subsystem's device list.
  * Clears sysfs entries for the removed device.
  */
-void rio_del_device(struct rio_dev *rdev)
+void rio_del_device(struct rio_dev *rdev, enum rio_device_state state)
 {
        pr_debug("RIO: %s: removing %s\n", __func__, rio_name(rdev));
+       atomic_set(&rdev->state, state);
        spin_lock(&rio_global_list_lock);
        list_del(&rdev->global_list);
        if (rdev->net) {
        return hdid[index];
 }
 
-int rio_register_mport(struct rio_mport *port)
+int rio_mport_initialize(struct rio_mport *mport)
 {
-       struct rio_scan_node *scan = NULL;
-       int res = 0;
-
        if (next_portid >= RIO_MAX_MPORTS) {
                pr_err("RIO: reached specified max number of mports\n");
-               return 1;
+               return -ENODEV;
        }
 
-       port->id = next_portid++;
-       port->host_deviceid = rio_get_hdid(port->id);
-       port->nscan = NULL;
+       atomic_set(&mport->state, RIO_DEVICE_INITIALIZING);
+       mport->id = next_portid++;
+       mport->host_deviceid = rio_get_hdid(mport->id);
+       mport->nscan = NULL;
 
-       dev_set_name(&port->dev, "rapidio%d", port->id);
-       port->dev.class = &rio_mport_class;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rio_mport_initialize);
 
-       res = device_register(&port->dev);
-       if (res)
-               dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n",
-                       port->id, res);
-       else
-               dev_dbg(&port->dev, "RIO: mport%d registered\n", port->id);
+int rio_register_mport(struct rio_mport *port)
+{
+       struct rio_scan_node *scan = NULL;
+       int res = 0;
 
        mutex_lock(&rio_mport_list_lock);
-       list_add_tail(&port->node, &rio_mports);
 
        /*
         * Check if there are any registered enumeration/discovery operations
                                break;
                }
        }
+
+       list_add_tail(&port->node, &rio_mports);
        mutex_unlock(&rio_mport_list_lock);
 
+       dev_set_name(&port->dev, "rapidio%d", port->id);
+       port->dev.class = &rio_mport_class;
+       atomic_set(&port->state, RIO_DEVICE_RUNNING);
+
+       res = device_register(&port->dev);
+       if (res)
+               dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n",
+                       port->id, res);
+       else
+               dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id);
+
+       return res;
+}
+EXPORT_SYMBOL_GPL(rio_register_mport);
+
+static int rio_mport_cleanup_callback(struct device *dev, void *data)
+{
+       struct rio_dev *rdev = to_rio_dev(dev);
+
+       if (dev->bus == &rio_bus_type)
+               rio_del_device(rdev, RIO_DEVICE_SHUTDOWN);
+       return 0;
+}
+
+static int rio_net_remove_children(struct rio_net *net)
+{
+       /*
+        * Unregister all RapidIO devices residing on this net (this will
+        * invoke notification of registered subsystem interfaces as well).
+        */
+       device_for_each_child(&net->dev, NULL, rio_mport_cleanup_callback);
+       return 0;
+}
+
+int rio_unregister_mport(struct rio_mport *port)
+{
        pr_debug("RIO: %s %s id=%d\n", __func__, port->name, port->id);
+
+       /* Transition mport to the SHUTDOWN state */
+       if (atomic_cmpxchg(&port->state,
+                          RIO_DEVICE_RUNNING,
+                          RIO_DEVICE_SHUTDOWN) != RIO_DEVICE_RUNNING) {
+               pr_err("RIO: %s unexpected state transition for mport %s\n",
+                       __func__, port->name);
+       }
+
+       if (port->net && port->net->hport == port) {
+               rio_net_remove_children(port->net);
+               rio_free_net(port->net);
+       }
+
+       /*
+        * Unregister all RapidIO devices attached to this mport (this will
+        * invoke notification of registered subsystem interfaces as well).
+        */
+       mutex_lock(&rio_mport_list_lock);
+       list_del(&port->node);
+       mutex_unlock(&rio_mport_list_lock);
+       device_unregister(&port->dev);
+
        return 0;
 }
-EXPORT_SYMBOL_GPL(rio_register_mport);
+EXPORT_SYMBOL_GPL(rio_unregister_mport);
 
 EXPORT_SYMBOL_GPL(rio_local_get_device_id);
 EXPORT_SYMBOL_GPL(rio_get_device);
 
        int (*em_handle) (struct rio_dev *dev, u8 swport);
 };
 
+enum rio_device_state {
+       RIO_DEVICE_INITIALIZING,
+       RIO_DEVICE_RUNNING,
+       RIO_DEVICE_GONE,
+       RIO_DEVICE_SHUTDOWN,
+};
+
 /**
  * struct rio_dev - RIO device info
  * @global_list: Node in list of all RIO devices
  * @destid: Network destination ID (or associated destid for switch)
  * @hopcount: Hopcount to this device
  * @prev: Previous RIO device connected to the current one
+ * @state: device state
  * @rswitch: struct rio_switch (if valid for this device)
  */
 struct rio_dev {
        u16 destid;
        u8 hopcount;
        struct rio_dev *prev;
+       atomic_t state;
        struct rio_switch rswitch[0];   /* RIO switch info */
 };
 
  * @priv: Master port private data
  * @dma: DMA device associated with mport
  * @nscan: RapidIO network enumeration/discovery operations
+ * @state: mport device state
  */
 struct rio_mport {
        struct list_head dbells;        /* list of doorbell events */
        struct dma_device       dma;
 #endif
        struct rio_scan *nscan;
+       atomic_t state;
 };
 
+static inline int rio_mport_is_running(struct rio_mport *mport)
+{
+       return atomic_read(&mport->state) == RIO_DEVICE_RUNNING;
+}
+
 /*
  * Enumeration/discovery control flags
  */
 };
 
 /* Architecture and hardware-specific functions */
+extern int rio_mport_initialize(struct rio_mport *);
 extern int rio_register_mport(struct rio_mport *);
+extern int rio_unregister_mport(struct rio_mport *);
 extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
 extern void rio_close_inb_mbox(struct rio_mport *, int);
 extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);