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 | |
parent | a24a6b22254bca8d54be6c8b7d8730d09f1058cc (diff) |
m68k: amiga - Amiga Gayle IDE platform device conversion
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-rw-r--r-- | arch/m68k/amiga/platform.c | 63 | ||||
-rw-r--r-- | arch/m68k/include/asm/amigayle.h | 6 | ||||
-rw-r--r-- | drivers/ide/gayle.c | 147 |
3 files changed, 150 insertions, 66 deletions
diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 027e4cae88ff..907f6f5f2cac 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/zorro.h> | 11 | #include <linux/zorro.h> |
12 | 12 | ||
13 | #include <asm/amigahw.h> | 13 | #include <asm/amigahw.h> |
14 | #include <asm/amigayle.h> | ||
14 | 15 | ||
15 | 16 | ||
16 | #ifdef CONFIG_ZORRO | 17 | #ifdef CONFIG_ZORRO |
@@ -55,7 +56,24 @@ static int __init amiga_init_bus(void) | |||
55 | 56 | ||
56 | subsys_initcall(amiga_init_bus); | 57 | subsys_initcall(amiga_init_bus); |
57 | 58 | ||
58 | #endif /* CONFIG_ZORRO */ | 59 | |
60 | static int z_dev_present(zorro_id id) | ||
61 | { | ||
62 | unsigned int i; | ||
63 | |||
64 | for (i = 0; i < zorro_num_autocon; i++) | ||
65 | if (zorro_autocon[i].rom.er_Manufacturer == ZORRO_MANUF(id) && | ||
66 | zorro_autocon[i].rom.er_Product == ZORRO_PROD(id)) | ||
67 | return 1; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | #else /* !CONFIG_ZORRO */ | ||
73 | |||
74 | static inline int z_dev_present(zorro_id id) { return 0; } | ||
75 | |||
76 | #endif /* !CONFIG_ZORRO */ | ||
59 | 77 | ||
60 | 78 | ||
61 | static const struct resource a3000_scsi_resource __initconst = { | 79 | static const struct resource a3000_scsi_resource __initconst = { |
@@ -72,8 +90,36 @@ static const struct resource a4000t_scsi_resource __initconst = { | |||
72 | }; | 90 | }; |
73 | 91 | ||
74 | 92 | ||
93 | static const struct resource a1200_ide_resource __initconst = { | ||
94 | .start = 0xda0000, | ||
95 | .end = 0xda1fff, | ||
96 | .flags = IORESOURCE_MEM, | ||
97 | }; | ||
98 | |||
99 | static const struct gayle_ide_platform_data a1200_ide_pdata __initconst = { | ||
100 | .base = 0xda0000, | ||
101 | .irqport = 0xda9000, | ||
102 | .explicit_ack = 1, | ||
103 | }; | ||
104 | |||
105 | |||
106 | static const struct resource a4000_ide_resource __initconst = { | ||
107 | .start = 0xdd2000, | ||
108 | .end = 0xdd3fff, | ||
109 | .flags = IORESOURCE_MEM, | ||
110 | }; | ||
111 | |||
112 | static const struct gayle_ide_platform_data a4000_ide_pdata __initconst = { | ||
113 | .base = 0xdd2020, | ||
114 | .irqport = 0xdd3020, | ||
115 | .explicit_ack = 0, | ||
116 | }; | ||
117 | |||
118 | |||
75 | static int __init amiga_init_devices(void) | 119 | static int __init amiga_init_devices(void) |
76 | { | 120 | { |
121 | struct platform_device *pdev; | ||
122 | |||
77 | if (!MACH_IS_AMIGA) | 123 | if (!MACH_IS_AMIGA) |
78 | return -ENODEV; | 124 | return -ENODEV; |
79 | 125 | ||
@@ -99,6 +145,21 @@ static int __init amiga_init_devices(void) | |||
99 | platform_device_register_simple("amiga-a4000t-scsi", -1, | 145 | platform_device_register_simple("amiga-a4000t-scsi", -1, |
100 | &a4000t_scsi_resource, 1); | 146 | &a4000t_scsi_resource, 1); |
101 | 147 | ||
148 | if (AMIGAHW_PRESENT(A1200_IDE) || | ||
149 | z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) { | ||
150 | pdev = platform_device_register_simple("amiga-gayle-ide", -1, | ||
151 | &a1200_ide_resource, 1); | ||
152 | platform_device_add_data(pdev, &a1200_ide_pdata, | ||
153 | sizeof(a1200_ide_pdata)); | ||
154 | } | ||
155 | |||
156 | if (AMIGAHW_PRESENT(A4000_IDE)) { | ||
157 | pdev = platform_device_register_simple("amiga-gayle-ide", -1, | ||
158 | &a4000_ide_resource, 1); | ||
159 | platform_device_add_data(pdev, &a4000_ide_pdata, | ||
160 | sizeof(a4000_ide_pdata)); | ||
161 | } | ||
162 | |||
102 | return 0; | 163 | return 0; |
103 | } | 164 | } |
104 | 165 | ||
diff --git a/arch/m68k/include/asm/amigayle.h b/arch/m68k/include/asm/amigayle.h index bb5a6aa329f3..a01453d9c231 100644 --- a/arch/m68k/include/asm/amigayle.h +++ b/arch/m68k/include/asm/amigayle.h | |||
@@ -104,4 +104,10 @@ struct GAYLE { | |||
104 | #define GAYLE_CFG_250NS 0x00 | 104 | #define GAYLE_CFG_250NS 0x00 |
105 | #define GAYLE_CFG_720NS 0x0c | 105 | #define GAYLE_CFG_720NS 0x0c |
106 | 106 | ||
107 | struct gayle_ide_platform_data { | ||
108 | unsigned long base; | ||
109 | unsigned long irqport; | ||
110 | int explicit_ack; /* A1200 IDE needs explicit ack */ | ||
111 | }; | ||
112 | |||
107 | #endif /* asm-m68k/amigayle.h */ | 113 | #endif /* asm-m68k/amigayle.h */ |
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"); | ||