sh: heartbeat consolidation for banked LEDs.

This consolidates the various board heartbeat LED implementations,
used for strobing the load average across a LED bank. Those boards
not implementing a full bank can hook in via the LED class.

We leave the compat hook in the machvec for now until those non-banked
boards are able to migrate to the drivers/leds.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/boards/mpc1211/Makefile b/arch/sh/boards/mpc1211/Makefile
index 1644ebe..8cd31b5 100644
--- a/arch/sh/boards/mpc1211/Makefile
+++ b/arch/sh/boards/mpc1211/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel
 #
 
-obj-y	 := setup.o rtc.o led.o
+obj-y	 := setup.o rtc.o
 
 obj-$(CONFIG_PCI) += pci.o
 
diff --git a/arch/sh/boards/mpc1211/led.c b/arch/sh/boards/mpc1211/led.c
deleted file mode 100644
index 8df1591..0000000
--- a/arch/sh/boards/mpc1211/led.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * linux/arch/sh/boards/mpc1211/led.c
- *
- * Copyright (C) 2001  Saito.K & Jeanne
- *
- * This file contains Interface MPC-1211 specific LED code.
- */
-
-
-static void mach_led(int position, int value)
-{
-	volatile unsigned char* p = (volatile unsigned char*)0xa2000000;
-
-	if (value) {
-		*p |= 1;
-	} else {
-		*p &= ~1;
-	}
-}
-
-#ifdef CONFIG_HEARTBEAT
-
-#include <linux/sched.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_mpc1211(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned char* p = (volatile unsigned char*)0xa2000000;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ( (300<<FSHIFT)/
-			 ((avenrun[0]/5) + (3<<FSHIFT)) );
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up=0;
-		} else {
-			bit ++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up=1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1<<bit;
-
-}
-#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
index 7c3d1d3..1a0604b 100644
--- a/arch/sh/boards/mpc1211/setup.c
+++ b/arch/sh/boards/mpc1211/setup.c
@@ -10,6 +10,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
 #include <asm/mpc1211/mpc1211.h>
@@ -281,6 +282,32 @@
 	return 0;
 }
 
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= 0xa2000000,
+		.end	= 0xa2000000 + 8 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *mpc1211_devices[] __initdata = {
+	&heartbeat_device,
+};
+
+static int __init mpc1211_devices_setup(void)
+{
+	return platform_add_devices(mpc1211_devices,
+				    ARRAY_SIZE(mpc1211_devices));
+}
+__initcall(mpc1211_devices_setup);
+
 /* arch/sh/boards/mpc1211/rtc.c */
 void mpc1211_time_init(void);
 
@@ -317,9 +344,5 @@
 	.mv_nr_irqs		= 48,
 	.mv_irq_demux		= mpc1211_irq_demux,
 	.mv_init_irq		= init_mpc1211_IRQ,
-
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_mpc1211,
-#endif
 };
 ALIAS_MV(mpc1211)
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index 574b031..3c93012 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -4,5 +4,4 @@
 
 obj-y	 := setup.o io.o irq.o
 
-obj-$(CONFIG_HEARTBEAT)		+= led.o
 obj-$(CONFIG_PUSH_SWITCH)	+= psw.o
diff --git a/arch/sh/boards/renesas/r7780rp/led.c b/arch/sh/boards/renesas/r7780rp/led.c
deleted file mode 100644
index 6a00a25..0000000
--- a/arch/sh/boards/renesas/r7780rp/led.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) Atom Create Engineering Co., Ltd.
- *
- * May be copied or modified under the terms of GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
- */
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <asm/r7780rp/r7780rp.h>
-
-/* Cycle the LED's in the clasic Knightriger/Sun pattern */
-void heartbeat_r7780rp(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short *p = (volatile unsigned short *)PA_OBLED;
-	static unsigned bit = 0, up = 1;
-	unsigned bit_pos[] = {2, 1, 0, 3, 6, 5, 4, 7};
-
-	cnt += 1;
-	if (cnt < period)
-		return;
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
-	 */
-	period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
-
-	*p = 1 << bit_pos[bit];
-	if (up)
-		if (bit == 7) {
-			bit--;
-			up = 0;
-		} else
-			bit++;
-	else if (bit == 0)
-		up = 1;
-	else
-		bit--;
-}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index b48f19f..c40f85c 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -17,7 +17,6 @@
 #include <asm/clock.h>
 #include <asm/io.h>
 
