aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-08-06 11:10:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-08-06 11:10:54 -0400
commiteba84481c7424f03c792d753fe02d9d6d3609fe0 (patch)
tree495d687f2cdf25411f3a21efaf323a18c1ece1f3
parentb8b786098b98f3b08dc8ab7cccf3963976b10336 (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.c28
1 files changed, 11 insertions, 17 deletions
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index 321d98b0bed..64a711776c4 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/* 333static 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 */
337static 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
354static 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
359static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) 360static 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
376static struct ata_port_operations pata_icside_port_ops = { 377static 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;