From 02603930da19fa447648952873e967fb9663ec18 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 18 Nov 2008 21:13:01 +0100
Subject: [PATCH 01/30] fbdev: atafb - Fix line length handling

  - Make sure par->next_line is always set (this was done for Falcon only),
    as all the text console drawing operations need a valid par->next_line,
  - Make sure fix->line_length is always set, as some userspace applications
    need it because they don't have fallback code for the case where it's zero.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/atafb.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 77eb8b34fbfa..b7646ad71bb3 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -614,7 +614,7 @@ static int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
 	fix->xpanstep = 0;
 	fix->ypanstep = 1;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	fix->accel = FB_ACCEL_ATARIBLITT;
 	return 0;
 }
@@ -691,6 +691,7 @@ static int tt_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
 		return -EINVAL;
 	par->yres_virtual = yres_virtual;
 	par->screen_base = screen_base + var->yoffset * linelen;
+	par->next_line = linelen;
 	return 0;
 }
 
@@ -918,7 +919,7 @@ static int falcon_encode_fix(struct fb_fix_screeninfo *fix,
 		fix->visual = FB_VISUAL_TRUECOLOR;
 		fix->xpanstep = 2;
 	}
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	fix->accel = FB_ACCEL_ATARIBLITT;
 	return 0;
 }
@@ -1852,7 +1853,7 @@ static int stste_encode_fix(struct fb_fix_screeninfo *fix,
 		fix->ypanstep = 0;
 	}
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	fix->accel = FB_ACCEL_ATARIBLITT;
 	return 0;
 }
@@ -1910,6 +1911,7 @@ static int stste_decode_var(struct fb_var_screeninfo *var,
 		return -EINVAL;
 	par->yres_virtual = yres_virtual;
 	par->screen_base = screen_base + var->yoffset * linelen;
+	par->next_line = linelen;
 	return 0;
 }
 
@@ -2169,7 +2171,7 @@ static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
 	fix->xpanstep = 0;
 	fix->ypanstep = 0;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	return 0;
 }
 
@@ -2184,6 +2186,8 @@ static int ext_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
 	    var->xoffset > 0 ||
 	    var->yoffset > 0)
 		return -EINVAL;
+
+	par->next_line = external_xres_virtual * external_depth / 8;
 	return 0;
 }
 

From 74511413dd0b8f6c9f5a47bf045eba434f4fdd2b Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 18 Nov 2008 21:13:01 +0100
Subject: [PATCH 02/30] fbdev: atafb - Fix 16 bpp console

  - 16 bpp must use the cfb_*() ops
  - 16 bpp needs to set up info->pseudo_palette[] (was fbcon_cfb16_cmap[] in
    2.4.x)
  - Kill commented out 2.4.x fbcon remnants

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/atafb.c | 74 ++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 44 deletions(-)

diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index b7646ad71bb3..f932c138fe1d 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -149,6 +149,7 @@ static struct atafb_par {
 			short mono;
 			short ste_mode;
 			short bpp;
+			u32 pseudo_palette[16];
 		} falcon;
 #endif
 		/* Nothing needed for external mode */
