]>
Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
f30c2269 | 2 | * drivers/ide/h8300/ide-h8300.c |
1da177e4 LT |
3 | * H8/300 generic IDE interface |
4 | */ | |
5 | ||
6 | #include <linux/init.h> | |
7 | #include <linux/ide.h> | |
1da177e4 LT |
8 | |
9 | #include <asm/io.h> | |
10 | #include <asm/irq.h> | |
11 | ||
12 | #define bswap(d) \ | |
13 | ({ \ | |
14 | u16 r; \ | |
15 | __asm__("mov.b %w1,r1h\n\t" \ | |
16 | "mov.b %x1,r1l\n\t" \ | |
17 | "mov.w r1,%0" \ | |
18 | :"=r"(r) \ | |
19 | :"r"(d) \ | |
20 | :"er1"); \ | |
21 | (r); \ | |
22 | }) | |
23 | ||
24 | static void mm_outw(u16 d, unsigned long a) | |
25 | { | |
26 | __asm__("mov.b %w0,r2h\n\t" | |
27 | "mov.b %x0,r2l\n\t" | |
28 | "mov.w r2,@%1" | |
29 | : | |
30 | :"r"(d),"r"(a) | |
31 | :"er2"); | |
32 | } | |
33 | ||
34 | static u16 mm_inw(unsigned long a) | |
35 | { | |
36 | register u16 r __asm__("er0"); | |
37 | __asm__("mov.w @%1,r2\n\t" | |
38 | "mov.b r2l,%x0\n\t" | |
39 | "mov.b r2h,%w0" | |
40 | :"=r"(r) | |
41 | :"r"(a) | |
42 | :"er2"); | |
43 | return r; | |
44 | } | |
45 | ||
46 | static void mm_outsw(unsigned long addr, void *buf, u32 len) | |
47 | { | |
48 | unsigned short *bp = (unsigned short *)buf; | |
49 | for (; len > 0; len--, bp++) | |
50 | *(volatile u16 *)addr = bswap(*bp); | |
51 | } | |
52 | ||
53 | static void mm_insw(unsigned long addr, void *buf, u32 len) | |
54 | { | |
55 | unsigned short *bp = (unsigned short *)buf; | |
56 | for (; len > 0; len--, bp++) | |
57 | *bp = bswap(*(volatile u16 *)addr); | |
58 | } | |
59 | ||
60 | #define H8300_IDE_GAP (2) | |
61 | ||
62 | static inline void hw_setup(hw_regs_t *hw) | |
63 | { | |
64 | int i; | |
65 | ||
66 | memset(hw, 0, sizeof(hw_regs_t)); | |
67 | for (i = 0; i <= IDE_STATUS_OFFSET; i++) | |
68 | hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i; | |
69 | hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT; | |
70 | hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ; | |
1da177e4 LT |
71 | hw->chipset = ide_generic; |
72 | } | |
73 | ||
74 | static inline void hwif_setup(ide_hwif_t *hwif) | |
75 | { | |
76 | default_hwif_iops(hwif); | |
77 | ||
2ad1e558 | 78 | hwif->mmio = 1; |
1da177e4 LT |
79 | hwif->OUTW = mm_outw; |
80 | hwif->OUTSW = mm_outsw; | |
81 | hwif->INW = mm_inw; | |
82 | hwif->INSW = mm_insw; | |
1da177e4 LT |
83 | hwif->OUTSL = NULL; |
84 | hwif->INSL = NULL; | |
85 | } | |
86 | ||
87 | void __init h8300_ide_init(void) | |
88 | { | |
89 | hw_regs_t hw; | |
90 | ide_hwif_t *hwif; | |
91 | int idx; | |
92 | ||
93 | if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) | |
94 | goto out_busy; | |
95 | if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) { | |
96 | release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8); | |
97 | goto out_busy; | |
98 | } | |
99 | ||
100 | hw_setup(&hw); | |
101 | ||
102 | /* register if */ | |
fd9bb539 | 103 | idx = ide_register_hw(&hw, NULL, 1, &hwif); |
1da177e4 LT |
104 | if (idx == -1) { |
105 | printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); | |
106 | return; | |
107 | } | |
108 | ||
109 | hwif_setup(hwif); | |
110 | printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", idx); | |
111 | return; | |
112 | ||
113 | out_busy: | |
114 | printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); | |
115 | } |