Procházet zdrojové kódy

sh: landisk updates.

Updates for the landisk board:

	- The push_switch framework was used.
	- landisk_pwb.c was divided into psw.c and gio.c.
	- pata_platform was supported in USL-5P.
	- irq.c was rewritten.
	- io.c was replaced with generic I/O routines.

Signed-off-by: kogiidena <kogiidena@eggplant.ddo.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
kogiidena před 18 roky
rodič
revize
00e8c494a1

+ 1 - 1
arch/sh/boards/landisk/Makefile

@@ -2,4 +2,4 @@
 # Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
 #
 
-obj-y	 := setup.o io.o irq.o rtc.o landisk_pwb.o
+obj-y	 := setup.o irq.o psw.o gio.o

+ 167 - 0
arch/sh/boards/landisk/gio.c

@@ -0,0 +1,167 @@
+/*
+ * arch/sh/boards/landisk/gio.c - driver for landisk
+ *
+ * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
+ * LANDISK and USL-5P Button, LED and GIO driver drive function.
+ *
+ *   Copylight (C) 2006 kogiidena
+ *   Copylight (C) 2002 Atom Create Engineering Co., Ltd. *
+ *
+ * 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/init.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/landisk/gio.h>
+#include <asm/landisk/iodata_landisk.h>
+
+#define DEVCOUNT                4
+#define GIO_MINOR	        2	/* GIO minor no. */
+
+static dev_t dev;
+static struct cdev *cdev_p;
+static int openCnt;
+
+static int gio_open(struct inode *inode, struct file *filp)
+{
+	int minor;
+
+	minor = MINOR(inode->i_rdev);
+	if (minor < DEVCOUNT) {
+		if (openCnt > 0) {
+			return -EALREADY;
+		} else {
+			openCnt++;
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+static int gio_close(struct inode *inode, struct file *filp)
+{
+	int minor;
+
+	minor = MINOR(inode->i_rdev);
+	if (minor < DEVCOUNT) {
+		openCnt--;
+	}
+	return 0;
+}
+
+static int gio_ioctl(struct inode *inode, struct file *filp,
+			     unsigned int cmd, unsigned long arg)
+{
+	unsigned int data;
+	static unsigned int addr = 0;
+
+	if (cmd & 0x01) {	/* write */
+		if (copy_from_user(&data, (int *)arg, sizeof(int))) {
+			return -EFAULT;
+		}
+	}
+
+	switch (cmd) {
+	case GIODRV_IOCSGIOSETADDR:	/* addres set */
+		addr = data;
+		break;
+
+	case GIODRV_IOCSGIODATA1:	/* write byte */
+		ctrl_outb((unsigned char)(0x0ff & data), addr);
+		break;
+
+	case GIODRV_IOCSGIODATA2:	/* write word */
+		if (addr & 0x01) {
+			return -EFAULT;
+		}
+		ctrl_outw((unsigned short int)(0x0ffff & data), addr);
+		break;
+
+	case GIODRV_IOCSGIODATA4:	/* write long */
+		if (addr & 0x03) {
+			return -EFAULT;
+		}
+		ctrl_outl(data, addr);
+		break;
+
+	case GIODRV_IOCGGIODATA1:	/* read byte */
+		data = ctrl_inb(addr);
+		break;
+
+	case GIODRV_IOCGGIODATA2:	/* read word */
+		if (addr & 0x01) {
+			return -EFAULT;
+		}
+		data = ctrl_inw(addr);
+		break;
+
+	case GIODRV_IOCGGIODATA4:	/* read long */
+		if (addr & 0x03) {
+			return -EFAULT;
+		}
+		data = ctrl_inl(addr);
+		break;
+	default:
+		return -EFAULT;
+		break;
+	}
+
+	if ((cmd & 0x01) == 0) {	/* read */
+		if (copy_to_user((int *)arg, &data, sizeof(int))) {
+			return -EFAULT;
+		}
+	}
+	return 0;
+}
+
+static struct file_operations gio_fops = {
+	.owner = THIS_MODULE,
+	.open = gio_open,	/* open */
+	.release = gio_close,	/* release */
+	.ioctl = gio_ioctl,	/* ioctl */
+};
+
+static int __init gio_init(void)
+{
+	int error;
+
+	printk(KERN_INFO "gio: driver initialized\n");
+
+	openCnt = 0;
+
+	if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) {
+		printk(KERN_ERR
+		       "gio: Couldn't alloc_chrdev_region, error=%d\n",
+		       error);
+		return 1;
+	}
+
+	cdev_p = cdev_alloc();
+	cdev_p->ops = &gio_fops;
+	error = cdev_add(cdev_p, dev, DEVCOUNT);
+	if (error) {
+		printk(KERN_ERR
+		       "gio: Couldn't cdev_add, error=%d\n", error);
+		return 1;
+	}
+
+	return 0;
+}
+
+static void __exit gio_exit(void)
+{
+	cdev_del(cdev_p);
+	unregister_chrdev_region(dev, DEVCOUNT);
+}
+
+module_init(gio_init);
+module_exit(gio_exit);
+
+MODULE_LICENSE("GPL");

+ 0 - 250
arch/sh/boards/landisk/io.c

@@ -1,250 +0,0 @@
-/*
- * arch/sh/boards/landisk/io.c
- *
- * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for I-O Data Device, Inc. LANDISK.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_landisk.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-/*
- * modifed by kogiidena
- * 2005.03.03
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/landisk/iodata_landisk.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-extern void *area5_io_base;	/* Area 5 I/O Base address */
-extern void *area6_io_base;	/* Area 6 I/O Base address */
-
-static inline unsigned long port2adr(unsigned int port)
-{
-	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
-		if (port == 0x3f6)
-			return ((unsigned long)area5_io_base + 0x2c);
-		else
-			return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
-				((port - 0x1f0) << 1));
-	else if ((0x170 <= port && port < 0x178) || port == 0x376)
-		if (port == 0x376)
-			return ((unsigned long)area6_io_base + 0x2c);
-		else
-			return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
-				((port - 0x170) << 1));
-	else
-		maybebadio((unsigned long)port);
-
-	return port;
-}
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used  w/o translation for
- * compatibility.
- */
-u8 landisk_inb(unsigned long port)
-{
-	if (PXSEG(port))
-		return ctrl_inb(port);
-	else if (is_pci_ioaddr(port))
-		return ctrl_inb(pci_ioaddr(port));
-
-	return ctrl_inw(port2adr(port)) & 0xff;
-}
-
-u8 landisk_inb_p(unsigned long port)
-{
-	u8 v;
-
-	if (PXSEG(port))
-		v = ctrl_inb(port);
-	else if (is_pci_ioaddr(port))
-		v = ctrl_inb(pci_ioaddr(port));
-	else
-		v = ctrl_inw(port2adr(port)) & 0xff;
-
-	ctrl_delay();
-
-	return v;
-}
-
-u16 landisk_inw(unsigned long port)
-{
-	if (PXSEG(port))
-		return ctrl_inw(port);
-	else if (is_pci_ioaddr(port))
-		return ctrl_inw(pci_ioaddr(port));
-	else
-		maybebadio(port);
-
-	return 0;
-}
-
-u32 landisk_inl(unsigned long port)
-{
-	if (PXSEG(port))
-		return ctrl_inl(port);
-	else if (is_pci_ioaddr(port))
-		return ctrl_inl(pci_ioaddr(port));
-	else
-		maybebadio(port);
-
-	return 0;
-}
-
-void landisk_outb(u8 value, unsigned long port)
-{
-	if (PXSEG(port))
-		ctrl_outb(value, port);
-	else if (is_pci_ioaddr(port))
-		ctrl_outb(value, pci_ioaddr(port));
-	else
-		ctrl_outw(value, port2adr(port));
-}
-
-void landisk_outb_p(u8 value, unsigned long port)
-{
-	if (PXSEG(port))
-		ctrl_outb(value, port);
-	else if (is_pci_ioaddr(port))
-		ctrl_outb(value, pci_ioaddr(port));
-	else
-		ctrl_outw(value, port2adr(port));
-	ctrl_delay();
-}
-
-void landisk_outw(u16 value, unsigned long port)
-{
-	if (PXSEG(port))
-		ctrl_outw(value, port);
-	else if (is_pci_ioaddr(port))
-		ctrl_outw(value, pci_ioaddr(port));
-	else
-		maybebadio(port);
-}
-
-void landisk_outl(u32 value, unsigned long port)
-{
-	if (PXSEG(port))
-		ctrl_outl(value, port);
-	else if (is_pci_ioaddr(port))
-		ctrl_outl(value, pci_ioaddr(port));
-	else
-		maybebadio(port);
-}
-
-void landisk_insb(unsigned long port, void *dst, unsigned long count)
-{
-        volatile u16 *p;
-        u8 *buf = dst;
-
-        if (PXSEG(port)) {
-                while (count--)
-                        *buf++ = *(volatile u8 *)port;
-	} else if (is_pci_ioaddr(port)) {
-                volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
-                while (count--)
-                        *buf++ = *bp;
-	} else {
-                p = (volatile u16 *)port2adr(port);
-                while (count--)
-                        *buf++ = *p & 0xff;
-	}
-}
-
-void landisk_insw(unsigned long port, void *dst, unsigned long count)
-{
-        volatile u16 *p;
-        u16 *buf = dst;
-
-	if (PXSEG(port))
-		p = (volatile u16 *)port;
-	else if (is_pci_ioaddr(port))
-		p = (volatile u16 *)pci_ioaddr(port);
-	else
-		p = (volatile u16 *)port2adr(port);
-	while (count--)
-		*buf++ = *p;
-}
-
-void landisk_insl(unsigned long port, void *dst, unsigned long count)
-{
-        u32 *buf = dst;
-
-	if (is_pci_ioaddr(port)) {
-                volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-
-                while (count--)
-                        *buf++ = *p;
-	} else
-		maybebadio(port);
-}
-
-void landisk_outsb(unsigned long port, const void *src, unsigned long count)
-{
-        volatile u16 *p;
-        const u8 *buf = src;
-
-	if (PXSEG(port))
-                while (count--)
-                        ctrl_outb(*buf++, port);
-	else if (is_pci_ioaddr(port)) {
-                volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
-                while (count--)
-                        *bp = *buf++;
-	} else {
-                p = (volatile u16 *)port2adr(port);
-                while (count--)
-                        *p = *buf++;
-	}
-}
-
-void landisk_outsw(unsigned long port, const void *src, unsigned long count)
-{
-        volatile u16 *p;
-        const u16 *buf = src;
-
-	if (PXSEG(port))
-                p = (volatile u16 *)port;
-	else if (is_pci_ioaddr(port))
-                p = (volatile u16 *)pci_ioaddr(port);
-	else
-                p = (volatile u16 *)port2adr(port);
-
-        while (count--)
-                *p = *buf++;
-}
-
-void landisk_outsl(unsigned long port, const void *src, unsigned long count)
-{
-        const u32 *buf = src;
-
-	if (is_pci_ioaddr(port)) {
-                volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-
-                while (count--)
-                        *p = *buf++;
-	} else
-		maybebadio(port);
-}
-
-void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
-{
-        if (PXSEG(port))
-                return (void __iomem *)port;
-        else if (is_pci_ioaddr(port))
-                return (void __iomem *)pci_ioaddr(port);
-
-        return (void __iomem *)port2adr(port);
-}

