Skip to content

Commit

Permalink
Merge branch 'upstream-linus' of git://github.com/jgarzik/libata-dev
Browse files Browse the repository at this point in the history
* 'upstream-linus' of git://github.com/jgarzik/libata-dev:
  ahci: support the STA2X11 I/O Hub
  pata_bf54x: fix BMIDE status register emulation
  ata: add ata port hibernate callbacks
  ata: update ata port's runtime status during system resume
  [SCSI] runtime resume parent for child's system-resume
  ahci: platform support for suspend/resume
  libata-core: kill duplicate statement in ata_do_set_mode()
  pata_of_platform: remove direct dependency on OF_IRQ
  SATA/PATA: convert drivers/ata/* to use module_platform_driver()
  pata_cs5536: forward port changes from cs5536
  libata-sff: use ATAPI_{COD|IO}
  ata: add ata port runtime PM callbacks
  ata: add ata port system PM callbacks
  [SCSI] sd: check runtime PM status in sd_shutdown
  [SCSI] check runtime PM status in system PM
  [SCSI] add flag to skip the runtime PM calls on the host
  ata: make ata port as parent device of scsi host
  ahci: start engine only during soft/hard resets
  • Loading branch information
Linus Torvalds committed Jan 10, 2012
2 parents 9016037 + 318893e commit abce00f
Show file tree
Hide file tree
Showing 28 changed files with 326 additions and 323 deletions.
2 changes: 1 addition & 1 deletion drivers/ata/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ config PATA_PLATFORM

config PATA_OF_PLATFORM
tristate "OpenFirmware platform device PATA support"
depends on PATA_PLATFORM && OF && OF_IRQ
depends on PATA_PLATFORM && OF
help
This option enables support for generic directly connected ATA
devices commonly found on embedded systems with OpenFirmware
Expand Down
26 changes: 21 additions & 5 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
#define DRV_VERSION "3.0"

enum {
AHCI_PCI_BAR = 5,
AHCI_PCI_BAR_STA2X11 = 0,
AHCI_PCI_BAR_STANDARD = 5,
};

enum board_ids {
Expand Down Expand Up @@ -375,6 +376,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 968 */
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */

/* ST Microelectronics */
{ PCI_VDEVICE(STMICRO, 0xCC06), board_ahci }, /* ST ConneXt */

/* Marvell */
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
{ PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */
Expand Down Expand Up @@ -622,6 +626,13 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
{
int rc;

/*
* If the device fixup already set the dma_mask to some non-standard
* value, don't extend it here. This happens on STA2X11, for example.
*/
if (pdev->dma_mask && pdev->dma_mask < DMA_BIT_MASK(32))
return 0;

if (using_dac &&
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
Expand Down Expand Up @@ -1026,6 +1037,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ahci_host_priv *hpriv;
struct ata_host *host;
int n_ports, i, rc;
int ahci_pci_bar = AHCI_PCI_BAR_STANDARD;

VPRINTK("ENTER\n");

Expand Down Expand Up @@ -1057,6 +1069,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info(&pdev->dev,
"PDC42819 can only drive SATA devices with this driver\n");

/* The Connext uses non-standard BAR */
if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06)
ahci_pci_bar = AHCI_PCI_BAR_STA2X11;

/* acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
Expand All @@ -1065,7 +1081,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* AHCI controllers often implement SFF compatible interface.
* Grab all PCI BARs just in case.
*/
rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
rc = pcim_iomap_regions_request_all(pdev, 1 << ahci_pci_bar, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
Expand Down Expand Up @@ -1108,7 +1124,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
pci_intx(pdev, 1);

hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];

/* save initial config */
ahci_pci_save_initial_config(pdev, hpriv);
Expand Down Expand Up @@ -1172,8 +1188,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];

ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
ata_port_pbar_desc(ap, AHCI_PCI_BAR,
ata_port_pbar_desc(ap, ahci_pci_bar, -1, "abar");
ata_port_pbar_desc(ap, ahci_pci_bar,
0x100 + ap->port_no * 0x80, "port");

/* set enclosure management message type */
Expand Down
68 changes: 68 additions & 0 deletions drivers/ata/ahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,71 @@ static int __devexit ahci_remove(struct platform_device *pdev)
return 0;
}

#ifdef CONFIG_PM
static int ahci_suspend(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->mmio;
u32 ctl;
int rc;

if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
dev_err(dev, "firmware update required for suspend/resume\n");
return -EIO;
}

/*
* AHCI spec rev1.1 section 8.3.3:
* Software must disable interrupts prior to requesting a
* transition of the HBA to D3 state.
*/
ctl = readl(mmio + HOST_CTL);
ctl &= ~HOST_IRQ_EN;
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */

rc = ata_host_suspend(host, PMSG_SUSPEND);
if (rc)
return rc;

if (pdata && pdata->suspend)
return pdata->suspend(dev);
return 0;
}

static int ahci_resume(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
int rc;

if (pdata && pdata->resume) {
rc = pdata->resume(dev);
if (rc)
return rc;
}

if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
rc = ahci_reset_controller(host);
if (rc)
return rc;

ahci_init_controller(host);
}

ata_host_resume(host);

return 0;
}

static struct dev_pm_ops ahci_pm_ops = {
.suspend = &ahci_suspend,
.resume = &ahci_resume,
};
#endif

static const struct of_device_id ahci_of_match[] = {
{ .compatible = "calxeda,hb-ahci", },
{},
Expand All @@ -214,6 +279,9 @@ static struct platform_driver ahci_driver = {
.name = "ahci",
.owner = THIS_MODULE,
.of_match_table = ahci_of_match,
#ifdef CONFIG_PM
.pm = &ahci_pm_ops,
#endif
},
.id_table = ahci_devtype,
};
Expand Down
5 changes: 1 addition & 4 deletions drivers/ata/libahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,9 +746,6 @@ static void ahci_start_port(struct ata_port *ap)
/* enable FIS reception */
ahci_start_fis_rx(ap);

/* enable DMA */
ahci_start_engine(ap);

/* turn on LEDs */
if (ap->flags & ATA_FLAG_EM) {
ata_for_each_link(link, ap, EDGE) {
Expand Down Expand Up @@ -2022,7 +2019,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
ahci_power_down(ap);
else {
ata_port_err(ap, "%s (%d)\n", emsg, rc);
ahci_start_port(ap);
ata_port_freeze(ap);
}

return rc;
Expand Down
Loading

0 comments on commit abce00f

Please sign in to comment.