diff options
| author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-08-06 11:10:54 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-08-06 11:10:54 -0400 |
| commit | eba84481c7424f03c792d753fe02d9d6d3609fe0 (patch) | |
| tree | 495d687f2cdf25411f3a21efaf323a18c1ece1f3 | |
| parent | b8b786098b98f3b08dc8ab7cccf3963976b10336 (diff) | |
[ARM] pata_icside: fix the FIXMEs
Alan Cox suggested that the solution to the FIXMEs in pata_icside is
to use a private postreset method to detect the lack of devices on a
port, and in such a case, disable the interrupt for the port.
This patch implements such a method, and removes the hard coded
disable of port 0. Tested as working.
Acked-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | drivers/ata/pata_icside.c | 28 |
1 files changed, 11 insertions, 17 deletions
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 321d98b0bed2..64a711776c45 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c | |||
| @@ -330,17 +330,12 @@ static void ata_dummy_noret(struct ata_port *port) | |||
| 330 | { | 330 | { |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | /* | 333 | static void pata_icside_postreset(struct ata_port *ap, unsigned int *classes) |
| 334 | * We need to shut down unused ports to prevent spurious interrupts. | ||
| 335 | * FIXME: the libata core doesn't call this function for PATA interfaces. | ||
| 336 | */ | ||
| 337 | static void pata_icside_port_disable(struct ata_port *ap) | ||
| 338 | { | 334 | { |
| 339 | struct pata_icside_state *state = ap->host->private_data; | 335 | struct pata_icside_state *state = ap->host->private_data; |
| 340 | 336 | ||
| 341 | ata_port_printk(ap, KERN_ERR, "disabling icside port\n"); | 337 | if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE) |
| 342 | 338 | return ata_std_postreset(ap, classes); | |
| 343 | ata_port_disable(ap); | ||
| 344 | 339 | ||
| 345 | state->port[ap->port_no].disabled = 1; | 340 | state->port[ap->port_no].disabled = 1; |
| 346 | 341 | ||
| @@ -356,6 +351,12 @@ static void pata_icside_port_disable(struct ata_port *ap) | |||
| 356 | } | 351 | } |
| 357 | } | 352 | } |
| 358 | 353 | ||
| 354 | static void pata_icside_error_handler(struct ata_port *ap) | ||
| 355 | { | ||
| 356 | ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL, | ||
| 357 | pata_icside_postreset); | ||
| 358 | } | ||
| 359 | |||
| 359 | static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) | 360 | static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) |
| 360 | { | 361 | { |
| 361 | unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; | 362 | unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; |
| @@ -374,7 +375,7 @@ static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) | |||
| 374 | } | 375 | } |
| 375 | 376 | ||
| 376 | static struct ata_port_operations pata_icside_port_ops = { | 377 | static struct ata_port_operations pata_icside_port_ops = { |
| 377 | .port_disable = pata_icside_port_disable, | 378 | .port_disable = ata_port_disable, |
| 378 | 379 | ||
| 379 | .set_dmamode = pata_icside_set_dmamode, | 380 | .set_dmamode = pata_icside_set_dmamode, |
| 380 | 381 | ||
| @@ -397,7 +398,7 @@ static struct ata_port_operations pata_icside_port_ops = { | |||
| 397 | 398 | ||
| 398 | .freeze = ata_bmdma_freeze, | 399 | .freeze = ata_bmdma_freeze, |
| 399 | .thaw = ata_bmdma_thaw, | 400 | .thaw = ata_bmdma_thaw, |
| 400 | .error_handler = ata_bmdma_error_handler, | 401 | .error_handler = pata_icside_error_handler, |
| 401 | .post_internal_cmd = pata_icside_bmdma_stop, | 402 | .post_internal_cmd = pata_icside_bmdma_stop, |
| 402 | 403 | ||
| 403 | .irq_clear = ata_dummy_noret, | 404 | .irq_clear = ata_dummy_noret, |
| @@ -484,13 +485,6 @@ static int __devinit pata_icside_register_v6(struct pata_icside_info *info) | |||
| 484 | state->port[0].port_sel = sel; | 485 | state->port[0].port_sel = sel; |
| 485 | state->port[1].port_sel = sel | 1; | 486 | state->port[1].port_sel = sel | 1; |
| 486 | 487 | ||
| 487 | /* | ||
| 488 | * FIXME: work around libata's aversion to calling port_disable. | ||
| 489 | * This permanently disables interrupts on port 0 - bad luck if | ||
| 490 | * you have a drive on that port. | ||
| 491 | */ | ||
| 492 | state->port[0].disabled = 1; | ||
| 493 | |||
| 494 | info->base = easi_base; | 488 | info->base = easi_base; |
| 495 | info->irqops = &pata_icside_ops_arcin_v6; | 489 | info->irqops = &pata_icside_ops_arcin_v6; |
| 496 | info->nr_ports = 2; | 490 | info->nr_ports = 2; |
