diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2009-12-08 14:12:20 -0500 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2010-05-26 13:51:09 -0400 |
commit | 9aed2302655854586069d90e0d59ce3a0e12809d (patch) | |
tree | 7d5314f1f7b60891cfe8adb8be4fd6fdbacfae0b /drivers/ide | |
parent | a24a6b22254bca8d54be6c8b7d8730d09f1058cc (diff) |
m68k: amiga - Amiga Gayle IDE platform device conversion
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/gayle.c | 147 |
1 files changed, 82 insertions, 65 deletions
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index b9e517de6a82..3feaa26410be 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/zorro.h> | 17 | #include <linux/zorro.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/platform_device.h> | ||
19 | 20 | ||
20 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
21 | #include <asm/amigahw.h> | 22 | #include <asm/amigahw.h> |
@@ -24,15 +25,6 @@ | |||
24 | 25 | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Bases of the IDE interfaces | ||
28 | */ | ||
29 | |||
30 | #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ | ||
31 | #define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ | ||
32 | |||
33 | #define GAYLE_IDEREG_SIZE 0x2000 | ||
34 | |||
35 | /* | ||
36 | * Offsets from one of the above bases | 28 | * Offsets from one of the above bases |
37 | */ | 29 | */ |
38 | 30 | ||
@@ -68,20 +60,20 @@ MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); | |||
68 | 60 | ||
69 | static int gayle_test_irq(ide_hwif_t *hwif) | 61 | static int gayle_test_irq(ide_hwif_t *hwif) |
70 | { | 62 | { |
71 | unsigned char ch; | 63 | unsigned char ch; |
72 | 64 | ||
73 | ch = z_readb(hwif->io_ports.irq_addr); | 65 | ch = z_readb(hwif->io_ports.irq_addr); |
74 | if (!(ch & GAYLE_IRQ_IDE)) | 66 | if (!(ch & GAYLE_IRQ_IDE)) |
75 | return 0; | 67 | return 0; |
76 | return 1; | 68 | return 1; |
77 | } | 69 | } |
78 | 70 | ||
79 | static void gayle_a1200_clear_irq(ide_drive_t *drive) | 71 | static void gayle_a1200_clear_irq(ide_drive_t *drive) |
80 | { | 72 | { |
81 | ide_hwif_t *hwif = drive->hwif; | 73 | ide_hwif_t *hwif = drive->hwif; |
82 | 74 | ||
83 | (void)z_readb(hwif->io_ports.status_addr); | 75 | (void)z_readb(hwif->io_ports.status_addr); |
84 | z_writeb(0x7c, hwif->io_ports.irq_addr); | 76 | z_writeb(0x7c, hwif->io_ports.irq_addr); |
85 | } | 77 | } |
86 | 78 | ||
87 | static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, | 79 | static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, |
@@ -122,64 +114,89 @@ static const struct ide_port_info gayle_port_info = { | |||
122 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) | 114 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) |
123 | */ | 115 | */ |
124 | 116 | ||
125 | static int __init gayle_init(void) | 117 | static int __init amiga_gayle_ide_probe(struct platform_device *pdev) |
126 | { | 118 | { |
127 | unsigned long phys_base, res_start, res_n; | 119 | struct resource *res; |
128 | unsigned long base, ctrlport, irqport; | 120 | struct gayle_ide_platform_data *pdata; |
129 | int a4000, i, rc; | 121 | unsigned long base, ctrlport, irqport; |
130 | struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; | 122 | unsigned int i; |
131 | struct ide_port_info d = gayle_port_info; | 123 | int error; |
132 | 124 | struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; | |
133 | if (!MACH_IS_AMIGA) | 125 | struct ide_port_info d = gayle_port_info; |
134 | return -ENODEV; | 126 | struct ide_host *host; |
135 | 127 | ||
136 | if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) | 128 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
137 | goto found; | 129 | if (!res) |
138 | 130 | return -ENODEV; | |
139 | #ifdef CONFIG_ZORRO | 131 | |
140 | if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, | 132 | if (!request_mem_region(res->start, resource_size(res), "IDE")) |
141 | NULL)) | 133 | return -EBUSY; |
142 | goto found; | 134 | |
143 | #endif | 135 | pdata = pdev->dev.platform_data; |
144 | return -ENODEV; | 136 | pr_info("ide: Gayle IDE controller (A%u style%s)\n", |
145 | 137 | pdata->explicit_ack ? 1200 : 4000, | |
146 | found: | 138 | ide_doubler ? ", IDE doubler" : ""); |
147 | printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", | 139 | |
148 | a4000 ? 4000 : 1200, | 140 | base = (unsigned long)ZTWO_VADDR(pdata->base); |
149 | ide_doubler ? ", IDE doubler" : ""); | 141 | ctrlport = 0; |
150 | 142 | irqport = (unsigned long)ZTWO_VADDR(pdata->irqport); | |
151 | if (a4000) { | 143 | if (pdata->explicit_ack) |
152 | phys_base = GAYLE_BASE_4000; | 144 | d.port_ops = &gayle_a1200_port_ops; |
153 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); | 145 | else |
154 | d.port_ops = &gayle_a4000_port_ops; | 146 | d.port_ops = &gayle_a4000_port_ops; |
155 | } else { | 147 | |
156 | phys_base = GAYLE_BASE_1200; | 148 | for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++, base += GAYLE_NEXT_PORT) { |
157 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); | 149 | if (GAYLE_HAS_CONTROL_REG) |
158 | d.port_ops = &gayle_a1200_port_ops; | 150 | ctrlport = base + GAYLE_CONTROL; |
151 | |||
152 | gayle_setup_ports(&hw[i], base, ctrlport, irqport); | ||
153 | hws[i] = &hw[i]; | ||
159 | } | 154 | } |
160 | 155 | ||
161 | res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); | 156 | error = ide_host_add(&d, hws, i, &host); |
162 | res_n = GAYLE_IDEREG_SIZE; | 157 | if (error) |
158 | goto out; | ||
163 | 159 | ||
164 | if (!request_mem_region(res_start, res_n, "IDE")) | 160 | platform_set_drvdata(pdev, host); |
165 | return -EBUSY; | 161 | return 0; |
166 | 162 | ||
167 | for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { | 163 | out: |
168 | base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); | 164 | release_mem_region(res->start, resource_size(res)); |
169 | ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; | 165 | return error; |
166 | } | ||
167 | |||
168 | static int __exit amiga_gayle_ide_remove(struct platform_device *pdev) | ||
169 | { | ||
170 | struct ide_host *host = platform_get_drvdata(pdev); | ||
171 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
172 | |||
173 | ide_host_remove(host); | ||
174 | release_mem_region(res->start, resource_size(res)); | ||
175 | return 0; | ||
176 | } | ||
170 | 177 | ||
171 | gayle_setup_ports(&hw[i], base, ctrlport, irqport); | 178 | static struct platform_driver amiga_gayle_ide_driver = { |
179 | .remove = __exit_p(amiga_gayle_ide_remove), | ||
180 | .driver = { | ||
181 | .name = "amiga-gayle-ide", | ||
182 | .owner = THIS_MODULE, | ||
183 | }, | ||
184 | }; | ||
172 | 185 | ||
173 | hws[i] = &hw[i]; | 186 | static int __init amiga_gayle_ide_init(void) |
174 | } | 187 | { |
188 | return platform_driver_probe(&amiga_gayle_ide_driver, | ||
189 | amiga_gayle_ide_probe); | ||
190 | } | ||
175 | 191 | ||
176 | rc = ide_host_add(&d, hws, i, NULL); | 192 | module_init(amiga_gayle_ide_init); |
177 | if (rc) | ||
178 | release_mem_region(res_start, res_n); | ||
179 | 193 | ||
180 | return rc; | 194 | static void __exit amiga_gayle_ide_exit(void) |
195 | { | ||
196 | platform_driver_unregister(&amiga_gayle_ide_driver); | ||
181 | } | 197 | } |
182 | 198 | ||
183 | module_init(gayle_init); | 199 | module_exit(amiga_gayle_ide_exit); |
184 | 200 | ||
185 | MODULE_LICENSE("GPL"); | 201 | MODULE_LICENSE("GPL"); |
202 | MODULE_ALIAS("platform:amiga-gayle-ide"); | ||