diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-21 14:57:23 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-21 14:57:23 -0400 |
commit | 2bfba3c444fe8b2ab1c38112a89d8f03b61136ca (patch) | |
tree | 17580eee63d868c9d6b97a6bc956a08f25631532 /drivers/ide/ide-h8300.c | |
parent | 2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4 (diff) |
ide: remove useless subdirs from drivers/ide/
Suggested-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-h8300.c')
-rw-r--r-- | drivers/ide/ide-h8300.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c new file mode 100644 index 000000000000..e2cdd2e9cdec --- /dev/null +++ b/drivers/ide/ide-h8300.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * H8/300 generic IDE interface | ||
3 | */ | ||
4 | |||
5 | #include <linux/init.h> | ||
6 | #include <linux/ide.h> | ||
7 | |||
8 | #include <asm/io.h> | ||
9 | #include <asm/irq.h> | ||
10 | |||
11 | #define DRV_NAME "ide-h8300" | ||
12 | |||
13 | #define bswap(d) \ | ||
14 | ({ \ | ||
15 | u16 r; \ | ||
16 | __asm__("mov.b %w1,r1h\n\t" \ | ||
17 | "mov.b %x1,r1l\n\t" \ | ||
18 | "mov.w r1,%0" \ | ||
19 | :"=r"(r) \ | ||
20 | :"r"(d) \ | ||
21 | :"er1"); \ | ||
22 | (r); \ | ||
23 | }) | ||
24 | |||
25 | static void mm_outw(u16 d, unsigned long a) | ||
26 | { | ||
27 | __asm__("mov.b %w0,r2h\n\t" | ||
28 | "mov.b %x0,r2l\n\t" | ||
29 | "mov.w r2,@%1" | ||
30 | : | ||
31 | :"r"(d),"r"(a) | ||
32 | :"er2"); | ||
33 | } | ||
34 | |||
35 | static u16 mm_inw(unsigned long a) | ||
36 | { | ||
37 | register u16 r __asm__("er0"); | ||
38 | __asm__("mov.w @%1,r2\n\t" | ||
39 | "mov.b r2l,%x0\n\t" | ||
40 | "mov.b r2h,%w0" | ||
41 | :"=r"(r) | ||
42 | :"r"(a) | ||
43 | :"er2"); | ||
44 | return r; | ||
45 | } | ||
46 | |||
47 | static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
48 | { | ||
49 | ide_hwif_t *hwif = drive->hwif; | ||
50 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
51 | struct ide_taskfile *tf = &task->tf; | ||
52 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
53 | |||
54 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | ||
55 | HIHI = 0xFF; | ||
56 | |||
57 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) | ||
58 | mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr); | ||
59 | |||
60 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
61 | outb(tf->hob_feature, io_ports->feature_addr); | ||
62 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
63 | outb(tf->hob_nsect, io_ports->nsect_addr); | ||
64 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
65 | outb(tf->hob_lbal, io_ports->lbal_addr); | ||
66 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
67 | outb(tf->hob_lbam, io_ports->lbam_addr); | ||
68 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
69 | outb(tf->hob_lbah, io_ports->lbah_addr); | ||
70 | |||
71 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
72 | outb(tf->feature, io_ports->feature_addr); | ||
73 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
74 | outb(tf->nsect, io_ports->nsect_addr); | ||
75 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
76 | outb(tf->lbal, io_ports->lbal_addr); | ||
77 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
78 | outb(tf->lbam, io_ports->lbam_addr); | ||
79 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
80 | outb(tf->lbah, io_ports->lbah_addr); | ||
81 | |||
82 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
83 | outb((tf->device & HIHI) | drive->select, | ||
84 | io_ports->device_addr); | ||
85 | } | ||
86 | |||
87 | static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) | ||
88 | { | ||
89 | ide_hwif_t *hwif = drive->hwif; | ||
90 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
91 | struct ide_taskfile *tf = &task->tf; | ||
92 | |||
93 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | ||
94 | u16 data = mm_inw(io_ports->data_addr); | ||
95 | |||
96 | tf->data = data & 0xff; | ||
97 | tf->hob_data = (data >> 8) & 0xff; | ||
98 | } | ||
99 | |||
100 | /* be sure we're looking at the low order bits */ | ||
101 | outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); | ||
102 | |||
103 | if (task->tf_flags & IDE_TFLAG_IN_FEATURE) | ||
104 | tf->feature = inb(io_ports->feature_addr); | ||
105 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | ||
106 | tf->nsect = inb(io_ports->nsect_addr); | ||
107 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | ||
108 | tf->lbal = inb(io_ports->lbal_addr); | ||
109 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | ||
110 | tf->lbam = inb(io_ports->lbam_addr); | ||
111 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | ||
112 | tf->lbah = inb(io_ports->lbah_addr); | ||
113 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
114 | tf->device = inb(io_ports->device_addr); | ||
115 | |||
116 | if (task->tf_flags & IDE_TFLAG_LBA48) { | ||
117 | outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); | ||
118 | |||
119 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | ||
120 | tf->hob_feature = inb(io_ports->feature_addr); | ||
121 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
122 | tf->hob_nsect = inb(io_ports->nsect_addr); | ||
123 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
124 | tf->hob_lbal = inb(io_ports->lbal_addr); | ||
125 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
126 | tf->hob_lbam = inb(io_ports->lbam_addr); | ||
127 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
128 | tf->hob_lbah = inb(io_ports->lbah_addr); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | static void mm_outsw(unsigned long addr, void *buf, u32 len) | ||
133 | { | ||
134 | unsigned short *bp = (unsigned short *)buf; | ||
135 | for (; len > 0; len--, bp++) | ||
136 | *(volatile u16 *)addr = bswap(*bp); | ||
137 | } | ||
138 | |||
139 | static void mm_insw(unsigned long addr, void *buf, u32 len) | ||
140 | { | ||
141 | unsigned short *bp = (unsigned short *)buf; | ||
142 | for (; len > 0; len--, bp++) | ||
143 | *bp = bswap(*(volatile u16 *)addr); | ||
144 | } | ||
145 | |||
146 | static void h8300_input_data(ide_drive_t *drive, struct request *rq, | ||
147 | void *buf, unsigned int len) | ||
148 | { | ||
149 | mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); | ||
150 | } | ||
151 | |||
152 | static void h8300_output_data(ide_drive_t *drive, struct request *rq, | ||
153 | void *buf, unsigned int len) | ||
154 | { | ||
155 | mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); | ||
156 | } | ||
157 | |||
158 | static const struct ide_tp_ops h8300_tp_ops = { | ||
159 | .exec_command = ide_exec_command, | ||
160 | .read_status = ide_read_status, | ||
161 | .read_altstatus = ide_read_altstatus, | ||
162 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
163 | |||
164 | .set_irq = ide_set_irq, | ||
165 | |||
166 | .tf_load = h8300_tf_load, | ||
167 | .tf_read = h8300_tf_read, | ||
168 | |||
169 | .input_data = h8300_input_data, | ||
170 | .output_data = h8300_output_data, | ||
171 | }; | ||
172 | |||
173 | #define H8300_IDE_GAP (2) | ||
174 | |||
175 | static inline void hw_setup(hw_regs_t *hw) | ||
176 | { | ||
177 | int i; | ||
178 | |||
179 | memset(hw, 0, sizeof(hw_regs_t)); | ||
180 | for (i = 0; i <= 7; i++) | ||
181 | hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i; | ||
182 | hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT; | ||
183 | hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ; | ||
184 | hw->chipset = ide_generic; | ||
185 | } | ||
186 | |||
187 | static const struct ide_port_info h8300_port_info = { | ||
188 | .tp_ops = &h8300_tp_ops, | ||
189 | .host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA, | ||
190 | }; | ||
191 | |||
192 | static int __init h8300_ide_init(void) | ||
193 | { | ||
194 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | ||
195 | |||
196 | printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n"); | ||
197 | |||
198 | if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) | ||
199 | goto out_busy; | ||
200 | if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) { | ||
201 | release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8); | ||
202 | goto out_busy; | ||
203 | } | ||
204 | |||
205 | hw_setup(&hw); | ||
206 | |||
207 | return ide_host_add(&h8300_port_info, hws, NULL); | ||
208 | |||
209 | out_busy: | ||
210 | printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); | ||
211 | |||
212 | return -EBUSY; | ||
213 | } | ||
214 | |||
215 | module_init(h8300_ide_init); | ||
216 | |||
217 | MODULE_LICENSE("GPL"); | ||