@@ -885,10 +886,6 @@ static int vdl_prescale[4][3] = {
 /* Default hsync timing [mon_type] in picoseconds */
 static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
 
-#ifdef FBCON_HAS_CFB16
-static u16 fbcon_cfb16_cmap[16];
-#endif
-
 static inline int hxx_prescale(struct falcon_hw *hw)
 {
 	return hw->ste_mode ? 16
@@ -1736,10 +1733,10 @@ static int falcon_setcolreg(unsigned int regno, unsigned int red,
 			(((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |
 			(((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |
 			((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
-#ifdef FBCON_HAS_CFB16
-		fbcon_cfb16_cmap[regno] = ((red & 0xf800) |
-					   ((green & 0xfc00) >> 5) |
-					   ((blue & 0xf800) >> 11));
+#ifdef ATAFB_FALCON
+		((u32 *)info->pseudo_palette)[regno] = ((red & 0xf800) |
+						       ((green & 0xfc00) >> 5) |
+						       ((blue & 0xf800) >> 11));
 #endif
 	}
 	return 0;
@@ -2447,42 +2444,6 @@ static void atafb_set_disp(struct fb_info *info)
 	atafb_get_fix(&info->fix, info);
 
 	info->screen_base = (void *)info->fix.smem_start;
-
-	switch (info->fix.type) {
-	case FB_TYPE_INTERLEAVED_PLANES:
-		switch (info->var.bits_per_pixel) {
-		case 2:
-			// display->dispsw = &fbcon_iplan2p2;
-			break;
-		case 4:
-			// display->dispsw = &fbcon_iplan2p4;
-			break;
-		case 8:
-			// display->dispsw = &fbcon_iplan2p8;
-			break;
-		}
-		break;
-	case FB_TYPE_PACKED_PIXELS:
-		switch (info->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
-		case 1:
-			// display->dispsw = &fbcon_mfb;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB8
-		case 8:
-			// display->dispsw = &fbcon_cfb8;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16:
-			// display->dispsw = &fbcon_cfb16;
-			// display->dispsw_data = fbcon_cfb16_cmap;
-			break;
-#endif
-		}
-		break;
-	}
 }
 
 static int atafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
@@ -2553,6 +2514,13 @@ static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 	if (!rect->width || !rect->height)
 		return;
 
+#ifdef ATAFB_FALCON
+	if (info->var.bits_per_pixel == 16) {
+		cfb_fillrect(info, rect);
+		return;
+	}
+#endif
+
 	/*
 	 * We could use hardware clipping but on many cards you get around
 	 * hardware clipping by writing to framebuffer directly.
@@ -2587,6 +2555,13 @@ static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 	u32 dx, dy, sx, sy, width, height;
 	int rev_copy = 0;
 
+#ifdef ATAFB_FALCON
+	if (info->var.bits_per_pixel == 16) {
+		cfb_copyarea(info, area);
+		return;
+	}
+#endif
+
 	/* clip the destination */
 	x2 = area->dx + area->width;
 	y2 = area->dy + area->height;
@@ -2636,6 +2611,13 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
 	const char *src;
 	u32 dx, dy, width, height, pitch;
 
+#ifdef ATAFB_FALCON
+	if (info->var.bits_per_pixel == 16) {
+		cfb_imageblit(info, image);
+		return;
+	}
+#endif
+
 	/*
 	 * We could use hardware clipping but on many cards you get around
 	 * hardware clipping by writing to framebuffer directly like we are
@@ -3229,6 +3211,10 @@ int __init atafb_init(void)
 	// tries to read from HW which may not be initialized yet
 	// so set sane var first, then call atafb_set_par
 	atafb_get_var(&fb_info.var, &fb_info);
+
+#ifdef ATAFB_FALCON
+	fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
+#endif
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
 	if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,

From 8280eb8a33d60be4f5fa76d5144f66656c71a680 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 4 Jan 2009 11:42:16 +0100
Subject: [PATCH 03/30] fbdev: c2p - Correct indentation

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/c2p.c | 232 ++++++++++++++++++++++----------------------
 1 file changed, 117 insertions(+), 115 deletions(-)

diff --git a/drivers/video/c2p.c b/drivers/video/c2p.c
index 376bc07ff952..f102b578ce10 100644
--- a/drivers/video/c2p.c
+++ b/drivers/video/c2p.c
@@ -21,71 +21,71 @@
      *  Basic transpose step
      */
 
-#define _transp(d, i1, i2, shift, mask)			\
-    do {						\
-	u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;	\
-	d[i1] ^= t;					\
-	d[i2] ^= t << shift;				\
-    } while (0)
+#define _transp(d, i1, i2, shift, mask)				\
+	do {							\
+		u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;	\
+		d[i1] ^= t;					\
+		d[i2] ^= t << shift;				\
+	} while (0)
 
 static inline u32 get_mask(int n)
 {
-    switch (n) {
+	switch (n) {
 	case 1:
-	    return 0x55555555;
-	    break;
+		return 0x55555555;
+		break;
 
 	case 2:
-	    return 0x33333333;
-	    break;
+		return 0x33333333;
+		break;
 
 	case 4:
-	    return 0x0f0f0f0f;
-	    break;
+		return 0x0f0f0f0f;
+		break;
 
 	case 8:
-	    return 0x00ff00ff;
-	    break;
+		return 0x00ff00ff;
+		break;
 
 	case 16:
-	    return 0x0000ffff;
-	    break;
-    }
-    return 0;
+		return 0x0000ffff;
+		break;
+	}
+	return 0;
 }
 
-#define transp_nx1(d, n)				\
-    do {						\
-	u32 mask = get_mask(n);				\
-	/* First block */				\
-	_transp(d, 0, 1, n, mask);			\
-	/* Second block */				\
-	_transp(d, 2, 3, n, mask);			\
-	/* Third block */				\
-	_transp(d, 4, 5, n, mask);			\
-	/* Fourth block */				\
-	_transp(d, 6, 7, n, mask);			\
-    } while (0)
+#define transp_nx1(d, n)					\
+	do {							\
+		u32 mask = get_mask(n);				\
+		/* First block */				\
+		_transp(d, 0, 1, n, mask);			\
+		/* Second block */				\
+		_transp(d, 2, 3, n, mask);			\
+		/* Third block */				\
+		_transp(d, 4, 5, n, mask);			\
+		/* Fourth block */				\
+		_transp(d, 6, 7, n, mask);			\
+	} while (0)
 
-#define transp_nx2(d, n)				\
-    do {						\
-	u32 mask = get_mask(n);				\
-	/* First block */				\
-	_transp(d, 0, 2, n, mask);			\
-	_transp(d, 1, 3, n, mask);			\
-	/* Second block */				\
-	_transp(d, 4, 6, n, mask);			\
-	_transp(d, 5, 7, n, mask);			\
-    } while (0)
+#define transp_nx2(d, n)					\
+	do {							\
+		u32 mask = get_mask(n);				\
+		/* First block */				\
+		_transp(d, 0, 2, n, mask);			\
+		_transp(d, 1, 3, n, mask);			\
+		/* Second block */				\
+		_transp(d, 4, 6, n, mask);			\
+		_transp(d, 5, 7, n, mask);			\
+	} while (0)
 
-#define transp_nx4(d, n)				\
-    do {						\
-	u32 mask = get_mask(n);				\
-	_transp(d, 0, 4, n, mask);			\
-	_transp(d, 1, 5, n, mask);			\
-	_transp(d, 2, 6, n, mask);			\
-	_transp(d, 3, 7, n, mask);			\
-    } while (0)
+#define transp_nx4(d, n)					\
+	do {							\
+		u32 mask = get_mask(n);				\
+		_transp(d, 0, 4, n, mask);			\
+		_transp(d, 1, 5, n, mask);			\
+		_transp(d, 2, 6, n, mask);			\
+		_transp(d, 3, 7, n, mask);			\
+	} while (0)
 
 #define transp(d, n, m)	transp_nx ## m(d, n)
 
@@ -99,11 +99,11 @@ static inline u32 get_mask(int n)
 
 static void c2p_8bpp(u32 d[8])
 {
-    transp(d, 16, 4);
-    transp(d, 8, 2);
-    transp(d, 4, 1);
-    transp(d, 2, 4);
-    transp(d, 1, 2);
+	transp(d, 16, 4);
+	transp(d, 8, 2);
+	transp(d, 4, 1);
+	transp(d, 2, 4);
+	transp(d, 1, 2);
 }
 
 
@@ -132,10 +132,10 @@ static inline unsigned long comp(unsigned long a, unsigned long b,
 
 static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
 {
-    int i;
+	int i;
 
-    for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = d[perm_c2p_8bpp[i]];
+	for (i = 0; i < bpp; i++, dst += dst_inc)
+		*(u32 *)dst = d[perm_c2p_8bpp[i]];
 }
 
 
@@ -146,10 +146,10 @@ static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
 static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
 				       u32 d[8], u32 mask)
 {
-    int i;
+	int i;
 
-    for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
+	for (i = 0; i < bpp; i++, dst += dst_inc)
+		*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
 }
 
 
@@ -169,63 +169,65 @@ static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
 void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
 	 u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp)
 {
-    int dst_idx;
-    u32 d[8], first, last, w;
-    const u8 *c;
-    u8 *p;
+	int dst_idx;
+	u32 d[8], first, last, w;
+	const u8 *c;
+	u8 *p;
 
-    dst += dy*dst_nextline+(dx & ~31);
-    dst_idx = dx % 32;
-    first = ~0UL >> dst_idx;
-    last = ~(~0UL >> ((dst_idx+width) % 32));
-    while (height--) {
-	c = src;
-	p = dst;
-	w = width;
-	if (dst_idx+width <= 32) {
-	    /* Single destination word */
-	    first &= last;
-	    memset(d, 0, sizeof(d));
-	    memcpy((u8 *)d+dst_idx, c, width);
-	    c += width;
-	    c2p_8bpp(d);
-	    store_planar_masked(p, dst_nextplane, bpp, d, first);
-	    p += 4;
-	} else {
-	    /* Multiple destination words */
-	    w = width;
-	    /* Leading bits */
-	    if (dst_idx) {
-		w = 32 - dst_idx;
-		memset(d, 0, dst_idx);
-		memcpy((u8 *)d+dst_idx, c, w);
-		c += w;
-		c2p_8bpp(d);
-		store_planar_masked(p, dst_nextplane, bpp, d, first);
-		p += 4;
-		w = width-w;
-	    }
-	    /* Main chunk */
-	    while (w >= 32) {
-		memcpy(d, c, 32);
-		c += 32;
-		c2p_8bpp(d);
-		store_planar(p, dst_nextplane, bpp, d);
-		p += 4;
-		w -= 32;
-	    }
-	    /* Trailing bits */
-	    w %= 32;
-	    if (w > 0) {
-		memcpy(d, c, w);
-		memset((u8 *)d+w, 0, 32-w);
-		c2p_8bpp(d);
-		store_planar_masked(p, dst_nextplane, bpp, d, last);
-	    }
+	dst += dy*dst_nextline+(dx & ~31);
+	dst_idx = dx % 32;
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+width) % 32));
+	while (height--) {
+		c = src;
+		p = dst;
+		w = width;
+		if (dst_idx+width <= 32) {
+			/* Single destination word */
+			first &= last;
+			memset(d, 0, sizeof(d));
+			memcpy((u8 *)d+dst_idx, c, width);
+			c += width;
+			c2p_8bpp(d);
+			store_planar_masked(p, dst_nextplane, bpp, d, first);
+			p += 4;
+		} else {
+			/* Multiple destination words */
+			w = width;
+			/* Leading bits */
+			if (dst_idx) {
+				w = 32 - dst_idx;
+				memset(d, 0, dst_idx);
+				memcpy((u8 *)d+dst_idx, c, w);
+				c += w;
+				c2p_8bpp(d);
+				store_planar_masked(p, dst_nextplane, bpp, d,
+						    first);
+				p += 4;
+				w = width-w;
+			}
+			/* Main chunk */
+			while (w >= 32) {
+				memcpy(d, c, 32);
+				c += 32;
+				c2p_8bpp(d);
+				store_planar(p, dst_nextplane, bpp, d);
+				p += 4;
+				w -= 32;
+			}
+			/* Trailing bits */
+			w %= 32;
+			if (w > 0) {
+				memcpy(d, c, w);
+				memset((u8 *)d+w, 0, 32-w);
+				c2p_8bpp(d);
+				store_planar_masked(p, dst_nextplane, bpp, d,
+						    last);
+			}
+		}
+		src += src_nextline;
+		dst += dst_nextline;
 	}
-	src += src_nextline;
-	dst += dst_nextline;
-    }
 }
 EXPORT_SYMBOL_GPL(c2p);
 

From 1f034456c140a8677d0ff3a9bdb3c4b620aae2cb Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 4 Jan 2009 11:43:00 +0100
Subject: [PATCH 04/30] fbdev: c2p - Cleanups

  - Improve comments and naming
  - Convert macros to static inline functions
  - Remove superfluous `break' after `return'
  - Make sure we get a build-time error (undefined reference to
    'c2p_unsupported') in case of future misuse
  - Replace `unsigned long' by `u32' in comp(), as that's what all callers use
  - Use {get,put}_unaligned_be32() in store_planar{,_masked}()
  - Use void * for arbitrary pointers
  - Use a union to represent pixels/words, to avoid casts

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/c2p.c | 175 +++++++++++++++++++++++---------------------
 drivers/video/c2p.h |   6 +-
 2 files changed, 96 insertions(+), 85 deletions(-)

diff --git a/drivers/video/c2p.c b/drivers/video/c2p.c
index f102b578ce10..c170fff0d35e 100644
--- a/drivers/video/c2p.c
+++ b/drivers/video/c2p.c
@@ -1,7 +1,7 @@
 /*
  *  Fast C2P (Chunky-to-Planar) Conversion
  *
- *  Copyright (C) 2003 Geert Uytterhoeven
+ *  Copyright (C) 2003-2008 Geert Uytterhoeven
  *
  *  NOTES:
  *    - This code was inspired by Scout's C2P tutorial
@@ -14,6 +14,9 @@
 
 #include <linux/module.h>
 #include <linux/string.h>
+
+#include <asm/unaligned.h>
+
 #include "c2p.h"
 
 
@@ -21,97 +24,100 @@
      *  Basic transpose step
      */
 
-#define _transp(d, i1, i2, shift, mask)				\
-	do {							\
-		u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;	\
-		d[i1] ^= t;					\
-		d[i2] ^= t << shift;				\
-	} while (0)
+static inline void _transp(u32 d[], unsigned int i1, unsigned int i2,
+			   unsigned int shift, u32 mask)
+{
+	u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;
 
-static inline u32 get_mask(int n)
+	d[i1] ^= t;
+	d[i2] ^= t << shift;
+}
+
+extern void c2p_unsupported(void);
+
+static inline u32 get_mask(unsigned int n)
 {
 	switch (n) {
 	case 1:
 		return 0x55555555;
-		break;
 
 	case 2:
 		return 0x33333333;
-		break;
 
 	case 4:
 		return 0x0f0f0f0f;
-		break;
 
 	case 8:
 		return 0x00ff00ff;
-		break;
 
 	case 16:
 		return 0x0000ffff;
-		break;
 	}
+
+	c2p_unsupported();
 	return 0;
 }
 
-#define transp_nx1(d, n)					\
-	do {							\
-		u32 mask = get_mask(n);				\
-		/* First block */				\
-		_transp(d, 0, 1, n, mask);			\
-		/* Second block */				\
-		_transp(d, 2, 3, n, mask);			\
-		/* Third block */				\
-		_transp(d, 4, 5, n, mask);			\
-		/* Fourth block */				\
-		_transp(d, 6, 7, n, mask);			\
-	} while (0)
+static inline void transp8(u32 d[], unsigned int n, unsigned int m)
+{
+	u32 mask = get_mask(n);
 
-#define transp_nx2(d, n)					\
-	do {							\
-		u32 mask = get_mask(n);				\
-		/* First block */				\
-		_transp(d, 0, 2, n, mask);			\
-		_transp(d, 1, 3, n, mask);			\
-		/* Second block */				\
-		_transp(d, 4, 6, n, mask);			\
-		_transp(d, 5, 7, n, mask);			\
-	} while (0)
+	switch (m) {
+	case 1:
+		/* First n x 1 block */
+		_transp(d, 0, 1, n, mask);
+		/* Second n x 1 block */
+		_transp(d, 2, 3, n, mask);
+		/* Third n x 1 block */
+		_transp(d, 4, 5, n, mask);
+		/* Fourth n x 1 block */
+		_transp(d, 6, 7, n, mask);
+		return;
 
-#define transp_nx4(d, n)					\
-	do {							\
-		u32 mask = get_mask(n);				\
-		_transp(d, 0, 4, n, mask);			\
-		_transp(d, 1, 5, n, mask);			\
-		_transp(d, 2, 6, n, mask);			\
-		_transp(d, 3, 7, n, mask);			\
-	} while (0)
+	case 2:
+		/* First n x 2 block */
+		_transp(d, 0, 2, n, mask);
+		_transp(d, 1, 3, n, mask);
+		/* Second n x 2 block */
+		_transp(d, 4, 6, n, mask);
+		_transp(d, 5, 7, n, mask);
+		return;
 
-#define transp(d, n, m)	transp_nx ## m(d, n)
+	case 4:
+		/* Single n x 4 block */
+		_transp(d, 0, 4, n, mask);
+		_transp(d, 1, 5, n, mask);
+		_transp(d, 2, 6, n, mask);
+		_transp(d, 3, 7, n, mask);
+		return;
+	}
+
+	c2p_unsupported();
+}
 
 
     /*
      *  Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words
      *  containing
      *    - 32 8-bit chunky pixels on input
-     *    - permuted planar data on output
+     *    - permutated planar data (1 plane per 32-bit word) on output
      */
 
-static void c2p_8bpp(u32 d[8])
+static void c2p_32x8(u32 d[8])
 {
-	transp(d, 16, 4);
-	transp(d, 8, 2);
-	transp(d, 4, 1);
-	transp(d, 2, 4);
-	transp(d, 1, 2);
+	transp8(d, 16, 4);
+	transp8(d, 8, 2);
+	transp8(d, 4, 1);
+	transp8(d, 2, 4);
+	transp8(d, 1, 2);
 }
 
 
     /*
-     *  Array containing the permution indices of the planar data after c2p
+     *  Array containing the permutation indices of the planar data after c2p
      */
 
-static const int perm_c2p_8bpp[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
+static const int perm_c2p_32x8[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
 
 
     /*
@@ -119,8 +125,7 @@ static const int perm_c2p_8bpp[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
      *  This is equivalent to (a & mask) | (b & ~mask)
      */
 
-static inline unsigned long comp(unsigned long a, unsigned long b,
-				 unsigned long mask)
+static inline u32 comp(u32 a, u32 b, u32 mask)
 {
 	return ((a ^ b) & mask) ^ b;
 }
@@ -130,12 +135,12 @@ static inline unsigned long comp(unsigned long a, unsigned long b,
      *  Store a full block of planar data after c2p conversion
      */
 
-static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
 {
 	int i;
 
 	for (i = 0; i < bpp; i++, dst += dst_inc)
-		*(u32 *)dst = d[perm_c2p_8bpp[i]];
+		put_unaligned_be32(d[perm_c2p_32x8[i]], dst);
 }
 
 
@@ -143,13 +148,15 @@ static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
      *  Store a partial block of planar data after c2p conversion
      */
 
-static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
 				       u32 d[8], u32 mask)
 {
 	int i;
 
 	for (i = 0; i < bpp; i++, dst += dst_inc)
-		*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
+		put_unaligned_be32(comp(d[perm_c2p_32x8[i]],
+					get_unaligned_be32(dst), mask),
+				   dst);
 }
 
 
@@ -166,18 +173,21 @@ static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
      *  @bpp: Bits per pixel of the planar frame buffer (1-8)
      */
 
-void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
+void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width, u32 height,
 	 u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp)
 {
-	int dst_idx;
-	u32 d[8], first, last, w;
+	union {
+		u8 pixels[32];
+		u32 words[8];
+	} d;
+	u32 dst_idx, first, last, w;
 	const u8 *c;
-	u8 *p;
+	void *p;
 
 	dst += dy*dst_nextline+(dx & ~31);
 	dst_idx = dx % 32;
-	first = ~0UL >> dst_idx;
-	last = ~(~0UL >> ((dst_idx+width) % 32));
+	first = 0xffffffffU >> dst_idx;
+	last = ~(0xffffffffU >> ((dst_idx+width) % 32));
 	while (height--) {
 		c = src;
 		p = dst;
@@ -185,11 +195,12 @@ void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
 		if (dst_idx+width <= 32) {
 			/* Single destination word */
 			first &= last;
-			memset(d, 0, sizeof(d));
-			memcpy((u8 *)d+dst_idx, c, width);
+			memset(d.pixels, 0, sizeof(d));
+			memcpy(d.pixels+dst_idx, c, width);
 			c += width;
-			c2p_8bpp(d);
-			store_planar_masked(p, dst_nextplane, bpp, d, first);
+			c2p_32x8(d.words);
+			store_planar_masked(p, dst_nextplane, bpp, d.words,
+					    first);
 			p += 4;
 		} else {
 			/* Multiple destination words */
@@ -197,32 +208,32 @@ void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
 			/* Leading bits */
 			if (dst_idx) {
 				w = 32 - dst_idx;
-				memset(d, 0, dst_idx);
-				memcpy((u8 *)d+dst_idx, c, w);
+				memset(d.pixels, 0, dst_idx);
+				memcpy(d.pixels+dst_idx, c, w);
 				c += w;
-				c2p_8bpp(d);
-				store_planar_masked(p, dst_nextplane, bpp, d,
-						    first);
+				c2p_32x8(d.words);
+				store_planar_masked(p, dst_nextplane, bpp,
+						    d.words, first);
 				p += 4;
 				w = width-w;
 			}
 			/* Main chunk */
 			while (w >= 32) {
-				memcpy(d, c, 32);
+				memcpy(d.pixels, c, 32);
 				c += 32;
-				c2p_8bpp(d);
-				store_planar(p, dst_nextplane, bpp, d);
+				c2p_32x8(d.words);
+				store_planar(p, dst_nextplane, bpp, d.words);
 				p += 4;
 				w -= 32;
 			}
 			/* Trailing bits */
 			w %= 32;
 			if (w > 0) {
-				memcpy(d, c, w);
-				memset((u8 *)d+w, 0, 32-w);
-				c2p_8bpp(d);
-				store_planar_masked(p, dst_nextplane, bpp, d,
-						    last);
+				memcpy(d.pixels, c, w);
+				memset(d.pixels+w, 0, 32-w);
+				c2p_32x8(d.words);
+				store_planar_masked(p, dst_nextplane, bpp,
+						    d.words, last);
 			}
 		}
 		src += src_nextline;
diff --git a/drivers/video/c2p.h b/drivers/video/c2p.h
index c77cbf17e043..daafd872601c 100644
--- a/drivers/video/c2p.h
+++ b/drivers/video/c2p.h
@@ -10,7 +10,7 @@
 
 #include <linux/types.h>
 
-extern void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
-		u32 dst_nextline, u32 dst_nextplane, u32 src_nextline,
-		u32 bpp);
+extern void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		u32 height, u32 dst_nextline, u32 dst_nextplane,
+		u32 src_nextline, u32 bpp);
 

From 2cd1de0a0ff1d3da08ff1f1437cf4a44deae6a00 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 4 Jan 2009 11:58:20 +0100
Subject: [PATCH 05/30] fbdev: c2p - Extract common c2p core to c2p_core.h

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/c2p.c      |  92 +--------------------------------
 drivers/video/c2p_core.h | 106 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 91 deletions(-)
 create mode 100644 drivers/video/c2p_core.h

diff --git a/drivers/video/c2p.c b/drivers/video/c2p.c
index c170fff0d35e..1238c8b912ea 100644
--- a/drivers/video/c2p.c
+++ b/drivers/video/c2p.c
@@ -3,10 +3,6 @@
  *
  *  Copyright (C) 2003-2008 Geert Uytterhoeven
  *
- *  NOTES:
- *    - This code was inspired by Scout's C2P tutorial
- *    - It assumes to run on a big endian system
- *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License. See the file COPYING in the main directory of this archive
  *  for more details.
@@ -18,82 +14,7 @@
 #include <asm/unaligned.h>
 
 #include "c2p.h"
-
-
-    /*
-     *  Basic transpose step
-     */
-
-static inline void _transp(u32 d[], unsigned int i1, unsigned int i2,
-			   unsigned int shift, u32 mask)
-{
-	u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;
-
-	d[i1] ^= t;
-	d[i2] ^= t << shift;
-}
-
-extern void c2p_unsupported(void);
-
-static inline u32 get_mask(unsigned int n)
-{
-	switch (n) {
-	case 1:
-		return 0x55555555;
-
-	case 2:
-		return 0x33333333;
-
-	case 4:
-		return 0x0f0f0f0f;
-
-	case 8:
-		return 0x00ff00ff;
-
-	case 16:
-		return 0x0000ffff;
-	}
-
-	c2p_unsupported();
-	return 0;
-}
-
-static inline void transp8(u32 d[], unsigned int n, unsigned int m)
-{
-	u32 mask = get_mask(n);
-
-	switch (m) {
-	case 1:
-		/* First n x 1 block */
-		_transp(d, 0, 1, n, mask);
-		/* Second n x 1 block */
-		_transp(d, 2, 3, n, mask);
-		/* Third n x 1 block */
-		_transp(d, 4, 5, n, mask);
-		/* Fourth n x 1 block */
-		_transp(d, 6, 7, n, mask);
-		return;
-
-	case 2:
-		/* First n x 2 block */
-		_transp(d, 0, 2, n, mask);
-		_transp(d, 1, 3, n, mask);
-		/* Second n x 2 block */
-		_transp(d, 4, 6, n, mask);
-		_transp(d, 5, 7, n, mask);
-		return;
-
-	case 4:
-		/* Single n x 4 block */
-		_transp(d, 0, 4, n, mask);
-		_transp(d, 1, 5, n, mask);
-		_transp(d, 2, 6, n, mask);
-		_transp(d, 3, 7, n, mask);
-		return;
-	}
-
-	c2p_unsupported();
-}
+#include "c2p_core.h"
 
 
     /*
@@ -120,17 +41,6 @@ static void c2p_32x8(u32 d[8])
 static const int perm_c2p_32x8[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
 
 
-    /*
-     *  Compose two values, using a bitmask as decision value
-     *  This is equivalent to (a & mask) | (b & ~mask)
-     */
-
-static inline u32 comp(u32 a, u32 b, u32 mask)
-{
-	return ((a ^ b) & mask) ^ b;
-}
-
-
     /*
      *  Store a full block of planar data after c2p conversion
      */
diff --git a/drivers/video/c2p_core.h b/drivers/video/c2p_core.h
new file mode 100644
index 000000000000..3573cf723e43
--- /dev/null
+++ b/drivers/video/c2p_core.h
@@ -0,0 +1,106 @@
+/*
+ *  Fast C2P (Chunky-to-Planar) Conversion
+ *
+ *  Copyright (C) 2003-2008 Geert Uytterhoeven
+ *
+ *  NOTES:
+ *    - This code was inspired by Scout's C2P tutorial
+ *    - It assumes to run on a big endian system
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+
+    /*
+     *  Basic transpose step
+     */
+
+static inline void _transp(u32 d[], unsigned int i1, unsigned int i2,
+			   unsigned int shift, u32 mask)
+{
+	u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;
+
+	d[i1] ^= t;
+	d[i2] ^= t << shift;
+}
+
+
+extern void c2p_unsupported(void);
+
+static inline u32 get_mask(unsigned int n)
+{
+	switch (n) {
+	case 1:
+		return 0x55555555;
+
+	case 2:
+		return 0x33333333;
+
+	case 4:
+		return 0x0f0f0f0f;
+
+	case 8:
+		return 0x00ff00ff;
+
+	case 16:
+		return 0x0000ffff;
+	}
+
+	c2p_unsupported();
+	return 0;
+}
+
+
+    /*
+     *  Transpose operations on 8 32-bit words
+     */
+
+static inline void transp8(u32 d[], unsigned int n, unsigned int m)
+{
+	u32 mask = get_mask(n);
+
+	switch (m) {
+	case 1:
+		/* First n x 1 block */
+		_transp(d, 0, 1, n, mask);
+		/* Second n x 1 block */
+		_transp(d, 2, 3, n, mask);
+		/* Third n x 1 block */
+		_transp(d, 4, 5, n, mask);
+		/* Fourth n x 1 block */
+		_transp(d, 6, 7, n, mask);
+		return;
+
+	case 2:
+		/* First n x 2 block */
+		_transp(d, 0, 2, n, mask);
+		_transp(d, 1, 3, n, mask);
+		/* Second n x 2 block */
+		_transp(d, 4, 6, n, mask);
+		_transp(d, 5, 7, n, mask);
+		return;
+
+	case 4:
+		/* Single n x 4 block */
+		_transp(d, 0, 4, n, mask);
+		_transp(d, 1, 5, n, mask);
+		_transp(d, 2, 6, n, mask);
+		_transp(d, 3, 7, n, mask);
+		return;
+	}
+
+	c2p_unsupported();
+}
+
+
+    /*
+     *  Compose two values, using a bitmask as decision value
+     *  This is equivalent to (a & mask) | (b & ~mask)
+     */
+
+static inline u32 comp(u32 a, u32 b, u32 mask)
+{
+	return ((a ^ b) & mask) ^ b;
+}

From 96f47d6105203ab06c2004e26979dea153bce073 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 21 Dec 2008 15:48:12 +0100
Subject: [PATCH 06/30] fbdev: c2p/atafb - Add support for Atari interleaved
 bitplanes

The c2p() for normal bitplanes is not suitable for interleaved bitplanes with
2 bytes of interleave, causing a garbled penguin logo. Add c2p_iplan2().

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/Makefile     |   2 +-
 drivers/video/atafb.c      |  15 +---
 drivers/video/c2p.h        |   5 +-
 drivers/video/c2p_core.h   |  47 ++++++++++++
 drivers/video/c2p_iplan2.c | 153 +++++++++++++++++++++++++++++++++++++
 5 files changed, 208 insertions(+), 14 deletions(-)
 create mode 100644 drivers/video/c2p_iplan2.c

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index e39e33e797da..4fc29eae5152 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -72,7 +72,7 @@ obj-$(CONFIG_FB_TCX)              += tcx.o sbuslib.o
 obj-$(CONFIG_FB_LEO)              += leo.o sbuslib.o
 obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o
 obj-$(CONFIG_FB_ACORN)            += acornfb.o
-obj-$(CONFIG_FB_ATARI)            += atafb.o c2p.o atafb_mfb.o \
+obj-$(CONFIG_FB_ATARI)            += atafb.o c2p_iplan2.o atafb_mfb.o \
                                      atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
 obj-$(CONFIG_FB_MAC)              += macfb.o
 obj-$(CONFIG_FB_HECUBA)           += hecubafb.o
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index f932c138fe1d..477ce55bbae9 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -122,7 +122,6 @@ static struct atafb_par {
 	void *screen_base;
 	int yres_virtual;
 	u_long next_line;
-	u_long next_plane;
 #if defined ATAFB_TT || defined ATAFB_STE
 	union {
 		struct {
@@ -1392,14 +1391,7 @@ set_screen_base:
 	par->screen_base = screen_base + var->yoffset * linelen;
 	par->hw.falcon.xoffset = 0;
 
-	// FIXME!!! sort of works, no crash
-	//par->next_line = linelen;
-	//par->next_plane = yres_virtual * linelen;
 	par->next_line = linelen;
-	par->next_plane = 2;
-	// crashes
-	//par->next_plane = linelen;
-	//par->next_line  = yres_virtual * linelen;
 
 	return 0;
 }
@@ -2662,10 +2654,9 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
 			src += pitch;
 		}
 	} else {
-		// only used for logo; broken
-		c2p(info->screen_base, image->data, dx, dy, width, height,
-		    par->next_line, par->next_plane, image->width,
-		    info->var.bits_per_pixel);
+		c2p_iplan2(info->screen_base, image->data, dx, dy, width,
+			   height, par->next_line, image->width,
+			   info->var.bits_per_pixel);
 	}
 }
 
diff --git a/drivers/video/c2p.h b/drivers/video/c2p.h
index daafd872601c..53641298b924 100644
--- a/drivers/video/c2p.h
+++ b/drivers/video/c2p.h
@@ -1,7 +1,7 @@
 /*
  *  Fast C2P (Chunky-to-Planar) Conversion
  *
- *  Copyright (C) 2003 Geert Uytterhoeven
+ *  Copyright (C) 2003-2008 Geert Uytterhoeven
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License. See the file COPYING in the main directory of this archive
@@ -14,3 +14,6 @@ extern void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width,
 		u32 height, u32 dst_nextline, u32 dst_nextplane,
 		u32 src_nextline, u32 bpp);
 
+extern void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		       u32 height, u32 dst_nextline, u32 src_nextline,
+		       u32 bpp);
diff --git a/drivers/video/c2p_core.h b/drivers/video/c2p_core.h
index 3573cf723e43..e1035a865fb9 100644
--- a/drivers/video/c2p_core.h
+++ b/drivers/video/c2p_core.h
@@ -95,6 +95,53 @@ static inline void transp8(u32 d[], unsigned int n, unsigned int m)
 }
 
 
+    /*
+     *  Transpose operations on 4 32-bit words
+     */
+
+static inline void transp4(u32 d[], unsigned int n, unsigned int m)
+{
+	u32 mask = get_mask(n);
+
+	switch (m) {
+	case 1:
+		/* First n x 1 block */
+		_transp(d, 0, 1, n, mask);
+		/* Second n x 1 block */
+		_transp(d, 2, 3, n, mask);
+		return;
+
+	case 2:
+		/* Single n x 2 block */
+		_transp(d, 0, 2, n, mask);
+		_transp(d, 1, 3, n, mask);
+		return;
+	}
+
+	c2p_unsupported();
+}
+
+
+    /*
+     *  Transpose operations on 4 32-bit words (reverse order)
+     */
+
+static inline void transp4x(u32 d[], unsigned int n, unsigned int m)
+{
+	u32 mask = get_mask(n);
+
+	switch (m) {
+	case 2:
+		/* Single n x 2 block */
+		_transp(d, 2, 0, n, mask);
+		_transp(d, 3, 1, n, mask);
+		return;
+	}
+
+	c2p_unsupported();
+}
+
+
     /*
      *  Compose two values, using a bitmask as decision value
      *  This is equivalent to (a & mask) | (b & ~mask)
diff --git a/drivers/video/c2p_iplan2.c b/drivers/video/c2p_iplan2.c
new file mode 100644
index 000000000000..19156dc6158c
--- /dev/null
+++ b/drivers/video/c2p_iplan2.c
@@ -0,0 +1,153 @@
+/*
+ *  Fast C2P (Chunky-to-Planar) Conversion
+ *
+ *  Copyright (C) 2003-2008 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <asm/unaligned.h>
+
+#include "c2p.h"
+#include "c2p_core.h"
+
+
+    /*
+     *  Perform a full C2P step on 16 8-bit pixels, stored in 4 32-bit words
+     *  containing
+     *    - 16 8-bit chunky pixels on input
+     *    - permutated planar data (2 planes per 32-bit word) on output
+     */
+
+static void c2p_16x8(u32 d[4])
+{
+	transp4(d, 8, 2);
+	transp4(d, 1, 2);
+	transp4x(d, 16, 2);
+	transp4x(d, 2, 2);
+	transp4(d, 4, 1);
+}
+
+
+    /*
+     *  Array containing the permutation indices of the planar data after c2p
+     */
+
+static const int perm_c2p_16x8[4] = { 1, 3, 0, 2 };
+
+
+    /*
+     *  Store a full block of iplan2 data after c2p conversion
+     */
+
+static inline void store_iplan2(void *dst, u32 bpp, u32 d[4])
+{
+	int i;
+
+	for (i = 0; i < bpp/2; i++, dst += 4)
+		put_unaligned_be32(d[perm_c2p_16x8[i]], dst);
+}
+
+
+    /*
+     *  Store a partial block of iplan2 data after c2p conversion
+     */
+
+static inline void store_iplan2_masked(void *dst, u32 bpp, u32 d[4], u32 mask)
+{
+	int i;
+
+	for (i = 0; i < bpp/2; i++, dst += 4)
+		put_unaligned_be32(comp(d[perm_c2p_16x8[i]],
+					get_unaligned_be32(dst), mask),
+				   dst);
+}
+
+
+    /*
+     *  c2p_iplan2 - Copy 8-bit chunky image data to an interleaved planar
+     *  frame buffer with 2 bytes of interleave
+     *  @dst: Starting address of the planar frame buffer
+     *  @dx: Horizontal destination offset (in pixels)
+     *  @dy: Vertical destination offset (in pixels)
+     *  @width: Image width (in pixels)
+     *  @height: Image height (in pixels)
+     *  @dst_nextline: Frame buffer offset to the next line (in bytes)
+     *  @src_nextline: Image offset to the next line (in bytes)
+     *  @bpp: Bits per pixel of the planar frame buffer (2, 4, or 8)
+     */
+
+void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		u32 height, u32 dst_nextline, u32 src_nextline, u32 bpp)
+{
+	union {
+		u8 pixels[16];
+		u32 words[4];
+	} d;
+	u32 dst_idx, first, last, w;
+	const u8 *c;
+	void *p;
+
+	dst += dy*dst_nextline+(dx & ~15)*bpp;
+	dst_idx = dx % 16;
+	first = 0xffffU >> dst_idx;
+	first |= first << 16;
+	last = 0xffffU ^ (0xffffU >> ((dst_idx+width) % 16));
+	last |= last << 16;
+	while (height--) {
+		c = src;
+		p = dst;
+		w = width;
+		if (dst_idx+width <= 16) {
+			/* Single destination word */
+			first &= last;
+			memset(d.pixels, 0, sizeof(d));
+			memcpy(d.pixels+dst_idx, c, width);
+			c += width;
+			c2p_16x8(d.words);
+			store_iplan2_masked(p, bpp, d.words, first);
+			p += bpp*2;
+		} else {
+			/* Multiple destination words */
+			w = width;
+			/* Leading bits */
+			if (dst_idx) {
+				w = 16 - dst_idx;
+				memset(d.pixels, 0, dst_idx);
+				memcpy(d.pixels+dst_idx, c, w);
+				c += w;
+				c2p_16x8(d.words);
+				store_iplan2_masked(p, bpp, d.words, first);
+				p += bpp*2;
+				w = width-w;
+			}
+			/* Main chunk */
+			while (w >= 16) {
+				memcpy(d.pixels, c, 16);
+				c += 16;
+				c2p_16x8(d.words);
+				store_iplan2(p, bpp, d.words);
+				p += bpp*2;
+				w -= 16;
+			}
+			/* Trailing bits */
+			w %= 16;
+			if (w > 0) {
+				memcpy(d.pixels, c, w);
+				memset(d.pixels+w, 0, 16-w);
+				c2p_16x8(d.words);
+				store_iplan2_masked(p, bpp, d.words, last);
+			}
+		}
+		src += src_nextline;
+		dst += dst_nextline;
+	}
+}
+EXPORT_SYMBOL_GPL(c2p_iplan2);
+
+MODULE_LICENSE("GPL");

From 2eab7ff843d2cb8c9b2ace869774bd85b2316090 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 21 Dec 2008 15:48:13 +0100
Subject: [PATCH 07/30] fbdev: c2p - Rename c2p to c2p_planar

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/Makefile                | 2 +-
 drivers/video/amifb.c                 | 6 +++---
 drivers/video/c2p.h                   | 6 +++---
 drivers/video/{c2p.c => c2p_planar.c} | 9 +++++----
 4 files changed, 12 insertions(+), 11 deletions(-)
 rename drivers/video/{c2p.c => c2p_planar.c} (93%)

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 4fc29eae5152..be2b657546ef 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_FB_DDC)           += fb_ddc.o
 obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
 
 # Hardware specific drivers go first
-obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
+obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index b8e9a8682f2d..100f23661465 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2159,9 +2159,9 @@ static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
 			src += pitch;
 		}
 	} else {
-		c2p(info->screen_base, image->data, dx, dy, width, height,
-		    par->next_line, par->next_plane, image->width,
-		    info->var.bits_per_pixel);
+		c2p_planar(info->screen_base, image->data, dx, dy, width,
+			   height, par->next_line, par->next_plane,
+			   image->width, info->var.bits_per_pixel);
 	}
 }
 
diff --git a/drivers/video/c2p.h b/drivers/video/c2p.h
index 53641298b924..6c38d40427d8 100644
--- a/drivers/video/c2p.h
+++ b/drivers/video/c2p.h
@@ -10,9 +10,9 @@
 
 #include <linux/types.h>
 
-extern void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width,
-		u32 height, u32 dst_nextline, u32 dst_nextplane,
-		u32 src_nextline, u32 bpp);
+extern void c2p_planar(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		       u32 height, u32 dst_nextline, u32 dst_nextplane,
+		       u32 src_nextline, u32 bpp);
 
 extern void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
 		       u32 height, u32 dst_nextline, u32 src_nextline,