-extern void heartbeat_r7780rp(void);
 extern void init_r7780rp_IRQ(void);
 
 static struct resource m66596_usb_host_resources[] = {
@@ -72,9 +71,30 @@
 	.resource	= cf_ide_resources,
 };
 
+static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 };
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_OBLED,
+		.end	= PA_OBLED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= heartbeat_bit_pos,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
 static struct platform_device *r7780rp_devices[] __initdata = {
 	&m66596_usb_host_device,
 	&cf_ide_device,
+	&heartbeat_device,
 };
 
 static int __init r7780rp_devices_setup(void)
@@ -185,8 +205,5 @@
 
 	.mv_ioport_map		= r7780rp_ioport_map,
 	.mv_init_irq		= init_r7780rp_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_r7780rp,
-#endif
 };
 ALIAS_MV(r7780rp)
diff --git a/arch/sh/boards/renesas/rts7751r2d/Makefile b/arch/sh/boards/renesas/rts7751r2d/Makefile
index 686fc9e..833de1e 100644
--- a/arch/sh/boards/renesas/rts7751r2d/Makefile
+++ b/arch/sh/boards/renesas/rts7751r2d/Makefile
@@ -3,4 +3,3 @@
 #
 
 obj-y	 := setup.o io.o irq.o
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c
deleted file mode 100644
index 509f548..0000000
--- a/arch/sh/boards/renesas/rts7751r2d/led.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * linux/arch/sh/boards/renesas/rts7751r2d/led.c
- *
- * Copyright (C) Atom Create Engineering Co., Ltd.
- *
- * May be copied or modified under the terms of GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Renesas Technology Sales RTS7751R2D specific LED code.
- */
-#include <linux/io.h>
-#include <linux/sched.h>
-#include <asm/rts7751r2d.h>
-
-/* Cycle the LED's in the clasic Knightriger/Sun pattern */
-void heartbeat_rts7751r2d(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short *p = (volatile unsigned short *)PA_OUTPORT;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period)
-		return;
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
-	 */
-	period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
-
-	*p = 1 << bit;
-	if (up)
-		if (bit == 7) {
-			bit--;
-			up = 0;
-		} else
-			bit++;
-	else if (bit == 0)
-		up = 1;
-	else
-		bit--;
-}
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 5c042d3..d97be12 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -69,8 +69,24 @@
 	},
 };
 
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_OUTPORT,
+		.end	= PA_OUTPORT + 8 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
 static struct platform_device *rts7751r2d_devices[] __initdata = {
 	&uart_device,
+	&heartbeat_device,
 };
 
 static int __init rts7751r2d_devices_setup(void)
@@ -129,9 +145,6 @@
 	.mv_outsl		= rts7751r2d_outsl,
 
 	.mv_init_irq		= init_rts7751r2d_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_rts7751r2d,
-#endif
 	.mv_irq_demux		= rts7751r2d_irq_demux,
 
 #ifdef CONFIG_USB_SM501
diff --git a/arch/sh/boards/se/7206/Makefile b/arch/sh/boards/se/7206/Makefile
index 63950f4f..63e7ed6 100644
--- a/arch/sh/boards/se/7206/Makefile
+++ b/arch/sh/boards/se/7206/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	 := setup.o io.o irq.o
-obj-$(CONFIG_HEARTBEAT) += led.o
-
diff --git a/arch/sh/boards/se/7206/led.c b/arch/sh/boards/se/7206/led.c
deleted file mode 100644
index ef79460..0000000
--- a/arch/sh/boards/se/7206/led.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * linux/arch/sh/kernel/led_se.c
- *
- * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Solution Engine specific LED code.
- */
-
-#include <linux/config.h>
-#include <asm/se7206.h>
-
-#ifdef CONFIG_HEARTBEAT
-
-#include <linux/sched.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_se(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ( (300<<FSHIFT)/
-			 ((avenrun[0]/5) + (3<<FSHIFT)) );
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up=0;
-		} else {
-			bit ++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up=1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1<<(bit+8);
-
-}
-#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c
index 0f42e91..ca71487 100644
--- a/arch/sh/boards/se/7206/setup.c
+++ b/arch/sh/boards/se/7206/setup.c
@@ -3,6 +3,7 @@
  * linux/arch/sh/boards/se/7206/setup.c
  *
  * Copyright (C) 2006  Yoshinori Sato
+ * Copyright (C) 2007  Paul Mundt
  *
  * Hitachi 7206 SolutionEngine Support.
  *
