#include <asm/ebus.h>
 #include <asm/auxio.h>
 
-/* This cannot be static, as it is referenced in entry.S */
+/* This cannot be static, as it is referenced in irq.c */
 void __iomem *auxio_register = NULL;
 
 enum auxio_type {
 
        ba,pt           %xcc, rtrap
         clr            %l6
 
-#ifdef CONFIG_BLK_DEV_FD
-       .globl          floppy_hardint
-floppy_hardint:
-       wr              %g0, (1 << 11), %clear_softint
-       sethi           %hi(doing_pdma), %g1
-       ld              [%g1 + %lo(doing_pdma)], %g2
-       brz,pn          %g2, floppy_dosoftint
-        sethi          %hi(fdc_status), %g3
-       ldx             [%g3 + %lo(fdc_status)], %g3
-       sethi           %hi(pdma_vaddr), %g5
-       ldx             [%g5 + %lo(pdma_vaddr)], %g4
-       sethi           %hi(pdma_size), %g5
-       ldx             [%g5 + %lo(pdma_size)], %g5
-
-next_byte:
-       lduba           [%g3] ASI_PHYS_BYPASS_EC_E, %g7
-       andcc           %g7, 0x80, %g0
-       be,pn           %icc, floppy_fifo_emptied
-        andcc          %g7, 0x20, %g0
-       be,pn           %icc, floppy_overrun
-        andcc          %g7, 0x40, %g0
-       be,pn           %icc, floppy_write
-        sub            %g5, 1, %g5
-
-       inc             %g3
-       lduba           [%g3] ASI_PHYS_BYPASS_EC_E, %g7
-       dec             %g3
-       orcc            %g0, %g5, %g0
-       stb             %g7, [%g4]
-       bne,pn          %xcc, next_byte
-        add            %g4, 1, %g4
-
-       b,pt            %xcc, floppy_tdone
-        nop
-
-floppy_write:
-       ldub            [%g4], %g7
-       orcc            %g0, %g5, %g0
-       inc             %g3
-       stba            %g7, [%g3] ASI_PHYS_BYPASS_EC_E
-       dec             %g3
-       bne,pn          %xcc, next_byte
-        add            %g4, 1, %g4
-
-floppy_tdone:
-       sethi           %hi(pdma_vaddr), %g1
-       stx             %g4, [%g1 + %lo(pdma_vaddr)]
-       sethi           %hi(pdma_size), %g1
-       stx             %g5, [%g1 + %lo(pdma_size)]
-       sethi           %hi(auxio_register), %g1
-       ldx             [%g1 + %lo(auxio_register)], %g7
-       lduba           [%g7] ASI_PHYS_BYPASS_EC_E, %g5
-       or              %g5, AUXIO_AUX1_FTCNT, %g5
-/*     andn            %g5, AUXIO_AUX1_MASK, %g5 */
-       stba            %g5, [%g7] ASI_PHYS_BYPASS_EC_E
-       andn            %g5, AUXIO_AUX1_FTCNT, %g5
-/*     andn            %g5, AUXIO_AUX1_MASK, %g5 */
-
-       nop; nop;  nop; nop;  nop; nop;
-       nop; nop;  nop; nop;  nop; nop;
-
-       stba            %g5, [%g7] ASI_PHYS_BYPASS_EC_E
-       sethi           %hi(doing_pdma), %g1
-       b,pt            %xcc, floppy_dosoftint
-        st             %g0, [%g1 + %lo(doing_pdma)]
-
-floppy_fifo_emptied:
-       sethi           %hi(pdma_vaddr), %g1
-       stx             %g4, [%g1 + %lo(pdma_vaddr)]
-       sethi           %hi(pdma_size), %g1
-       stx             %g5, [%g1 + %lo(pdma_size)]
-       sethi           %hi(irq_action), %g1
-       or              %g1, %lo(irq_action), %g1
-       ldx             [%g1 + (11 << 3)], %g3          ! irqaction[floppy_irq]
-       ldx             [%g3 + 0x08], %g4               ! action->flags>>48==ino
-       sethi           %hi(ivector_table), %g3
-       srlx            %g4, 48, %g4
-       or              %g3, %lo(ivector_table), %g3
-       sllx            %g4, 5, %g4
-       ldx             [%g3 + %g4], %g4                ! &ivector_table[ino]
-       ldx             [%g4 + 0x10], %g4               ! bucket->iclr
-       stwa            %g0, [%g4] ASI_PHYS_BYPASS_EC_E ! ICLR_IDLE
-       membar          #Sync                           ! probably not needed...
-       retry
-
-floppy_overrun:
-       sethi           %hi(pdma_vaddr), %g1
-       stx             %g4, [%g1 + %lo(pdma_vaddr)]
-       sethi           %hi(pdma_size), %g1
-       stx             %g5, [%g1 + %lo(pdma_size)]
-       sethi           %hi(doing_pdma), %g1
-       st              %g0, [%g1 + %lo(doing_pdma)]
-
-floppy_dosoftint:
-       rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
-       sethi           %hi(109f), %g7
-       b,pt            %xcc, etrap_irq
-109:    or             %g7, %lo(109b), %g7
-
-       mov             11, %o0
-       mov             0, %o1
-       call            sparc_floppy_irq
-        add            %sp, PTREGS_OFF, %o2
-
-       b,pt            %xcc, rtrap_irq
-        nop
-
-#endif /* CONFIG_BLK_DEV_FD */
-
        /* XXX Here is stuff we still need to write... -DaveM XXX */
        .globl          netbsd_syscall
 netbsd_syscall:
 
 #include <asm/uaccess.h>
 #include <asm/cache.h>
 #include <asm/cpudata.h>
+#include <asm/auxio.h>
 
 #ifdef CONFIG_SMP
 static void distribute_irqs(void);
 }
 
 #ifdef CONFIG_BLK_DEV_FD
-extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs);
+extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);;
 
-void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
-{
-       struct irqaction *action = *(irq + irq_action);
-       struct ino_bucket *bucket;
-       int cpu = smp_processor_id();
-
-       irq_enter();
-       kstat_this_cpu.irqs[irq]++;
-
-       *(irq_work(cpu, irq)) = 0;
-       bucket = get_ino_in_irqaction(action) + ivector_table;
-
-       bucket->flags |= IBF_INPROGRESS;
-
-       floppy_interrupt(irq, dev_cookie, regs);
-       upa_writel(ICLR_IDLE, bucket->iclr);
-
-       bucket->flags &= ~IBF_INPROGRESS;
-
-       irq_exit();
-}
-#endif
-
-/* The following assumes that the branch lies before the place we
- * are branching to.  This is the case for a trap vector...
- * You have been warned.
- */
-#define SPARC_BRANCH(dest_addr, inst_addr) \
-          (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff))
-
-#define SPARC_NOP (0x01000000)
+/* XXX No easy way to include asm/floppy.h XXX */
+extern unsigned char *pdma_vaddr;
+extern unsigned long pdma_size;
+extern volatile int doing_pdma;
+extern unsigned long fdc_status;
 
-static void install_fast_irq(unsigned int cpu_irq,
-                            irqreturn_t (*handler)(int, void *, struct pt_regs *))
+irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
 {
-       extern unsigned long sparc64_ttable_tl0;
-       unsigned long ttent = (unsigned long) &sparc64_ttable_tl0;
-       unsigned int *insns;
-
-       ttent += 0x820;
-       ttent += (cpu_irq - 1) << 5;
-       insns = (unsigned int *) ttent;
-       insns[0] = SPARC_BRANCH(((unsigned long) handler),
-                               ((unsigned long)&insns[0]));
-       insns[1] = SPARC_NOP;
-       __asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent));
-}
-
-int request_fast_irq(unsigned int irq,
-                    irqreturn_t (*handler)(int, void *, struct pt_regs *),
-                    unsigned long irqflags, const char *name, void *dev_id)
-{
-       struct irqaction *action;
-       struct ino_bucket *bucket = __bucket(irq);
-       unsigned long flags;
-
-       /* No pil0 dummy buckets allowed here. */
-       if (bucket < &ivector_table[0] ||
-           bucket >= &ivector_table[NUM_IVECS]) {
-               unsigned int *caller;
-
-               __asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
-               printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt "
-                      "from %p, irq %08x.\n", caller, irq);
-               return -EINVAL;
-       }       
-       
-       if (!handler)
-               return -EINVAL;
+       if (likely(doing_pdma)) {
+               void __iomem *stat = (void __iomem *) fdc_status;
+               unsigned char *vaddr = pdma_vaddr;
+               unsigned long size = pdma_size;
+               u8 val;
+
+               while (size) {
+                       val = readb(stat);
+                       if (unlikely(!(val & 0x80))) {
+                               pdma_vaddr = vaddr;
+                               pdma_size = size;
+                               return IRQ_HANDLED;
+                       }
+                       if (unlikely(!(val & 0x20))) {
+                               pdma_vaddr = vaddr;
+                               pdma_size = size;
+                               doing_pdma = 0;
+                               goto main_interrupt;
+                       }
+                       if (val & 0x40) {
+                               /* read */
+                               *vaddr++ = readb(stat + 1);
+                       } else {
+                               unsigned char data = *vaddr++;
 
-       if ((bucket->pil == 0) || (bucket->pil == 14)) {
-               printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n");
-               return -EBUSY;
-       }
+                               /* write */
+                               writeb(data, stat + 1);
+                       }
+                       size--;
+               }
 
-       spin_lock_irqsave(&irq_action_lock, flags);
+               pdma_vaddr = vaddr;
+               pdma_size = size;
 
-       action = *(bucket->pil + irq_action);
-       if (action) {
-               if (action->flags & SA_SHIRQ)
-                       panic("Trying to register fast irq when already shared.\n");
-               if (irqflags & SA_SHIRQ)
-                       panic("Trying to register fast irq as shared.\n");
-               printk("request_fast_irq: Trying to register yet already owned.\n");
-               spin_unlock_irqrestore(&irq_action_lock, flags);
-               return -EBUSY;
-       }
+               /* Send Terminal Count pulse to floppy controller. */
+               val = readb(auxio_register);
+               val |= AUXIO_AUX1_FTCNT;
+               writeb(val, auxio_register);
+               val &= AUXIO_AUX1_FTCNT;
+               writeb(val, auxio_register);
 
-       /*
-        * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we
-        * support smp intr affinity in this path.
-        */
-       if (irqflags & SA_STATIC_ALLOC) {
-               if (static_irq_count < MAX_STATIC_ALLOC)
-                       action = &static_irqaction[static_irq_count++];
-               else
-                       printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
-                              "using kmalloc\n", bucket->pil, name);
-       }
-       if (action == NULL)
-               action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
-                                                    GFP_ATOMIC);
-       if (!action) {
-               spin_unlock_irqrestore(&irq_action_lock, flags);
-               return -ENOMEM;
+               doing_pdma = 0;
        }