diff --git a/drivers/video/c2p.c b/drivers/video/c2p_planar.c
similarity index 93%
rename from drivers/video/c2p.c
rename to drivers/video/c2p_planar.c
index 1238c8b912ea..ec7ac8526f06 100644
--- a/drivers/video/c2p.c
+++ b/drivers/video/c2p_planar.c
@@ -71,7 +71,7 @@ static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
 
 
     /*
-     *  c2p - Copy 8-bit chunky image data to a planar frame buffer
+     *  c2p_planar - Copy 8-bit chunky image data to a planar frame buffer
      *  @dst: Starting address of the planar frame buffer
      *  @dx: Horizontal destination offset (in pixels)
      *  @dy: Vertical destination offset (in pixels)
@@ -83,8 +83,9 @@ static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
      *  @bpp: Bits per pixel of the planar frame buffer (1-8)
      */
 
-void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width, u32 height,
-	 u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp)
+void c2p_planar(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		u32 height, u32 dst_nextline, u32 dst_nextplane,
+		u32 src_nextline, u32 bpp)
 {
 	union {
 		u8 pixels[32];
@@ -150,6 +151,6 @@ void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width, u32 height,
 		dst += dst_nextline;
 	}
 }
-EXPORT_SYMBOL_GPL(c2p);
+EXPORT_SYMBOL_GPL(c2p_planar);
 
 MODULE_LICENSE("GPL");