+ 21 - 62
arch/sh/boards/landisk/irq.c

@@ -1,18 +1,16 @@
 /*
  * arch/sh/boards/landisk/irq.c
  *
+ * I-O DATA Device, Inc. LANDISK Support
+ *
+ * Copyright (C) 2005-2007 kogiidena
+ *
  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
  * Based largely on io_se.c.
  *
- * I/O routine for I-O Data Device, Inc. LANDISK.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_landisk.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-/*
- * modified by kogiidena
- * 2005.03.03
+ * 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/init.h>
 #include <linux/irq.h>
@@ -20,71 +18,27 @@
 #include <linux/io.h>
 #include <asm/landisk/iodata_landisk.h>
 
-static void enable_landisk_irq(unsigned int irq);
-static void disable_landisk_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_landisk_irq disable_landisk_irq
-
-static void ack_landisk_irq(unsigned int irq);
-static void end_landisk_irq(unsigned int irq);
-
-static unsigned int startup_landisk_irq(unsigned int irq)
-{
-	enable_landisk_irq(irq);
-	return 0;		/* never anything pending */
-}
-
 static void disable_landisk_irq(unsigned int irq)
 {
-	unsigned char val;
 	unsigned char mask = 0xff ^ (0x01 << (irq - 5));
 
-	/* Set the priority in IPR to 0 */
-	val = ctrl_inb(PA_IMASK);
-	val &= mask;
-	ctrl_outb(val, PA_IMASK);
+	ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK);
 }
 
 static void enable_landisk_irq(unsigned int irq)
 {
-	unsigned char val;
 	unsigned char value = (0x01 << (irq - 5));
 
-	/* Set priority in IPR back to original value */
-	val = ctrl_inb(PA_IMASK);
-	val |= value;
-	ctrl_outb(val, PA_IMASK);
-}
-
-static void ack_landisk_irq(unsigned int irq)
-{
-	disable_landisk_irq(irq);
-}
-
-static void end_landisk_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_landisk_irq(irq);
+	ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK);
 }
 
