struct gsm_dlci *dlci[NUM_DLCI];
        int old_c_iflag;                /* termios c_iflag value before attach */
        bool constipated;               /* Asked by remote to shut up */
+       bool has_devices;               /* Devices were registered */
 
        spinlock_t tx_lock;
        unsigned int tx_bytes;          /* TX data outstanding */
        kfree(prefix);
 }
 
+/**
+ *     gsm_register_devices    -       register all tty devices for a given mux index
+ *
+ *     @driver: the tty driver that describes the tty devices
+ *     @index:  the mux number is used to calculate the minor numbers of the
+ *              ttys for this mux and may differ from the position in the
+ *              mux array.
+ */
+static int gsm_register_devices(struct tty_driver *driver, unsigned int index)
+{
+       struct device *dev;
+       int i;
+       unsigned int base;
+
+       if (!driver || index >= MAX_MUX)
+               return -EINVAL;
+
+       base = index * NUM_DLCI; /* first minor for this index */
+       for (i = 1; i < NUM_DLCI; i++) {
+               /* Don't register device 0 - this is the control channel
+                * and not a usable tty interface
+                */
+               dev = tty_register_device(gsm_tty_driver, base + i, NULL);
+               if (IS_ERR(dev)) {
+                       if (debug & 8)
+                               pr_info("%s failed to register device minor %u",
+                                       __func__, base + i);
+                       for (i--; i >= 1; i--)
+                               tty_unregister_device(gsm_tty_driver, base + i);
+                       return PTR_ERR(dev);
+               }
+       }
+
+       return 0;
+}
+
+/**
+ *     gsm_unregister_devices  -       unregister all tty devices for a given mux index
+ *
+ *     @driver: the tty driver that describes the tty devices
+ *     @index:  the mux number is used to calculate the minor numbers of the
+ *              ttys for this mux and may differ from the position in the
+ *              mux array.
+ */
+static void gsm_unregister_devices(struct tty_driver *driver,
+                                  unsigned int index)
+{
+       int i;
+       unsigned int base;
+
+       if (!driver || index >= MAX_MUX)
+               return;
+
+       base = index * NUM_DLCI; /* first minor for this index */
+       for (i = 1; i < NUM_DLCI; i++) {
+               /* Don't unregister device 0 - this is the control
+                * channel and not a usable tty interface
+                */
+               tty_unregister_device(gsm_tty_driver, base + i);
+       }
+}
+
 /**
  *     gsm_print_packet        -       display a frame for debug
  *     @hdr: header to print before decode
        del_timer_sync(&gsm->t2_timer);
 
        /* Free up any link layer users and finally the control channel */
+       if (gsm->has_devices) {
+               gsm_unregister_devices(gsm_tty_driver, gsm->num);
+               gsm->has_devices = false;
+       }
        for (i = NUM_DLCI - 1; i >= 0; i--)
                if (gsm->dlci[i])
                        gsm_dlci_release(gsm->dlci[i]);
 static int gsm_activate_mux(struct gsm_mux *gsm)
 {
        struct gsm_dlci *dlci;
+       int ret;
 
        timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
        init_waitqueue_head(&gsm->event);
        else
                gsm->receive = gsm1_receive;
 
+       ret = gsm_register_devices(gsm_tty_driver, gsm->num);
+       if (ret)
+               return ret;
+
        dlci = gsm_dlci_alloc(gsm, 0);
        if (dlci == NULL)
                return -ENOMEM;
+       gsm->has_devices = true;
        gsm->dead = false;              /* Tty opens are now permissible */
        return 0;
 }
  *     will need moving to an ioctl path.
  */
 
-static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+static void gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
 {
-       unsigned int base;
-       int ret, i;
-
        gsm->tty = tty_kref_get(tty);
        /* Turn off tty XON/XOFF handling to handle it explicitly. */
        gsm->old_c_iflag = tty->termios.c_iflag;
        tty->termios.c_iflag &= (IXON | IXOFF);
-       ret =  gsm_activate_mux(gsm);
-       if (ret != 0)
-               tty_kref_put(gsm->tty);
-       else {
-               /* Don't register device 0 - this is the control channel and not
-                  a usable tty interface */
-               base = mux_num_to_base(gsm); /* Base for this MUX */
-               for (i = 1; i < NUM_DLCI; i++) {
-                       struct device *dev;
-
-                       dev = tty_register_device(gsm_tty_driver,
-                                                       base + i, NULL);
-                       if (IS_ERR(dev)) {
-                               for (i--; i >= 1; i--)
-                                       tty_unregister_device(gsm_tty_driver,
-                                                               base + i);
-                               return PTR_ERR(dev);
-                       }
-               }
-       }
-       return ret;
 }
 
-
 /**
  *     gsmld_detach_gsm        -       stop doing 0710 mux
  *     @tty: tty attached to the mux
 
 static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
 {
-       unsigned int base = mux_num_to_base(gsm); /* Base for this MUX */
-       int i;
-
        WARN_ON(tty != gsm->tty);
-       for (i = 1; i < NUM_DLCI; i++)
-               tty_unregister_device(gsm_tty_driver, base + i);
        /* Restore tty XON/XOFF handling. */
        gsm->tty->termios.c_iflag = gsm->old_c_iflag;
        tty_kref_put(gsm->tty);
 static int gsmld_open(struct tty_struct *tty)
 {
        struct gsm_mux *gsm;
-       int ret;
 
        if (tty->ops->write == NULL)
                return -EINVAL;
        /* Attach the initial passive connection */
        gsm->encoding = 1;
 
-       ret = gsmld_attach_gsm(tty, gsm);
-       if (ret != 0) {
-               gsm_cleanup_mux(gsm, false);
-               mux_put(gsm);
-       }
-       return ret;
+       gsmld_attach_gsm(tty, gsm);
+
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+
+       return 0;
 }
 
 /**