From 2455e3c60583961c6f3ddb33201a422404564d8f Mon Sep 17 00:00:00 2001
From: Kars de Jong <jongk@linux-m68k.org>
Date: Thu, 20 Nov 2008 14:28:30 +0100
Subject: [PATCH 08/30] m68k: Add vmlinux.lds to .gitignore

arch/m68k/kernel/.gitignore: Added vmlinux.lds to .gitignore file because it
shouldn't be tracked.

Signed-off-by: Kars de Jong <jongk@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/kernel/.gitignore | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 arch/m68k/kernel/.gitignore

diff --git a/arch/m68k/kernel/.gitignore b/arch/m68k/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/m68k/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds

From dc8ee69c760317be0bb4eac2bd2fd81eb663627a Mon Sep 17 00:00:00 2001
From: Kars de Jong <jongk@linux-m68k.org>
Date: Fri, 21 Nov 2008 13:18:12 +0100
Subject: [PATCH 09/30] m68k: zorro - Add devlist.h and gen-devlist to
 .gitignore

drivers/zorro/.gitignore: Added devlist.h and gen-devlist to .gitignore file
because they shouldn't be tracked.

Signed-off-by: Kars de Jong <jongk@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/zorro/.gitignore | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 drivers/zorro/.gitignore

diff --git a/drivers/zorro/.gitignore b/drivers/zorro/.gitignore
new file mode 100644
index 000000000000..34f980bd8ff6
--- /dev/null
+++ b/drivers/zorro/.gitignore
@@ -0,0 +1,2 @@
+devlist.h
+gen-devlist

From 6d0be946e150ac17da7381b27fd40603ca40b58f Mon Sep 17 00:00:00 2001
From: Andreas Bombe <aeb@debian.org>
Date: Wed, 10 Dec 2008 02:02:19 +0100
Subject: [PATCH 10/30] m68k: amiflop - Get rid of sleep_on calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Apart from sleep_on() calls that could be easily converted to
wait_event() and completion calls amiflop also used a flag in ms_delay()
and ms_isr() as a custom mutex for ms_delay() without a need for
explicit unlocking.  I converted that to a standard mutex.

The replacement for the unconditional sleep_on() in fd_motor_on() is a
complete_all() together with a INIT_COMPLETION() before the mod_timer()
call.  It appears to me that fd_motor_on() might be called concurrently
and fd_select() does not guarantee mutual exclusivity in the case the
same drive gets selected again.

Signed-off-by: Andreas Bombe <aeb@debian.org>
Acked-by: Jörg Dorchain <joerg@dorchain.net>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/block/amiflop.c | 40 ++++++++++++++++------------------------
 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 4b1d4ac960f1..8df436ff7068 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -156,7 +156,7 @@ static volatile int fdc_busy = -1;
 static volatile int fdc_nested;
 static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
  
-static DECLARE_WAIT_QUEUE_HEAD(motor_wait);
+static DECLARE_COMPLETION(motor_on_completion);
 
 static volatile int selected = -1;	/* currently selected drive */
 
@@ -184,8 +184,7 @@ static unsigned char mfmencode[16]={
 static unsigned char mfmdecode[128];
 
 /* floppy internal millisecond timer stuff */
-static volatile int ms_busy = -1;
-static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
+static DECLARE_COMPLETION(ms_wait_completion);
 #define MS_TICKS ((amiga_eclock+50)/1000)
 
 /*
@@ -211,8 +210,7 @@ static int fd_device[4] = { 0, 0, 0, 0 };
 
 static irqreturn_t ms_isr(int irq, void *dummy)
 {
-	ms_busy = -1;
-	wake_up(&ms_wait);
+	complete(&ms_wait_completion);
 	return IRQ_HANDLED;
 }
 
@@ -220,19 +218,17 @@ static irqreturn_t ms_isr(int irq, void *dummy)
    A more generic routine would do a schedule a la timer.device */
 static void ms_delay(int ms)
 {
-	unsigned long flags;
 	int ticks;
+	static DEFINE_MUTEX(mutex);
+
 	if (ms > 0) {
-		local_irq_save(flags);
-		while (ms_busy == 0)
-			sleep_on(&ms_wait);
-		ms_busy = 0;
-		local_irq_restore(flags);
+		mutex_lock(&mutex);
 		ticks = MS_TICKS*ms-1;
 		ciaa.tblo=ticks%256;
 		ciaa.tbhi=ticks/256;
 		ciaa.crb=0x19; /*count eclock, force load, one-shoot, start */
-		sleep_on(&ms_wait);
+		wait_for_completion(&ms_wait_completion);
+		mutex_unlock(&mutex);
 	}
 }
 
@@ -254,8 +250,7 @@ static void get_fdc(int drive)
 	printk("get_fdc: drive %d  fdc_busy %d  fdc_nested %d\n",drive,fdc_busy,fdc_nested);
 #endif
 	local_irq_save(flags);
-	while (!try_fdc(drive))
-		sleep_on(&fdc_wait);
+	wait_event(fdc_wait, try_fdc(drive));
 	fdc_busy = drive;
 	fdc_nested++;
 	local_irq_restore(flags);
@@ -330,7 +325,7 @@ static void fd_deselect (int drive)
 static void motor_on_callback(unsigned long nr)
 {
 	if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
-		wake_up (&motor_wait);
+		complete_all(&motor_on_completion);
 	} else {
 		motor_on_timer.expires = jiffies + HZ/10;
 		add_timer(&motor_on_timer);
@@ -347,11 +342,12 @@ static int fd_motor_on(int nr)
 		unit[nr].motor = 1;
 		fd_select(nr);
 
+		INIT_COMPLETION(motor_on_completion);
 		motor_on_timer.data = nr;
 		mod_timer(&motor_on_timer, jiffies + HZ/2);
 
 		on_attempts = 10;
-		sleep_on (&motor_wait);
+		wait_for_completion(&motor_on_completion);
 		fd_deselect(nr);
 	}
 
@@ -582,8 +578,7 @@ static void raw_read(int drive)
 {
 	drive&=3;
 	get_fdc(drive);
-	while (block_flag)
-		sleep_on(&wait_fd_block);
+	wait_event(wait_fd_block, !block_flag);
 	fd_select(drive);
 	/* setup adkcon bits correctly */
 	custom.adkcon = ADK_MSBSYNC;
@@ -598,8 +593,7 @@ static void raw_read(int drive)
 
 	block_flag = 1;
 
-	while (block_flag)
-		sleep_on (&wait_fd_block);
+	wait_event(wait_fd_block, !block_flag);
 
 	custom.dsklen = 0;
 	fd_deselect(drive);
@@ -616,8 +610,7 @@ static int raw_write(int drive)
 		rel_fdc();
 		return 0;
 	}
-	while (block_flag)
-		sleep_on(&wait_fd_block);
+	wait_event(wait_fd_block, !block_flag);
 	fd_select(drive);
 	/* clear adkcon bits */
 	custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
@@ -1294,8 +1287,7 @@ static int non_int_flush_track (unsigned long nr)
 			writepending = 0;
 			return 0;
 		}
-		while (block_flag == 2)
-			sleep_on (&wait_fd_block);
+		wait_event(wait_fd_block, block_flag != 2);
 	}
 	else {
 		local_irq_restore(flags);

From c85627fbf5f47045b25bf66f1b4a7001b5b157af Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 21 Dec 2008 12:03:37 +0100
Subject: [PATCH 11/30] m68k: Kill several external declarations in source
 files

  - Replace external declarations by proper includes where availiable.
    The accesses to some symbols had to be modified, as before they were
    declared using e.g. "extern int _end", while asm-generic/sections.h uses
    e.g. "extern char _end[]"
  - Remove unused or superfluous external declarations

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/apollo/config.c   |  4 ----
 arch/m68k/atari/atakeyb.c   |  1 -
 arch/m68k/bvme6000/config.c |  1 -
 arch/m68k/kernel/setup.c    | 11 +++++------
 arch/m68k/mac/config.c      | 12 ------------
 arch/m68k/mac/debug.c       |  1 -
 arch/m68k/mac/macints.c     | 10 +---------
 arch/m68k/mac/misc.c        |  1 -
 arch/m68k/mac/via.c         |  2 +-
 arch/m68k/math-emu/fp_log.c |  1 -
 arch/m68k/mm/init.c         |  4 +---
 arch/m68k/mm/motorola.c     |  7 +++----
 arch/m68k/mvme147/config.c  |  1 -
 arch/m68k/mvme16x/config.c  |  1 -
 arch/m68k/q40/config.c      |  3 ---
 arch/m68k/sun3/config.c     |  8 +++-----
 arch/m68k/sun3/mmu_emu.c    |  1 -
 arch/m68k/sun3x/config.c    |  1 -
 18 files changed, 14 insertions(+), 56 deletions(-)

diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 78df98f2029a..cf215a082cc6 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -31,10 +31,6 @@ extern unsigned long dn_gettimeoffset(void);
 extern int dn_dummy_hwclk(int, struct rtc_time *);
 extern int dn_dummy_set_clock_mmss(unsigned long);
 extern void dn_dummy_reset(void);
-extern void dn_dummy_waitbut(void);
-extern struct fb_info *dn_fb_init(long *);
-extern void dn_dummy_debug_init(void);
-extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp);
 #ifdef CONFIG_HEARTBEAT
 static void dn_heartbeat(int on);
 #endif
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index c038b7c7eff0..f3c343be51ee 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -33,7 +33,6 @@
 #include <asm/atari_joystick.h>
 #include <asm/irq.h>
 
