diff options
-rw-r--r-- | drivers/ata/ahci.c | 10 | ||||
-rw-r--r-- | drivers/ata/ahci.h | 6 | ||||
-rw-r--r-- | drivers/ata/ahci_platform.c | 11 | ||||
-rw-r--r-- | drivers/ata/ata_piix.c | 8 | ||||
-rw-r--r-- | drivers/ata/libahci.c | 5 | ||||
-rw-r--r-- | drivers/ata/pata_arasan_cf.c | 12 | ||||
-rw-r--r-- | drivers/ata/pata_cmd64x.c | 147 | ||||
-rw-r--r-- | drivers/ata/pata_legacy.c | 3 | ||||
-rw-r--r-- | drivers/ata/pata_mpc52xx.c | 44 | ||||
-rw-r--r-- | drivers/ata/sata_fsl.c | 111 |
10 files changed, 281 insertions, 76 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index d07bf0366d99..79a1e9dd56d9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -103,8 +103,6 @@ static struct ata_port_operations ahci_p5wdh_ops = { | |||
103 | .hardreset = ahci_p5wdh_hardreset, | 103 | .hardreset = ahci_p5wdh_hardreset, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | ||
107 | |||
108 | static const struct ata_port_info ahci_port_info[] = { | 106 | static const struct ata_port_info ahci_port_info[] = { |
109 | /* by features */ | 107 | /* by features */ |
110 | [board_ahci] = | 108 | [board_ahci] = |
@@ -261,6 +259,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
261 | { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ | 259 | { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ |
262 | { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ | 260 | { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ |
263 | { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ | 261 | { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ |
262 | { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */ | ||
263 | { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */ | ||
264 | { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */ | ||
265 | { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */ | ||
266 | { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */ | ||
267 | { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ | ||
268 | { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ | ||
269 | { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ | ||
264 | 270 | ||
265 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 271 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
266 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 272 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index b1750007c8dc..c2594ddf25b0 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -195,6 +195,9 @@ enum { | |||
195 | PORT_FBS_EN = (1 << 0), /* Enable FBS */ | 195 | PORT_FBS_EN = (1 << 0), /* Enable FBS */ |
196 | 196 | ||
197 | /* hpriv->flags bits */ | 197 | /* hpriv->flags bits */ |
198 | |||
199 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | ||
200 | |||
198 | AHCI_HFLAG_NO_NCQ = (1 << 0), | 201 | AHCI_HFLAG_NO_NCQ = (1 << 0), |
199 | AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */ | 202 | AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */ |
200 | AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */ | 203 | AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */ |
@@ -210,6 +213,9 @@ enum { | |||
210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ | 213 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ |
211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ | 214 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ |
212 | AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ | 215 | AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ |
216 | AHCI_HFLAG_DELAY_ENGINE = (1 << 15), /* do not start engine on | ||
217 | port start (wait until | ||
218 | error-handling stage) */ | ||
213 | 219 | ||
214 | /* ap->flags bits */ | 220 | /* ap->flags bits */ |
215 | 221 | ||
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 48be4e189163..0c86c77764bc 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -26,6 +26,7 @@ | |||
26 | enum ahci_type { | 26 | enum ahci_type { |
27 | AHCI, /* standard platform ahci */ | 27 | AHCI, /* standard platform ahci */ |
28 | IMX53_AHCI, /* ahci on i.mx53 */ | 28 | IMX53_AHCI, /* ahci on i.mx53 */ |
29 | STRICT_AHCI, /* delayed DMA engine start */ | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | static struct platform_device_id ahci_devtype[] = { | 32 | static struct platform_device_id ahci_devtype[] = { |
@@ -36,6 +37,9 @@ static struct platform_device_id ahci_devtype[] = { | |||
36 | .name = "imx53-ahci", | 37 | .name = "imx53-ahci", |
37 | .driver_data = IMX53_AHCI, | 38 | .driver_data = IMX53_AHCI, |
38 | }, { | 39 | }, { |
40 | .name = "strict-ahci", | ||
41 | .driver_data = STRICT_AHCI, | ||
42 | }, { | ||
39 | /* sentinel */ | 43 | /* sentinel */ |
40 | } | 44 | } |
41 | }; | 45 | }; |
@@ -56,6 +60,13 @@ static const struct ata_port_info ahci_port_info[] = { | |||
56 | .udma_mask = ATA_UDMA6, | 60 | .udma_mask = ATA_UDMA6, |
57 | .port_ops = &ahci_pmp_retry_srst_ops, | 61 | .port_ops = &ahci_pmp_retry_srst_ops, |
58 | }, | 62 | }, |
63 | [STRICT_AHCI] = { | ||
64 | AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE), | ||
65 | .flags = AHCI_FLAG_COMMON, | ||
66 | .pio_mask = ATA_PIO4, | ||
67 | .udma_mask = ATA_UDMA6, | ||
68 | .port_ops = &ahci_ops, | ||
69 | }, | ||
59 | }; | 70 | }; |
60 | 71 | ||
61 | static struct scsi_host_template ahci_platform_sht = { | 72 | static struct scsi_host_template ahci_platform_sht = { |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index fdf27b9fce43..68013f96729f 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -321,6 +321,14 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
321 | { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 321 | { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
322 | /* SATA Controller IDE (Panther Point) */ | 322 | /* SATA Controller IDE (Panther Point) */ |
323 | { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 323 | { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
324 | /* SATA Controller IDE (Lynx Point) */ | ||
325 | { 0x8086, 0x8c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
326 | /* SATA Controller IDE (Lynx Point) */ | ||
327 | { 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
328 | /* SATA Controller IDE (Lynx Point) */ | ||
329 | { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
330 | /* SATA Controller IDE (Lynx Point) */ | ||
331 | { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
324 | { } /* terminate list */ | 332 | { } /* terminate list */ |
325 | }; | 333 | }; |
326 | 334 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index a72bfd0ecfee..f9eaa82311a9 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -737,6 +737,7 @@ static void ahci_power_down(struct ata_port *ap) | |||
737 | 737 | ||
738 | static void ahci_start_port(struct ata_port *ap) | 738 | static void ahci_start_port(struct ata_port *ap) |
739 | { | 739 | { |
740 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
740 | struct ahci_port_priv *pp = ap->private_data; | 741 | struct ahci_port_priv *pp = ap->private_data; |
741 | struct ata_link *link; | 742 | struct ata_link *link; |
742 | struct ahci_em_priv *emp; | 743 | struct ahci_em_priv *emp; |
@@ -746,6 +747,10 @@ static void ahci_start_port(struct ata_port *ap) | |||
746 | /* enable FIS reception */ | 747 | /* enable FIS reception */ |
747 | ahci_start_fis_rx(ap); | 748 | ahci_start_fis_rx(ap); |
748 | 749 | ||
750 | /* enable DMA */ | ||
751 | if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE)) | ||
752 | ahci_start_engine(ap); | ||
753 | |||
749 | /* turn on LEDs */ | 754 | /* turn on LEDs */ |
750 | if (ap->flags & ATA_FLAG_EM) { | 755 | if (ap->flags & ATA_FLAG_EM) { |
751 | ata_for_each_link(link, ap, EDGE) { | 756 | ata_for_each_link(link, ap, EDGE) { |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 048589fad2ca..fc2db2a89a6b 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
@@ -925,11 +925,10 @@ static int arasan_cf_suspend(struct device *dev) | |||
925 | struct ata_host *host = dev_get_drvdata(dev); | 925 | struct ata_host *host = dev_get_drvdata(dev); |
926 | struct arasan_cf_dev *acdev = host->ports[0]->private_data; | 926 | struct arasan_cf_dev *acdev = host->ports[0]->private_data; |
927 | 927 | ||
928 | if (acdev->dma_chan) { | 928 | if (acdev->dma_chan) |
929 | acdev->dma_chan->device->device_control(acdev->dma_chan, | 929 | acdev->dma_chan->device->device_control(acdev->dma_chan, |
930 | DMA_TERMINATE_ALL, 0); | 930 | DMA_TERMINATE_ALL, 0); |
931 | dma_release_channel(acdev->dma_chan); | 931 | |
932 | } | ||
933 | cf_exit(acdev); | 932 | cf_exit(acdev); |
934 | return ata_host_suspend(host, PMSG_SUSPEND); | 933 | return ata_host_suspend(host, PMSG_SUSPEND); |
935 | } | 934 | } |
@@ -945,10 +944,7 @@ static int arasan_cf_resume(struct device *dev) | |||
945 | return 0; | 944 | return 0; |
946 | } | 945 | } |
947 | 946 | ||
948 | static const struct dev_pm_ops arasan_cf_pm_ops = { | 947 | static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); |
949 | .suspend = arasan_cf_suspend, | ||
950 | .resume = arasan_cf_resume, | ||
951 | }; | ||
952 | #endif | 948 | #endif |
953 | 949 | ||
954 | static struct platform_driver arasan_cf_driver = { | 950 | static struct platform_driver arasan_cf_driver = { |
@@ -958,7 +954,7 @@ static struct platform_driver arasan_cf_driver = { | |||
958 | .name = DRIVER_NAME, | 954 | .name = DRIVER_NAME, |
959 | .owner = THIS_MODULE, | 955 | .owner = THIS_MODULE, |
960 | #ifdef CONFIG_PM | 956 | #ifdef CONFIG_PM |
961 | .pm = &arasan_cf_pm_ops, | 957 | .pm = &arasan_cf_pm_ops, |
962 | #endif | 958 | #endif |
963 | }, | 959 | }, |
964 | }; | 960 | }; |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index e1fb39a74ce1..1c17cd1e8b2d 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * (C) 2005 Red Hat Inc | 3 | * (C) 2005 Red Hat Inc |
4 | * Alan Cox <alan@lxorguk.ukuu.org.uk> | 4 | * Alan Cox <alan@lxorguk.ukuu.org.uk> |
5 | * (C) 2009-2010 Bartlomiej Zolnierkiewicz | 5 | * (C) 2009-2010 Bartlomiej Zolnierkiewicz |
6 | * (C) 2012 MontaVista Software, LLC <source@mvista.com> | ||
6 | * | 7 | * |
7 | * Based upon | 8 | * Based upon |
8 | * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 | 9 | * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 |
@@ -32,7 +33,7 @@ | |||
32 | #include <linux/libata.h> | 33 | #include <linux/libata.h> |
33 | 34 | ||
34 | #define DRV_NAME "pata_cmd64x" | 35 | #define DRV_NAME "pata_cmd64x" |
35 | #define DRV_VERSION "0.2.5" | 36 | #define DRV_VERSION "0.2.18" |
36 | 37 | ||
37 | /* | 38 | /* |
38 | * CMD64x specific registers definition. | 39 | * CMD64x specific registers definition. |
@@ -229,28 +230,85 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
229 | } | 230 | } |
230 | 231 | ||
231 | /** | 232 | /** |
232 | * cmd648_dma_stop - DMA stop callback | 233 | * cmd64x_sff_irq_check - check IDE interrupt |
233 | * @qc: Command in progress | 234 | * @ap: ATA interface |
234 | * | 235 | * |
235 | * DMA has completed. | 236 | * Check IDE interrupt in CFR/ARTTIM23 registers. |
236 | */ | 237 | */ |
237 | 238 | ||
238 | static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) | 239 | static bool cmd64x_sff_irq_check(struct ata_port *ap) |
239 | { | 240 | { |
240 | struct ata_port *ap = qc->ap; | ||
241 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 241 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
242 | u8 dma_intr; | 242 | int irq_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; |
243 | int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; | 243 | int irq_reg = ap->port_no ? ARTTIM23 : CFR; |
244 | int dma_reg = ap->port_no ? ARTTIM23 : CFR; | 244 | u8 irq_stat; |
245 | 245 | ||
246 | ata_bmdma_stop(qc); | 246 | /* NOTE: reading the register should clear the interrupt */ |
247 | pci_read_config_byte(pdev, irq_reg, &irq_stat); | ||
248 | |||
249 | return irq_stat & irq_mask; | ||
250 | } | ||
251 | |||
252 | /** | ||
253 | * cmd64x_sff_irq_clear - clear IDE interrupt | ||
254 | * @ap: ATA interface | ||
255 | * | ||
256 | * Clear IDE interrupt in CFR/ARTTIM23 and DMA status registers. | ||
257 | */ | ||
258 | |||
259 | static void cmd64x_sff_irq_clear(struct ata_port *ap) | ||
260 | { | ||
261 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
262 | int irq_reg = ap->port_no ? ARTTIM23 : CFR; | ||
263 | u8 irq_stat; | ||
264 | |||
265 | ata_bmdma_irq_clear(ap); | ||
247 | 266 | ||
248 | pci_read_config_byte(pdev, dma_reg, &dma_intr); | 267 | /* Reading the register should be enough to clear the interrupt */ |
249 | pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask); | 268 | pci_read_config_byte(pdev, irq_reg, &irq_stat); |
250 | } | 269 | } |
251 | 270 | ||
252 | /** | 271 | /** |
253 | * cmd646r1_dma_stop - DMA stop callback | 272 | * cmd648_sff_irq_check - check IDE interrupt |
273 | * @ap: ATA interface | ||
274 | * | ||
275 | * Check IDE interrupt in MRDMODE register. | ||
276 | */ | ||
277 | |||
278 | static bool cmd648_sff_irq_check(struct ata_port *ap) | ||
279 | { | ||
280 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
281 | unsigned long base = pci_resource_start(pdev, 4); | ||
282 | int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; | ||
283 | u8 mrdmode = inb(base + 1); | ||
284 | |||
285 | return mrdmode & irq_mask; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * cmd648_sff_irq_clear - clear IDE interrupt | ||
290 | * @ap: ATA interface | ||
291 | * | ||
292 | * Clear IDE interrupt in MRDMODE and DMA status registers. | ||
293 | */ | ||
294 | |||
295 | static void cmd648_sff_irq_clear(struct ata_port *ap) | ||
296 | { | ||
297 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
298 | unsigned long base = pci_resource_start(pdev, 4); | ||
299 | int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; | ||
300 | u8 mrdmode; | ||
301 | |||
302 | ata_bmdma_irq_clear(ap); | ||
303 | |||
304 | /* Clear this port's interrupt bit (leaving the other port alone) */ | ||
305 | mrdmode = inb(base + 1); | ||
306 | mrdmode &= ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1); | ||
307 | outb(mrdmode | irq_mask, base + 1); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * cmd646r1_bmdma_stop - DMA stop callback | ||
254 | * @qc: Command in progress | 312 | * @qc: Command in progress |
255 | * | 313 | * |
256 | * Stub for now while investigating the r1 quirk in the old driver. | 314 | * Stub for now while investigating the r1 quirk in the old driver. |
@@ -273,18 +331,30 @@ static const struct ata_port_operations cmd64x_base_ops = { | |||
273 | 331 | ||
274 | static struct ata_port_operations cmd64x_port_ops = { | 332 | static struct ata_port_operations cmd64x_port_ops = { |
275 | .inherits = &cmd64x_base_ops, | 333 | .inherits = &cmd64x_base_ops, |
334 | .sff_irq_check = cmd64x_sff_irq_check, | ||
335 | .sff_irq_clear = cmd64x_sff_irq_clear, | ||
276 | .cable_detect = ata_cable_40wire, | 336 | .cable_detect = ata_cable_40wire, |
277 | }; | 337 | }; |
278 | 338 | ||
279 | static struct ata_port_operations cmd646r1_port_ops = { | 339 | static struct ata_port_operations cmd646r1_port_ops = { |
280 | .inherits = &cmd64x_base_ops, | 340 | .inherits = &cmd64x_base_ops, |
341 | .sff_irq_check = cmd64x_sff_irq_check, | ||
342 | .sff_irq_clear = cmd64x_sff_irq_clear, | ||
281 | .bmdma_stop = cmd646r1_bmdma_stop, | 343 | .bmdma_stop = cmd646r1_bmdma_stop, |
282 | .cable_detect = ata_cable_40wire, | 344 | .cable_detect = ata_cable_40wire, |
283 | }; | 345 | }; |
284 | 346 | ||
347 | static struct ata_port_operations cmd646r3_port_ops = { | ||
348 | .inherits = &cmd64x_base_ops, | ||
349 | .sff_irq_check = cmd648_sff_irq_check, | ||
350 | .sff_irq_clear = cmd648_sff_irq_clear, | ||
351 | .cable_detect = ata_cable_40wire, | ||
352 | }; | ||
353 | |||
285 | static struct ata_port_operations cmd648_port_ops = { | 354 | static struct ata_port_operations cmd648_port_ops = { |
286 | .inherits = &cmd64x_base_ops, | 355 | .inherits = &cmd64x_base_ops, |
287 | .bmdma_stop = cmd648_bmdma_stop, | 356 | .sff_irq_check = cmd648_sff_irq_check, |
357 | .sff_irq_clear = cmd648_sff_irq_clear, | ||
288 | .cable_detect = cmd648_cable_detect, | 358 | .cable_detect = cmd648_cable_detect, |
289 | }; | 359 | }; |
290 | 360 | ||
@@ -306,7 +376,7 @@ static void cmd64x_fixup(struct pci_dev *pdev) | |||
306 | 376 | ||
307 | static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 377 | static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
308 | { | 378 | { |
309 | static const struct ata_port_info cmd_info[6] = { | 379 | static const struct ata_port_info cmd_info[7] = { |
310 | { /* CMD 643 - no UDMA */ | 380 | { /* CMD 643 - no UDMA */ |
311 | .flags = ATA_FLAG_SLAVE_POSS, | 381 | .flags = ATA_FLAG_SLAVE_POSS, |
312 | .pio_mask = ATA_PIO4, | 382 | .pio_mask = ATA_PIO4, |
@@ -319,12 +389,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
319 | .mwdma_mask = ATA_MWDMA2, | 389 | .mwdma_mask = ATA_MWDMA2, |
320 | .port_ops = &cmd64x_port_ops | 390 | .port_ops = &cmd64x_port_ops |
321 | }, | 391 | }, |
322 | { /* CMD 646 with working UDMA */ | 392 | { /* CMD 646U with broken UDMA */ |
393 | .flags = ATA_FLAG_SLAVE_POSS, | ||
394 | .pio_mask = ATA_PIO4, | ||
395 | .mwdma_mask = ATA_MWDMA2, | ||
396 | .port_ops = &cmd646r3_port_ops | ||
397 | }, | ||
398 | { /* CMD 646U2 with working UDMA */ | ||
323 | .flags = ATA_FLAG_SLAVE_POSS, | 399 | .flags = ATA_FLAG_SLAVE_POSS, |
324 | .pio_mask = ATA_PIO4, | 400 | .pio_mask = ATA_PIO4, |
325 | .mwdma_mask = ATA_MWDMA2, | 401 | .mwdma_mask = ATA_MWDMA2, |
326 | .udma_mask = ATA_UDMA2, | 402 | .udma_mask = ATA_UDMA2, |
327 | .port_ops = &cmd64x_port_ops | 403 | .port_ops = &cmd646r3_port_ops |
328 | }, | 404 | }, |
329 | { /* CMD 646 rev 1 */ | 405 | { /* CMD 646 rev 1 */ |
330 | .flags = ATA_FLAG_SLAVE_POSS, | 406 | .flags = ATA_FLAG_SLAVE_POSS, |
@@ -368,21 +444,30 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
368 | if (id->driver_data == 0) /* 643 */ | 444 | if (id->driver_data == 0) /* 643 */ |
369 | ata_pci_bmdma_clear_simplex(pdev); | 445 | ata_pci_bmdma_clear_simplex(pdev); |
370 | 446 | ||
371 | if (pdev->device == PCI_DEVICE_ID_CMD_646) { | 447 | if (pdev->device == PCI_DEVICE_ID_CMD_646) |
372 | /* Does UDMA work ? */ | 448 | switch (pdev->revision) { |
373 | if (pdev->revision > 4) { | 449 | /* UDMA works since rev 5 */ |
374 | ppi[0] = &cmd_info[2]; | 450 | default: |
375 | ppi[1] = &cmd_info[2]; | ||
376 | } | ||
377 | /* Early rev with other problems ? */ | ||
378 | else if (pdev->revision == 1) { | ||
379 | ppi[0] = &cmd_info[3]; | 451 | ppi[0] = &cmd_info[3]; |
380 | ppi[1] = &cmd_info[3]; | 452 | ppi[1] = &cmd_info[3]; |
381 | } | 453 | break; |
382 | /* revs 1,2 have no CNTRL_CH0 */ | 454 | /* Interrupts in MRDMODE since rev 3 */ |
383 | if (pdev->revision < 3) | 455 | case 3: |
456 | case 4: | ||
457 | ppi[0] = &cmd_info[2]; | ||
458 | ppi[1] = &cmd_info[2]; | ||
459 | break; | ||
460 | /* Rev 1 with other problems? */ | ||
461 | case 1: | ||
462 | ppi[0] = &cmd_info[4]; | ||
463 | ppi[1] = &cmd_info[4]; | ||
464 | /* FALL THRU */ | ||
465 | /* Early revs have no CNTRL_CH0 */ | ||
466 | case 2: | ||
467 | case 0: | ||
384 | cntrl_ch0_ok = 0; | 468 | cntrl_ch0_ok = 0; |
385 | } | 469 | break; |
470 | } | ||
386 | 471 | ||
387 | cmd64x_fixup(pdev); | 472 | cmd64x_fixup(pdev); |
388 | 473 | ||
@@ -423,8 +508,8 @@ static int cmd64x_reinit_one(struct pci_dev *pdev) | |||
423 | static const struct pci_device_id cmd64x[] = { | 508 | static const struct pci_device_id cmd64x[] = { |
424 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, | 509 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, |
425 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 }, | 510 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 }, |
426 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 4 }, | 511 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 5 }, |
427 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 5 }, | 512 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 6 }, |
428 | 513 | ||
429 | { }, | 514 | { }, |
430 | }; | 515 | }; |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 35aca7d1a3eb..4fe9d2138d48 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -401,8 +401,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
401 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | 401 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); |
402 | 402 | ||
403 | active = clamp_val(t.active, 2, 15); | 403 | active = clamp_val(t.active, 2, 15); |
404 | recover = clamp_val(t.recover, 2, 16); | 404 | recover = clamp_val(t.recover, 2, 16) & 0x0F; |
405 | recover &= 0x15; | ||
406 | 405 | ||
407 | inb(0x3E6); | 406 | inb(0x3E6); |
408 | inb(0x3E6); | 407 | inb(0x3E6); |
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 00748ae1a016..d2c102fd4330 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c | |||
@@ -687,11 +687,11 @@ mpc52xx_ata_probe(struct platform_device *op) | |||
687 | int ata_irq = 0; | 687 | int ata_irq = 0; |
688 | struct mpc52xx_ata __iomem *ata_regs; | 688 | struct mpc52xx_ata __iomem *ata_regs; |
689 | struct mpc52xx_ata_priv *priv = NULL; | 689 | struct mpc52xx_ata_priv *priv = NULL; |
690 | int rv, ret, task_irq = 0; | 690 | int rv, task_irq; |
691 | int mwdma_mask = 0, udma_mask = 0; | 691 | int mwdma_mask = 0, udma_mask = 0; |
692 | const __be32 *prop; | 692 | const __be32 *prop; |
693 | int proplen; | 693 | int proplen; |
694 | struct bcom_task *dmatsk = NULL; | 694 | struct bcom_task *dmatsk; |
695 | 695 | ||
696 | /* Get ipb frequency */ | 696 | /* Get ipb frequency */ |
697 | ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); | 697 | ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); |
@@ -717,8 +717,7 @@ mpc52xx_ata_probe(struct platform_device *op) | |||
717 | ata_regs = devm_ioremap(&op->dev, res_mem.start, sizeof(*ata_regs)); | 717 | ata_regs = devm_ioremap(&op->dev, res_mem.start, sizeof(*ata_regs)); |
718 | if (!ata_regs) { | 718 | if (!ata_regs) { |
719 | dev_err(&op->dev, "error mapping device registers\n"); | 719 | dev_err(&op->dev, "error mapping device registers\n"); |
720 | rv = -ENOMEM; | 720 | return -ENOMEM; |
721 | goto err; | ||
722 | } | 721 | } |
723 | 722 | ||
724 | /* | 723 | /* |
@@ -753,7 +752,7 @@ mpc52xx_ata_probe(struct platform_device *op) | |||
753 | if (!priv) { | 752 | if (!priv) { |
754 | dev_err(&op->dev, "error allocating private structure\n"); | 753 | dev_err(&op->dev, "error allocating private structure\n"); |
755 | rv = -ENOMEM; | 754 | rv = -ENOMEM; |
756 | goto err; | 755 | goto err1; |
757 | } | 756 | } |
758 | 757 | ||
759 | priv->ipb_period = 1000000000 / (ipb_freq / 1000); | 758 | priv->ipb_period = 1000000000 / (ipb_freq / 1000); |
@@ -776,15 +775,15 @@ mpc52xx_ata_probe(struct platform_device *op) | |||
776 | if (!dmatsk) { | 775 | if (!dmatsk) { |
777 | dev_err(&op->dev, "bestcomm initialization failed\n"); | 776 | dev_err(&op->dev, "bestcomm initialization failed\n"); |
778 | rv = -ENOMEM; | 777 | rv = -ENOMEM; |
779 | goto err; | 778 | goto err1; |
780 | } | 779 | } |
781 | 780 | ||
782 | task_irq = bcom_get_task_irq(dmatsk); | 781 | task_irq = bcom_get_task_irq(dmatsk); |
783 | ret = request_irq(task_irq, &mpc52xx_ata_task_irq, 0, | 782 | rv = devm_request_irq(&op->dev, task_irq, &mpc52xx_ata_task_irq, 0, |
784 | "ATA task", priv); | 783 | "ATA task", priv); |
785 | if (ret) { | 784 | if (rv) { |
786 | dev_err(&op->dev, "error requesting DMA IRQ\n"); | 785 | dev_err(&op->dev, "error requesting DMA IRQ\n"); |
787 | goto err; | 786 | goto err2; |
788 | } | 787 | } |
789 | priv->dmatsk = dmatsk; | 788 | priv->dmatsk = dmatsk; |
790 | 789 | ||
@@ -792,7 +791,7 @@ mpc52xx_ata_probe(struct platform_device *op) | |||
792 | rv = mpc52xx_ata_hw_init(priv); | 791 | rv = mpc52xx_ata_hw_init(priv); |
793 | if (rv) { | 792 | if (rv) { |
794 | dev_err(&op->dev, "error initializing hardware\n"); | 793 | dev_err(&op->dev, "error initializing hardware\n"); |
795 | goto err; | 794 | goto err2; |
796 | } | 795 | } |
797 | 796 | ||
798 | /* Register ourselves to libata */ | 797 | /* Register ourselves to libata */ |
@@ -800,23 +799,16 @@ mpc52xx_ata_probe(struct platform_device *op) | |||
800 | mwdma_mask, udma_mask); | 799 | mwdma_mask, udma_mask); |
801 | if (rv) { | 800 | if (rv) { |
802 | dev_err(&op->dev, "error registering with ATA layer\n"); | 801 | dev_err(&op->dev, "error registering with ATA layer\n"); |
803 | goto err; | 802 | goto err2; |
804 | } | 803 | } |
805 | 804 | ||
806 | return 0; | 805 | return 0; |
807 | 806 | ||
808 | err: | 807 | err2: |
809 | devm_release_mem_region(&op->dev, res_mem.start, sizeof(*ata_regs)); | 808 | irq_dispose_mapping(task_irq); |
810 | if (ata_irq) | 809 | bcom_ata_release(dmatsk); |
811 | irq_dispose_mapping(ata_irq); | 810 | err1: |
812 | if (task_irq) | 811 | irq_dispose_mapping(ata_irq); |
813 | irq_dispose_mapping(task_irq); | ||
814 | if (dmatsk) | ||
815 | bcom_ata_release(dmatsk); | ||
816 | if (ata_regs) | ||
817 | devm_iounmap(&op->dev, ata_regs); | ||
818 | if (priv) | ||
819 | devm_kfree(&op->dev, priv); | ||
820 | return rv; | 812 | return rv; |
821 | } | 813 | } |
822 | 814 | ||
@@ -835,12 +827,6 @@ mpc52xx_ata_remove(struct platform_device *op) | |||
835 | bcom_ata_release(priv->dmatsk); | 827 | bcom_ata_release(priv->dmatsk); |
836 | irq_dispose_mapping(priv->ata_irq); | 828 | irq_dispose_mapping(priv->ata_irq); |
837 | 829 | ||
838 | /* Clear up IO allocations */ | ||
839 | devm_iounmap(&op->dev, priv->ata_regs); | ||
840 | devm_release_mem_region(&op->dev, priv->ata_regs_pa, | ||
841 | sizeof(*priv->ata_regs)); | ||
842 | devm_kfree(&op->dev, priv); | ||
843 | |||
844 | return 0; | 830 | return 0; |
845 | } | 831 | } |
846 | 832 | ||
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 0120b0d1e9a5..d6577b93bee3 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Author: Ashish Kalra <ashish.kalra@freescale.com> | 6 | * Author: Ashish Kalra <ashish.kalra@freescale.com> |
7 | * Li Yang <leoli@freescale.com> | 7 | * Li Yang <leoli@freescale.com> |
8 | * | 8 | * |
9 | * Copyright (c) 2006-2007, 2011 Freescale Semiconductor, Inc. | 9 | * Copyright (c) 2006-2007, 2011-2012 Freescale Semiconductor, Inc. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
@@ -26,6 +26,15 @@ | |||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <linux/of_platform.h> | 27 | #include <linux/of_platform.h> |
28 | 28 | ||
29 | static unsigned int intr_coalescing_count; | ||
30 | module_param(intr_coalescing_count, int, S_IRUGO); | ||
31 | MODULE_PARM_DESC(intr_coalescing_count, | ||
32 | "INT coalescing count threshold (1..31)"); | ||
33 | |||
34 | static unsigned int intr_coalescing_ticks; | ||
35 | module_param(intr_coalescing_ticks, int, S_IRUGO); | ||
36 | MODULE_PARM_DESC(intr_coalescing_ticks, | ||
37 | "INT coalescing timer threshold in AHB ticks"); | ||
29 | /* Controller information */ | 38 | /* Controller information */ |
30 | enum { | 39 | enum { |
31 | SATA_FSL_QUEUE_DEPTH = 16, | 40 | SATA_FSL_QUEUE_DEPTH = 16, |
@@ -83,6 +92,16 @@ enum { | |||
83 | }; | 92 | }; |
84 | 93 | ||
85 | /* | 94 | /* |
95 | * Interrupt Coalescing Control Register bitdefs */ | ||
96 | enum { | ||
97 | ICC_MIN_INT_COUNT_THRESHOLD = 1, | ||
98 | ICC_MAX_INT_COUNT_THRESHOLD = ((1 << 5) - 1), | ||
99 | ICC_MIN_INT_TICKS_THRESHOLD = 0, | ||
100 | ICC_MAX_INT_TICKS_THRESHOLD = ((1 << 19) - 1), | ||
101 | ICC_SAFE_INT_TICKS = 1, | ||
102 | }; | ||
103 | |||
104 | /* | ||
86 | * Host Controller command register set - per port | 105 | * Host Controller command register set - per port |
87 | */ | 106 | */ |
88 | enum { | 107 | enum { |
@@ -263,8 +282,65 @@ struct sata_fsl_host_priv { | |||
263 | void __iomem *csr_base; | 282 | void __iomem *csr_base; |
264 | int irq; | 283 | int irq; |
265 | int data_snoop; | 284 | int data_snoop; |
285 | struct device_attribute intr_coalescing; | ||
266 | }; | 286 | }; |
267 | 287 | ||
288 | static void fsl_sata_set_irq_coalescing(struct ata_host *host, | ||
289 | unsigned int count, unsigned int ticks) | ||
290 | { | ||
291 | struct sata_fsl_host_priv *host_priv = host->private_data; | ||
292 | void __iomem *hcr_base = host_priv->hcr_base; | ||
293 | |||
294 | if (count > ICC_MAX_INT_COUNT_THRESHOLD) | ||
295 | count = ICC_MAX_INT_COUNT_THRESHOLD; | ||
296 | else if (count < ICC_MIN_INT_COUNT_THRESHOLD) | ||
297 | count = ICC_MIN_INT_COUNT_THRESHOLD; | ||
298 | |||
299 | if (ticks > ICC_MAX_INT_TICKS_THRESHOLD) | ||
300 | ticks = ICC_MAX_INT_TICKS_THRESHOLD; | ||
301 | else if ((ICC_MIN_INT_TICKS_THRESHOLD == ticks) && | ||
302 | (count > ICC_MIN_INT_COUNT_THRESHOLD)) | ||
303 | ticks = ICC_SAFE_INT_TICKS; | ||
304 | |||
305 | spin_lock(&host->lock); | ||
306 | iowrite32((count << 24 | ticks), hcr_base + ICC); | ||
307 | |||
308 | intr_coalescing_count = count; | ||
309 | intr_coalescing_ticks = ticks; | ||
310 | spin_unlock(&host->lock); | ||
311 | |||
312 | DPRINTK("intrrupt coalescing, count = 0x%x, ticks = %x\n", | ||
313 | intr_coalescing_count, intr_coalescing_ticks); | ||
314 | DPRINTK("ICC register status: (hcr base: 0x%x) = 0x%x\n", | ||
315 | hcr_base, ioread32(hcr_base + ICC)); | ||
316 | } | ||
317 | |||
318 | static ssize_t fsl_sata_intr_coalescing_show(struct device *dev, | ||
319 | struct device_attribute *attr, char *buf) | ||
320 | { | ||
321 | return sprintf(buf, "%d %d\n", | ||
322 | intr_coalescing_count, intr_coalescing_ticks); | ||
323 | } | ||
324 | |||
325 | static ssize_t fsl_sata_intr_coalescing_store(struct device *dev, | ||
326 | struct device_attribute *attr, | ||
327 | const char *buf, size_t count) | ||
328 | { | ||
329 | unsigned int coalescing_count, coalescing_ticks; | ||
330 | |||
331 | if (sscanf(buf, "%d%d", | ||
332 | &coalescing_count, | ||
333 | &coalescing_ticks) != 2) { | ||
334 | printk(KERN_ERR "fsl-sata: wrong parameter format.\n"); | ||
335 | return -EINVAL; | ||
336 | } | ||
337 | |||
338 | fsl_sata_set_irq_coalescing(dev_get_drvdata(dev), | ||
339 | coalescing_count, coalescing_ticks); | ||
340 | |||
341 | return strlen(buf); | ||
342 | } | ||
343 | |||
268 | static inline unsigned int sata_fsl_tag(unsigned int tag, | 344 | static inline unsigned int sata_fsl_tag(unsigned int tag, |
269 | void __iomem *hcr_base) | 345 | void __iomem *hcr_base) |
270 | { | 346 | { |
@@ -346,10 +422,10 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, | |||
346 | (unsigned long long)sg_addr, sg_len); | 422 | (unsigned long long)sg_addr, sg_len); |
347 | 423 | ||
348 | /* warn if each s/g element is not dword aligned */ | 424 | /* warn if each s/g element is not dword aligned */ |
349 | if (sg_addr & 0x03) | 425 | if (unlikely(sg_addr & 0x03)) |
350 | ata_port_err(qc->ap, "s/g addr unaligned : 0x%llx\n", | 426 | ata_port_err(qc->ap, "s/g addr unaligned : 0x%llx\n", |
351 | (unsigned long long)sg_addr); | 427 | (unsigned long long)sg_addr); |
352 | if (sg_len & 0x03) | 428 | if (unlikely(sg_len & 0x03)) |
353 | ata_port_err(qc->ap, "s/g len unaligned : 0x%x\n", | 429 | ata_port_err(qc->ap, "s/g len unaligned : 0x%x\n", |
354 | sg_len); | 430 | sg_len); |
355 | 431 | ||
@@ -1245,6 +1321,13 @@ static int sata_fsl_init_controller(struct ata_host *host) | |||
1245 | iowrite32(0x00000FFFF, hcr_base + CE); | 1321 | iowrite32(0x00000FFFF, hcr_base + CE); |
1246 | iowrite32(0x00000FFFF, hcr_base + DE); | 1322 | iowrite32(0x00000FFFF, hcr_base + DE); |
1247 | 1323 | ||
1324 | /* | ||
1325 | * reset the number of command complete bits which will cause the | ||
1326 | * interrupt to be signaled | ||
1327 | */ | ||
1328 | fsl_sata_set_irq_coalescing(host, intr_coalescing_count, | ||
1329 | intr_coalescing_ticks); | ||
1330 | |||
1248 | /* | 1331 | /* |
1249 | * host controller will be brought on-line, during xx_port_start() | 1332 | * host controller will be brought on-line, during xx_port_start() |
1250 | * callback, that should also initiate the OOB, COMINIT sequence | 1333 | * callback, that should also initiate the OOB, COMINIT sequence |
@@ -1309,7 +1392,7 @@ static int sata_fsl_probe(struct platform_device *ofdev) | |||
1309 | void __iomem *csr_base = NULL; | 1392 | void __iomem *csr_base = NULL; |
1310 | struct sata_fsl_host_priv *host_priv = NULL; | 1393 | struct sata_fsl_host_priv *host_priv = NULL; |
1311 | int irq; | 1394 | int irq; |
1312 | struct ata_host *host; | 1395 | struct ata_host *host = NULL; |
1313 | u32 temp; | 1396 | u32 temp; |
1314 | 1397 | ||
1315 | struct ata_port_info pi = sata_fsl_port_info[0]; | 1398 | struct ata_port_info pi = sata_fsl_port_info[0]; |
@@ -1356,6 +1439,10 @@ static int sata_fsl_probe(struct platform_device *ofdev) | |||
1356 | 1439 | ||
1357 | /* allocate host structure */ | 1440 | /* allocate host structure */ |
1358 | host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); | 1441 | host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); |
1442 | if (!host) { | ||
1443 | retval = -ENOMEM; | ||
1444 | goto error_exit_with_cleanup; | ||
1445 | } | ||
1359 | 1446 | ||
1360 | /* host->iomap is not used currently */ | 1447 | /* host->iomap is not used currently */ |
1361 | host->private_data = host_priv; | 1448 | host->private_data = host_priv; |
@@ -1373,10 +1460,24 @@ static int sata_fsl_probe(struct platform_device *ofdev) | |||
1373 | 1460 | ||
1374 | dev_set_drvdata(&ofdev->dev, host); | 1461 | dev_set_drvdata(&ofdev->dev, host); |
1375 | 1462 | ||
1463 | host_priv->intr_coalescing.show = fsl_sata_intr_coalescing_show; | ||
1464 | host_priv->intr_coalescing.store = fsl_sata_intr_coalescing_store; | ||
1465 | sysfs_attr_init(&host_priv->intr_coalescing.attr); | ||
1466 | host_priv->intr_coalescing.attr.name = "intr_coalescing"; | ||
1467 | host_priv->intr_coalescing.attr.mode = S_IRUGO | S_IWUSR; | ||
1468 | retval = device_create_file(host->dev, &host_priv->intr_coalescing); | ||
1469 | if (retval) | ||
1470 | goto error_exit_with_cleanup; | ||
1471 | |||
1376 | return 0; | 1472 | return 0; |
1377 | 1473 | ||
1378 | error_exit_with_cleanup: | 1474 | error_exit_with_cleanup: |
1379 | 1475 | ||
1476 | if (host) { | ||
1477 | dev_set_drvdata(&ofdev->dev, NULL); | ||
1478 | ata_host_detach(host); | ||
1479 | } | ||
1480 | |||
1380 | if (hcr_base) | 1481 | if (hcr_base) |
1381 | iounmap(hcr_base); | 1482 | iounmap(hcr_base); |
1382 | if (host_priv) | 1483 | if (host_priv) |
@@ -1390,6 +1491,8 @@ static int sata_fsl_remove(struct platform_device *ofdev) | |||
1390 | struct ata_host *host = dev_get_drvdata(&ofdev->dev); | 1491 | struct ata_host *host = dev_get_drvdata(&ofdev->dev); |
1391 | struct sata_fsl_host_priv *host_priv = host->private_data; | 1492 | struct sata_fsl_host_priv *host_priv = host->private_data; |
1392 | 1493 | ||
1494 | device_remove_file(&ofdev->dev, &host_priv->intr_coalescing); | ||
1495 | |||
1393 | ata_host_detach(host); | 1496 | ata_host_detach(host); |
1394 | 1497 | ||
1395 | dev_set_drvdata(&ofdev->dev, NULL); | 1498 | dev_set_drvdata(&ofdev->dev, NULL); |