aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2011-10-13 06:59:35 -0400
committerJeff Garzik <jgarzik@redhat.com>2011-10-14 13:32:54 -0400
commit067f8c7b490edc8cc947666516f2c6833b676a2e (patch)
treedec01f0519c6c12a907cb5efdb33d05344e8edcc
parent81452182be1a95567da3718773dfcb45b42a579c (diff)
pata_artop: add Power Management support
Fixes IDE -> libata regression. There shouldn't be any problems with it as corresponding IDE's host driver (aec62xx) has been supporting PCI Power Management since Oct 10 2008 (commit feb22b7f "ide: add proper PCI PM support (v2)") and IDE PM since Jun 14 2003 (patch v2.5.73 "ide: Power Management"). Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/pata_artop.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index ef2bec0d4479..4b8b22efc00b 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -2,7 +2,7 @@
2 * pata_artop.c - ARTOP ATA controller driver 2 * pata_artop.c - ARTOP ATA controller driver
3 * 3 *
4 * (C) 2006 Red Hat 4 * (C) 2006 Red Hat
5 * (C) 2007 Bartlomiej Zolnierkiewicz 5 * (C) 2007,2011 Bartlomiej Zolnierkiewicz
6 * 6 *
7 * Based in part on drivers/ide/pci/aec62xx.c 7 * Based in part on drivers/ide/pci/aec62xx.c
8 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> 8 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
@@ -28,7 +28,7 @@
28#include <linux/ata.h> 28#include <linux/ata.h>
29 29
30#define DRV_NAME "pata_artop" 30#define DRV_NAME "pata_artop"
31#define DRV_VERSION "0.4.5" 31#define DRV_VERSION "0.4.6"
32 32
33/* 33/*
34 * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we 34 * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
@@ -313,6 +313,33 @@ static struct ata_port_operations artop6260_ops = {
313 .prereset = artop62x0_pre_reset, 313 .prereset = artop62x0_pre_reset,
314}; 314};
315 315
316static void atp8xx_fixup(struct pci_dev *pdev)
317{
318 if (pdev->device == 0x0005)
319 /* BIOS may have left us in UDMA, clear it before libata probe */
320 pci_write_config_byte(pdev, 0x54, 0);
321 else if (pdev->device == 0x0008 || pdev->device == 0x0009) {
322 u8 reg;
323
324 /* Mac systems come up with some registers not set as we
325 will need them */
326
327 /* Clear reset & test bits */
328 pci_read_config_byte(pdev, 0x49, &reg);
329 pci_write_config_byte(pdev, 0x49, reg & ~0x30);
330
331 /* PCI latency must be > 0x80 for burst mode, tweak it
332 * if required.
333 */
334 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &reg);
335 if (reg <= 0x80)
336 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90);
337
338 /* Enable IRQ output and burst mode */
339 pci_read_config_byte(pdev, 0x4a, &reg);
340 pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
341 }
342}
316 343
317/** 344/**
318 * artop_init_one - Register ARTOP ATA PCI device with kernel services 345 * artop_init_one - Register ARTOP ATA PCI device with kernel services
@@ -367,42 +394,22 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
367 if (rc) 394 if (rc)
368 return rc; 395 return rc;
369 396
370 if (id->driver_data == 0) { /* 6210 variant */ 397 if (id->driver_data == 0) /* 6210 variant */
371 ppi[0] = &info_6210; 398 ppi[0] = &info_6210;
372 /* BIOS may have left us in UDMA, clear it before libata probe */
373 pci_write_config_byte(pdev, 0x54, 0);
374 }
375 else if (id->driver_data == 1) /* 6260 */ 399 else if (id->driver_data == 1) /* 6260 */
376 ppi[0] = &info_626x; 400 ppi[0] = &info_626x;
377 else if (id->driver_data == 2) { /* 6280 or 6280 + fast */ 401 else if (id->driver_data == 2) { /* 6280 or 6280 + fast */
378 unsigned long io = pci_resource_start(pdev, 4); 402 unsigned long io = pci_resource_start(pdev, 4);
379 u8 reg;
380 403
381 ppi[0] = &info_628x; 404 ppi[0] = &info_628x;
382 if (inb(io) & 0x10) 405 if (inb(io) & 0x10)
383 ppi[0] = &info_628x_fast; 406 ppi[0] = &info_628x_fast;
384 /* Mac systems come up with some registers not set as we
385 will need them */
386
387 /* Clear reset & test bits */
388 pci_read_config_byte(pdev, 0x49, &reg);
389 pci_write_config_byte(pdev, 0x49, reg & ~ 0x30);
390
391 /* PCI latency must be > 0x80 for burst mode, tweak it
392 * if required.
393 */
394 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &reg);
395 if (reg <= 0x80)
396 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90);
397
398 /* Enable IRQ output and burst mode */
399 pci_read_config_byte(pdev, 0x4a, &reg);
400 pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
401
402 } 407 }
403 408
404 BUG_ON(ppi[0] == NULL); 409 BUG_ON(ppi[0] == NULL);
405 410
411 atp8xx_fixup(pdev);
412
406 return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0); 413 return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0);
407} 414}
408 415
@@ -416,11 +423,32 @@ static const struct pci_device_id artop_pci_tbl[] = {
416 { } /* terminate list */ 423 { } /* terminate list */
417}; 424};
418 425
426#ifdef CONFIG_PM
427static int atp8xx_reinit_one(struct pci_dev *pdev)
428{
429 struct ata_host *host = dev_get_drvdata(&pdev->dev);
430 int rc;
431
432 rc = ata_pci_device_do_resume(pdev);
433 if (rc)
434 return rc;
435
436 atp8xx_fixup(pdev);
437
438 ata_host_resume(host);
439 return 0;
440}
441#endif
442
419static struct pci_driver artop_pci_driver = { 443static struct pci_driver artop_pci_driver = {
420 .name = DRV_NAME, 444 .name = DRV_NAME,
421 .id_table = artop_pci_tbl, 445 .id_table = artop_pci_tbl,
422 .probe = artop_init_one, 446 .probe = artop_init_one,
423 .remove = ata_pci_remove_one, 447 .remove = ata_pci_remove_one,
448#ifdef CONFIG_PM
449 .suspend = ata_pci_device_suspend,
450 .resume = atp8xx_reinit_one,
451#endif
424}; 452};
425 453
426static int __init artop_init(void) 454static int __init artop_init(void)
@@ -436,9 +464,8 @@ static void __exit artop_exit(void)
436module_init(artop_init); 464module_init(artop_init);
437module_exit(artop_exit); 465module_exit(artop_exit);
438 466
439MODULE_AUTHOR("Alan Cox"); 467MODULE_AUTHOR("Alan Cox, Bartlomiej Zolnierkiewicz");
440MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA"); 468MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA");
441MODULE_LICENSE("GPL"); 469MODULE_LICENSE("GPL");
442MODULE_DEVICE_TABLE(pci, artop_pci_tbl); 470MODULE_DEVICE_TABLE(pci, artop_pci_tbl);
443MODULE_VERSION(DRV_VERSION); 471MODULE_VERSION(DRV_VERSION);
444