-extern unsigned int keymap_count;
 
 /* Hook for MIDI serial driver */
 void (*atari_MIDI_interrupt_hook) (void);
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index c072595928c0..9fe6fefb5e14 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -43,7 +43,6 @@ extern unsigned long bvme6000_gettimeoffset (void);
 extern int bvme6000_hwclk (int, struct rtc_time *);
 extern int bvme6000_set_clock_mmss (unsigned long);
 extern void bvme6000_reset (void);
-extern void bvme6000_waitbut(void);
 void bvme6000_set_vectors (void);
 
 /* Save tick handler routine pointer, will point to do_timer() in
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 4d97bd2bd573..303730afb1c9 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -26,6 +26,7 @@
 #include <linux/initrd.h>
 
 #include <asm/bootinfo.h>
+#include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/fpu.h>
 #include <asm/irq.h>
@@ -62,7 +63,6 @@ EXPORT_SYMBOL(vme_brdtype);
 int m68k_is040or060;
 EXPORT_SYMBOL(m68k_is040or060);
 
-extern int end;
 extern unsigned long availmem;
 
 int m68k_num_memory;
@@ -215,11 +215,10 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
 
 void __init setup_arch(char **cmdline_p)
 {
-	extern int _etext, _edata, _end;
 	int i;
 
 	/* The bootinfo is located right after the kernel bss */
-	m68k_parse_bootinfo((const struct bi_record *)&_end);
+	m68k_parse_bootinfo((const struct bi_record *)_end);
 
 	if (CPU_IS_040)
 		m68k_is040or060 = 4;
@@ -252,9 +251,9 @@ void __init setup_arch(char **cmdline_p)
 	}
 
 	init_mm.start_code = PAGE_OFFSET;
-	init_mm.end_code = (unsigned long) &_etext;
-	init_mm.end_data = (unsigned long) &_edata;
-	init_mm.brk = (unsigned long) &_end;
+	init_mm.end_code = (unsigned long)_etext;
+	init_mm.end_data = (unsigned long)_edata;
+	init_mm.brk = (unsigned long)_end;
 
 	*cmdline_p = m68k_command_line;
 	memcpy(boot_command_line, *cmdline_p, CL_SIZE);
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 8819b97be324..98b6bcfb37bf 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -47,13 +47,6 @@
 
 struct mac_booter_data mac_bi_data;
 
-/* New m68k bootinfo stuff and videobase */
-
-extern int m68k_num_memory;
-extern struct mem_info m68k_memory[NUM_MEMINFO];
-
-extern struct mem_info m68k_ramdisk;
-
 /* The phys. video addr. - might be bogus on some machines */
 static unsigned long mac_orig_videoaddr;
 
@@ -61,7 +54,6 @@ static unsigned long mac_orig_videoaddr;
 extern unsigned long mac_gettimeoffset(void);
 extern int mac_hwclk(int, struct rtc_time *);
 extern int mac_set_clock_mmss(unsigned long);
-extern int show_mac_interrupts(struct seq_file *, void *);
 extern void iop_preinit(void);
 extern void iop_init(void);
 extern void via_init(void);
@@ -805,10 +797,6 @@ static void __init mac_identify(void)
 		mac_bi_data.boottime, mac_bi_data.gmtbias);
 	printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n",
 		mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize);
-#if 0
-	printk("Ramdisk: addr 0x%lx size 0x%lx\n",
-		m68k_ramdisk.addr, m68k_ramdisk.size);
-#endif
 
 	iop_init();
 	via_init();
diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c
index 65dd77a742a3..bce074ceb768 100644
--- a/arch/m68k/mac/debug.c
+++ b/arch/m68k/mac/debug.c
@@ -27,7 +27,6 @@
 #include <asm/macints.h>
 
 extern unsigned long mac_videobase;
-extern unsigned long mac_videodepth;
 extern unsigned long mac_rowbytes;
 
 extern void mac_serial_print(const char *);
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 82e560c076ce..7d0cbf3e1ff3 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -134,6 +134,7 @@
 #include <asm/errno.h>
 #include <asm/macints.h>
 #include <asm/irq_regs.h>
+#include <asm/mac_oss.h>
 
 #define DEBUG_SPURIOUS
 #define SHUTUP_SONIC
@@ -146,7 +147,6 @@ static int scc_mask;
  * VIA/RBV hooks
  */
 
-extern void via_init(void);
 extern void via_register_interrupts(void);
 extern void via_irq_enable(int);
 extern void via_irq_disable(int);
@@ -157,9 +157,6 @@ extern int  via_irq_pending(int);
  * OSS hooks
  */
 
-extern int oss_present;
-
-extern void oss_init(void);
 extern void oss_register_interrupts(void);
 extern void oss_irq_enable(int);
 extern void oss_irq_disable(int);
@@ -170,9 +167,6 @@ extern int  oss_irq_pending(int);
  * PSC hooks
  */
 
-extern int psc_present;
-
-extern void psc_init(void);
 extern void psc_register_interrupts(void);
 extern void psc_irq_enable(int);
 extern void psc_irq_disable(int);
@@ -191,12 +185,10 @@ extern void iop_register_interrupts(void);
 
 extern int baboon_present;
 
-extern void baboon_init(void);
 extern void baboon_register_interrupts(void);
 extern void baboon_irq_enable(int);
 extern void baboon_irq_disable(int);
 extern void baboon_irq_clear(int);
-extern int  baboon_irq_pending(int);
 
 /*
  * SCC interrupt routines
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index a44c7086ab39..5d818568b343 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -35,7 +35,6 @@
 
 #define RTC_OFFSET 2082844800
 
-extern struct mac_booter_data mac_bi_data;
 static void (*rom_reset)(void);
 
 #ifdef CONFIG_ADB_CUDA
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index f01d418e64fe..dfffb9c483a2 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -34,6 +34,7 @@
 #include <asm/macints.h>
 #include <asm/mac_via.h>
 #include <asm/mac_psc.h>
+#include <asm/mac_oss.h>
 
 volatile __u8 *via1, *via2;
 int rbv_present;
@@ -84,7 +85,6 @@ void via_irq_disable(int irq);
 void via_irq_clear(int irq);
 
 extern irqreturn_t mac_scc_dispatch(int, void *);
-extern int oss_present;
 
 /*
  * Initialize the VIAs
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c
index b1033ae0d6f0..367ecee2f981 100644
--- a/arch/m68k/math-emu/fp_log.c
+++ b/arch/m68k/math-emu/fp_log.c
@@ -24,7 +24,6 @@ static const struct fp_ext fp_one =
 
 extern struct fp_ext *fp_fadd(struct fp_ext *dest, const struct fp_ext *src);
 extern struct fp_ext *fp_fdiv(struct fp_ext *dest, const struct fp_ext *src);
-extern struct fp_ext *fp_fmul(struct fp_ext *dest, const struct fp_ext *src);
 
 struct fp_ext *
 fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index 81bb08ceec18..0007b2adf3a3 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -28,6 +28,7 @@
 #ifdef CONFIG_ATARI
 #include <asm/atari_stram.h>
 #endif
+#include <asm/sections.h>
 #include <asm/tlb.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -73,9 +74,6 @@ extern void init_pointer_table(unsigned long ptable);
 
 /* References to section boundaries */
 
-extern char _text[], _etext[];
-extern char __init_begin[], __init_end[];
-
 extern pmd_t *zero_pgtable;
 
 void __init mem_init(void)
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index c5dbb9bdb322..4665fc84b7dc 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -30,6 +30,7 @@
 #ifdef CONFIG_ATARI
 #include <asm/atari_stram.h>
 #endif
+#include <asm/sections.h>
 
 #undef DEBUG
 
@@ -301,14 +302,12 @@ void __init paging_init(void)
 	}
 }
 
-extern char __init_begin, __init_end;
-
 void free_initmem(void)
 {
 	unsigned long addr;
 
-	addr = (unsigned long)&__init_begin;
-	for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) {
+	addr = (unsigned long)__init_begin;
+	for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
 		virt_to_page(addr)->flags &= ~(1 << PG_reserved);
 		init_page_count(virt_to_page(addr));
 		free_page(addr);
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index 43cdf476ffab..b72f079ec2f3 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -42,7 +42,6 @@ extern unsigned long mvme147_gettimeoffset (void);
 extern int mvme147_hwclk (int, struct rtc_time *);
 extern int mvme147_set_clock_mmss (unsigned long);
 extern void mvme147_reset (void);
-extern void mvme147_waitbut(void);
 
 
 static int bcd2int (unsigned char b);
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index 1521826fc3c7..11edf61cc2c4 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -48,7 +48,6 @@ extern unsigned long mvme16x_gettimeoffset (void);
 extern int mvme16x_hwclk (int, struct rtc_time *);
 extern int mvme16x_set_clock_mmss (unsigned long);
 extern void mvme16x_reset (void);
-extern void mvme16x_waitbut(void);
 
 int bcd2int (unsigned char b);
 
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 7110546e3c00..31ab3f08bbda 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -36,7 +36,6 @@
 #include <asm/machdep.h>
 #include <asm/q40_master.h>
 
-extern irqreturn_t q40_process_int(int level, struct pt_regs *regs);
 extern void q40_init_IRQ(void);
 static void q40_get_model(char *model);
 extern void q40_sched_init(irq_handler_t handler);
@@ -47,8 +46,6 @@ static unsigned int q40_get_ss(void);
 static int q40_set_clock_mmss(unsigned long);
 static int q40_get_rtc_pll(struct rtc_pll_info *pll);
 static int q40_set_rtc_pll(struct rtc_pll_info *pll);
-extern void q40_waitbut(void);
-void q40_set_vectors(void);
 
 extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/);
 
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index 8dfaa201342e..2ca25bd01a96 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -27,23 +27,21 @@
 #include <asm/sun3mmu.h>
 #include <asm/rtc.h>
 #include <asm/machdep.h>
+#include <asm/idprom.h>
 #include <asm/intersil.h>
 #include <asm/irq.h>
+#include <asm/sections.h>
 #include <asm/segment.h>
 #include <asm/sun3ints.h>
 
-extern char _text, _end;
-
 char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
 
 extern unsigned long sun3_gettimeoffset(void);
 static void sun3_sched_init(irq_handler_t handler);
 extern void sun3_get_model (char* model);
-extern void idprom_init (void);
 extern int sun3_hwclk(int set, struct rtc_time *t);
 
 volatile char* clock_va;
-extern volatile unsigned char* sun3_intreg;
 extern unsigned long availmem;
 unsigned long num_pages;
 
@@ -149,7 +147,7 @@ void __init config_sun3(void)
 	mach_halt	     =  sun3_halt;
 	mach_get_hardware_list = sun3_get_hardware_list;
 
-	memory_start = ((((int)&_end) + 0x2000) & ~0x1fff);
+	memory_start = ((((unsigned long)_end) + 0x2000) & ~0x1fff);
 // PROM seems to want the last couple of physical pages. --m
 	memory_end   = *(romvec->pv_sun3mem) + PAGE_OFFSET - 2*PAGE_SIZE;
 
diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
index 60f9d4500d72..3cd19390aae5 100644
--- a/arch/m68k/sun3/mmu_emu.c
+++ b/arch/m68k/sun3/mmu_emu.c
@@ -27,7 +27,6 @@
 #include <asm/mmu_context.h>
 #include <asm/dvma.h>
 
-extern void prom_reboot (char *) __attribute__ ((__noreturn__));
 
 #undef DEBUG_MMU_EMU
 #define DEBUG_PROM_MAPS
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
index 2b1ca2db070f..fc599fad4a54 100644
--- a/arch/m68k/sun3x/config.c
+++ b/arch/m68k/sun3x/config.c
@@ -23,7 +23,6 @@
 #include "time.h"
 
 volatile char *clock_va;
-extern volatile unsigned char *sun3_intreg;
 
 extern void sun3_get_model(char *model);
 

