diff options
Diffstat (limited to 'arch/sh/boards/mach-landisk')
-rw-r--r-- | arch/sh/boards/mach-landisk/Makefile | 5 | ||||
-rw-r--r-- | arch/sh/boards/mach-landisk/gio.c | 171 | ||||
-rw-r--r-- | arch/sh/boards/mach-landisk/irq.c | 56 | ||||
-rw-r--r-- | arch/sh/boards/mach-landisk/psw.c | 143 | ||||
-rw-r--r-- | arch/sh/boards/mach-landisk/setup.c | 105 |
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 | |||
5 | obj-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 | |||
29 | static dev_t dev; | ||
30 | static struct cdev *cdev_p; | ||
31 | static int openCnt; | ||
32 | |||
33 | static 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 | |||
52 | static 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 | |||
63 | static 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 | |||
128 | static 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 | |||
135 | static 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 | |||
162 | static void __exit gio_exit(void) | ||
163 | { | ||
164 | cdev_del(cdev_p); | ||
165 | unregister_chrdev_region(dev, DEVCOUNT); | ||
166 | } | ||
167 | |||
168 | module_init(gio_init); | ||
169 | module_exit(gio_exit); | ||
170 | |||
171 | MODULE_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 | |||
21 | static 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 | |||
28 | static 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 | |||
35 | static 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 | */ | ||
45 | void __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 | |||
20 | static 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 | |||
43 | out: | ||
44 | /* Clear the switch IRQs */ | ||
45 | ctrl_outb(0x00, PA_PWRINT_CLR); | ||
46 | |||
47 | return IRQ_RETVAL(ret); | ||
48 | } | ||
49 | |||
50 | static struct resource psw_power_resources[] = { | ||
51 | [0] = { | ||
52 | .start = IRQ_POWER, | ||
53 | .flags = IORESOURCE_IRQ, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static struct resource psw_usl5p_resources[] = { | ||
58 | [0] = { | ||
59 | .start = IRQ_BUTTON, | ||
60 | .flags = IORESOURCE_IRQ, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static 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 | |||
71 | static 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 | |||
78 | static 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 | |||
85 | static 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 | |||
92 | static 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 | |||
102 | static 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 | |||
112 | static 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 | |||
122 | static 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 | |||
132 | static struct platform_device *psw_devices[] = { | ||
133 | &psw_power_switch_device, | ||
134 | &psw1_switch_device, | ||
135 | &psw2_switch_device, | ||
136 | &psw3_switch_device, | ||
137 | }; | ||
138 | |||
139 | static int __init psw_init(void) | ||
140 | { | ||
141 | return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); | ||
142 | } | ||
143 | module_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 | |||
24 | void init_landisk_IRQ(void); | ||
25 | |||
26 | static void landisk_power_off(void) | ||
27 | { | ||
28 | ctrl_outb(0x01, PA_SHUTDOWN); | ||
29 | } | ||
30 | |||
31 | static struct resource cf_ide_resources[3]; | ||
32 | |||
33 | static struct pata_platform_info pata_info = { | ||
34 | .ioport_shift = 1, | ||
35 | }; | ||
36 | |||
37 | static 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 | |||
47 | static struct platform_device rtc_device = { | ||
48 | .name = "rs5c313", | ||
49 | .id = -1, | ||
50 | }; | ||
51 | |||
52 | static struct platform_device *landisk_devices[] __initdata = { | ||
53 | &cf_ide_device, | ||
54 | &rtc_device, | ||
55 | }; | ||
56 | |||
57 | static 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 | |||
88 | static 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 | */ | ||
100 | static 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 | }; | ||