summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkogiidena <kogiidena@eggplant.ddo.jp>2007-03-19 08:24:12 +0100
committerPaul Mundt <lethal@hera.kernel.org>2007-05-07 04:10:54 +0200
commit00e8c494a1603eac0a2cae9836e624a752ad45b1 (patch)
tree078da0b39207f1265ae307140e10d1b36618da14
parentsh: hp6xx driver compile fixes. (diff)
downloadlinux-00e8c494a1603eac0a2cae9836e624a752ad45b1.tar.xz
linux-00e8c494a1603eac0a2cae9836e624a752ad45b1.zip
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>
-rw-r--r--arch/sh/boards/landisk/Makefile2
-rw-r--r--arch/sh/boards/landisk/gio.c167
-rw-r--r--arch/sh/boards/landisk/io.c250
-rw-r--r--arch/sh/boards/landisk/irq.c83
-rw-r--r--arch/sh/boards/landisk/landisk_pwb.c346
-rw-r--r--arch/sh/boards/landisk/psw.c143
-rw-r--r--arch/sh/boards/landisk/rtc.c91
-rw-r--r--arch/sh/boards/landisk/setup.c163
-rw-r--r--arch/sh/drivers/pci/ops-landisk.c4
9 files changed, 377 insertions, 872 deletions
diff --git a/arch/sh/boards/landisk/Makefile b/arch/sh/boards/landisk/Makefile
index 89e4beb2ad47..a696b4277fa9 100644
--- a/arch/sh/boards/landisk/Makefile
+++ b/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
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c
new file mode 100644
index 000000000000..50d38be62f01
--- /dev/null
+++ b/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");
diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c
deleted file mode 100644
index 92498b4947d5..000000000000
--- a/arch/sh/boards/landisk/io.c
+++ /dev/null
@@ -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);
-}
diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c
index 3eba6d086d7f..258649491d44 100644
--- a/arch/sh/boards/landisk/irq.c
+++ b/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);
}
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
deleted file mode 100644
index 47a63c6617ed..000000000000
--- a/arch/sh/boards/landisk/landisk_pwb.c
+++ /dev/null
@@ -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;
-}
diff --git a/arch/sh/boards/landisk/psw.c b/arch/sh/boards/landisk/psw.c
new file mode 100644
index 000000000000..5a9b70b5decb
--- /dev/null
+++ b/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);
diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c
deleted file mode 100644
index 0a9a2a2ad05b..000000000000
--- a/arch/sh/boards/landisk/rtc.c
+++ /dev/null
@@ -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;
-}
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
index 122d69962637..a83a5d9587bb 100644
--- a/arch/sh/boards/landisk/setup.c
+++ b/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)
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
index d06030815a96..bff09ecf3419 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/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
};