From 66acd2581259d80935fc5216b4b1268d639d9143 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:00:34 +0100
Subject: [PATCH 12/30] m68k: amiga core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/amiga/amiints.c | 12 ++++++++----
 arch/m68k/amiga/cia.c     |  4 +++-
 arch/m68k/amiga/config.c  |  3 ++-
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 907a5533c845..c5b5212cc3f9 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -72,10 +72,14 @@ static struct irq_controller amiga_irq_controller = {
 
 void __init amiga_init_IRQ(void)
 {
-	request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL);
-	request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL);
-	request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL);
-	request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL);
+	if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL))
+		pr_err("Couldn't register int%d\n", 1);
+	if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL))
+		pr_err("Couldn't register int%d\n", 3);
+	if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL))
+		pr_err("Couldn't register int%d\n", 4);
+	if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL))
+		pr_err("Couldn't register int%d\n", 5);
 
 	m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS);
 
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index 343fab49bd9a..ecd0f7ca6f0e 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -176,5 +176,7 @@ void __init cia_init_IRQ(struct ciabase *base)
 	/* override auto int and install CIA handler */
 	m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1);
 	m68k_irq_startup(base->handler_irq);
-	request_irq(base->handler_irq, cia_handler, IRQF_SHARED, base->name, base);
+	if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED,
+			base->name, base))
+		pr_err("Couldn't register %s interrupt\n", base->name);
 }
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index ab9862c3a136..6e562751ad51 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -493,7 +493,8 @@ static void __init amiga_sched_init(irq_handler_t timer_routine)
 	 * Please don't change this to use ciaa, as it interferes with the
 	 * SCSI code. We'll have to take a look at this later
 	 */
-	request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL);
+	if (request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL))
+		pr_err("Couldn't register timer interrupt\n");
 	/* start timer */
 	ciab.cra |= 0x11;
 }

From 844306538920b3aaf6806e238f0c0309a1e2bb5f Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:01:07 +0100
Subject: [PATCH 13/30] m68k: apollo core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/apollo/config.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index cf215a082cc6..8d3eafab1ffe 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -200,7 +200,8 @@ void dn_sched_init(irq_handler_t timer_routine)
 	printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
 #endif
 
-	request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine);
+	if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine))
+		pr_err("Couldn't register timer interrupt\n");
 }
 
 unsigned long dn_gettimeoffset(void) {

From 5b8b4c3d1b0ed4ccac3b1985acd0a973dfa00801 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:01:32 +0100
Subject: [PATCH 14/30] m68k: atari core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/atari/atakeyb.c | 9 +++++++--
 arch/m68k/atari/stdma.c   | 5 +++--
 arch/m68k/atari/time.c    | 5 +++--
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index f3c343be51ee..a5f33c059979 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -566,14 +566,19 @@ static int atari_keyb_done = 0;
 
 int atari_keyb_init(void)
 {
+	int error;
+
 	if (atari_keyb_done)
 		return 0;
 
 	kb_state.state = KEYBOARD;
 	kb_state.len = 0;
 
-	request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, IRQ_TYPE_SLOW,
-		    "keyboard/mouse/MIDI", atari_keyboard_interrupt);
+	error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt,
+			    IRQ_TYPE_SLOW, "keyboard/mouse/MIDI",
+			    atari_keyboard_interrupt);
+	if (error)
+		return error;
 
 	atari_turnoff_irq(IRQ_MFP_ACIA);
 	do {
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index d1bd029a34ac..604329fafbb8 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -179,8 +179,9 @@ EXPORT_SYMBOL(stdma_islocked);
 void __init stdma_init(void)
 {
 	stdma_isr = NULL;
-	request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | IRQF_SHARED,
-	            "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int);
+	if (request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | IRQF_SHARED,
+			"ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int))
+		pr_err("Couldn't register ST-DMA interrupt\n");
 }
 
 
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 1edde27fa32d..d076ff8d1b39 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -31,8 +31,9 @@ atari_sched_init(irq_handler_t timer_routine)
     /* start timer C, div = 1:100 */
     mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60;
     /* install interrupt service routine for MFP Timer C */
-    request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
-                "timer", timer_routine);
+    if (request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
+		    "timer", timer_routine))
+	pr_err("Couldn't register timer interrupt\n");
 }
 
 /* ++andreas: gettimeoffset fixed to check for pending interrupt */

From 8bd3968bd1653b4499e843bf86a167ead7c86b74 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:02:06 +0100
Subject: [PATCH 15/30] m68k: hp300 core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/hp300/time.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index dd7c8a2583d3..f6312c7d8727 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -70,7 +70,8 @@ void __init hp300_sched_init(irq_handler_t vector)
 
   asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
 
-  request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
+  if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector))
+    pr_err("Couldn't register timer interrupt\n");
 
   out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
   out_8(CLOCKBASE + CLKCR1, 0x40);		/* enable irq */

From 92c3dd15cd0589adf66c13c7b6114790c207e5a2 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:02:27 +0100
Subject: [PATCH 16/30] m68k: mac core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/mac/baboon.c  |  3 ++-
 arch/m68k/mac/iop.c     | 10 ++++++----
 arch/m68k/mac/macints.c |  5 +++--
 arch/m68k/mac/oss.c     | 25 +++++++++++++++----------
 arch/m68k/mac/psc.c     | 12 ++++++++----
 arch/m68k/mac/via.c     | 33 ++++++++++++++++++++-------------
 6 files changed, 54 insertions(+), 34 deletions(-)

diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
index 245d16d078ad..2a96bebd8969 100644
--- a/arch/m68k/mac/baboon.c
+++ b/arch/m68k/mac/baboon.c
@@ -92,7 +92,8 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
 void __init baboon_register_interrupts(void)
 {
 	baboon_disabled = 0;
-	request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon);
+	if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon))
+		pr_err("Couldn't register baboon interrupt\n");
 }
 
 /*
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 326fb9978094..1ad4e9d80eba 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -305,14 +305,16 @@ void __init iop_register_interrupts(void)
 {
 	if (iop_ism_present) {
 		if (oss_present) {
-			request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
+			if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
 					IRQ_FLG_LOCK, "ISM IOP",
-					(void *) IOP_NUM_ISM);
+					(void *) IOP_NUM_ISM))
+				pr_err("Couldn't register ISM IOP interrupt\n");
 			oss_irq_enable(IRQ_MAC_ADB);
 		} else {
-			request_irq(IRQ_VIA2_0, iop_ism_irq,
+			if (request_irq(IRQ_VIA2_0, iop_ism_irq,
 					IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP",
-					(void *) IOP_NUM_ISM);
+					(void *) IOP_NUM_ISM))
+				pr_err("Couldn't register ISM IOP interrupt\n");
 		}
 		if (!iop_alive(iop_base[IOP_NUM_ISM])) {
 			printk("IOP: oh my god, they killed the ISM IOP!\n");
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 7d0cbf3e1ff3..23711074e0e2 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -250,8 +250,9 @@ void __init mac_init_IRQ(void)
 	if (baboon_present)
 		baboon_register_interrupts();
 	iop_register_interrupts();
-	request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI",
-			mac_nmi_handler);
+	if (request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI",
+			mac_nmi_handler))
+		pr_err("Couldn't register NMI\n");
 #ifdef DEBUG_MACINTS
 	printk("mac_init_IRQ(): Done!\n");
 #endif
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index 8426501119ca..f3d23d6ebcf8 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -66,16 +66,21 @@ void __init oss_init(void)
 
 void __init oss_register_interrupts(void)
 {
-	request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
-			"scsi", (void *) oss);
-	request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
-			"scc", mac_scc_dispatch);
-	request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
-			"nubus", (void *) oss);
-	request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
-			"sound", (void *) oss);
-	request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
-			"via1", (void *) via1);
+	if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
+			"scsi", (void *) oss))
+		pr_err("Couldn't register %s interrupt\n", "scsi");
+	if (request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
+			"scc", mac_scc_dispatch))
+		pr_err("Couldn't register %s interrupt\n", "scc");
+	if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
+			"nubus", (void *) oss))
+		pr_err("Couldn't register %s interrupt\n", "nubus");
+	if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
+			"sound", (void *) oss))
+		pr_err("Couldn't register %s interrupt\n", "sound");
+	if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
+			"via1", (void *) via1))
+		pr_err("Couldn't register %s interrupt\n", "via1");
 }
 
 /*
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index f84a4dd64f94..ba6ccab64018 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -117,10 +117,14 @@ void __init psc_init(void)
 
 void __init psc_register_interrupts(void)
 {
-	request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30);
-	request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40);
-	request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50);
-	request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60);
+	if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30))
+		pr_err("Couldn't register psc%d interrupt\n", 3);
+	if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40))
+		pr_err("Couldn't register psc%d interrupt\n", 4);
+	if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50))
+		pr_err("Couldn't register psc%d interrupt\n", 5);
+	if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60))
+		pr_err("Couldn't register psc%d interrupt\n", 6);
 }
 
 /*
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index dfffb9c483a2..7d97ba54536e 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -283,7 +283,8 @@ void __init via_init_clock(irq_handler_t func)
 	via1[vT1CL] = MAC_CLOCK_LOW;
 	via1[vT1CH] = MAC_CLOCK_HIGH;
 
-	request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func);
+	if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func))
+		pr_err("Couldn't register %s interrupt\n", "timer");
 }
 
 /*
@@ -293,25 +294,31 @@ void __init via_init_clock(irq_handler_t func)
 void __init via_register_interrupts(void)
 {
 	if (via_alt_mapping) {
-		request_irq(IRQ_AUTO_1, via1_irq,
+		if (request_irq(IRQ_AUTO_1, via1_irq,
 				IRQ_FLG_LOCK|IRQ_FLG_FAST, "software",
-				(void *) via1);
-		request_irq(IRQ_AUTO_6, via1_irq,
+				(void *) via1))
+			pr_err("Couldn't register %s interrupt\n", "software");
+		if (request_irq(IRQ_AUTO_6, via1_irq,
 				IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
-				(void *) via1);
+				(void *) via1))
+			pr_err("Couldn't register %s interrupt\n", "via1");
 	} else {
-		request_irq(IRQ_AUTO_1, via1_irq,
+		if (request_irq(IRQ_AUTO_1, via1_irq,
 				IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
-				(void *) via1);
+				(void *) via1))
+			pr_err("Couldn't register %s interrupt\n", "via1");
 	}
-	request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
-			"via2", (void *) via2);
+	if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
+			"via2", (void *) via2))
+		pr_err("Couldn't register %s interrupt\n", "via2");
 	if (!psc_present) {
-		request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
-				"scc", mac_scc_dispatch);
+		if (request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
+				"scc", mac_scc_dispatch))
+			pr_err("Couldn't register %s interrupt\n", "scc");
 	}
-	request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
-			"nubus", (void *) via2);
+	if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq,
+			IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2))
+		pr_err("Couldn't register %s interrupt\n", "nubus");
 }
 
 /*

From 41904f8fe160202b8bfcc5da91dd927be40775b3 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:03:28 +0100
Subject: [PATCH 17/30] m68k: mvme147 core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/mvme147/config.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index b72f079ec2f3..100baaa692a1 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -114,8 +114,9 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
 void mvme147_sched_init (irq_handler_t timer_routine)
 {
 	tick_handler = timer_routine;
-	request_irq (PCC_IRQ_TIMER1, mvme147_timer_int,
-		IRQ_FLG_REPLACE, "timer 1", NULL);
+	if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE,
+			"timer 1", NULL))
+		pr_err("Couldn't register timer interrupt\n");
 
 	/* Init the clock with a value */
 	/* our clock goes off every 6.25us */

From 07e449b5b43b4b82c54e3026fc26bd4d8c81b080 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:05:24 +0100
Subject: [PATCH 18/30] m68k: sun3 core - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/sun3/sun3ints.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 7364cd67455e..ad90393a3361 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -105,7 +105,10 @@ void __init sun3_init_IRQ(void)
 	m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7);
 	m68k_setup_user_interrupt(VEC_USER, 128, NULL);
 
-	request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL);
-	request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL);
-	request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL);
+	if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL))
+		pr_err("Couldn't register %s interrupt\n", "int5");
+	if (request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL))
+		pr_err("Couldn't register %s interrupt\n", "int7");
+	if (request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL))
+		pr_err("Couldn't register %s interrupt\n", "vec255");
 }

From c36a4e40389a17bb439e2f38b1ae9632ba8af7ae Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:07:07 +0100
Subject: [PATCH 19/30] m68k: vme_scc - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
---
 drivers/char/vme_scc.c | 166 +++++++++++++++++++++++++++++++++--------
 1 file changed, 136 insertions(+), 30 deletions(-)

diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index 0e8234bd0e19..994e1a58b987 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -198,6 +198,7 @@ static void scc_init_portstructs(void)
 static int mvme147_scc_init(void)
 {
 	struct scc_port *port;
+	int error;
 
 	printk(KERN_INFO "SCC: MVME147 Serial Driver\n");
 	/* Init channel A */
@@ -207,14 +208,23 @@ static int mvme147_scc_init(void)
 	port->datap = port->ctrlp + 1;
 	port->port_a = &scc_ports[0];
 	port->port_b = &scc_ports[1];
-	request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
+	error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
 		            "SCC-A TX", port);
-	request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
+	if (error)
+		goto fail;
+	error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
 		            "SCC-A status", port);
-	request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_a_tx;
+	error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
 		            "SCC-A RX", port);
-	request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
-		            "SCC-A special cond", port);
+	if (error)
+		goto fail_free_a_stat;
+	error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int,
+			    IRQF_DISABLED, "SCC-A special cond", port);
+	if (error)
+		goto fail_free_a_rx;
+
 	{
 		SCC_ACCESS_INIT(port);
 
@@ -234,14 +244,23 @@ static int mvme147_scc_init(void)
 	port->datap = port->ctrlp + 1;
 	port->port_a = &scc_ports[0];
 	port->port_b = &scc_ports[1];
-	request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
+	error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
 		            "SCC-B TX", port);
-	request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_a_spcond;
+	error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
 		            "SCC-B status", port);
-	request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_b_tx;
+	error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
 		            "SCC-B RX", port);
