lkml.org 
[lkml]   [2021]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2/2] spi: tegra210-quad: add acpi support
Date
Support ACPI device enumeration for Tegra QUAD SPI driver.
Also pick device features from device tree.

Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
drivers/spi/spi-tegra210-quad.c | 74 ++++++++++++++++++++++++++++-------------
1 file changed, 51 insertions(+), 23 deletions(-)

diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index ce1bdb4..20c1fa6 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -21,6 +21,8 @@
#include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
+#include <linux/acpi.h>
+#include <linux/property.h>

#define QSPI_COMMAND1 0x000
#define QSPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
@@ -767,7 +769,7 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran
u32 tx_tap = 0, rx_tap = 0;
int req_mode;

- if (speed != tqspi->cur_speed) {
+ if (!has_acpi_companion(tqspi->dev) && speed != tqspi->cur_speed) {
clk_set_rate(tqspi->clk, speed);
tqspi->cur_speed = speed;
}
@@ -875,16 +877,15 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi,
static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi)
{
struct tegra_qspi_client_data *cdata;
- struct device_node *slave_np = spi->dev.of_node;

cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL);
if (!cdata)
return NULL;

- of_property_read_u32(slave_np, "nvidia,tx-clk-tap-delay",
- &cdata->tx_clk_tap_delay);
- of_property_read_u32(slave_np, "nvidia,rx-clk-tap-delay",
- &cdata->rx_clk_tap_delay);
+ device_property_read_u32(&spi->dev, "nvidia,tx-clk-tap-delay",
+ &cdata->tx_clk_tap_delay);
+ device_property_read_u32(&spi->dev, "nvidia,rx-clk-tap-delay",
+ &cdata->rx_clk_tap_delay);
return cdata;
}

@@ -943,14 +944,27 @@ static void tegra_qspi_dump_regs(struct tegra_qspi *tqspi)
tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS));
}

+static void tegra_qspi_reset(struct tegra_qspi *tqspi)
+{
+ if (tqspi->rst) {
+ reset_control_assert(tqspi->rst);
+ udelay(2);
+ reset_control_deassert(tqspi->rst);
+ return;
+ }
+#ifdef CONFIG_ACPI
+ if (ACPI_FAILURE(acpi_evaluate_object(ACPI_HANDLE(tqspi->dev),
+ "_RST", NULL, NULL)))
+ dev_err(tqspi->dev, "failed to reset device\n");
+#endif
+}
+
static void tegra_qspi_handle_error(struct tegra_qspi *tqspi)
{
dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg);
tegra_qspi_dump_regs(tqspi);
tegra_qspi_flush_fifos(tqspi, true);
- reset_control_assert(tqspi->rst);
- udelay(2);
- reset_control_deassert(tqspi->rst);
+ tegra_qspi_reset(tqspi);
}

static void tegra_qspi_transfer_end(struct spi_device *spi)
@@ -1202,6 +1216,14 @@ static const struct of_device_id tegra_qspi_of_match[] = {

MODULE_DEVICE_TABLE(of, tegra_qspi_of_match);

+#ifdef CONFIG_ACPI
+static const struct acpi_device_id tegra_qspi_acpi_match[] = {
+ { .id = "NVDA14E2", },
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, tegra_qspi_acpi_match);
+#endif
+
static int tegra_qspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
@@ -1242,18 +1264,20 @@ static int tegra_qspi_probe(struct platform_device *pdev)
qspi_irq = platform_get_irq(pdev, 0);
tqspi->irq = qspi_irq;

- tqspi->clk = devm_clk_get(&pdev->dev, "qspi");
- if (IS_ERR(tqspi->clk)) {
- ret = PTR_ERR(tqspi->clk);
- dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
- return ret;
- }
+ if (!has_acpi_companion(tqspi->dev)) {
+ tqspi->clk = devm_clk_get(&pdev->dev, "qspi");
+ if (IS_ERR(tqspi->clk)) {
+ ret = PTR_ERR(tqspi->clk);
+ dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
+ return ret;
+ }

- tqspi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
- if (IS_ERR(tqspi->rst)) {
- ret = PTR_ERR(tqspi->rst);
- dev_err(&pdev->dev, "failed to get reset control: %d\n", ret);
- return ret;
+ tqspi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ if (IS_ERR(tqspi->rst)) {
+ dev_err(&pdev->dev, "failed to get reset control: %d\n", ret);
+ ret = PTR_ERR(tqspi->rst);
+ return ret;
+ }
}

tqspi->max_buf_size = QSPI_FIFO_DEPTH << 2;
@@ -1277,9 +1301,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
goto exit_pm_disable;
}

- reset_control_assert(tqspi->rst);
- udelay(2);
- reset_control_deassert(tqspi->rst);
+ tegra_qspi_reset(tqspi);

tqspi->def_command1_reg = QSPI_M_S | QSPI_CS_SW_HW | QSPI_CS_SW_VAL;
tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1);
@@ -1353,6 +1375,10 @@ static int __maybe_unused tegra_qspi_resume(struct device *dev)
return spi_master_resume(master);
}

+#ifdef CONFIG_ACPI
+static int __maybe_unused tegra_qspi_runtime_suspend(struct device *dev) { return 0; }
+static int __maybe_unused tegra_qspi_runtime_resume(struct device *dev) { return 0; }
+#else
static int __maybe_unused tegra_qspi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
@@ -1378,6 +1404,7 @@ static int __maybe_unused tegra_qspi_runtime_resume(struct device *dev)

return ret;
}
+#endif

static const struct dev_pm_ops tegra_qspi_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_qspi_runtime_suspend, tegra_qspi_runtime_resume, NULL)
@@ -1389,6 +1416,7 @@ static struct platform_driver tegra_qspi_driver = {
.name = "tegra-qspi",
.pm = &tegra_qspi_pm_ops,
.of_match_table = tegra_qspi_of_match,
+ .acpi_match_table = ACPI_PTR(tegra_qspi_acpi_match),
},
.probe = tegra_qspi_probe,
.remove = tegra_qspi_remove,
--
2.7.4
\
 
 \ /
  Last update: 2021-11-25 10:58    [W:0.083 / U:0.720 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site