diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index eac38388f5fd3..88d2cefd01bee 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1,7 +1,6 @@
-/* $Id: entry.S,v 1.170 2001/11/13 00:57:05 davem Exp $
- * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
+/* arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  * Copyright (C) 1996-1999 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
@@ -129,7 +128,7 @@ trap_low:
 	RESTORE_ALL
 #endif
 
-#ifdef CONFIG_BLK_DEV_FD
+#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
 	.text
 	.align	4
 	.globl	floppy_hardint
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 75b2240ad0f9e..b76dc03fc3187 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -351,34 +351,14 @@ void handler_irq(int irq, struct pt_regs * regs)
 	set_irq_regs(old_regs);
 }
 
-#ifdef CONFIG_BLK_DEV_FD
-extern void floppy_interrupt(int irq, void *dev_id);
-
-void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct pt_regs *old_regs;
-	int cpu = smp_processor_id();
-
-	old_regs = set_irq_regs(regs);
-	disable_pil_irq(irq);
-	irq_enter();
-	kstat_cpu(cpu).irqs[irq]++;
-	floppy_interrupt(irq, dev_id);
-	irq_exit();
-	enable_pil_irq(irq);
-	set_irq_regs(old_regs);
-	// XXX Eek, it's totally changed with preempt_count() and such
-	// if (softirq_pending(cpu))
-	//	do_softirq();
-}
-#endif
+#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
 
 /* Fast IRQs on the Sparc can only have one routine attached to them,
  * thus no sharing possible.
  */
