return ld;
 }
 
-static inline void put_ldisc(struct tty_ldisc *ld)
+static void put_ldisc(struct tty_ldisc *ld)
 {
+       unsigned long flags;
+
        if (WARN_ON_ONCE(!ld))
                return;
 
        /*
         * If this is the last user, free the ldisc, and
         * release the ldisc ops.
+        *
+        * We really want an "atomic_dec_and_lock_irqsave()",
+        * but we don't have it, so this does it by hand.
         */
-       if (atomic_dec_and_test(&ld->users)) {
-               unsigned long flags;
+       local_irq_save(flags);
+       if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
                struct tty_ldisc_ops *ldo = ld->ops;
 
-               kfree(ld);
-               spin_lock_irqsave(&tty_ldisc_lock, flags);
                ldo->refcount--;
                module_put(ldo->owner);
                spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+               kfree(ld);
+               return;
        }
+       local_irq_restore(flags);
 }
 
 /**