-static struct hw_interrupt_type landisk_irq_type = {
-	.typename = "LANDISK IRQ",
-	.startup = startup_landisk_irq,
-	.shutdown = shutdown_landisk_irq,
-	.enable = enable_landisk_irq,
-	.disable = disable_landisk_irq,
-	.ack = ack_landisk_irq,
-	.end = end_landisk_irq
+static struct irq_chip landisk_irq_chip __read_mostly = {
+	.name		= "LANDISK",
+	.mask		= disable_landisk_irq,
+	.unmask		= enable_landisk_irq,
+	.mask_ack	= disable_landisk_irq,
 };
 
-static void make_landisk_irq(unsigned int irq)
-{
-	disable_irq_nosync(irq);
-	irq_desc[irq].chip = &landisk_irq_type;
-	disable_landisk_irq(irq);
-}
-
 /*
  * Initialize IRQ setting
  */
@@ -92,6 +46,11 @@ void __init init_landisk_IRQ(void)
 {
 	int i;
 
-	for (i = 5; i < 14; i++)
-		make_landisk_irq(i);
+	for (i = 5; i < 14; i++) {
+		disable_irq_nosync(i);
+		set_irq_chip_and_handler_name(i, &landisk_irq_chip,
+					      handle_level_irq, "level");
+		enable_landisk_irq(i);
+	}
+	ctrl_outb(0x00, PA_PWRINT_CLR);
 }

+ 0 - 346
arch/sh/boards/landisk/landisk_pwb.c

@@ -1,346 +0,0 @@
-/*
- * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch.
- *
- * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
- *
- * 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.
- *
- * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
- *
- * LED control drive function added by kogiidena
- */
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/landisk/iodata_landisk.h>
-
-#define SHUTDOWN_BTN_MINOR	1	/* Shutdown button device minor no. */
-#define LED_MINOR	       21	/* LED minor no. */
-#define BTN_MINOR	       22	/* BUTTON minor no. */
-#define GIO_MINOR	       40	/* GIO minor no. */
-
-static int openCnt;
-static int openCntLED;
-static int openCntGio;
-static int openCntBtn;
-static int landisk_btn;
-static int landisk_btnctrlpid;
-/*
- * Functions prototypes
- */
-
-static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-		     unsigned long arg);
-
-static int swdrv_open(struct inode *inode, struct file *filp)
-{
-	int minor;
-
-	minor = MINOR(inode->i_rdev);
-	filp->private_data = (void *)minor;
-
-	if (minor == SHUTDOWN_BTN_MINOR) {
-		if (openCnt > 0) {
-			return -EALREADY;
-		} else {
-			openCnt++;
-			return 0;
-		}
-	} else if (minor == LED_MINOR) {
-		if (openCntLED > 0) {
-			return -EALREADY;
-		} else {
-			openCntLED++;
-			return 0;
-		}
-	} else if (minor == BTN_MINOR) {
-		if (openCntBtn > 0) {
-			return -EALREADY;
-		} else {
-			openCntBtn++;
-			return 0;
-		}
-	} else if (minor == GIO_MINOR) {
-		if (openCntGio > 0) {
-			return -EALREADY;
-		} else {
-			openCntGio++;
-			return 0;
-		}
-	}
-	return -ENOENT;
-
-}
-
-static int swdrv_close(struct inode *inode, struct file *filp)
-{
-	int minor;
-
-	minor = MINOR(inode->i_rdev);
-	if (minor == SHUTDOWN_BTN_MINOR) {
-		openCnt--;
-	} else if (minor == LED_MINOR) {
-		openCntLED--;
-	} else if (minor == BTN_MINOR) {
-		openCntBtn--;
-	} else if (minor == GIO_MINOR) {
-		openCntGio--;
-	}
-	return 0;
-}
-
-static int swdrv_read(struct file *filp, char *buff, size_t count,
-		      loff_t * ppos)
-{
-	int minor;
-	minor = (int)(filp->private_data);
-
-	if (!access_ok(VERIFY_WRITE, (void *)buff, count))
-		return -EFAULT;
-
-	if (minor == SHUTDOWN_BTN_MINOR) {
-		if (landisk_btn & 0x10) {
-			put_user(1, buff);
-			return 1;
-		} else {
-			return 0;
-		}
-	}
-	return 0;
-}
-
-static int swdrv_write(struct file *filp, const char *buff, size_t count,
-		       loff_t * ppos)
-{
-	int minor;
-	minor = (int)(filp->private_data);
-
-	if (minor == SHUTDOWN_BTN_MINOR) {
-		return count;
-	}
-	return count;
-}
-
-static irqreturn_t sw_interrupt(int irq, void *dev_id)
-{
-	landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
-	disable_irq(IRQ_BUTTON);
-	disable_irq(IRQ_POWER);
-	ctrl_outb(0x00, PA_PWRINT_CLR);
-
-	if (landisk_btnctrlpid != 0) {
-		kill_proc(landisk_btnctrlpid, SIGUSR1, 1);
-		landisk_btnctrlpid = 0;
-	}
-
-	return IRQ_HANDLED;
-}
-
-static const struct file_operations swdrv_fops = {
-	.read = swdrv_read,	/* read */
-	.write = swdrv_write,	/* write */
-	.open = swdrv_open,	/* open */
-	.release = swdrv_close,	/* release */
-	.ioctl = gio_ioctl,	/* ioctl */
-
-};
-
-static char banner[] __initdata =
-    KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n";
-
-int __init swdrv_init(void)
-{
-	int error;
-
-	printk("%s", banner);
-
-	openCnt = 0;
-	openCntLED = 0;
-	openCntBtn = 0;
-	openCntGio = 0;
-	landisk_btn = 0;
-	landisk_btnctrlpid = 0;
-
-	if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) {
-		printk(KERN_ERR
-		       "Button, LED and GIO driver:Couldn't register driver, error=%d\n",
-		       error);
-		return 1;
-	}
-
-	if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) {
-		printk(KERN_ERR "Unable to get IRQ 11.\n");
-		return 1;
-	}
-	if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) {
-		printk(KERN_ERR "Unable to get IRQ 12.\n");
-		return 1;
-	}
-	ctrl_outb(0x00, PA_PWRINT_CLR);
-
-	return 0;
-}
-
-module_init(swdrv_init);
-
-/*
- * gio driver
- *
- */
-
-#include <asm/landisk/gio.h>
-
-static int gio_ioctl(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	int minor;
-	unsigned int data, mask;
-	static unsigned int addr = 0;
-
-	minor = (int)(filp->private_data);
-
-	/* access control */
-	if (minor == GIO_MINOR) {
-		;
-	} else if (minor == LED_MINOR) {
-		if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) {
-			;
-		} else {
-			return -EINVAL;
-		}
-	} else if (minor == BTN_MINOR) {
-		if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) {
-			;
-		} else {
-			return -EINVAL;
-		}
-	} else {
-		return -EINVAL;
-	}
-
-	if (cmd & 0x01) {	/* write */
-		if (copy_from_user(&data, (int *)arg, sizeof(int))) {
-			return -EFAULT;
-		}
-	}
-
-	switch (cmd) {
-	case GIODRV_IOCSGIOSETADDR:	/* addres set */
-		addr = data;
-		break;
-
-	case GIODRV_IOCSGIODATA1:	/* write byte */
-		ctrl_outb((unsigned char)(0x0ff & data), addr);
-		break;
-
-	case GIODRV_IOCSGIODATA2:	/* write word */
-		if (addr & 0x01) {
-			return -EFAULT;
-		}
-		ctrl_outw((unsigned short int)(0x0ffff & data), addr);
-		break;
-
-	case GIODRV_IOCSGIODATA4:	/* write long */
-		if (addr & 0x03) {
-			return -EFAULT;
-		}
-		ctrl_outl(data, addr);
-		break;
-
-	case GIODRV_IOCGGIODATA1:	/* read byte */
-		data = ctrl_inb(addr);
-		break;
-
-	case GIODRV_IOCGGIODATA2:	/* read word */
-		if (addr & 0x01) {
-			return -EFAULT;
-		}
-		data = ctrl_inw(addr);
-		break;
-
-	case GIODRV_IOCGGIODATA4:	/* read long */
-		if (addr & 0x03) {
-			return -EFAULT;
-		}
-		data = ctrl_inl(addr);
-		break;
-	case GIODRV_IOCSGIO_LED:	/* write */
-		mask = ((data & 0x00ffffff) << 8)
-		    | ((data & 0x0000ffff) << 16)
-		    | ((data & 0x000000ff) << 24);
-		landisk_ledparam = data & (~mask);
-		if (landisk_arch == 0) {	/* arch == landisk */
-			landisk_ledparam &= 0x03030303;
-			mask = (~(landisk_ledparam >> 22)) & 0x000c;
-			landisk_ledparam |= mask;
-		} else {	                /* arch == usl-5p */
-			mask = (landisk_ledparam >> 24) & 0x0001;
-			landisk_ledparam |= mask;
-			landisk_ledparam &= 0x007f7f7f;
-		}
-		landisk_ledparam |= 0x80;
-		break;
-	case GIODRV_IOCGGIO_LED:	/* read */
-		data = landisk_ledparam;
-		if (landisk_arch == 0) {	/* arch == landisk */
-			data &= 0x03030303;
-		} else {	                /* arch == usl-5p */
-			;
-		}
-		data &= (~0x080);
-		break;
-	case GIODRV_IOCSGIO_BUZZER:	/* write */
-		landisk_buzzerparam = data;
-		landisk_ledparam |= 0x80;
-		break;
-	case GIODRV_IOCGGIO_LANDISK:	/* read */
-		data = landisk_arch & 0x01;
-		break;
-	case GIODRV_IOCGGIO_BTN:	/* read */
-		data = (0x0ff & ctrl_inb(PA_PWRINT_CLR));
-		data <<= 8;
-		data |= (0x0ff & ctrl_inb(PA_IMASK));
-		data <<= 8;
-		data |= (0x0ff & landisk_btn);
-		data <<= 8;
-		data |= (0x0ff & (~ctrl_inb(PA_STATUS)));
-		break;
-	case GIODRV_IOCSGIO_BTNPID:	/* write */
-		landisk_btnctrlpid = data;
-		landisk_btn = 0;
-		if (irq_desc[IRQ_BUTTON].depth) {
-			enable_irq(IRQ_BUTTON);
-		}
-		if (irq_desc[IRQ_POWER].depth) {
-			enable_irq(IRQ_POWER);
-		}
-		break;
-	case GIODRV_IOCGGIO_BTNPID:	/* read */
-		data = landisk_btnctrlpid;
-		break;
-	default:
-		return -EFAULT;
-		break;
-	}
-
-	if ((cmd & 0x01) == 0) {	/* read */
-		if (copy_to_user((int *)arg, &data, sizeof(int))) {
-			return -EFAULT;
-		}
-	}
-	return 0;
-}