-	request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
-		            "SCC-B special cond", port);
+	if (error)
+		goto fail_free_b_stat;
+	error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int,
+			    IRQF_DISABLED, "SCC-B special cond", port);
+	if (error)
+		goto fail_free_b_rx;
+
 	{
 		SCC_ACCESS_INIT(port);
 
@@ -257,6 +276,23 @@ static int mvme147_scc_init(void)
 	scc_init_drivers();
 
 	return 0;
+
+fail_free_b_rx:
+	free_irq(MVME147_IRQ_SCCB_RX, port);
+fail_free_b_stat:
+	free_irq(MVME147_IRQ_SCCB_STAT, port);
+fail_free_b_tx:
+	free_irq(MVME147_IRQ_SCCB_TX, port);
+fail_free_a_spcond:
+	free_irq(MVME147_IRQ_SCCA_SPCOND, port);
+fail_free_a_rx:
+	free_irq(MVME147_IRQ_SCCA_RX, port);
+fail_free_a_stat:
+	free_irq(MVME147_IRQ_SCCA_STAT, port);
+fail_free_a_tx:
+	free_irq(MVME147_IRQ_SCCA_TX, port);
+fail:
+	return error;
 }
 #endif
 
@@ -265,6 +301,7 @@ static int mvme147_scc_init(void)
 static int mvme162_scc_init(void)
 {
 	struct scc_port *port;
+	int error;
 
 	if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA))
 		return (-ENODEV);
@@ -277,14 +314,23 @@ static int mvme162_scc_init(void)
 	port->datap = port->ctrlp + 2;
 	port->port_a = &scc_ports[0];
 	port->port_b = &scc_ports[1];
-	request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
+	error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
 		            "SCC-A TX", port);
-	request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
+	if (error)
+		goto fail;
+	error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
 		            "SCC-A status", port);
-	request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_a_tx;
+	error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
 		            "SCC-A RX", port);
-	request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
-		            "SCC-A special cond", port);
+	if (error)
+		goto fail_free_a_stat;
+	error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int,
+			    IRQF_DISABLED, "SCC-A special cond", port);
+	if (error)
+		goto fail_free_a_rx;
+
 	{
 		SCC_ACCESS_INIT(port);
 
@@ -304,14 +350,22 @@ static int mvme162_scc_init(void)
 	port->datap = port->ctrlp + 2;
 	port->port_a = &scc_ports[0];
 	port->port_b = &scc_ports[1];
-	request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
+	error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
 		            "SCC-B TX", port);
-	request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_a_spcond;
+	error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
 		            "SCC-B status", port);
-	request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_b_tx;
+	error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
 		            "SCC-B RX", port);
-	request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
-		            "SCC-B special cond", port);
+	if (error)
+		goto fail_free_b_stat;
+	error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int,
+			    IRQF_DISABLED, "SCC-B special cond", port);
+	if (error)
+		goto fail_free_b_rx;
 
 	{
 		SCC_ACCESS_INIT(port);	/* Either channel will do */
@@ -328,6 +382,23 @@ static int mvme162_scc_init(void)
 	scc_init_drivers();
 
 	return 0;
+
+fail_free_b_rx:
+	free_irq(MVME162_IRQ_SCCB_RX, port);
+fail_free_b_stat:
+	free_irq(MVME162_IRQ_SCCB_STAT, port);
+fail_free_b_tx:
+	free_irq(MVME162_IRQ_SCCB_TX, port);
+fail_free_a_spcond:
+	free_irq(MVME162_IRQ_SCCA_SPCOND, port);
+fail_free_a_rx:
+	free_irq(MVME162_IRQ_SCCA_RX, port);
+fail_free_a_stat:
+	free_irq(MVME162_IRQ_SCCA_STAT, port);
+fail_free_a_tx:
+	free_irq(MVME162_IRQ_SCCA_TX, port);
+fail:
+	return error;
 }
 #endif
 
@@ -336,6 +407,7 @@ static int mvme162_scc_init(void)
 static int bvme6000_scc_init(void)
 {
 	struct scc_port *port;
+	int error;
 
 	printk(KERN_INFO "SCC: BVME6000 Serial Driver\n");
 	/* Init channel A */
@@ -345,14 +417,23 @@ static int bvme6000_scc_init(void)
 	port->datap = port->ctrlp + 4;
 	port->port_a = &scc_ports[0];
 	port->port_b = &scc_ports[1];
-	request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
+	error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
 		            "SCC-A TX", port);
-	request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
+	if (error)
+		goto fail;
+	error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
 		            "SCC-A status", port);
-	request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_a_tx;
+	error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
 		            "SCC-A RX", port);
-	request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
-		            "SCC-A special cond", port);
+	if (error)
+		goto fail_free_a_stat;
+	error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int,
+			    IRQF_DISABLED, "SCC-A special cond", port);
+	if (error)
+		goto fail_free_a_rx;
+
 	{
 		SCC_ACCESS_INIT(port);
 
@@ -372,14 +453,22 @@ static int bvme6000_scc_init(void)
 	port->datap = port->ctrlp + 4;
 	port->port_a = &scc_ports[0];
 	port->port_b = &scc_ports[1];
-	request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
+	error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
 		            "SCC-B TX", port);
-	request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_a_spcond;
+	error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
 		            "SCC-B status", port);
-	request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
+	if (error)
+		goto fail_free_b_tx;
+	error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
 		            "SCC-B RX", port);
-	request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
-		            "SCC-B special cond", port);
+	if (error)
+		goto fail_free_b_stat;
+	error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int,
+			    IRQF_DISABLED, "SCC-B special cond", port);
+	if (error)
+		goto fail_free_b_rx;
 
 	{
 		SCC_ACCESS_INIT(port);	/* Either channel will do */
@@ -393,6 +482,23 @@ static int bvme6000_scc_init(void)
 	scc_init_drivers();
 
 	return 0;
+
+fail:
+	free_irq(BVME_IRQ_SCCA_STAT, port);
+fail_free_a_tx:
+	free_irq(BVME_IRQ_SCCA_RX, port);
+fail_free_a_stat:
+	free_irq(BVME_IRQ_SCCA_SPCOND, port);
+fail_free_a_rx:
+	free_irq(BVME_IRQ_SCCB_TX, port);
+fail_free_a_spcond:
+	free_irq(BVME_IRQ_SCCB_STAT, port);
+fail_free_b_tx:
+	free_irq(BVME_IRQ_SCCB_RX, port);
+fail_free_b_stat:
+	free_irq(BVME_IRQ_SCCB_SPCOND, port);
+fail_free_b_rx:
+	return error;
 }
 #endif
 

From 67c53c34660c535083c4c8753e547a9338802ec6 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:08:21 +0100
Subject: [PATCH 20/30] m68k: ser_a2232 - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
---
 drivers/char/ser_a2232.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 33872a219df6..33a2b531802e 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -718,6 +718,7 @@ static int __init a2232board_init(void)
 	u_char *from;
 	volatile u_char *to;
 	volatile struct a2232memory *mem;
+	int error, i;
 
 #ifdef CONFIG_SMP
 	return -ENODEV;	/* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */
@@ -797,8 +798,15 @@ static int __init a2232board_init(void)
 	*/
 	if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx?
 
-	request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0, "A2232 serial VBL", a2232_driver_ID);
-	return 0;
+	error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0,
+			    "A2232 serial VBL", a2232_driver_ID);
+	if (error) {
+		for (i = 0; i < nr_a2232; i++)
+			zorro_release_device(zd_a2232[i]);
+		tty_unregister_driver(a2232_driver);
+		put_tty_driver(a2232_driver);
+	}
+	return error;
 }
 
 static void __exit a2232board_exit(void)

From 5edc304f49f3b1a246a3cc4ecc248e8fe7174840 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:13:41 +0100
Subject: [PATCH 21/30] m68k: amiserial - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

and clean up the error path handling.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
---
 drivers/char/amiserial.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 4e0cfdeab146..a58869ea8513 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1963,6 +1963,7 @@ static int __init rs_init(void)
 {
 	unsigned long flags;
 	struct serial_state * state;
+	int error;
 
 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_SERIAL))
 		return -ENODEV;
@@ -1975,8 +1976,11 @@ static int __init rs_init(void)
 	 *  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;
 
@@ -1997,8 +2001,9 @@ static int __init rs_init(void)
 	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;
@@ -2024,8 +2029,14 @@ static int __init rs_init(void)
 	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;
@@ -2045,6 +2056,16 @@ static int __init rs_init(void)
 	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) 
@@ -2064,6 +2085,9 @@ 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);
 }
 

From 639274d8106e25c2f91bf92270f46aaa3d104040 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:10:11 +0100
Subject: [PATCH 22/30] m68k: atafb - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/atafb.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 477ce55bbae9..8058572a7428 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -3075,8 +3075,7 @@ int __init atafb_setup(char *options)
 
 int __init atafb_init(void)
 {
-	int pad;
-	int detected_mode;
+	int pad, detected_mode, error;
 	unsigned int defmode = 0;
 	unsigned long mem_req;
 
@@ -3116,8 +3115,12 @@ int __init atafb_init(void)
 			printk("atafb_init: initializing Falcon hw\n");
 			fbhw = &falcon_switch;
 			atafb_ops.fb_setcolreg = &falcon_setcolreg;
-			request_irq(IRQ_AUTO_4, falcon_vbl_switcher, IRQ_TYPE_PRIO,
-			            "framebuffer/modeswitch", falcon_vbl_switcher);
+			error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher,
+					    IRQ_TYPE_PRIO,
+					    "framebuffer/modeswitch",
+					    falcon_vbl_switcher);
+			if (error)
+				return error;
 			defmode = DEFMODE_F30;
 			break;
 		}

From 2e4c77bea3d8b17d94f8ee382411f359b708560f Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:16:41 +0100
Subject: [PATCH 23/30] m68k: dio - Kill warn_unused_result warnings

warning: ignoring return value of 'device_register', declared with attribute
warn_unused_result
warning: ignoring return value of 'device_create_file', declared with
attribute warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/dio/dio-sysfs.c | 16 ++++++++++------
 drivers/dio/dio.c       | 18 +++++++++++++++---
 include/linux/dio.h     |  2 +-
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/dio/dio-sysfs.c b/drivers/dio/dio-sysfs.c
index f46463038847..91d5f4da8769 100644
--- a/drivers/dio/dio-sysfs.c
+++ b/drivers/dio/dio-sysfs.c
@@ -63,15 +63,19 @@ static ssize_t dio_show_resource(struct device *dev, struct device_attribute *at
 }
 static DEVICE_ATTR(resource, S_IRUGO, dio_show_resource, NULL);
 
-void dio_create_sysfs_dev_files(struct dio_dev *d)
+int dio_create_sysfs_dev_files(struct dio_dev *d)
 {
 	struct device *dev = &d->dev;
+	int error;
 
 	/* current configuration's attributes */
-	device_create_file(dev, &dev_attr_id);
-	device_create_file(dev, &dev_attr_ipl);
-	device_create_file(dev, &dev_attr_secid);
-	device_create_file(dev, &dev_attr_name);
-	device_create_file(dev, &dev_attr_resource);
+	if ((error = device_create_file(dev, &dev_attr_id)) ||
+	    (error = device_create_file(dev, &dev_attr_ipl)) ||
+	    (error = device_create_file(dev, &dev_attr_secid)) ||
+	    (error = device_create_file(dev, &dev_attr_name)) ||
+	    (error = device_create_file(dev, &dev_attr_resource)))
+		return error;
+
+	return 0;
 }
 
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index 07f274f853d9..10c3c498358c 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -173,6 +173,7 @@ static int __init dio_init(void)
 	mm_segment_t fs;
 	int i;
 	struct dio_dev *dev;
+	int error;
 
 	if (!MACH_IS_HP300)
 		return 0;
@@ -182,7 +183,11 @@ static int __init dio_init(void)
 	/* Initialize the DIO bus */ 
 	INIT_LIST_HEAD(&dio_bus.devices);
 	strcpy(dio_bus.dev.bus_id, "dio");
-	device_register(&dio_bus.dev);
+	error = device_register(&dio_bus.dev);
+	if (error) {
+		pr_err("DIO: Error registering dio_bus\n");
+		return error;
+	}
 
 	/* Request all resources */
 	dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
@@ -252,8 +257,15 @@ static int __init dio_init(void)
 
 		if (scode >= DIOII_SCBASE)
 			iounmap(va);
-		device_register(&dev->dev);
-		dio_create_sysfs_dev_files(dev);
+		error = device_register(&dev->dev);
+		if (error) {
+			pr_err("DIO: Error registering device %s\n",
+			       dev->name);
+			continue;
+		}
+		error = dio_create_sysfs_dev_files(dev);
+		if (error)
+			dev_err(&dev->dev, "Error creating sysfs files\n");
         }
 	return 0;
 }
