aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/mach-landisk
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/mach-landisk')
-rw-r--r--arch/sh/boards/mach-landisk/Makefile5
-rw-r--r--arch/sh/boards/mach-landisk/gio.c171
-rw-r--r--arch/sh/boards/mach-landisk/irq.c56
-rw-r--r--arch/sh/boards/mach-landisk/psw.c143
-rw-r--r--arch/sh/boards/mach-landisk/setup.c105
5 files changed, 480 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-landisk/Makefile b/arch/sh/boards/mach-landisk/Makefile
new file mode 100644
index 000000000000..a696b4277fa9
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
3#
4
5obj-y := setup.o irq.o psw.o gio.o
diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c
new file mode 100644
index 000000000000..25cdf7358000
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/gio.c
@@ -0,0 +1,171 @@
1/*
2 * arch/sh/boards/landisk/gio.c - driver for landisk
3 *
4 * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
5 * LANDISK and USL-5P Button, LED and GIO driver drive function.
6 *
7 * Copylight (C) 2006 kogiidena
8 * Copylight (C) 2002 Atom Create Engineering Co., Ltd. *
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 *
14 */
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/smp_lock.h>
18#include <linux/kdev_t.h>
19#include <linux/cdev.h>
20#include <linux/fs.h>
21#include <asm/io.h>
22#include <asm/uaccess.h>
23#include <mach-landisk/mach/gio.h>
24#include <mach-landisk/mach/iodata_landisk.h>
25
26#define DEVCOUNT 4
27#define GIO_MINOR 2 /* GIO minor no. */
28
29static dev_t dev;
30static struct cdev *cdev_p;
31static int openCnt;
32
33static int gio_open(struct inode *inode, struct file *filp)
34{
35 int minor;
36 int ret = -ENOENT;
37
38 lock_kernel();
39 minor = MINOR(inode->i_rdev);
40 if (minor < DEVCOUNT) {
41 if (openCnt > 0) {
42 ret = -EALREADY;
43 } else {
44 openCnt++;
45 ret = 0;
46 }
47 }
48 unlock_kernel();
49 return ret;
50}
51
52static int gio_close(struct inode *inode, struct file *filp)
53{
54 int minor;
55
56 minor = MINOR(inode->i_rdev);
57 if (minor < DEVCOUNT) {
58 openCnt--;
59 }
60 return 0;
61}
62
63static int gio_ioctl(struct inode *inode, struct file *filp,
64 unsigned int cmd, unsigned long arg)
65{
66 unsigned int data;
67 static unsigned int addr = 0;
68
69 if (cmd & 0x01) { /* write */
70 if (copy_from_user(&data, (int *)arg, sizeof(int))) {
71 return -EFAULT;
72 }
73 }
74
75 switch (cmd) {
76 case GIODRV_IOCSGIOSETADDR: /* address set */
77 addr = data;
78 break;
79
80 case GIODRV_IOCSGIODATA1: /* write byte */
81 ctrl_outb((unsigned char)(0x0ff & data), addr);
82 break;
83
84 case GIODRV_IOCSGIODATA2: /* write word */
85 if (addr & 0x01) {
86 return -EFAULT;
87 }
88 ctrl_outw((unsigned short int)(0x0ffff & data), addr);
89 break;
90
91 case GIODRV_IOCSGIODATA4: /* write long */
92 if (addr & 0x03) {
93 return -EFAULT;
94 }
95 ctrl_outl(data, addr);
96 break;
97
98 case GIODRV_IOCGGIODATA1: /* read byte */
99 data = ctrl_inb(addr);
100 break;
101
102 case GIODRV_IOCGGIODATA2: /* read word */
103 if (addr & 0x01) {
104 return -EFAULT;
105 }
106 data = ctrl_inw(addr);
107 break;
108
109 case GIODRV_IOCGGIODATA4: /* read long */
110 if (addr & 0x03) {
111 return -EFAULT;
112 }
113 data = ctrl_inl(addr);
114 break;
115 default:
116 return -EFAULT;
117 break;
118 }
119
120 if ((cmd & 0x01) == 0) { /* read */
121 if (copy_to_user((int *)arg, &data, sizeof(int))) {
122 return -EFAULT;
123 }
124 }
125 return 0;
126}
127
128static const struct file_operations gio_fops = {
129 .owner = THIS_MODULE,
130 .open = gio_open, /* open */
131 .release = gio_close, /* release */
132 .ioctl = gio_ioctl, /* ioctl */
133};
134
135static int __init gio_init(void)
136{
137 int error;
138
139 printk(KERN_INFO "gio: driver initialized\n");
140
141 openCnt = 0;
142
143 if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) {
144 printk(KERN_ERR
145 "gio: Couldn't alloc_chrdev_region, error=%d\n",
146 error);
147 return 1;
148 }
149
150 cdev_p = cdev_alloc();
151 cdev_p->ops = &gio_fops;
152 error = cdev_add(cdev_p, dev, DEVCOUNT);
153 if (error) {
154 printk(KERN_ERR
155 "gio: Couldn't cdev_add, error=%d\n", error);
156 return 1;
157 }
158
159 return 0;
160}
161
162static void __exit gio_exit(void)
163{
164 cdev_del(cdev_p);
165 unregister_chrdev_region(dev, DEVCOUNT);
166}
167
168module_init(gio_init);
169module_exit(gio_exit);
170
171MODULE_LICENSE("GPL");
diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c
new file mode 100644
index 000000000000..7b284cde1f58
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/irq.c
@@ -0,0 +1,56 @@
1/*
2 * arch/sh/boards/landisk/irq.c
3 *
4 * I-O DATA Device, Inc. LANDISK Support
5 *
6 * Copyright (C) 2005-2007 kogiidena
7 *
8 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
9 * Based largely on io_se.c.
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <mach-landisk/mach/iodata_landisk.h>
20
21static void disable_landisk_irq(unsigned int irq)
22{
23 unsigned char mask = 0xff ^ (0x01 << (irq - 5));
24
25 ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK);
26}
27
28static void enable_landisk_irq(unsigned int irq)
29{
30 unsigned char value = (0x01 << (irq - 5));
31
32 ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK);
33}
34
35static struct irq_chip landisk_irq_chip __read_mostly = {
36 .name = "LANDISK",
37 .mask = disable_landisk_irq,
38 .unmask = enable_landisk_irq,
39 .mask_ack = disable_landisk_irq,
40};
41
42/*
43 * Initialize IRQ setting
44 */
45void __init init_landisk_IRQ(void)
46{
47 int i;
48
49 for (i = 5; i < 14; i++) {
50 disable_irq_nosync(i);
51 set_irq_chip_and_handler_name(i, &landisk_irq_chip,
52 handle_level_irq, "level");
53 enable_landisk_irq(i);
54 }
55 ctrl_outb(0x00, PA_PWRINT_CLR);
56}
diff --git a/arch/sh/boards/mach-landisk/psw.c b/arch/sh/boards/mach-landisk/psw.c
new file mode 100644
index 000000000000..e6b0efa098d1
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/psw.c
@@ -0,0 +1,143 @@
1/*
2 * arch/sh/boards/landisk/psw.c
3 *
4 * push switch support for LANDISK and USL-5P
5 *
6 * Copyright (C) 2006-2007 Paul Mundt
7 * Copyright (C) 2007 kogiidena
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/io.h>
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <mach-landisk/mach/iodata_landisk.h>
18#include <asm/push-switch.h>
19
20static irqreturn_t psw_irq_handler(int irq, void *arg)
21{
22 struct platform_device *pdev = arg;
23 struct push_switch *psw = platform_get_drvdata(pdev);
24 struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
25 unsigned int sw_value;
26 int ret = 0;
27
28 sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
29
30 /* Nothing to do if there's no state change */
31 if (psw->state) {
32 ret = 1;
33 goto out;
34 }
35
36 /* Figure out who raised it */
37 if (sw_value & (1 << psw_info->bit)) {
38 psw->state = 1;
39 mod_timer(&psw->debounce, jiffies + 50);
40 ret = 1;
41 }
42
43out:
44 /* Clear the switch IRQs */
45 ctrl_outb(0x00, PA_PWRINT_CLR);
46
47 return IRQ_RETVAL(ret);
48}
49
50static struct resource psw_power_resources[] = {
51 [0] = {
52 .start = IRQ_POWER,
53 .flags = IORESOURCE_IRQ,
54 },
55};
56
57static struct resource psw_usl5p_resources[] = {
58 [0] = {
59 .start = IRQ_BUTTON,
60 .flags = IORESOURCE_IRQ,
61 },
62};
63
64static struct push_switch_platform_info psw_power_platform_data = {
65 .name = "psw_power",
66 .bit = 4,
67 .irq_flags = IRQF_SHARED,
68 .irq_handler = psw_irq_handler,
69};
70
71static struct push_switch_platform_info psw1_platform_data = {
72 .name = "psw1",
73 .bit = 0,
74 .irq_flags = IRQF_SHARED,
75 .irq_handler = psw_irq_handler,
76};
77
78static struct push_switch_platform_info psw2_platform_data = {
79 .name = "psw2",
80 .bit = 2,
81 .irq_flags = IRQF_SHARED,
82 .irq_handler = psw_irq_handler,
83};
84
85static struct push_switch_platform_info psw3_platform_data = {
86 .name = "psw3",
87 .bit = 1,
88 .irq_flags = IRQF_SHARED,
89 .irq_handler = psw_irq_handler,
90};
91
92static struct platform_device psw_power_switch_device = {
93 .name = "push-switch",
94 .id = 0,
95 .num_resources = ARRAY_SIZE(psw_power_resources),
96 .resource = psw_power_resources,
97 .dev = {
98 .platform_data = &psw_power_platform_data,
99 },
100};
101
102static struct platform_device psw1_switch_device = {
103 .name = "push-switch",
104 .id = 1,
105 .num_resources = ARRAY_SIZE(psw_usl5p_resources),
106 .resource = psw_usl5p_resources,
107 .dev = {
108 .platform_data = &psw1_platform_data,
109 },
110};
111
112static struct platform_device psw2_switch_device = {
113 .name = "push-switch",
114 .id = 2,
115 .num_resources = ARRAY_SIZE(psw_usl5p_resources),
116 .resource = psw_usl5p_resources,
117 .dev = {
118 .platform_data = &psw2_platform_data,
119 },
120};
121
122static struct platform_device psw3_switch_device = {
123 .name = "push-switch",
124 .id = 3,
125 .num_resources = ARRAY_SIZE(psw_usl5p_resources),
126 .resource = psw_usl5p_resources,
127 .dev = {
128 .platform_data = &psw3_platform_data,
129 },
130};
131
132static struct platform_device *psw_devices[] = {
133 &psw_power_switch_device,
134 &psw1_switch_device,
135 &psw2_switch_device,
136 &psw3_switch_device,
137};
138
139static int __init psw_init(void)
140{
141 return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
142}
143module_init(psw_init);
diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c
new file mode 100644
index 000000000000..db22ea2e6d49
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/setup.c
@@ -0,0 +1,105 @@
1/*
2 * arch/sh/boards/landisk/setup.c
3 *
4 * I-O DATA Device, Inc. LANDISK Support.
5 *
6 * Copyright (C) 2000 Kazumoto Kojima
7 * Copyright (C) 2002 Paul Mundt
8 * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
9 * Copyright (C) 2005-2007 kogiidena
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/ata_platform.h>
18#include <linux/pm.h>
19#include <linux/mm.h>
20#include <asm/machvec.h>
21#include <mach-landisk/mach/iodata_landisk.h>
22#include <asm/io.h>
23
24void init_landisk_IRQ(void);
25
26static void landisk_power_off(void)
27{
28 ctrl_outb(0x01, PA_SHUTDOWN);
29}
30
31static struct resource cf_ide_resources[3];
32
33static struct pata_platform_info pata_info = {
34 .ioport_shift = 1,
35};
36
37static struct platform_device cf_ide_device = {
38 .name = "pata_platform",
39 .id = -1,
40 .num_resources = ARRAY_SIZE(cf_ide_resources),
41 .resource = cf_ide_resources,
42 .dev = {
43 .platform_data = &pata_info,
44 },
45};
46
47static struct platform_device rtc_device = {
48 .name = "rs5c313",
49 .id = -1,
50};
51
52static struct platform_device *landisk_devices[] __initdata = {
53 &cf_ide_device,
54 &rtc_device,
55};
56
57static int __init landisk_devices_setup(void)
58{
59 pgprot_t prot;
60 unsigned long paddrbase;
61 void *cf_ide_base;
62
63 /* open I/O area window */
64 paddrbase = virt_to_phys((void *)PA_AREA5_IO);
65 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
66 cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
67 if (!cf_ide_base) {
68 printk("allocate_cf_area : can't open CF I/O window!\n");
69 return -ENOMEM;
70 }
71
72 /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
73 cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40;
74 cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f;
75 cf_ide_resources[0].flags = IORESOURCE_IO;
76 cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c;
77 cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03;
78 cf_ide_resources[1].flags = IORESOURCE_IO;
79 cf_ide_resources[2].start = IRQ_FATA;
80 cf_ide_resources[2].flags = IORESOURCE_IRQ;
81
82 return platform_add_devices(landisk_devices,
83 ARRAY_SIZE(landisk_devices));
84}
85
86__initcall(landisk_devices_setup);
87
88static void __init landisk_setup(char **cmdline_p)
89{
90 /* LED ON */
91 ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED);
92
93 printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
94 pm_power_off = landisk_power_off;
95}
96
97/*
98 * The Machine Vector
99 */
100static struct sh_machine_vector mv_landisk __initmv = {
101 .mv_name = "LANDISK",
102 .mv_nr_irqs = 72,
103 .mv_setup = landisk_setup,
104 .mv_init_irq = init_landisk_IRQ,
105};