-       install_fast_irq(bucket->pil, handler);
 
-       bucket->irq_info = action;
-       bucket->flags |= IBF_ACTIVE;
-
-       action->handler = handler;
-       action->flags = irqflags;
-       action->dev_id = NULL;
-       action->name = name;
-       action->next = NULL;
-       put_ino_in_irqaction(action, irq);
-       put_smpaff_in_irqaction(action, CPU_MASK_NONE);
-
-       *(bucket->pil + irq_action) = action;
-       enable_irq(irq);
-
-       spin_unlock_irqrestore(&irq_action_lock, flags);
-
-#ifdef CONFIG_SMP
-       distribute_irqs();
-#endif
-       return 0;
+main_interrupt:
+       return floppy_interrupt(irq, dev_cookie, regs);
 }
+EXPORT_SYMBOL(sparc_floppy_irq);
+#endif
 
 /* We really don't need these at all on the Sparc.  We only have
  * stubs here because they are exported to modules.
 
 
 EXPORT_SYMBOL(mostek_lock);
 EXPORT_SYMBOL(mstk48t02_regs);
-EXPORT_SYMBOL(request_fast_irq);
 #ifdef CONFIG_SUN_AUXIO
 EXPORT_SYMBOL(auxio_set_led);
 EXPORT_SYMBOL(auxio_set_lte);
 
 
 #ifndef __ASSEMBLY__
 
+extern void __iomem *auxio_register;
+
 #define AUXIO_LTE_ON   1
 #define AUXIO_LTE_OFF  0
 
 
  * underruns.  If non-zero, doing_pdma encodes the direction of
  * the transfer for debugging.  1=read 2=write
  */
-char *pdma_vaddr;
+unsigned char *pdma_vaddr;
 unsigned long pdma_size;
 volatile int doing_pdma = 0;
 
        pdma_areasize = pdma_size;
 }
 
-/* Our low-level entry point in arch/sparc/kernel/entry.S */
-extern irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs);
+extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *);
 
 static int sun_fd_request_irq(void)
 {
        if(!once) {
                once = 1;
 
-               error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 
-                                        SA_INTERRUPT, "floppy", NULL);
+               error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 
+                                   SA_INTERRUPT, "floppy", NULL);
 
                return ((error == 0) ? 0 : -1);
        }
                struct linux_ebus *ebus;
                struct linux_ebus_device *edev = NULL;
                unsigned long config = 0;
-               unsigned long auxio_reg;
+               void __iomem *auxio_reg;
 
                for_each_ebus(ebus) {
                        for_each_ebusdev(edev, ebus) {
                /* Make sure the high density bit is set, some systems
                 * (most notably Ultra5/Ultra10) come up with it clear.
                 */
-               auxio_reg = edev->resource[2].start;
+               auxio_reg = (void __iomem *) edev->resource[2].start;
                writel(readl(auxio_reg)|0x2, auxio_reg);
 
                sun_pci_ebus_dev = ebus->self;
                spin_lock_init(&sun_pci_fd_ebus_dma.lock);
 
                /* XXX ioremap */
-               sun_pci_fd_ebus_dma.regs = edev->resource[1].start;
+               sun_pci_fd_ebus_dma.regs = (void __iomem *)
+                       edev->resource[1].start;
                if (!sun_pci_fd_ebus_dma.regs)
                        return 0;
 
 
 /* You should not mess with this directly. That's the job of irq.c.
  *
  * If you make changes here, please update hand coded assembler of
- * SBUS/floppy interrupt handler in entry.S -DaveM
+ * the vectored interrupt trap handler in entry.S -DaveM
  *
  * This is currently one DCACHE line, two buckets per L2 cache
  * line.  Keep this in mind please.
 extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap);
 extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
 
-extern int request_fast_irq(unsigned int irq,
-                           irqreturn_t (*handler)(int, void *, struct pt_regs *),
-                           unsigned long flags, __const__ char *devname,
-                           void *dev_id);
-
 static __inline__ void set_softint(unsigned long bits)
 {
        __asm__ __volatile__("wr        %0, 0x0, %%set_softint"