summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorPreetham Chandru R <pchandru@nvidia.com>2016-06-10 05:27:18 -0400
committerPreetham Chandru R <pchandru@nvidia.com>2017-08-21 05:16:34 -0400
commit4a851ae145a82d3b7a7a4e3311ca56d68f9d5bed (patch)
treefc6e0c161cc95a9cfc0b823678c4919ce37e9345 /drivers/ata
parent4ed89d15ea82e5325638c74ce95a37e2435765dc (diff)
ata: ahci_tegra: Inetgrate with upstream RTPM
Bug 200207932 Change-Id: I68957d41f2b9fc06ae0a599b13c86a1d7b1999da Signed-off-by: Preetham Chandru R <pchandru@nvidia.com> Reviewed-on: http://git-master/r/1164717 (cherry picked from commit de3089dd3ead92df9cb6b879eb25f508de8ed686)
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/tegra/ahci_tegra.c123
-rw-r--r--drivers/ata/tegra/ahci_tegra.h1
2 files changed, 6 insertions, 118 deletions
diff --git a/drivers/ata/tegra/ahci_tegra.c b/drivers/ata/tegra/ahci_tegra.c
index 65bd546e3..97efb7684 100644
--- a/drivers/ata/tegra/ahci_tegra.c
+++ b/drivers/ata/tegra/ahci_tegra.c
@@ -80,6 +80,9 @@ static int tegra_ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
80 lpm_state = TEGRA_AHCI_PORT_RUNTIME_ACTIVE; 80 lpm_state = TEGRA_AHCI_PORT_RUNTIME_ACTIVE;
81 tegra->skip_rtpm = false; 81 tegra->skip_rtpm = false;
82 82
83 if (!ata_dev_enabled(ap->link.device))
84 goto skip;
85
83 port_status = tegra_ahci_bar5_readl(hpriv, T_AHCI_PORT_PXSSTS); 86 port_status = tegra_ahci_bar5_readl(hpriv, T_AHCI_PORT_PXSSTS);
84 port_status = (port_status & T_AHCI_PORT_PXSSTS_IPM_MASK) >> 87 port_status = (port_status & T_AHCI_PORT_PXSSTS_IPM_MASK) >>
85 T_AHCI_PORT_PXSSTS_IPM_SHIFT; 88 T_AHCI_PORT_PXSSTS_IPM_SHIFT;
@@ -146,13 +149,10 @@ static int tegra_ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
146 return 0; 149 return 0;
147 } 150 }
148 } 151 }
152skip:
149 153
150 if (!ret && !(ap->pflags & ATA_PFLAG_SUSPENDED)) { 154 if (!ret && !(ap->pflags & ATA_PFLAG_SUSPENDED)) {
151 ret = ahci_ops.port_suspend(ap, mesg); 155 ret = ahci_ops.port_suspend(ap, mesg);
152 if (ret == 0) {
153 pm_runtime_mark_last_busy(&tegra->pdev->dev);
154 pm_runtime_put_sync_autosuspend(&tegra->pdev->dev);
155 }
156 } 156 }
157 157
158 return ret; 158 return ret;
@@ -175,14 +175,6 @@ static int tegra_ahci_port_resume(struct ata_port *ap)
175 return 0; 175 return 0;
176 } 176 }
177 177
178 ret = pm_runtime_get_sync(&tegra->pdev->dev);
179 if (ret < 0) {
180 dev_err(&tegra->pdev->dev,
181 "%s(%d) Failed to resume the devcie err=%d\n",
182 __func__, __LINE__, ret);
183 return AC_ERR_SYSTEM;
184 }
185
186 if (ap->pm_mesg.event & PM_EVENT_RESUME) { 178 if (ap->pm_mesg.event & PM_EVENT_RESUME) {
187 if (ap->pm_mesg.event & PM_EVENT_AUTO) 179 if (ap->pm_mesg.event & PM_EVENT_AUTO)
188 ata_for_each_link(link, ap, HOST_FIRST) { 180 ata_for_each_link(link, ap, HOST_FIRST) {
@@ -1300,89 +1292,6 @@ static void tegra_ahci_shutdown(struct platform_device *pdev)
1300 } 1292 }
1301} 1293}
1302 1294
1303/*
1304 This function is similar to ahci_enable_ahci which is
1305 defined in libahci.c.
1306 Since tegra_ahci_enable needs to be called before a
1307 host is allocated we will not be able to call ahci_enable_ahci
1308*/
1309
1310static void tegra_ahci_enable(struct ahci_host_priv *hpriv)
1311{
1312 int i;
1313 u32 tmp;
1314 u32 val;
1315 u32 mask;
1316
1317 /* turn on AHCI_EN */
1318 tmp = tegra_ahci_bar5_readl(hpriv, T_AHCI_HBA_GHC);
1319 if (tmp & HOST_AHCI_EN)
1320 return;
1321
1322 /* Some controllers need AHCI_EN to be written multiple times.
1323 * Try a few times before giving up.
1324 */
1325 for (i = 0; i < 5; i++) {
1326 val = mask = T_AHCI_HBA_GHC_AE;
1327 tegra_ahci_bar5_update(hpriv, val, mask, T_AHCI_HBA_GHC);
1328 tmp = tegra_ahci_bar5_readl(hpriv, T_AHCI_HBA_GHC);
1329 if (tmp & T_AHCI_HBA_GHC_AE)
1330 return;
1331 msleep(10);
1332 }
1333
1334 WARN_ON(1);
1335}
1336
1337/*
1338 This function is similar to ahci_reset_controller which is
1339 defined in libahci.c.
1340 Since tegra_ahci_reset_controller needs to be called before a
1341 host is allocated we will not be able to call ahci_reset_controller
1342*/
1343static int tegra_ahci_reset_controller(struct ahci_host_priv *hpriv)
1344{
1345 struct tegra_ahci_priv *tegra = hpriv->plat_data;
1346 void __iomem *mmio = tegra->base_list[TEGRA_SATA_AHCI];
1347 struct platform_device *pdev = tegra->pdev;
1348 struct device *dev = &pdev->dev;
1349 u32 tmp;
1350 u32 val;
1351 u32 mask;
1352
1353 /* we must be in AHCI mode, before using anything
1354 * AHCI-specific, such as HOST_RESET.
1355 */
1356 tegra_ahci_enable(hpriv);
1357
1358 /* global controller reset */
1359 tmp = tegra_ahci_bar5_readl(hpriv, T_AHCI_HBA_GHC);
1360 if ((tmp & T_AHCI_HBA_GHC_HR) == 0) {
1361 val = mask = T_AHCI_HBA_GHC_HR;
1362 tegra_ahci_bar5_update(hpriv, val, mask, T_AHCI_HBA_GHC);
1363
1364 tmp = tegra_ahci_bar5_readl(hpriv, T_AHCI_HBA_GHC);
1365 }
1366
1367 /*
1368 * to perform host reset, OS should set HOST_RESET
1369 * and poll until this bit is read to be "0".
1370 * reset must complete within 1 second, or
1371 * the hardware should be considered fried.
1372 */
1373 tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET,
1374 HOST_RESET, 10, 1000);
1375
1376 if (tmp & T_AHCI_HBA_GHC_HR) {
1377 dev_err(dev, "controller reset failed (0x%x)\n",
1378 tmp);
1379 return -EIO;
1380 }
1381 mdelay(20);
1382
1383 return 0;
1384}
1385
1386static int tegra_ahci_probe(struct platform_device *pdev) 1295static int tegra_ahci_probe(struct platform_device *pdev)
1387{ 1296{
1388 struct ahci_host_priv *hpriv; 1297 struct ahci_host_priv *hpriv;
@@ -1418,20 +1327,6 @@ static int tegra_ahci_probe(struct platform_device *pdev)
1418 if (ret) 1327 if (ret)
1419 goto poweroff_controller; 1328 goto poweroff_controller;
1420 1329
1421 ret = tegra_ahci_reset_controller(hpriv);
1422 if (ret)
1423 goto poweroff_controller;
1424
1425 if (!tegra_ahci_bar5_readl(hpriv, T_AHCI_PORT_PXSSTS)) {
1426 struct platform_driver *drv =
1427 to_platform_driver(pdev->dev.driver);
1428
1429 dev_info(&pdev->dev, "Drive not present\n");
1430 drv->driver.pm = NULL;
1431 ret = -ENODEV;
1432 goto poweroff_controller;
1433 }
1434
1435 1330
1436 ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info, 1331 ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
1437 &ahci_platform_sht); 1332 &ahci_platform_sht);
@@ -1446,17 +1341,11 @@ static int tegra_ahci_probe(struct platform_device *pdev)
1446 } 1341 }
1447 1342
1448 ret = pm_runtime_set_active(&pdev->dev); 1343 ret = pm_runtime_set_active(&pdev->dev);
1449 if (ret) { 1344 if (ret)
1450 dev_dbg(&pdev->dev, "unable to set runtime pm active err=%d\n", 1345 dev_dbg(&pdev->dev, "unable to set runtime pm active err=%d\n",
1451 ret); 1346 ret);
1452 } else { 1347 else
1453 pm_runtime_set_autosuspend_delay(&pdev->dev,
1454 TEGRA_AHCI_DEFAULT_IDLE_TIME);
1455 pm_runtime_use_autosuspend(&pdev->dev);
1456 pm_suspend_ignore_children(&pdev->dev, true);
1457 pm_runtime_get_noresume(&pdev->dev);
1458 pm_runtime_enable(&pdev->dev); 1348 pm_runtime_enable(&pdev->dev);
1459 }
1460 1349
1461#ifdef CONFIG_DEBUG_FS 1350#ifdef CONFIG_DEBUG_FS
1462 tegra_ahci_dump_debuginit(hpriv); 1351 tegra_ahci_dump_debuginit(hpriv);
diff --git a/drivers/ata/tegra/ahci_tegra.h b/drivers/ata/tegra/ahci_tegra.h
index ca4d4bac9..5bcb0bcf1 100644
--- a/drivers/ata/tegra/ahci_tegra.h
+++ b/drivers/ata/tegra/ahci_tegra.h
@@ -172,7 +172,6 @@
172#define PMC_IMPL_SATA_PWRGT_0_PG_INFO BIT(6) 172#define PMC_IMPL_SATA_PWRGT_0_PG_INFO BIT(6)
173 173
174#define TEGRA_AHCI_MAX_CLKS 2 174#define TEGRA_AHCI_MAX_CLKS 2
175#define TEGRA_AHCI_DEFAULT_IDLE_TIME 10000
176#define TEGRA_AHCI_LPM_TIMEOUT 500 175#define TEGRA_AHCI_LPM_TIMEOUT 500
177 176
178#define TEGRA_AHCI_READ_LOG_EXT_NOENTRY 0x80 177#define TEGRA_AHCI_READ_LOG_EXT_NOENTRY 0x80