Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 328647
b: refs/heads/master
c: f1e70c2
h: refs/heads/master
i:
  328645: 16e5f67
  328643: e357643
  328639: 9c0cee6
v: v3
  • Loading branch information
Viresh Kumar authored and Jeff Garzik committed Sep 13, 2012
1 parent 8fb7652 commit bcb7f8b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 26fdaa7453db49de80cc216cb696233b23d0b9d1
refs/heads/master: f1e70c2c535923de253eea2021376a936eb8d478
2 changes: 2 additions & 0 deletions trunk/drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#ifndef _AHCI_H
#define _AHCI_H

#include <linux/clk.h>
#include <linux/libata.h>

/* Enclosure Management Control */
Expand Down Expand Up @@ -316,6 +317,7 @@ struct ahci_host_priv {
u32 em_loc; /* enclosure management location */
u32 em_buf_sz; /* EM buffer size in byte */
u32 em_msg_type; /* EM message type */
struct clk *clk; /* Only for platforms supporting clk */
};

extern int ahci_ignore_sss;
Expand Down
57 changes: 50 additions & 7 deletions trunk/drivers/ata/ahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* any later version.
*/

#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/module.h>
Expand Down Expand Up @@ -118,6 +119,17 @@ static int __init ahci_probe(struct platform_device *pdev)
return -ENOMEM;
}

hpriv->clk = clk_get(dev, NULL);
if (IS_ERR(hpriv->clk)) {
dev_err(dev, "can't get clock\n");
} else {
rc = clk_prepare_enable(hpriv->clk);
if (rc) {
dev_err(dev, "clock prepare enable failed");
goto free_clk;
}
}

/*
* Some platforms might need to prepare for mmio region access,
* which could be done in the following init call. So, the mmio
Expand All @@ -127,7 +139,7 @@ static int __init ahci_probe(struct platform_device *pdev)
if (pdata && pdata->init) {
rc = pdata->init(dev, hpriv->mmio);
if (rc)
return rc;
goto disable_unprepare_clk;
}

ahci_save_initial_config(dev, hpriv,
Expand All @@ -153,7 +165,7 @@ static int __init ahci_probe(struct platform_device *pdev)
host = ata_host_alloc_pinfo(dev, ppi, n_ports);
if (!host) {
rc = -ENOMEM;
goto err0;
goto pdata_exit;
}

host->private_data = hpriv;
Expand Down Expand Up @@ -183,20 +195,26 @@ static int __init ahci_probe(struct platform_device *pdev)

rc = ahci_reset_controller(host);
if (rc)
goto err0;
goto pdata_exit;

ahci_init_controller(host);
ahci_print_info(host, "platform");

rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
&ahci_platform_sht);
if (rc)
goto err0;
goto pdata_exit;

return 0;
err0:
pdata_exit:
if (pdata && pdata->exit)
pdata->exit(dev);
disable_unprepare_clk:
if (!IS_ERR(hpriv->clk))
clk_disable_unprepare(hpriv->clk);
free_clk:
if (!IS_ERR(hpriv->clk))
clk_put(hpriv->clk);
return rc;
}

Expand All @@ -205,12 +223,18 @@ static int __devexit ahci_remove(struct platform_device *pdev)
struct device *dev = &pdev->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;

ata_host_detach(host);

if (pdata && pdata->exit)
pdata->exit(dev);

if (!IS_ERR(hpriv->clk)) {
clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
}

return 0;
}

Expand Down Expand Up @@ -245,32 +269,51 @@ static int ahci_suspend(struct device *dev)

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

if (!IS_ERR(hpriv->clk))
clk_disable_unprepare(hpriv->clk);

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);
struct ahci_host_priv *hpriv = host->private_data;
int rc;

if (!IS_ERR(hpriv->clk)) {
rc = clk_prepare_enable(hpriv->clk);
if (rc) {
dev_err(dev, "clock prepare enable failed");
return rc;
}
}

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

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

ahci_init_controller(host);
}

ata_host_resume(host);

return 0;

disable_unprepare_clk:
if (!IS_ERR(hpriv->clk))
clk_disable_unprepare(hpriv->clk);

return rc;
}
#endif

Expand Down

0 comments on commit bcb7f8b

Please sign in to comment.