return 0;
}
+/* Unregister a regular WWAN port (e.g. AT, MBIM, etc) */
+static void wwan_port_unregister_wwan(struct wwan_port *port)
+{
+ struct wwan_device *wwandev = to_wwan_dev(port->dev.parent);
+
+ dev_set_drvdata(&port->dev, NULL);
+
+ dev_info(&wwandev->dev, "port %s disconnected\n", dev_name(&port->dev));
+
+ device_del(&port->dev);
+}
+
struct wwan_port *wwan_create_port(struct device *parent,
enum wwan_port_type type,
const struct wwan_port_ops *ops,
struct wwan_device *wwandev = to_wwan_dev(port->dev.parent);
mutex_lock(&port->ops_lock);
- if (port->start_count)
+ if (port->start_count) {
port->ops->stop(port);
+ port->start_count = 0;
+ }
port->ops = NULL; /* Prevent any new port operations (e.g. from fops) */
mutex_unlock(&port->ops_lock);
wake_up_interruptible(&port->waitqueue);
-
skb_queue_purge(&port->rxq);
- dev_set_drvdata(&port->dev, NULL);
- dev_info(&wwandev->dev, "port %s disconnected\n", dev_name(&port->dev));
- device_unregister(&port->dev);
+ wwan_port_unregister_wwan(port);
+
+ put_device(&port->dev);
/* Release related wwan device */
wwan_remove_dev(wwandev);