diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-01-19 10:47:23 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:17 -0500 |
commit | b832548773b0cd98216534caa31b9ed7607c4e76 (patch) | |
tree | fa546516db295b65dd337dab1bb6e0477e44ca1c /drivers/ata | |
parent | 5e8f757cb2e0f67bf43f71d5180a8bf0ab3484eb (diff) |
pata_legacy: Merge winbond support
This puts winbond VLB in with the other ISA/VLB support and means we can
lose pata_winbond.c. With all the VLB/ISA probe in one space (and out of
the core libata) this makes legacy probing work sanely.
Also switch to devm_ for resource handling on the ports post probe
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/pata_legacy.c | 178 |
1 files changed, 144 insertions, 34 deletions
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index c4a939b506c9..333dc15f8ccf 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -28,7 +28,6 @@ | |||
28 | * | 28 | * |
29 | * Unsupported but docs exist: | 29 | * Unsupported but docs exist: |
30 | * Appian/Adaptec AIC25VL01/Cirrus Logic PD7220 | 30 | * Appian/Adaptec AIC25VL01/Cirrus Logic PD7220 |
31 | * Winbond W83759A | ||
32 | * | 31 | * |
33 | * This driver handles legacy (that is "ISA/VLB side") IDE ports found | 32 | * This driver handles legacy (that is "ISA/VLB side") IDE ports found |
34 | * on PC class systems. There are three hybrid devices that are exceptions | 33 | * on PC class systems. There are three hybrid devices that are exceptions |
@@ -36,7 +35,7 @@ | |||
36 | * the MPIIX where the tuning is PCI side but the IDE is "ISA side". | 35 | * the MPIIX where the tuning is PCI side but the IDE is "ISA side". |
37 | * | 36 | * |
38 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ | 37 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ |
39 | * opti82c465mv/promise 20230c/20630 | 38 | * opti82c465mv/promise 20230c/20630/winbond83759A |
40 | * | 39 | * |
41 | * Use the autospeed and pio_mask options with: | 40 | * Use the autospeed and pio_mask options with: |
42 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. | 41 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. |
@@ -47,9 +46,6 @@ | |||
47 | * For now use autospeed and pio_mask as above with the W83759A. This may | 46 | * For now use autospeed and pio_mask as above with the W83759A. This may |
48 | * change. | 47 | * change. |
49 | * | 48 | * |
50 | * TODO | ||
51 | * Merge existing pata_qdi driver | ||
52 | * | ||
53 | */ | 49 | */ |
54 | 50 | ||
55 | #include <linux/kernel.h> | 51 | #include <linux/kernel.h> |
@@ -64,7 +60,7 @@ | |||
64 | #include <linux/platform_device.h> | 60 | #include <linux/platform_device.h> |
65 | 61 | ||
66 | #define DRV_NAME "pata_legacy" | 62 | #define DRV_NAME "pata_legacy" |
67 | #define DRV_VERSION "0.5.5" | 63 | #define DRV_VERSION "0.6.5" |
68 | 64 | ||
69 | #define NR_HOST 6 | 65 | #define NR_HOST 6 |
70 | 66 | ||
@@ -92,6 +88,7 @@ enum controller { | |||
92 | QDI6500 = 7, | 88 | QDI6500 = 7, |
93 | QDI6580 = 8, | 89 | QDI6580 = 8, |
94 | QDI6580DP = 9, /* Dual channel mode is different */ | 90 | QDI6580DP = 9, /* Dual channel mode is different */ |
91 | W83759A = 10, | ||
95 | 92 | ||
96 | UNKNOWN = -1 | 93 | UNKNOWN = -1 |
97 | }; | 94 | }; |
@@ -111,7 +108,8 @@ struct legacy_controller { | |||
111 | struct ata_port_operations *ops; | 108 | struct ata_port_operations *ops; |
112 | unsigned int pio_mask; | 109 | unsigned int pio_mask; |
113 | unsigned int flags; | 110 | unsigned int flags; |
114 | int (*setup)(struct legacy_probe *probe, struct legacy_data *data); | 111 | int (*setup)(struct platform_device *, struct legacy_probe *probe, |
112 | struct legacy_data *data); | ||
115 | }; | 113 | }; |
116 | 114 | ||
117 | static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; | 115 | static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; |
@@ -128,6 +126,8 @@ static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ | |||
128 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ | 126 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ |
129 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ | 127 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ |
130 | static int qdi; /* Set to probe QDI controllers */ | 128 | static int qdi; /* Set to probe QDI controllers */ |
129 | static int winbond; /* Set to probe Winbond controllers, | ||
130 | give I/O port if non stdanard */ | ||
131 | static int autospeed; /* Chip present which snoops speed changes */ | 131 | static int autospeed; /* Chip present which snoops speed changes */ |
132 | static int pio_mask = 0x1F; /* PIO range for autospeed devices */ | 132 | static int pio_mask = 0x1F; /* PIO range for autospeed devices */ |
133 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ | 133 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ |
@@ -891,9 +891,7 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc) | |||
891 | return ata_qc_issue_prot(qc); | 891 | return ata_qc_issue_prot(qc); |
892 | } | 892 | } |
893 | 893 | ||
894 | /* For the 6580 can we flip the FIFO on/off at this point ? */ | 894 | static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, |
895 | |||
896 | static unsigned int qdi_data_xfer(struct ata_device *adev, unsigned char *buf, | ||
897 | unsigned int buflen, int rw) | 895 | unsigned int buflen, int rw) |
898 | { | 896 | { |
899 | struct ata_port *ap = adev->link->ap; | 897 | struct ata_port *ap = adev->link->ap; |
@@ -922,6 +920,15 @@ static unsigned int qdi_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
922 | return ata_data_xfer(adev, buf, buflen, rw); | 920 | return ata_data_xfer(adev, buf, buflen, rw); |
923 | } | 921 | } |
924 | 922 | ||
923 | static int qdi_port(struct platform_device *dev, | ||
924 | struct legacy_probe *lp, struct legacy_data *ld) | ||
925 | { | ||
926 | if (devm_request_region(&dev->dev, lp->private, 4, "qdi") == NULL) | ||
927 | return -EBUSY; | ||
928 | ld->timing = lp->private; | ||
929 | return 0; | ||
930 | } | ||
931 | |||
925 | static struct ata_port_operations qdi6500_port_ops = { | 932 | static struct ata_port_operations qdi6500_port_ops = { |
926 | .set_piomode = qdi6500_set_piomode, | 933 | .set_piomode = qdi6500_set_piomode, |
927 | 934 | ||
@@ -940,7 +947,7 @@ static struct ata_port_operations qdi6500_port_ops = { | |||
940 | .qc_prep = ata_qc_prep, | 947 | .qc_prep = ata_qc_prep, |
941 | .qc_issue = qdi_qc_issue_prot, | 948 | .qc_issue = qdi_qc_issue_prot, |
942 | 949 | ||
943 | .data_xfer = qdi_data_xfer, | 950 | .data_xfer = vlb32_data_xfer, |
944 | 951 | ||
945 | .irq_handler = ata_interrupt, | 952 | .irq_handler = ata_interrupt, |
946 | .irq_clear = ata_bmdma_irq_clear, | 953 | .irq_clear = ata_bmdma_irq_clear, |
@@ -967,7 +974,7 @@ static struct ata_port_operations qdi6580_port_ops = { | |||
967 | .qc_prep = ata_qc_prep, | 974 | .qc_prep = ata_qc_prep, |
968 | .qc_issue = ata_qc_issue_prot, | 975 | .qc_issue = ata_qc_issue_prot, |
969 | 976 | ||
970 | .data_xfer = qdi_data_xfer, | 977 | .data_xfer = vlb32_data_xfer, |
971 | 978 | ||
972 | .irq_handler = ata_interrupt, | 979 | .irq_handler = ata_interrupt, |
973 | .irq_clear = ata_bmdma_irq_clear, | 980 | .irq_clear = ata_bmdma_irq_clear, |
@@ -994,7 +1001,7 @@ static struct ata_port_operations qdi6580dp_port_ops = { | |||
994 | .qc_prep = ata_qc_prep, | 1001 | .qc_prep = ata_qc_prep, |
995 | .qc_issue = qdi_qc_issue_prot, | 1002 | .qc_issue = qdi_qc_issue_prot, |
996 | 1003 | ||
997 | .data_xfer = qdi_data_xfer, | 1004 | .data_xfer = vlb32_data_xfer, |
998 | 1005 | ||
999 | .irq_handler = ata_interrupt, | 1006 | .irq_handler = ata_interrupt, |
1000 | .irq_clear = ata_bmdma_irq_clear, | 1007 | .irq_clear = ata_bmdma_irq_clear, |
@@ -1003,6 +1010,97 @@ static struct ata_port_operations qdi6580dp_port_ops = { | |||
1003 | .port_start = ata_sff_port_start, | 1010 | .port_start = ata_sff_port_start, |
1004 | }; | 1011 | }; |
1005 | 1012 | ||
1013 | static DEFINE_SPINLOCK(winbond_lock); | ||
1014 | |||
1015 | static void winbond_writecfg(unsigned long port, u8 reg, u8 val) | ||
1016 | { | ||
1017 | unsigned long flags; | ||
1018 | spin_lock_irqsave(&winbond_lock, flags); | ||
1019 | outb(reg, port + 0x01); | ||
1020 | outb(val, port + 0x02); | ||
1021 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
1022 | } | ||
1023 | |||
1024 | static u8 winbond_readcfg(unsigned long port, u8 reg) | ||
1025 | { | ||
1026 | u8 val; | ||
1027 | |||
1028 | unsigned long flags; | ||
1029 | spin_lock_irqsave(&winbond_lock, flags); | ||
1030 | outb(reg, port + 0x01); | ||
1031 | val = inb(port + 0x02); | ||
1032 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
1033 | |||
1034 | return val; | ||
1035 | } | ||
1036 | |||
1037 | static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
1038 | { | ||
1039 | struct ata_timing t; | ||
1040 | struct legacy_data *winbond = ap->host->private_data; | ||
1041 | int active, recovery; | ||
1042 | u8 reg; | ||
1043 | int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2); | ||
1044 | |||
1045 | reg = winbond_readcfg(winbond->timing, 0x81); | ||
1046 | |||
1047 | /* Get the timing data in cycles */ | ||
1048 | if (reg & 0x40) /* Fast VLB bus, assume 50MHz */ | ||
1049 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | ||
1050 | else | ||
1051 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | ||
1052 | |||
1053 | active = (FIT(t.active, 3, 17) - 1) & 0x0F; | ||
1054 | recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; | ||
1055 | timing = (active << 4) | recovery; | ||
1056 | winbond_writecfg(winbond->timing, timing, reg); | ||
1057 | |||
1058 | /* Load the setup timing */ | ||
1059 | |||
1060 | reg = 0x35; | ||
1061 | if (adev->class != ATA_DEV_ATA) | ||
1062 | reg |= 0x08; /* FIFO off */ | ||
1063 | if (!ata_pio_need_iordy(adev)) | ||
1064 | reg |= 0x02; /* IORDY off */ | ||
1065 | reg |= (FIT(t.setup, 0, 3) << 6); | ||
1066 | winbond_writecfg(winbond->timing, timing + 1, reg); | ||
1067 | } | ||
1068 | |||
1069 | static int winbond_port(struct platform_device *dev, | ||
1070 | struct legacy_probe *lp, struct legacy_data *ld) | ||
1071 | { | ||
1072 | if (devm_request_region(&dev->dev, lp->private, 4, "winbond") == NULL) | ||
1073 | return -EBUSY; | ||
1074 | ld->timing = lp->private; | ||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | static struct ata_port_operations winbond_port_ops = { | ||
1079 | .set_piomode = winbond_set_piomode, | ||
1080 | |||
1081 | .tf_load = ata_tf_load, | ||
1082 | .tf_read = ata_tf_read, | ||
1083 | .check_status = ata_check_status, | ||
1084 | .exec_command = ata_exec_command, | ||
1085 | .dev_select = ata_std_dev_select, | ||
1086 | |||
1087 | .freeze = ata_bmdma_freeze, | ||
1088 | .thaw = ata_bmdma_thaw, | ||
1089 | .error_handler = ata_bmdma_error_handler, | ||
1090 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
1091 | .cable_detect = ata_cable_40wire, | ||
1092 | |||
1093 | .qc_prep = ata_qc_prep, | ||
1094 | .qc_issue = ata_qc_issue_prot, | ||
1095 | |||
1096 | .data_xfer = vlb32_data_xfer, | ||
1097 | |||
1098 | .irq_clear = ata_bmdma_irq_clear, | ||
1099 | .irq_on = ata_irq_on, | ||
1100 | |||
1101 | .port_start = ata_sff_port_start, | ||
1102 | }; | ||
1103 | |||
1006 | static struct legacy_controller controllers[] = { | 1104 | static struct legacy_controller controllers[] = { |
1007 | {"BIOS", &legacy_port_ops, 0x1F, | 1105 | {"BIOS", &legacy_port_ops, 0x1F, |
1008 | ATA_FLAG_NO_IORDY, NULL }, | 1106 | ATA_FLAG_NO_IORDY, NULL }, |
@@ -1019,11 +1117,13 @@ static struct legacy_controller controllers[] = { | |||
1019 | {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, | 1117 | {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, |
1020 | 0 , NULL }, | 1118 | 0 , NULL }, |
1021 | {"QDI6500", &qdi6500_port_ops, 0x07, | 1119 | {"QDI6500", &qdi6500_port_ops, 0x07, |
1022 | ATA_FLAG_NO_IORDY, NULL }, | 1120 | ATA_FLAG_NO_IORDY, qdi_port }, |
1023 | {"QDI6580", &qdi6580_port_ops, 0x1F, | 1121 | {"QDI6580", &qdi6580_port_ops, 0x1F, |
1024 | 0 , NULL }, | 1122 | 0 , qdi_port }, |
1025 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, | 1123 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, |
1026 | 0 , NULL } | 1124 | 0 , qdi_port }, |
1125 | {"W83759A", &winbond_port_ops, 0x1F, | ||
1126 | 0 , winbond_port } | ||
1027 | }; | 1127 | }; |
1028 | 1128 | ||
1029 | /** | 1129 | /** |
@@ -1034,10 +1134,26 @@ static struct legacy_controller controllers[] = { | |||
1034 | * check if the controller appears to be driveless at this point. | 1134 | * check if the controller appears to be driveless at this point. |
1035 | */ | 1135 | */ |
1036 | 1136 | ||
1037 | static int probe_chip_type(struct legacy_probe *probe) | 1137 | static __init int probe_chip_type(struct legacy_probe *probe) |
1038 | { | 1138 | { |
1039 | int mask = 1 << probe->slot; | 1139 | int mask = 1 << probe->slot; |
1040 | 1140 | ||
1141 | if (winbond && (probe->port == 0x1F0 || probe->port == 0x170)) { | ||
1142 | u8 reg = winbond_readcfg(winbond, 0x81); | ||
1143 | reg |= 0x80; /* jumpered mode off */ | ||
1144 | winbond_writecfg(winbond, 0x81, reg); | ||
1145 | reg = winbond_readcfg(winbond, 0x83); | ||
1146 | reg |= 0xF0; /* local control */ | ||
1147 | winbond_writecfg(winbond, 0x83, reg); | ||
1148 | reg = winbond_readcfg(winbond, 0x85); | ||
1149 | reg |= 0xF0; /* programmable timing */ | ||
1150 | winbond_writecfg(winbond, 0x85, reg); | ||
1151 | |||
1152 | reg = winbond_readcfg(winbond, 0x81); | ||
1153 | |||
1154 | if (reg & mask) | ||
1155 | return W83759A; | ||
1156 | } | ||
1041 | if (probe->port == 0x1F0) { | 1157 | if (probe->port == 0x1F0) { |
1042 | unsigned long flags; | 1158 | unsigned long flags; |
1043 | local_irq_save(flags); | 1159 | local_irq_save(flags); |
@@ -1127,7 +1243,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1127 | if (!io_addr || !ctrl_addr) | 1243 | if (!io_addr || !ctrl_addr) |
1128 | goto fail; | 1244 | goto fail; |
1129 | if (controller->setup) | 1245 | if (controller->setup) |
1130 | if (controller->setup(probe, ld) < 0) | 1246 | if (controller->setup(pdev, probe, ld) < 0) |
1131 | goto fail; | 1247 | goto fail; |
1132 | host = ata_host_alloc(&pdev->dev, 1); | 1248 | host = ata_host_alloc(&pdev->dev, 1); |
1133 | if (!host) | 1249 | if (!host) |
@@ -1141,7 +1257,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1141 | ap->ioaddr.altstatus_addr = ctrl_addr; | 1257 | ap->ioaddr.altstatus_addr = ctrl_addr; |
1142 | ap->ioaddr.ctl_addr = ctrl_addr; | 1258 | ap->ioaddr.ctl_addr = ctrl_addr; |
1143 | ata_std_ports(&ap->ioaddr); | 1259 | ata_std_ports(&ap->ioaddr); |
1144 | ap->private_data = ld; | 1260 | ap->host->private_data = ld; |
1145 | 1261 | ||
1146 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206); | 1262 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206); |
1147 | 1263 | ||
@@ -1164,9 +1280,6 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1164 | fail: | 1280 | fail: |
1165 | if (host) | 1281 | if (host) |
1166 | ata_host_detach(host); | 1282 | ata_host_detach(host); |
1167 | /* FIXME: use devm for this */ | ||
1168 | if (ld->timing) | ||
1169 | release_region(ld->timing, 2); | ||
1170 | platform_device_unregister(pdev); | 1283 | platform_device_unregister(pdev); |
1171 | return ret; | 1284 | return ret; |
1172 | } | 1285 | } |
@@ -1184,7 +1297,7 @@ fail: | |||
1184 | * is the right driver anyway. | 1297 | * is the right driver anyway. |
1185 | */ | 1298 | */ |
1186 | 1299 | ||
1187 | static void legacy_check_special_cases(struct pci_dev *p, int *primary, | 1300 | static void __init legacy_check_special_cases(struct pci_dev *p, int *primary, |
1188 | int *secondary) | 1301 | int *secondary) |
1189 | { | 1302 | { |
1190 | /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ | 1303 | /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ |
@@ -1249,11 +1362,9 @@ static __init void qdi65_identify_port(u8 r, u8 res, unsigned long port) | |||
1249 | /* Check card type */ | 1362 | /* Check card type */ |
1250 | if ((r & 0xF0) == 0xC0) { | 1363 | if ((r & 0xF0) == 0xC0) { |
1251 | /* QD6500: single channel */ | 1364 | /* QD6500: single channel */ |
1252 | if (r & 8) { | 1365 | if (r & 8) |
1253 | /* Disabled ? */ | 1366 | /* Disabled ? */ |
1254 | release_region(port, 2); | ||
1255 | return; | 1367 | return; |
1256 | } | ||
1257 | legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01), | 1368 | legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01), |
1258 | QDI6500, port); | 1369 | QDI6500, port); |
1259 | } | 1370 | } |
@@ -1273,6 +1384,7 @@ static __init void qdi65_identify_port(u8 r, u8 res, unsigned long port) | |||
1273 | /* port + 0x02, r & 0x04 */ | 1384 | /* port + 0x02, r & 0x04 */ |
1274 | legacy_probe_add(0x170, 15, QDI6580DP, port + 2); | 1385 | legacy_probe_add(0x170, 15, QDI6580DP, port + 2); |
1275 | } | 1386 | } |
1387 | release_region(port + 2, 2); | ||
1276 | } | 1388 | } |
1277 | } | 1389 | } |
1278 | 1390 | ||
@@ -1315,11 +1427,9 @@ static __init void probe_qdi_vlb(void) | |||
1315 | r = inb(port + 1); | 1427 | r = inb(port + 1); |
1316 | udelay(1); | 1428 | udelay(1); |
1317 | /* Check port agrees with port set */ | 1429 | /* Check port agrees with port set */ |
1318 | if ((r & 2) >> 1 != i) { | 1430 | if ((r & 2) >> 1 == i) |
1319 | release_region(port, 2); | 1431 | qdi65_identify_port(r, res, port); |
1320 | continue; | 1432 | release_region(port, 2); |
1321 | } | ||
1322 | qdi65_identify_port(r, res, port); | ||
1323 | } | 1433 | } |
1324 | } | 1434 | } |
1325 | } | 1435 | } |
@@ -1365,6 +1475,9 @@ static __init int legacy_init(void) | |||
1365 | pci_present = 1; | 1475 | pci_present = 1; |
1366 | } | 1476 | } |
1367 | 1477 | ||
1478 | if (winbond == 1) | ||
1479 | winbond = 0x130; /* Default port, alt is 1B0 */ | ||
1480 | |||
1368 | if (primary == 0 || all) | 1481 | if (primary == 0 || all) |
1369 | legacy_probe_add(0x1F0, 14, UNKNOWN, 0); | 1482 | legacy_probe_add(0x1F0, 14, UNKNOWN, 0); |
1370 | if (secondary == 0 || all) | 1483 | if (secondary == 0 || all) |
@@ -1383,7 +1496,6 @@ static __init int legacy_init(void) | |||
1383 | if (qdi) | 1496 | if (qdi) |
1384 | probe_qdi_vlb(); | 1497 | probe_qdi_vlb(); |
1385 | 1498 | ||
1386 | |||
1387 | for (i = 0; i < NR_HOST; i++, pl++) { | 1499 | for (i = 0; i < NR_HOST; i++, pl++) { |
1388 | if (pl->port == 0) | 1500 | if (pl->port == 0) |
1389 | continue; | 1501 | continue; |
@@ -1406,8 +1518,6 @@ static __exit void legacy_exit(void) | |||
1406 | struct legacy_data *ld = &legacy_data[i]; | 1518 | struct legacy_data *ld = &legacy_data[i]; |
1407 | ata_host_detach(legacy_host[i]); | 1519 | ata_host_detach(legacy_host[i]); |
1408 | platform_device_unregister(ld->platform_dev); | 1520 | platform_device_unregister(ld->platform_dev); |
1409 | if (ld->timing) | ||
1410 | release_region(ld->timing, 2); | ||
1411 | } | 1521 | } |
1412 | } | 1522 | } |
1413 | 1523 | ||