{
        unsigned long flags;
        struct serial_state * state;
+       int error;
 
        if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_SERIAL))
                return -ENODEV;
         *  We request SERDAT and SERPER only, because the serial registers are
         *  too spreaded over the custom register space
         */
-       if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4, "amiserial [Paula]"))
-               return -EBUSY;
+       if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4,
+                               "amiserial [Paula]")) {
+               error = -EBUSY;
+               goto fail_put_tty_driver;
+       }
 
        IRQ_ports = NULL;
 
        serial_driver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(serial_driver, &serial_ops);
 
-       if (tty_register_driver(serial_driver))
-               panic("Couldn't register serial driver\n");
+       error = tty_register_driver(serial_driver);
+       if (error)
+               goto fail_release_mem_region;
 
        state = rs_table;
        state->magic = SSTATE_MAGIC;
        local_irq_save(flags);
 
        /* set ISRs, and then disable the rx interrupts */
-       request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
-       request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED, "serial RX", state);
+       error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
+       if (error)
+               goto fail_unregister;
+
+       error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED,
+                           "serial RX", state);
+       if (error)
+               goto fail_free_irq;
 
        /* turn off Rx and Tx interrupts */
        custom.intena = IF_RBF | IF_TBE;
        ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR);  /* inputs */
 
        return 0;
+
+fail_free_irq:
+       free_irq(IRQ_AMIGA_TBE, state);
+fail_unregister:
+       tty_unregister_driver(serial_driver);
+fail_release_mem_region:
+       release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
+fail_put_tty_driver:
+       put_tty_driver(serial_driver);
+       return error;
 }
 
 static __exit void rs_exit(void) 
          kfree(info);
        }
 
+       free_irq(IRQ_AMIGA_TBE, rs_table);
+       free_irq(IRQ_AMIGA_RBF, rs_table);
+
        release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
 }