+ 143 - 0
arch/sh/boards/landisk/psw.c

@@ -0,0 +1,143 @@
+/*
+ * arch/sh/boards/landisk/psw.c
+ *
+ * push switch support for LANDISK and USL-5P
+ *
+ * Copyright (C) 2006-2007  Paul Mundt
+ * Copyright (C) 2007  kogiidena
+ *
+ * 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/io.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/landisk/iodata_landisk.h>
+#include <asm/push-switch.h>
+
+static irqreturn_t psw_irq_handler(int irq, void *arg)
+{
+	struct platform_device *pdev = arg;
+	struct push_switch *psw = platform_get_drvdata(pdev);
+	struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
+	unsigned int sw_value;
+	int ret = 0;
+
+	sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
+
+	/* Nothing to do if there's no state change */
+	if (psw->state) {
+		ret = 1;
+		goto out;
+	}
+
+	/* Figure out who raised it */
+	if (sw_value & (1 << psw_info->bit)) {
+		psw->state = 1;
+		mod_timer(&psw->debounce, jiffies + 50);
+		ret = 1;
+	}
+
+out:
+	/* Clear the switch IRQs */
+	ctrl_outb(0x00, PA_PWRINT_CLR);
+
+	return IRQ_RETVAL(ret);
+}
+
+static struct resource psw_power_resources[] = {
+	[0] = {
+		.start = IRQ_POWER,
+		.flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource psw_usl5p_resources[] = {
+	[0] = {
+		.start = IRQ_BUTTON,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct push_switch_platform_info psw_power_platform_data = {
+	.name		= "psw_power",
+	.bit		= 4,
+	.irq_flags	= IRQF_SHARED,
+	.irq_handler	= psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw1_platform_data = {
+	.name		= "psw1",
+	.bit		= 0,
+	.irq_flags	= IRQF_SHARED,
+	.irq_handler	= psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw2_platform_data = {
+	.name		= "psw2",
+	.bit		= 2,
+	.irq_flags	= IRQF_SHARED,
+	.irq_handler	= psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw3_platform_data = {
+	.name		= "psw3",
+	.bit		= 1,
+	.irq_flags	= IRQF_SHARED,
+	.irq_handler	= psw_irq_handler,
+};
+
+static struct platform_device psw_power_switch_device = {
+	.name		= "push-switch",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(psw_power_resources),
+	.resource	= psw_power_resources,
+	.dev		= {
+		.platform_data = &psw_power_platform_data,
+	},
+};
+
+static struct platform_device psw1_switch_device = {
+	.name		= "push-switch",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(psw_usl5p_resources),
+	.resource	= psw_usl5p_resources,
+	.dev		= {
+		.platform_data = &psw1_platform_data,
+	},
+};
+
+static struct platform_device psw2_switch_device = {
+	.name		= "push-switch",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(psw_usl5p_resources),
+	.resource	= psw_usl5p_resources,
+	.dev		= {
+		.platform_data = &psw2_platform_data,
+	},
+};
+
+static struct platform_device psw3_switch_device = {
+	.name		= "push-switch",
+	.id		= 3,
+	.num_resources	= ARRAY_SIZE(psw_usl5p_resources),
+	.resource	= psw_usl5p_resources,
+	.dev = {
+		.platform_data = &psw3_platform_data,
+	},
+};
+
+static struct platform_device *psw_devices[] = {
+	&psw_power_switch_device,
+	&psw1_switch_device,
+	&psw2_switch_device,
+	&psw3_switch_device,
+};
+
+static int __init psw_init(void)
+{
+	return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
+}
+module_init(psw_init);

+ 0 - 91
arch/sh/boards/landisk/rtc.c

@@ -1,91 +0,0 @@
-/*
- * arch/sh/boards/landisk/rtc.c --  RTC support
- *
- *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
- *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
- */
-/*
- * modifed by kogiidena
- * 2005.09.16
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/bcd.h>
-#include <asm/rtc.h>
-
-extern spinlock_t rtc_lock;
-
-extern void
-rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon,
-		      unsigned int BCD_day, unsigned int BCD_hr,
-		      unsigned int BCD_min, unsigned int BCD_sec);
-
-extern unsigned long
-rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon,
-		      unsigned int *BCD_day, unsigned int *BCD_hr,
-		      unsigned int *BCD_min, unsigned int *BCD_sec);
-
-void landisk_rtc_gettimeofday(struct timespec *tv)
-{
-	unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
-	unsigned long flags;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	tv->tv_sec = rs5c313_get_cmos_time
-	    (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
-	tv->tv_nsec = 0;
-	spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
-int landisk_rtc_settimeofday(const time_t secs)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned long flags;
-	unsigned long nowtime = secs;
-	unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-
-	rs5c313_get_cmos_time
-	  (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
-	cmos_minutes = BCD_min;
-	BCD_TO_BIN(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
-		real_minutes += 30;	/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		BIN_TO_BCD(real_seconds);
-		BIN_TO_BCD(real_minutes);
-		rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr,
-				      real_minutes, real_seconds);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_time: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	return retval;
-}
-
-void landisk_time_init(void)
-{
-	rtc_sh_get_time = landisk_rtc_gettimeofday;
-	rtc_sh_set_time = landisk_rtc_settimeofday;
-}

+ 43 - 120
arch/sh/boards/landisk/setup.c

@@ -1,144 +1,90 @@
 /*
  * arch/sh/boards/landisk/setup.c
  *
- * Copyright (C) 2000 Kazumoto Kojima
- * Copyright (C) 2002 Paul Mundt
- *
  * I-O DATA Device, Inc. LANDISK Support.
  *
- * Modified for LANDISK by
- * Atom Create Engineering Co., Ltd. 2002.
- *
- * modifed by kogiidena
- * 2005.09.16
+ * Copyright (C) 2000 Kazumoto Kojima
+ * Copyright (C) 2002 Paul Mundt
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2005-2007 kogiidena
  *
  * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/pata_platform.h>
 #include <linux/pm.h>
 #include <linux/mm.h>
 #include <asm/machvec.h>
-#include <asm/rtc.h>
 #include <asm/landisk/iodata_landisk.h>
 #include <asm/io.h>
 
-void landisk_time_init(void);
 void init_landisk_IRQ(void);
 
-int landisk_ledparam;
-int landisk_buzzerparam;
-int landisk_arch;
-
-/* cycle the led's in the clasic knightrider/sun pattern */
-static void heartbeat_landisk(void)
-{
-	static unsigned int cnt = 0, blink = 0x00, period = 25;
-        volatile u8 *p = (volatile u8 *)PA_LED;
-	char data;
-
-        if ((landisk_ledparam & 0x080) == 0)
-		return;
-
-	cnt += 1;
-
-        if (cnt < period)
-		return;
-
-	cnt = 0;
-	blink++;
-
-	data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0;
-	data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0;
-	data |= landisk_ledparam;
-
-	/* buzzer */
-	if (landisk_buzzerparam & 0x1) {
-		data |= 0x80;
-	} else {
-		data &= 0x7f;
-	}
-	*p = data;
-
-        if (((landisk_ledparam & 0x007f7f00) == 0) &&
-             (landisk_buzzerparam == 0))
-		landisk_ledparam &= (~0x0080);
-
-	landisk_buzzerparam >>= 1;
-}
-
 static void landisk_power_off(void)
 {
         ctrl_outb(0x01, PA_SHUTDOWN);
 }
 
-static void check_usl5p(void)
-{
-        volatile u8 *p = (volatile u8 *)PA_LED;
-        u8 tmp1, tmp2;
+static struct resource cf_ide_resources[3];
 
-        tmp1 = *p;
-        *p = 0x40;
-        tmp2 = *p;
-        *p = tmp1;
+static struct pata_platform_info pata_info = {
+	.ioport_shift	= 1,
+};
 
-        landisk_arch = (tmp2 == 0x40);
-        if (landisk_arch == 1) {
-                /* arch == usl-5p */
-                landisk_ledparam = 0x00000380;
-                landisk_ledparam |= (tmp1 & 0x07c);
-        } else {
-                /* arch == landisk */
-                landisk_ledparam = 0x02000180;
-                landisk_ledparam |= 0x04;
-        }
-}
+static struct platform_device cf_ide_device = {
+	.name		= "pata_platform",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(cf_ide_resources),
+	.resource	= cf_ide_resources,
+	.dev		= {
+		.platform_data = &pata_info,
+	},
+};
 
-void *area5_io_base;
-void *area6_io_base;
+static struct platform_device *landisk_devices[] __initdata = {
+	&cf_ide_device,
+};
 
-static int __init landisk_cf_init(void)
+static int __init landisk_devices_setup(void)
 {
 	pgprot_t prot;
-	unsigned long paddrbase, psize;
+	unsigned long paddrbase;
+	void *cf_ide_base;
 
 	/* open I/O area window */
 	paddrbase = virt_to_phys((void *)PA_AREA5_IO);
-	psize = PAGE_SIZE;
 	prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
-	area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
-	if (!area5_io_base) {
+	cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+	if (!cf_ide_base) {
 		printk("allocate_cf_area : can't open CF I/O window!\n");
 		return -ENOMEM;
 	}
 
-	paddrbase = virt_to_phys((void *)PA_AREA6_IO);
-	psize = PAGE_SIZE;
-	prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
-	area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
-	if (!area6_io_base) {
-		printk("allocate_cf_area : can't open HDD I/O window!\n");
-		return -ENOMEM;
-	}
-
-	printk(KERN_INFO "Allocate Area5/6 success.\n");
-
-	/* XXX : do we need attribute and common-memory area also? */
-
-	return 0;
+	/* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
+	cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40;
+	cf_ide_resources[0].end   = (unsigned long)cf_ide_base + 0x40 + 0x0f;
+	cf_ide_resources[0].flags = IORESOURCE_IO;
+	cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c;
+	cf_ide_resources[1].end   = (unsigned long)cf_ide_base + 0x2c + 0x03;
+	cf_ide_resources[1].flags = IORESOURCE_IO;
+	cf_ide_resources[2].start = IRQ_FATA;
+	cf_ide_resources[2].flags = IORESOURCE_IRQ;
+
+	return platform_add_devices(landisk_devices,
+				    ARRAY_SIZE(landisk_devices));
 }
 
+__initcall(landisk_devices_setup);
+
 static void __init landisk_setup(char **cmdline_p)
 {
-	device_initcall(landisk_cf_init);
-
-	landisk_buzzerparam = 0;
-	check_usl5p();
+        /* LED ON */
+	ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED);
 
 	printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
-
-	board_time_init = landisk_time_init;
 	pm_power_off = landisk_power_off;
 }
 
@@ -148,29 +94,6 @@ static void __init landisk_setup(char **cmdline_p)
 struct sh_machine_vector mv_landisk __initmv = {
 	.mv_name = "LANDISK",
 	.mv_setup = landisk_setup,
-	.mv_nr_irqs = 72,
-	.mv_inb = landisk_inb,
-	.mv_inw = landisk_inw,
-	.mv_inl = landisk_inl,
-	.mv_outb = landisk_outb,
-	.mv_outw = landisk_outw,
-	.mv_outl = landisk_outl,
-	.mv_inb_p = landisk_inb_p,
-	.mv_inw_p = landisk_inw,
-	.mv_inl_p = landisk_inl,
-	.mv_outb_p = landisk_outb_p,
-	.mv_outw_p = landisk_outw,
-	.mv_outl_p = landisk_outl,
-	.mv_insb = landisk_insb,
-	.mv_insw = landisk_insw,
-	.mv_insl = landisk_insl,
-	.mv_outsb = landisk_outsb,
-	.mv_outsw = landisk_outsw,
-	.mv_outsl = landisk_outsl,
-	.mv_ioport_map = landisk_ioport_map,
 	.mv_init_irq = init_landisk_IRQ,
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat = heartbeat_landisk,
-#endif
 };
 ALIAS_MV(landisk)

+ 2 - 2
arch/sh/drivers/pci/ops-landisk.c

@@ -17,8 +17,8 @@
 
 static struct resource sh7751_io_resource = {
 	.name = "SH7751 IO",
-	.start = 0x4000,
-	.end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
+	.start = SH7751_PCI_IO_BASE,
+	.end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
 	.flags = IORESOURCE_IO
 };