diff --git a/include/linux/dio.h b/include/linux/dio.h
index 1e65ebc2a3db..b2dd31ca1710 100644
--- a/include/linux/dio.h
+++ b/include/linux/dio.h
@@ -241,7 +241,7 @@ struct dio_driver {
 
 extern int dio_find(int deviceid);
 extern unsigned long dio_scodetophysaddr(int scode);
-extern void dio_create_sysfs_dev_files(struct dio_dev *);
+extern int dio_create_sysfs_dev_files(struct dio_dev *);
 
 /* New-style probing */
 extern int dio_register_driver(struct dio_driver *);

From 11a8b2c5cde1377c716087df0866d7dc5a6d5d10 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:21:19 +0100
Subject: [PATCH 24/30] m68k: zorro - Kill warn_unused_result warnings

warning: ignoring return value of 'device_register', declared with attribute
warn_unused_result
warning: ignoring return value of 'device_create_file', declared with
attribute warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/zorro/zorro-sysfs.c | 20 ++++++++++++--------
 drivers/zorro/zorro.c       | 17 ++++++++++++++---
 drivers/zorro/zorro.h       |  2 +-
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 5290552d2ef7..1d2a772ea14c 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -77,17 +77,21 @@ static struct bin_attribute zorro_config_attr = {
 	.read = zorro_read_config,
 };
 
-void zorro_create_sysfs_dev_files(struct zorro_dev *z)
+int zorro_create_sysfs_dev_files(struct zorro_dev *z)
 {
 	struct device *dev = &z->dev;
+	int error;
 
 	/* current configuration's attributes */
-	device_create_file(dev, &dev_attr_id);
-	device_create_file(dev, &dev_attr_type);
-	device_create_file(dev, &dev_attr_serial);
-	device_create_file(dev, &dev_attr_slotaddr);
-	device_create_file(dev, &dev_attr_slotsize);
-	device_create_file(dev, &dev_attr_resource);
-	sysfs_create_bin_file(&dev->kobj, &zorro_config_attr);
+	if ((error = device_create_file(dev, &dev_attr_id)) ||
+	    (error = device_create_file(dev, &dev_attr_type)) ||
+	    (error = device_create_file(dev, &dev_attr_serial)) ||
+	    (error = device_create_file(dev, &dev_attr_slotaddr)) ||
+	    (error = device_create_file(dev, &dev_attr_slotsize)) ||
+	    (error = device_create_file(dev, &dev_attr_resource)) ||
+	    (error = sysfs_create_bin_file(&dev->kobj, &zorro_config_attr)))
+		return error;
+
+	return 0;
 }
 
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index dff16d9767d8..2dda20ac6b36 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -130,6 +130,7 @@ static int __init zorro_init(void)
 {
     struct zorro_dev *z;
     unsigned int i;
+    int error;
 
     if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
 	return 0;
@@ -140,7 +141,11 @@ static int __init zorro_init(void)
     /* Initialize the Zorro bus */
     INIT_LIST_HEAD(&zorro_bus.devices);
     strcpy(zorro_bus.dev.bus_id, "zorro");
-    device_register(&zorro_bus.dev);
+    error = device_register(&zorro_bus.dev);
+    if (error) {
+	pr_err("Zorro: Error registering zorro_bus\n");
+	return error;
+    }
 
     /* Request the resources */
     zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
@@ -167,8 +172,14 @@ static int __init zorro_init(void)
 	sprintf(z->dev.bus_id, "%02x", i);
 	z->dev.parent = &zorro_bus.dev;
 	z->dev.bus = &zorro_bus_type;
-	device_register(&z->dev);
-	zorro_create_sysfs_dev_files(z);
+	error = device_register(&z->dev);
+	if (error) {
+	    pr_err("Zorro: Error registering device %s\n", z->name);
+	    continue;
+	}
+	error = zorro_create_sysfs_dev_files(z);
+	if (error)
+	    dev_err(&z->dev, "Error creating sysfs files\n");
     }
 
     /* Mark all available Zorro II memory */
diff --git a/drivers/zorro/zorro.h b/drivers/zorro/zorro.h
index 5c91adac4df1..b682d5ccd63f 100644
--- a/drivers/zorro/zorro.h
+++ b/drivers/zorro/zorro.h
@@ -1,4 +1,4 @@
 
 extern void zorro_name_device(struct zorro_dev *z);
-extern void zorro_create_sysfs_dev_files(struct zorro_dev *z);
+extern int zorro_create_sysfs_dev_files(struct zorro_dev *z);
 

From 89bde7b86e21291ef091dc6ad3e63412f7c6ddd9 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:25:31 +0100
Subject: [PATCH 25/30] m68k: dmasound - Kill warn_unused_result warnings

warning: ignoring return value of 'request_irq', declared with attribute
warn_unused_result

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 sound/oss/dmasound/dmasound_atari.c |  5 +++--
 sound/oss/dmasound/dmasound_q40.c   | 16 ++++++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 4d45bd63718b..57d9f154c88b 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -851,8 +851,9 @@ static int __init AtaIrqInit(void)
 	mfp.tim_dt_a = 1;	/* Cause interrupt after first event. */
 	mfp.tim_ct_a = 8;	/* Turn on event counting. */
 	/* Register interrupt handler. */
-	request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
-		    AtaInterrupt);
+	if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
+			AtaInterrupt))
+		return 0;
 	mfp.int_en_a |= 0x20;	/* Turn interrupt on. */
 	mfp.int_mk_a |= 0x20;
 	return 1;
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 1855b14d90c3..99bcb21c2281 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -371,8 +371,9 @@ static void Q40Free(void *ptr, unsigned int size)
 static int __init Q40IrqInit(void)
 {
 	/* Register interrupt handler. */
-	request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
-		    "DMA sound", Q40Interrupt);
+	if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
+		    "DMA sound", Q40Interrupt))
+		return 0;
 
 	return(1);
 }
@@ -401,6 +402,7 @@ static void Q40PlayNextFrame(int index)
 	u_char *start;
 	u_long size;
 	u_char speed;
+	int error;
 
 	/* used by Q40Play() if all doubts whether there really is something
 	 * to be played are already wiped out.
@@ -419,11 +421,13 @@ static void Q40PlayNextFrame(int index)
 	master_outb( 0,SAMPLE_ENABLE_REG);
 	free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
 	if (dmasound.soft.stereo)
-	  	request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
-		    "Q40 sound", Q40Interrupt);
+		error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
+				    "Q40 sound", Q40Interrupt);
 	  else
-	        request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
-		    "Q40 sound", Q40Interrupt);
+		error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
+				    "Q40 sound", Q40Interrupt);
+	if (error && printk_ratelimit())
+		pr_err("Couldn't register sound interrupt\n");
 
 	master_outb( speed, SAMPLE_RATE_REG);
 	master_outb( 1,SAMPLE_CLEAR_REG);

From fae3306ac0c74be0e1ab32e1c77120e792ab2a33 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:22:01 +0100
Subject: [PATCH 26/30] m68k: dio - Kill resource_size_t format warnings

warning: format '%08lx' expects type 'long unsigned int', but argument 3 has
type 'resource_size_t'

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/dio/dio-sysfs.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dio/dio-sysfs.c b/drivers/dio/dio-sysfs.c
index 91d5f4da8769..ee1a3b59bd4e 100644
--- a/drivers/dio/dio-sysfs.c
+++ b/drivers/dio/dio-sysfs.c
@@ -58,7 +58,8 @@ static ssize_t dio_show_resource(struct device *dev, struct device_attribute *at
 	struct dio_dev *d = to_dio_dev(dev);
 
 	return sprintf(buf, "0x%08lx 0x%08lx 0x%08lx\n",
-		       dio_resource_start(d), dio_resource_end(d),
+		       (unsigned long)dio_resource_start(d),
+		       (unsigned long)dio_resource_end(d),
 		       dio_resource_flags(d));
 }
 static DEVICE_ATTR(resource, S_IRUGO, dio_show_resource, NULL);

From b01e3b07ec29e98464a4f580ae000291cf0d2f87 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:23:35 +0100
Subject: [PATCH 27/30] m68k: zorro - Use %pR to print resources

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/zorro/zorro.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index 2dda20ac6b36..a1585d6f6486 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -165,10 +165,8 @@ static int __init zorro_init(void)
 	zorro_name_device(z);
 	z->resource.name = z->name;
 	if (request_resource(zorro_find_parent_resource(z), &z->resource))
-	    printk(KERN_ERR "Zorro: Address space collision on device %s "
-		   "[%lx:%lx]\n",
-		   z->name, (unsigned long)zorro_resource_start(z),
-		   (unsigned long)zorro_resource_end(z));
+	    pr_err("Zorro: Address space collision on device %s %pR\n",
+		   z->name, &z->resource);
 	sprintf(z->dev.bus_id, "%02x", i);
 	z->dev.parent = &zorro_bus.dev;
 	z->dev.bus = &zorro_bus_type;

From 1fa0b29f3a43f9dd8080d24cd16790b15ef963f5 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Tue, 30 Dec 2008 14:11:23 +0100
Subject: [PATCH 28/30] fbdev: Kill Atari vblank cursor blinking

Kill the last remaining vblank cursor blinking user

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/console/fbcon.c | 38 -----------------------------------
 1 file changed, 38 deletions(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 4bcff81b50e0..1657b9608b04 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -78,13 +78,6 @@
 #include <asm/fb.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#ifdef CONFIG_ATARI
-#include <asm/atariints.h>
-#endif
-#if defined(__mc68000__)
-#include <asm/machdep.h>
-#include <asm/setup.h>
-#endif
 
 #include "fbcon.h"
 
@@ -155,9 +148,6 @@ static int fbcon_set_origin(struct vc_data *);
 
 #define CURSOR_DRAW_DELAY		(1)
 
-/* # VBL ints between cursor state changes */
-#define ATARI_CURSOR_BLINK_RATE		(42)
-
 static int vbl_cursor_cnt;
 static int fbcon_cursor_noblink;
 
@@ -403,20 +393,6 @@ static void fb_flashcursor(struct work_struct *work)
 	release_console_sem();
 }
 
-#ifdef CONFIG_ATARI
-static int cursor_blink_rate;
-static irqreturn_t fb_vbl_handler(int irq, void *dev_id)
-{
-	struct fb_info *info = dev_id;
-
-	if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
-		schedule_work(&info->queue);	
-		vbl_cursor_cnt = cursor_blink_rate; 
-	}
-	return IRQ_HANDLED;
-}
-#endif
-	
 static void cursor_timer_handler(unsigned long dev_addr)
 {
 	struct fb_info *info = (struct fb_info *) dev_addr;
@@ -1017,15 +993,6 @@ static const char *fbcon_startup(void)
 		info->var.yres,
 		info->var.bits_per_pixel);
 
-#ifdef CONFIG_ATARI
-	if (MACH_IS_ATARI) {
-		cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
-		(void)request_irq(IRQ_AUTO_4, fb_vbl_handler,
-				IRQ_TYPE_PRIO, "framebuffer vbl",
-				info);
-	}
-#endif /* CONFIG_ATARI */
-
 	fbcon_add_cursor_timer(info);
 	fbcon_has_exited = 0;
 	return display_desc;
@@ -3454,11 +3421,6 @@ static void fbcon_exit(void)
 	if (fbcon_has_exited)
 		return;
 
-#ifdef CONFIG_ATARI
-	if (MACH_IS_ATARI)
-		free_irq(IRQ_AUTO_4, fb_vbl_handler);
-#endif
-
 	kfree((void *)softback_buf);
 	softback_buf = 0UL;
 

From c162564ebf001e79448e8aa7a6e0ffee00b55f74 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Mon, 29 Dec 2008 19:34:57 +0100
Subject: [PATCH 29/30] m68k: Wire up sys_restart_syscall

Make restart blocks working, required for proper syscall restarting.

Signed-off-by: Andreas Schwab <schwab@suse.de>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/kernel/entry.S  |  2 +-
 arch/m68k/kernel/signal.c | 15 +++++++++++++++
 include/asm-m68k/unistd.h |  4 +---
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index f28404d9a2bc..5b780826647c 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -424,7 +424,7 @@ resume:
 .data
 ALIGN
 sys_call_table:
-	.long sys_ni_syscall	/* 0  -  old "setup()" system call*/
+	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
 	.long sys_fork
 	.long sys_read
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index f9af893cd289..de2d05ddd86d 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -326,6 +326,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
 	struct sigcontext context;
 	int err;
 
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 	/* get previous context */
 	if (copy_from_user(&context, usc, sizeof(context)))
 		goto badframe;
@@ -411,6 +414,9 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
 	unsigned long usp;
 	int err;
 
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 	err = __get_user(temp, &uc->uc_mcontext.version);
 	if (temp != MCONTEXT_VERSION)
 		goto badframe;
@@ -937,6 +943,15 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
 		regs->d0 = -EINTR;
 		break;
 
+	case -ERESTART_RESTARTBLOCK:
+		if (!has_handler) {
+			regs->d0 = __NR_restart_syscall;
+			regs->pc -= 2;
+			break;
+		}
+		regs->d0 = -EINTR;
+		break;
+
 	case -ERESTARTSYS:
 		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
 			regs->d0 = -EINTR;
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index 965abb8bc7ff..3c19027331fa 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -5,6 +5,7 @@
  * This file contains the system call numbers.
  */
 
+#define __NR_restart_syscall	  0
 #define __NR_exit		  1
 #define __NR_fork		  2
 #define __NR_read		  3
@@ -359,9 +360,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-/* whitelist for checksyscalls */
-#define __IGNORE_restart_syscall
-
 /*
  * "Conditional" syscalls
  *

From 877d52431f4d3cda4adea077ffbe88f3fd1755d3 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@ZenIV.linux.org.uk>
Date: Mon, 5 Jan 2009 17:28:10 +0000
Subject: [PATCH 30/30] m68k: Fix --build-id breakage for sun3

Counterpart of commit 08a3db94f2a36c28278922732bc281c1722ceb18 ("m68k: Add
NOTES to init data so its discarded at boot") for sun3 build.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/kernel/vmlinux-sun3.lds | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 8a4919e4d36a..d9368c0709ba 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -33,6 +33,7 @@ SECTIONS
 	} :data
   /* End of data goes *here* so that freeing init code works properly. */
   _edata = .;
+  NOTES
 
   /* will be freed after init */
   . = ALIGN(PAGE_SIZE);	/* Init code and data */