-int request_fast_irq(unsigned int irq,
-		     irq_handler_t handler,
-		     unsigned long irqflags, const char *devname)
+static int request_fast_irq(unsigned int irq,
+			    void (*handler)(void),
+			    unsigned long irqflags, const char *devname)
 {
 	struct irqaction *action;
 	unsigned long flags;
@@ -457,7 +437,6 @@ int request_fast_irq(unsigned int irq,
 	 */
 	flush_cache_all();
 
-	action->handler = handler;
 	action->flags = irqflags;
 	cpus_clear(action->mask);
 	action->name = devname;
@@ -475,6 +454,61 @@ int request_fast_irq(unsigned int irq,
 	return ret;
 }
 
+/* These variables are used to access state from the assembler
+ * interrupt handler, floppy_hardint, so we cannot put these in
+ * the floppy driver image because that would not work in the
+ * modular case.
+ */
+volatile unsigned char *fdc_status;
+EXPORT_SYMBOL(fdc_status);
+
+char *pdma_vaddr;
+EXPORT_SYMBOL(pdma_vaddr);
+
+unsigned long pdma_size;
+EXPORT_SYMBOL(pdma_size);
+
+volatile int doing_pdma;
+EXPORT_SYMBOL(doing_pdma);
+
+char *pdma_base;
+EXPORT_SYMBOL(pdma_base);
+
+unsigned long pdma_areasize;
+EXPORT_SYMBOL(pdma_areasize);
+
+extern void floppy_hardint(void);
+
+static irqreturn_t (*floppy_irq_handler)(int irq, void *dev_id);
+
+void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct pt_regs *old_regs;
+	int cpu = smp_processor_id();
+
+	old_regs = set_irq_regs(regs);
+	disable_pil_irq(irq);
+	irq_enter();
+	kstat_cpu(cpu).irqs[irq]++;
+	floppy_irq_handler(irq, dev_id);
+	irq_exit();
+	enable_pil_irq(irq);
+	set_irq_regs(old_regs);
+	// XXX Eek, it's totally changed with preempt_count() and such
+	// if (softirq_pending(cpu))
+	//	do_softirq();
+}
+
+int sparc_floppy_request_irq(int irq, unsigned long flags,
+			     irqreturn_t (*irq_handler)(int irq, void *))
+{
+	floppy_irq_handler = irq_handler;
+	return request_fast_irq(irq, floppy_hardint, flags, "floppy");
+}
+EXPORT_SYMBOL(sparc_floppy_request_irq);
+
+#endif
+
 int request_irq(unsigned int irq,
 		irq_handler_t handler,
 		unsigned long irqflags, const char * devname, void *dev_id)
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 7b4abde43028a..ef647acc479e4 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -143,7 +143,6 @@ EXPORT_SYMBOL(mstk48t02_regs);
 EXPORT_SYMBOL(set_auxio);
 EXPORT_SYMBOL(get_auxio);
 #endif
-EXPORT_SYMBOL(request_fast_irq);
 EXPORT_SYMBOL(io_remap_pfn_range);
   /* P3: iounit_xxx may be needed, sun4d users */
 /* EXPORT_SYMBOL(iounit_map_dma_init); */
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 87c7471235387..ee9046db9c7da 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -677,6 +677,7 @@ static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *
 	struct fb_info *info;
 	struct cg6_par *par;
 	int linebytes, err;
+	int dblbuf;
 
 	info = framebuffer_alloc(sizeof(struct cg6_par), &op->dev);
 
@@ -698,7 +699,9 @@ static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *
 	linebytes = of_getintprop_default(dp, "linebytes",
 					  info->var.xres);
 	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
-	if (of_find_property(dp, "dblbuf", NULL))
+
+	dblbuf = of_getintprop_default(dp, "dblbuf", 0);
+	if (dblbuf)
 		par->fbsize *= 4;
 
 	par->fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET,
diff --git a/include/asm-sparc/fcntl.h b/include/asm-sparc/fcntl.h
index 5db60b5ae7b09..7bbdfc77accd6 100644
--- a/include/asm-sparc/fcntl.h
+++ b/include/asm-sparc/fcntl.h
@@ -16,6 +16,7 @@
 #define O_LARGEFILE	0x40000
 #define O_DIRECT        0x100000 /* direct disk access hint */
 #define O_NOATIME	0x200000
+#define O_CLOEXEC	0x400000
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
@@ -31,6 +32,5 @@
 #define __ARCH_FLOCK_PAD	short __unused;
 #define __ARCH_FLOCK64_PAD	short __unused;
 
-#include <asm-generic/fcntl.h>
 
 #endif
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
index 28ce2b9c3da80..acd06d8ff70a0 100644
--- a/include/asm-sparc/floppy.h
+++ b/include/asm-sparc/floppy.h
@@ -48,7 +48,7 @@ struct sun_flpy_controller {
 
 /* You'll only ever find one controller on a SparcStation anyways. */
 static struct sun_flpy_controller *sun_fdc = NULL;
-volatile unsigned char *fdc_status;
+extern volatile unsigned char *fdc_status;
 
 struct sun_floppy_ops {
 	unsigned char (*fd_inb)(int port);
@@ -225,13 +225,13 @@ static void sun_82077_fd_outb(unsigned char value, int port)
  * underruns.  If non-zero, doing_pdma encodes the direction of
  * the transfer for debugging.  1=read 2=write
  */
-char *pdma_vaddr;
-unsigned long pdma_size;
-volatile int doing_pdma = 0;
+extern char *pdma_vaddr;
+extern unsigned long pdma_size;
+extern volatile int doing_pdma;
 
 /* This is software state */
-char *pdma_base = NULL;
-unsigned long pdma_areasize;
+extern char *pdma_base;
+extern unsigned long pdma_areasize;
 
 /* Common routines to all controller types on the Sparc. */
 static __inline__ void virtual_dma_init(void)
@@ -281,7 +281,8 @@ static __inline__ void sun_fd_enable_dma(void)
 }
 
 /* Our low-level entry point in arch/sparc/kernel/entry.S */
-irqreturn_t floppy_hardint(int irq, void *unused);
+extern int sparc_floppy_request_irq(int irq, unsigned long flags,
+				    irqreturn_t (*irq_handler)(int irq, void *));
 
 static int sun_fd_request_irq(void)
 {
@@ -290,8 +291,9 @@ static int sun_fd_request_irq(void)
 
 	if(!once) {
 		once = 1;
-		error = request_fast_irq(FLOPPY_IRQ, floppy_hardint,
-					 IRQF_DISABLED, "floppy");
+		error = sparc_floppy_request_irq(FLOPPY_IRQ,
+						 IRQF_DISABLED,
+						 floppy_interrupt);
 		return ((error == 0) ? 0 : -1);
 	} else return 0;
 }
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
index 61fb99643afd3..fe205cc444b88 100644
--- a/include/asm-sparc/irq.h
+++ b/include/asm-sparc/irq.h
@@ -1,7 +1,6 @@
-/* $Id: irq.h,v 1.32 2000/08/26 02:42:28 anton Exp $
- * irq.h: IRQ registers on the Sparc.
+/* irq.h: IRQ registers on the Sparc.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #ifndef _SPARC_IRQ_H
@@ -13,6 +12,4 @@
 
 #define irq_canonicalize(irq)	(irq)
 
-extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname);
-
 #endif
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index a72a5f271f315..1fc655452b812 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -108,6 +108,25 @@ static inline void dma_sync_single_for_device(struct device *dev,
 	dma_ops->sync_single_for_device(dev, dma_handle, size, direction);
 }
 
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+						 dma_addr_t dma_handle,
+						 unsigned long offset,
+						 size_t size,
+						 enum dma_data_direction direction)
+{
+	dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+						    dma_addr_t dma_handle,
+						    unsigned long offset,
+						    size_t size,
+						    enum dma_data_direction direction)
+{
+	dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
+}
+
+
 static inline void dma_sync_sg_for_cpu(struct device *dev,
 				       struct scatterlist *sg, int nelems,
 				       enum dma_data_direction direction)
diff --git a/include/asm-sparc64/fcntl.h b/include/asm-sparc64/fcntl.h
index b2aecf0054bd2..111f6b3b8925a 100644
--- a/include/asm-sparc64/fcntl.h
+++ b/include/asm-sparc64/fcntl.h
@@ -16,7 +16,7 @@
 #define O_LARGEFILE	0x40000
 #define O_DIRECT        0x100000 /* direct disk access hint */
 #define O_NOATIME	0x200000
-
+#define O_CLOEXEC	0x400000
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index dca0344cc1bc3..f2950cab74a62 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -74,7 +74,6 @@ struct cs4231_dma_control {
         void		(*enable)(struct cs4231_dma_control *dma_cont, int on);
         int		(*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len);
         unsigned int	(*address)(struct cs4231_dma_control *dma_cont);
-        void		(*reset)(struct snd_cs4231 *chip); 
         void		(*preallocate)(struct snd_cs4231 *chip, struct snd_pcm *pcm); 
 #ifdef EBUS_SUPPORT
 	struct		ebus_dma_info	ebus_info;
@@ -1214,10 +1213,6 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
 
 	spin_lock_irqsave(&chip->lock, flags);
 
-
-	/* Reset DMA engine (sbus only).  */
-	chip->p_dma.reset(chip);
-
 	__cs4231_readb(chip, CS4231P(chip, STATUS));	/* clear any pendings IRQ */
 	__cs4231_writeb(chip, 0, CS4231P(chip, STATUS));
 	mb();
@@ -1861,14 +1856,13 @@ static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
 	if (!on) {
 		sbus_writel(0, base->regs + base->dir + APCNC);
 		sbus_writel(0, base->regs + base->dir + APCNVA);
-		sbus_writel(0, base->regs + base->dir + APCC);
-		sbus_writel(0, base->regs + base->dir + APCVA);
+		if ( base->dir == APC_PLAY ) {
+			sbus_writel(0, base->regs + base->dir + APCC);
+			sbus_writel(0, base->regs + base->dir + APCVA);
+		}
 
-		/* ACK any APC interrupts. */
-		csr = sbus_readl(base->regs + APCCSR);
-		sbus_writel(csr, base->regs + APCCSR);
+		udelay(1200);
 	} 
-	udelay(1000);
 	csr = sbus_readl(base->regs + APCCSR);
 	shift = 0;
 	if ( base->dir == APC_PLAY )
@@ -1894,23 +1888,6 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
         return sbus_readl(base->regs + base->dir + APCVA);
 }
 
-static void sbus_dma_reset(struct snd_cs4231 *chip)
-{
-        sbus_writel(APC_CHIP_RESET, chip->port + APCCSR);
-        sbus_writel(0x00, chip->port + APCCSR);
-        sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET,
-		    chip->port + APCCSR);
-  
-        udelay(20);
-  
-        sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET,
-		    chip->port + APCCSR);
-        sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA |
-		       APC_XINT_PENA |
-		       APC_XINT_CENA),
-	               chip->port + APCCSR);
-}
-
 static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
 {
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
@@ -1986,14 +1963,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
 	chip->p_dma.enable = sbus_dma_enable;
 	chip->p_dma.request = sbus_dma_request;
 	chip->p_dma.address = sbus_dma_addr;
-	chip->p_dma.reset = sbus_dma_reset;
 	chip->p_dma.preallocate = sbus_dma_preallocate;
 
 	chip->c_dma.prepare = sbus_dma_prepare;
 	chip->c_dma.enable = sbus_dma_enable;
 	chip->c_dma.request = sbus_dma_request;
 	chip->c_dma.address = sbus_dma_addr;
-	chip->c_dma.reset = sbus_dma_reset;
 	chip->c_dma.preallocate = sbus_dma_preallocate;
 
 	if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
@@ -2087,11 +2062,6 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
 	return ebus_dma_addr(&dma_cont->ebus_info);
 }
 
-static void _ebus_dma_reset(struct snd_cs4231 *chip)
-{
-	return;
-}
-
 static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
 {
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
@@ -2171,14 +2141,12 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
 	chip->p_dma.enable = _ebus_dma_enable;
 	chip->p_dma.request = _ebus_dma_request;
 	chip->p_dma.address = _ebus_dma_addr;
-	chip->p_dma.reset = _ebus_dma_reset;
 	chip->p_dma.preallocate = _ebus_dma_preallocate;
 
 	chip->c_dma.prepare = _ebus_dma_prepare;
 	chip->c_dma.enable = _ebus_dma_enable;
 	chip->c_dma.request = _ebus_dma_request;
 	chip->c_dma.address = _ebus_dma_addr;
-	chip->c_dma.reset = _ebus_dma_reset;
 	chip->c_dma.preallocate = _ebus_dma_preallocate;
 
 	chip->port = ioremap(edev->resource[0].start, 0x10);