@@ -34,15 +35,37 @@
 	.resource	= smc91x_resources,
 };
 
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_LED,
+		.end	= PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= heartbeat_bit_pos,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *se7206_devices[] __initdata = {
+	&smc91x_device,
+	&heartbeat_device,
+};
+
 static int __init se7206_devices_setup(void)
 {
-	return platform_device_register(&smc91x_device);
+	return platform_add_devices(se7206_devices, ARRAY_SIZE(se7206_devices));
 }
-
 __initcall(se7206_devices_setup);
 
-void heartbeat_se(void);
-
 /*
  * The Machine Vector
  */
@@ -72,8 +95,5 @@
 	.mv_outsl		= se7206_outsl,
 
 	.mv_init_irq		= init_se7206_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_se,
-#endif
 };
 ALIAS_MV(se)
diff --git a/arch/sh/boards/se/7300/Makefile b/arch/sh/boards/se/7300/Makefile
index 0fbd4f4..4624736 100644
--- a/arch/sh/boards/se/7300/Makefile
+++ b/arch/sh/boards/se/7300/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	 := setup.o io.o irq.o
-
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c
deleted file mode 100644
index 4d03bb7..0000000
--- a/arch/sh/boards/se/7300/led.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * linux/arch/sh/boards/se/7300/led.c
- *
- * Derived from linux/arch/sh/boards/se/770x/led.c
- *
- * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Solution Engine specific LED code.
- */
-
-#include <linux/sched.h>
-#include <asm/se7300.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_7300se(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short *p = (volatile unsigned short *) PA_LED;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up = 0;
-		} else {
-			bit++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up = 1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1 << (bit + 8);
-
-}
-
diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c
index 6f082a7..f196095 100644
--- a/arch/sh/boards/se/7300/setup.c
+++ b/arch/sh/boards/se/7300/setup.c
@@ -6,14 +6,43 @@
  * SH-Mobile SolutionEngine 7300 Support.
  *
  */
-
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <asm/machvec.h>
 #include <asm/se7300.h>
 
-void heartbeat_7300se(void);
 void init_7300se_IRQ(void);
 
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_LED,
+		.end	= PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= heartbeat_bit_pos,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *se7300_devices[] __initdata = {
+	&heartbeat_device,
+};
+
+static int __init se7300_devices_setup(void)
+{
+	return platform_add_devices(se7300_devices, ARRAY_SIZE(se7300_devices));
+}
+__initcall(se7300_devices_setup);
+
 /*
  * The Machine Vector
  */
@@ -42,8 +71,5 @@
 	.mv_outsl = sh7300se_outsl,
 
 	.mv_init_irq = init_7300se_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat = heartbeat_7300se,
-#endif
 };
 ALIAS_MV(7300se)
diff --git a/arch/sh/boards/se/73180/Makefile b/arch/sh/boards/se/73180/Makefile
index 8f63886..e7c0996 100644
--- a/arch/sh/boards/se/73180/Makefile
+++ b/arch/sh/boards/se/73180/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	 := setup.o io.o irq.o
-
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/73180/led.c b/arch/sh/boards/se/73180/led.c
deleted file mode 100644
index 4b72e9a..0000000
--- a/arch/sh/boards/se/73180/led.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/sh/boards/se/73180/led.c
- *
- * Derived from arch/sh/boards/se/770x/led.c
- *
- * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Solution Engine specific LED code.
- */
-
-#include <linux/sched.h>
-#include <asm/mach/se73180.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_73180se(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short *p = (volatile unsigned short *) PA_LED;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up = 0;
-		} else {
-			bit++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up = 1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1 << (bit + LED_SHIFT);
-
-}
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c
index b38ef50..911ce1c 100644
--- a/arch/sh/boards/se/73180/setup.c
+++ b/arch/sh/boards/se/73180/setup.c
@@ -10,13 +10,39 @@
  */
 
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <asm/machvec.h>
 #include <asm/se73180.h>
 #include <asm/irq.h>
 
-void heartbeat_73180se(void);
 void init_73180se_IRQ(void);
 
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_LED,
+		.end	= PA_LED + 8 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *se73180_devices[] __initdata = {
+	&heartbeat_device,
+};
+
+static int __init se73180_devices_setup(void)
+{
+	return platform_add_devices(sh7343se_platform_devices,
+				    ARRAY_SIZE(sh7343se_platform_devices));
+}
+__initcall(se73180_devices_setup);
+
 /*
  * The Machine Vector
  */
@@ -46,8 +72,5 @@
 
 	.mv_init_irq = init_73180se_IRQ,
 	.mv_irq_demux = shmse_irq_demux,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat = heartbeat_73180se,
