diff options
author | Mark A. Greer <mgreer@animalcreek.com> | 2014-09-02 18:12:35 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2014-09-07 17:13:44 -0400 |
commit | ceccd6aa50887352e66d0edf68d8be510a639da6 (patch) | |
tree | 7afbd15222cc440b6089e6edf40b23bef85a7710 /drivers/nfc | |
parent | b5e17d9b5bd7e53696bce21e38eec5b9bb8abb88 (diff) |
NFC: trf7970a: Don't assume CONFIG_PM_RUNTIME is enabled
The current code assumes that CONFIG_PM_RUNTIME
is always defined so it won't power up the trf7970a
when it isn't enabled. Fix this by moving the power
up/down code from the pm_runtime_resume/suspend
routines into their own routines and calling the
power up function from the probe routine. This
ensures the device is powered up even when
CONFIG_PM_RUNTIME is not defined.
In order to not power on/off a device that is
already powered on/off, create a new state to
indicate that the power is off (TRF7970A_ST_PWR_OFF).
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r-- | drivers/nfc/trf7970a.c | 132 |
1 files changed, 96 insertions, 36 deletions
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index cda854b98cf3..84a9c3f78621 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c | |||
@@ -332,6 +332,7 @@ | |||
332 | (ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE) | 332 | (ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE) |
333 | 333 | ||
334 | enum trf7970a_state { | 334 | enum trf7970a_state { |
335 | TRF7970A_ST_PWR_OFF, | ||
335 | TRF7970A_ST_RF_OFF, | 336 | TRF7970A_ST_RF_OFF, |
336 | TRF7970A_ST_IDLE, | 337 | TRF7970A_ST_IDLE, |
337 | TRF7970A_ST_IDLE_RX_BLOCKED, | 338 | TRF7970A_ST_IDLE_RX_BLOCKED, |
@@ -877,6 +878,12 @@ static int trf7970a_switch_rf_on(struct trf7970a *trf) | |||
877 | 878 | ||
878 | pm_runtime_get_sync(trf->dev); | 879 | pm_runtime_get_sync(trf->dev); |
879 | 880 | ||
881 | if (trf->state != TRF7970A_ST_RF_OFF) { /* Power on, RF off */ | ||
882 | dev_err(trf->dev, "%s - Incorrect state: %d\n", __func__, | ||
883 | trf->state); | ||
884 | return -EINVAL; | ||
885 | } | ||
886 | |||
880 | ret = trf7970a_init(trf); | 887 | ret = trf7970a_init(trf); |
881 | if (ret) { | 888 | if (ret) { |
882 | dev_err(trf->dev, "%s - Can't initialize: %d\n", __func__, ret); | 889 | dev_err(trf->dev, "%s - Can't initialize: %d\n", __func__, ret); |
@@ -899,6 +906,7 @@ static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on) | |||
899 | 906 | ||
900 | if (on) { | 907 | if (on) { |
901 | switch (trf->state) { | 908 | switch (trf->state) { |
909 | case TRF7970A_ST_PWR_OFF: | ||
902 | case TRF7970A_ST_RF_OFF: | 910 | case TRF7970A_ST_RF_OFF: |
903 | ret = trf7970a_switch_rf_on(trf); | 911 | ret = trf7970a_switch_rf_on(trf); |
904 | break; | 912 | break; |
@@ -913,6 +921,7 @@ static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on) | |||
913 | } | 921 | } |
914 | } else { | 922 | } else { |
915 | switch (trf->state) { | 923 | switch (trf->state) { |
924 | case TRF7970A_ST_PWR_OFF: | ||
916 | case TRF7970A_ST_RF_OFF: | 925 | case TRF7970A_ST_RF_OFF: |
917 | break; | 926 | break; |
918 | default: | 927 | default: |
@@ -1045,7 +1054,8 @@ static int trf7970a_in_configure_hw(struct nfc_digital_dev *ddev, int type, | |||
1045 | 1054 | ||
1046 | mutex_lock(&trf->lock); | 1055 | mutex_lock(&trf->lock); |
1047 | 1056 | ||
1048 | if (trf->state == TRF7970A_ST_RF_OFF) { | 1057 | if ((trf->state == TRF7970A_ST_PWR_OFF) || |
1058 | (trf->state == TRF7970A_ST_RF_OFF)) { | ||
1049 | ret = trf7970a_switch_rf_on(trf); | 1059 | ret = trf7970a_switch_rf_on(trf); |
1050 | if (ret) | 1060 | if (ret) |
1051 | goto err_unlock; | 1061 | goto err_unlock; |
@@ -1316,6 +1326,65 @@ static struct nfc_digital_ops trf7970a_nfc_ops = { | |||
1316 | .abort_cmd = trf7970a_abort_cmd, | 1326 | .abort_cmd = trf7970a_abort_cmd, |
1317 | }; | 1327 | }; |
1318 | 1328 | ||
1329 | static int trf7970a_power_up(struct trf7970a *trf) | ||
1330 | { | ||
1331 | int ret; | ||
1332 | |||
1333 | dev_dbg(trf->dev, "Powering up - state: %d\n", trf->state); | ||
1334 | |||
1335 | if (trf->state != TRF7970A_ST_PWR_OFF) | ||
1336 | return 0; | ||
1337 | |||
1338 | ret = regulator_enable(trf->regulator); | ||
1339 | if (ret) { | ||
1340 | dev_err(trf->dev, "%s - Can't enable VIN: %d\n", __func__, ret); | ||
1341 | return ret; | ||
1342 | } | ||
1343 | |||
1344 | usleep_range(5000, 6000); | ||
1345 | |||
1346 | if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) { | ||
1347 | gpio_set_value(trf->en2_gpio, 1); | ||
1348 | usleep_range(1000, 2000); | ||
1349 | } | ||
1350 | |||
1351 | gpio_set_value(trf->en_gpio, 1); | ||
1352 | |||
1353 | usleep_range(20000, 21000); | ||
1354 | |||
1355 | trf->state = TRF7970A_ST_RF_OFF; | ||
1356 | |||
1357 | return 0; | ||
1358 | } | ||
1359 | |||
1360 | static int trf7970a_power_down(struct trf7970a *trf) | ||
1361 | { | ||
1362 | int ret; | ||
1363 | |||
1364 | dev_dbg(trf->dev, "Powering down - state: %d\n", trf->state); | ||
1365 | |||
1366 | if (trf->state == TRF7970A_ST_PWR_OFF) | ||
1367 | return 0; | ||
1368 | |||
1369 | if (trf->state != TRF7970A_ST_RF_OFF) { | ||
1370 | dev_dbg(trf->dev, "Can't power down - not RF_OFF state (%d)\n", | ||
1371 | trf->state); | ||
1372 | return -EBUSY; | ||
1373 | } | ||
1374 | |||
1375 | gpio_set_value(trf->en_gpio, 0); | ||
1376 | gpio_set_value(trf->en2_gpio, 0); | ||
1377 | |||
1378 | ret = regulator_disable(trf->regulator); | ||
1379 | if (ret) | ||
1380 | dev_err(trf->dev, "%s - Can't disable VIN: %d\n", __func__, | ||
1381 | ret); | ||
1382 | |||
1383 | trf->state = TRF7970A_ST_PWR_OFF; | ||
1384 | |||
1385 | return ret; | ||
1386 | } | ||
1387 | |||
1319 | static int trf7970a_get_autosuspend_delay(struct device_node *np) | 1388 | static int trf7970a_get_autosuspend_delay(struct device_node *np) |
1320 | { | 1389 | { |
1321 | int autosuspend_delay, ret; | 1390 | int autosuspend_delay, ret; |
@@ -1348,7 +1417,7 @@ static int trf7970a_probe(struct spi_device *spi) | |||
1348 | if (!trf) | 1417 | if (!trf) |
1349 | return -ENOMEM; | 1418 | return -ENOMEM; |
1350 | 1419 | ||
1351 | trf->state = TRF7970A_ST_RF_OFF; | 1420 | trf->state = TRF7970A_ST_PWR_OFF; |
1352 | trf->dev = &spi->dev; | 1421 | trf->dev = &spi->dev; |
1353 | trf->spi = spi; | 1422 | trf->spi = spi; |
1354 | 1423 | ||
@@ -1442,19 +1511,29 @@ static int trf7970a_probe(struct spi_device *spi) | |||
1442 | 1511 | ||
1443 | pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay); | 1512 | pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay); |
1444 | pm_runtime_use_autosuspend(trf->dev); | 1513 | pm_runtime_use_autosuspend(trf->dev); |
1514 | |||
1515 | ret = trf7970a_power_up(trf); | ||
1516 | if (ret) | ||
1517 | goto err_free_ddev; | ||
1518 | |||
1519 | pm_runtime_set_active(trf->dev); | ||
1445 | pm_runtime_enable(trf->dev); | 1520 | pm_runtime_enable(trf->dev); |
1521 | pm_runtime_mark_last_busy(trf->dev); | ||
1446 | 1522 | ||
1447 | ret = nfc_digital_register_device(trf->ddev); | 1523 | ret = nfc_digital_register_device(trf->ddev); |
1448 | if (ret) { | 1524 | if (ret) { |
1449 | dev_err(trf->dev, "Can't register NFC digital device: %d\n", | 1525 | dev_err(trf->dev, "Can't register NFC digital device: %d\n", |
1450 | ret); | 1526 | ret); |
1451 | goto err_free_ddev; | 1527 | goto err_power_down; |
1452 | } | 1528 | } |
1453 | 1529 | ||
1454 | return 0; | 1530 | return 0; |
1455 | 1531 | ||
1456 | err_free_ddev: | 1532 | err_power_down: |
1457 | pm_runtime_disable(trf->dev); | 1533 | pm_runtime_disable(trf->dev); |
1534 | pm_runtime_set_suspended(trf->dev); | ||
1535 | trf7970a_power_down(trf); | ||
1536 | err_free_ddev: | ||
1458 | nfc_digital_free_device(trf->ddev); | 1537 | nfc_digital_free_device(trf->ddev); |
1459 | err_disable_regulator: | 1538 | err_disable_regulator: |
1460 | regulator_disable(trf->regulator); | 1539 | regulator_disable(trf->regulator); |
@@ -1478,15 +1557,18 @@ static int trf7970a_remove(struct spi_device *spi) | |||
1478 | /* FALLTHROUGH */ | 1557 | /* FALLTHROUGH */ |
1479 | case TRF7970A_ST_IDLE: | 1558 | case TRF7970A_ST_IDLE: |
1480 | case TRF7970A_ST_IDLE_RX_BLOCKED: | 1559 | case TRF7970A_ST_IDLE_RX_BLOCKED: |
1481 | pm_runtime_put_sync(trf->dev); | 1560 | trf7970a_switch_rf_off(trf); |
1482 | break; | 1561 | break; |
1483 | default: | 1562 | default: |
1484 | break; | 1563 | break; |
1485 | } | 1564 | } |
1486 | 1565 | ||
1487 | mutex_unlock(&trf->lock); | ||
1488 | |||
1489 | pm_runtime_disable(trf->dev); | 1566 | pm_runtime_disable(trf->dev); |
1567 | pm_runtime_set_suspended(trf->dev); | ||
1568 | |||
1569 | trf7970a_power_down(trf); | ||
1570 | |||
1571 | mutex_unlock(&trf->lock); | ||
1490 | 1572 | ||
1491 | nfc_digital_unregister_device(trf->ddev); | 1573 | nfc_digital_unregister_device(trf->ddev); |
1492 | nfc_digital_free_device(trf->ddev); | 1574 | nfc_digital_free_device(trf->ddev); |
@@ -1507,18 +1589,11 @@ static int trf7970a_pm_runtime_suspend(struct device *dev) | |||
1507 | 1589 | ||
1508 | dev_dbg(dev, "Runtime suspend\n"); | 1590 | dev_dbg(dev, "Runtime suspend\n"); |
1509 | 1591 | ||
1510 | if (trf->state != TRF7970A_ST_RF_OFF) { | 1592 | mutex_lock(&trf->lock); |
1511 | dev_dbg(dev, "Can't suspend - not in OFF state (%d)\n", | ||
1512 | trf->state); | ||
1513 | return -EBUSY; | ||
1514 | } | ||
1515 | 1593 | ||
1516 | gpio_set_value(trf->en_gpio, 0); | 1594 | ret = trf7970a_power_down(trf); |
1517 | gpio_set_value(trf->en2_gpio, 0); | ||
1518 | 1595 | ||
1519 | ret = regulator_disable(trf->regulator); | 1596 | mutex_unlock(&trf->lock); |
1520 | if (ret) | ||
1521 | dev_err(dev, "%s - Can't disable VIN: %d\n", __func__, ret); | ||
1522 | 1597 | ||
1523 | return ret; | 1598 | return ret; |
1524 | } | 1599 | } |
@@ -1531,26 +1606,11 @@ static int trf7970a_pm_runtime_resume(struct device *dev) | |||
1531 | 1606 | ||
1532 | dev_dbg(dev, "Runtime resume\n"); | 1607 | dev_dbg(dev, "Runtime resume\n"); |
1533 | 1608 | ||
1534 | ret = regulator_enable(trf->regulator); | 1609 | ret = trf7970a_power_up(trf); |
1535 | if (ret) { | 1610 | if (!ret) |
1536 | dev_err(dev, "%s - Can't enable VIN: %d\n", __func__, ret); | 1611 | pm_runtime_mark_last_busy(dev); |
1537 | return ret; | ||
1538 | } | ||
1539 | |||
1540 | usleep_range(5000, 6000); | ||
1541 | |||
1542 | if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) { | ||
1543 | gpio_set_value(trf->en2_gpio, 1); | ||
1544 | usleep_range(1000, 2000); | ||
1545 | } | ||
1546 | |||
1547 | gpio_set_value(trf->en_gpio, 1); | ||
1548 | |||
1549 | usleep_range(20000, 21000); | ||
1550 | 1612 | ||
1551 | pm_runtime_mark_last_busy(dev); | 1613 | return ret; |
1552 | |||
1553 | return 0; | ||
1554 | } | 1614 | } |
1555 | #endif | 1615 | #endif |
1556 | 1616 | ||