-#endif
 };
 ALIAS_MV(73180se)
diff --git a/arch/sh/boards/se/7343/Makefile b/arch/sh/boards/se/7343/Makefile
index 4291069..3024796 100644
--- a/arch/sh/boards/se/7343/Makefile
+++ b/arch/sh/boards/se/7343/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	 := setup.o io.o irq.o
-
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/7343/led.c b/arch/sh/boards/se/7343/led.c
deleted file mode 100644
index 6b39e19..0000000
--- a/arch/sh/boards/se/7343/led.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * arch/sh/boards/se/7343/led.c
- *
- */
-#include <linux/sched.h>
-#include <asm/mach/se7343.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_7343se(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short *p = (volatile unsigned short *) PA_LED;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up = 0;
-		} else {
-			bit++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up = 1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1 << (bit + LED_SHIFT);
-
-}
diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c
index c7d17fe..3fdb16f 100644
--- a/arch/sh/boards/se/7343/setup.c
+++ b/arch/sh/boards/se/7343/setup.c
@@ -4,7 +4,6 @@
 #include <asm/mach/se7343.h>
 #include <asm/irq.h>
 
-void heartbeat_7343se(void);
 void init_7343se_IRQ(void);
 
 static struct resource smc91x_resources[] = {
@@ -31,14 +30,30 @@
 	.resource	= smc91x_resources,
 };
 
-static struct platform_device *smc91x_platform_devices[] __initdata = {
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_LED,
+		.end	= PA_LED + 8 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *sh7343se_platform_devices[] __initdata = {
 	&smc91x_device,
+	&heartbeat_device,
 };
 
 static int __init sh7343se_devices_setup(void)
 {
-	return platform_add_devices(smc91x_platform_devices,
-				    ARRAY_SIZE(smc91x_platform_devices));
+	return platform_add_devices(sh7343se_platform_devices,
+				    ARRAY_SIZE(sh7343se_platform_devices));
 }
 
 static void __init sh7343se_setup(char **cmdline_p)
@@ -76,8 +91,5 @@
 
 	.mv_init_irq = init_7343se_IRQ,
 	.mv_irq_demux = shmse_irq_demux,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat = heartbeat_7343se,
-#endif
 };
 ALIAS_MV(7343se)
diff --git a/arch/sh/boards/se/770x/Makefile b/arch/sh/boards/se/770x/Makefile
index 9a5035f..8e624b0 100644
--- a/arch/sh/boards/se/770x/Makefile
+++ b/arch/sh/boards/se/770x/Makefile
@@ -3,4 +3,3 @@
 #
 
 obj-y	 := setup.o io.o irq.o
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/770x/led.c b/arch/sh/boards/se/770x/led.c
deleted file mode 100644
index d93dd83..0000000
--- a/arch/sh/boards/se/770x/led.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * linux/arch/sh/boards/se/770x/led.c
- *
- * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Solution Engine specific LED code.
- */
-
-#include <linux/sched.h>
-#include <asm/se.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_se(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ( (300<<FSHIFT)/
-			 ((avenrun[0]/5) + (3<<FSHIFT)) );
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up=0;
-		} else {
-			bit ++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up=1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1<<(bit+8);
-
-}
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index 84f2e48..45cbc36 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -7,12 +7,12 @@
  *
  */
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <asm/machvec.h>
 #include <asm/se.h>
 #include <asm/io.h>
 #include <asm/smc37c93x.h>
 
-void heartbeat_se(void);
 void init_se_IRQ(void);
 
 /*
@@ -63,6 +63,36 @@
 	outb_p(CONFIG_EXIT, CONFIG_PORT);
 }
 
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_LED,
+		.end	= PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= heartbeat_bit_pos,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *se_devices[] __initdata = {
+	&heartbeat_device,
+};
+
+static int __init se_devices_setup(void)
+{
+	return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
+}
+__initcall(se_devices_setup);
+
 /*
  * The Machine Vector
  */
@@ -101,8 +131,5 @@
 	.mv_outsl		= se_outsl,
 
 	.mv_init_irq		= init_se_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_se,
-#endif
 };
 ALIAS_MV(se)
diff --git a/arch/sh/boards/se/7751/Makefile b/arch/sh/boards/se/7751/Makefile
index 188900c..dbc29f3 100644
--- a/arch/sh/boards/se/7751/Makefile
+++ b/arch/sh/boards/se/7751/Makefile
@@ -5,4 +5,3 @@
 obj-y	 := setup.o io.o irq.o
 
 obj-$(CONFIG_PCI) += pci.o
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/7751/led.c b/arch/sh/boards/se/7751/led.c
deleted file mode 100644
index de4194d..0000000
--- a/arch/sh/boards/se/7751/led.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * linux/arch/sh/boards/se/7751/led.c
- *
- * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * This file contains Solution Engine specific LED code.
- */
-#include <linux/sched.h>
-#include <asm/se7751.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_7751se(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ( (300<<FSHIFT)/
-			 ((avenrun[0]/5) + (3<<FSHIFT)) );
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up=0;
-		} else {
-			bit ++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up=1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1<<(bit+8);
-
-}
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index f7e1dd3..e3feae6 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -9,11 +9,11 @@
  * Ian da Silva and Jeremy Siegel, 2001.
  */
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <asm/machvec.h>
 #include <asm/se7751.h>
 #include <asm/io.h>
 
-void heartbeat_7751se(void);
 void init_7751se_IRQ(void);
 
 #ifdef CONFIG_SH_KGDB
@@ -161,11 +161,40 @@
 }
 #endif /* CONFIG_SH_KGDB */
 
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PA_LED,
+		.end	= PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= heartbeat_bit_pos,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *se7751_devices[] __initdata = {
+	&smc91x_device,
+	&heartbeat_device,
+};
+
+static int __init se7751_devices_setup(void)
+{
+	return platform_add_devices(se7751_devices, ARRAY_SIZE(se7751_devices));
+}
+__initcall(se7751_devices_setup);
 
 /*
  * The Machine Vector
  */
-
 struct sh_machine_vector mv_7751se __initmv = {
 	.mv_name		= "7751 SolutionEngine",
 	.mv_setup		= sh7751se_setup,
@@ -189,8 +218,5 @@
 	.mv_outsl		= sh7751se_outsl,
 
 	.mv_init_irq		= init_7751se_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_7751se,
-#endif
 };
 ALIAS_MV(7751se)
diff --git a/arch/sh/boards/sh03/Makefile b/arch/sh/boards/sh03/Makefile
index 321be50..400306a 100644
--- a/arch/sh/boards/sh03/Makefile
+++ b/arch/sh/boards/sh03/Makefile
@@ -3,4 +3,3 @@
 #
 
 obj-y	 := setup.o rtc.o
-obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/sh03/led.c b/arch/sh/boards/sh03/led.c
deleted file mode 100644
index d38562a..0000000
--- a/arch/sh/boards/sh03/led.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * linux/arch/sh/boards/sh03/led.c
- *
- * Copyright (C) 2004  Saito.K Interface Corporation.
- *
- * This file contains Interface CTP/PCI-SH03 specific LED code.
- */
-
-#include <linux/sched.h>
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_sh03(void)
-{
-	static unsigned int cnt = 0, period = 0;
-	volatile unsigned char* p = (volatile unsigned char*)0xa0800000;
-	static unsigned bit = 0, up = 1;
-
-	cnt += 1;
-	if (cnt < period) {
-		return;
-	}
-
-	cnt = 0;
-
-	/* Go through the points (roughly!):
-	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
-	 */
-	period = 110 - ( (300<<FSHIFT)/
-			 ((avenrun[0]/5) + (3<<FSHIFT)) );
-
-	if (up) {
-		if (bit == 7) {
-			bit--;
-			up=0;
-		} else {
-			bit ++;
-		}
-	} else {
-		if (bit == 0) {
-			bit++;
-			up=1;
-		} else {
-			bit--;
-		}
-	}
-	*p = 1<<bit;
-
-}
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index 5ad1e19..c069c44 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/rtc.h>
 #include <asm/sh03/io.h>
@@ -48,15 +49,36 @@
 	board_time_init = sh03_time_init;
 }
 
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= 0xa0800000,
+		.end	= 0xa0800000 + 8 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *sh03_devices[] __initdata = {
+	&heartbeat_device,
+};
+
+static int __init sh03_devices_setup(void)
+{
+	return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices));
+}
+__initcall(sh03_devices_setup);
+
 struct sh_machine_vector mv_sh03 __initmv = {
 	.mv_name		= "Interface (CTP/PCI-SH03)",
 	.mv_setup		= sh03_setup,
 	.mv_nr_irqs		= 48,
 	.mv_ioport_map		= sh03_ioport_map,
 	.mv_init_irq		= init_sh03_IRQ,
-
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= heartbeat_sh03,
-#endif
 };
 ALIAS_MV(sh03)