aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaresh Bhat <naresh.bhat@linaro.org>2013-12-09 17:23:41 +0530
committerGraeme Gregory <graeme.gregory@linaro.org>2014-06-03 09:24:40 +0100
commit337a30ff28ac7a3e9c9b11785e65479daa3b5d4f (patch)
tree8d6b3aa109ae1457ce1b75ea3c305b8b99032927
parent566a3daf4dc86377f52c7b64aba1e49f5da12026 (diff)
downloadleg-kernel-337a30ff28ac7a3e9c9b11785e65479daa3b5d4f.tar.gz
ACPI/ARM: Add ACPI to AMBA SPI driver
Neither Foundation nor RTSM have a SPI device, but here are the necessary driver changes as an example of how to use acpi_amba_dsm_lookup() to get non-standard parameters from ACPI. This was tested by wiring up a SPI device into an RTSM Fast Model. Signed-off-by: Brandon Anderson <brandon.anderson@amd.com> Reviewed-by: Naresh Bhat <naresh.bhat@linaro.org>
-rw-r--r--drivers/spi/spi-pl022.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 51d99779682f..b0bbd57328bb 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -43,6 +43,7 @@
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/amba/acpi.h>
/*
* This macro is used to define some register default values.
@@ -2066,6 +2067,49 @@ pl022_platform_data_dt_get(struct device *dev)
return pd;
}
+#ifdef CONFIG_ACPI
+static struct pl022_ssp_controller *
+acpi_pl022_get_platform_data(struct device *dev)
+{
+ struct pl022_ssp_controller *pd, *ret;
+ struct acpi_amba_dsm_entry entry;
+
+ pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "cannot allocate platform data memory\n");
+ return NULL;
+ }
+ ret = pd;
+
+ pd->bus_id = -1;
+ pd->enable_dma = 1;
+ if (acpi_amba_dsm_lookup(ACPI_HANDLE(dev), "num-cs", 0, &entry) == 0) {
+ if (kstrtou8(entry.value, 0, &pd->num_chipselect) != 0) {
+ dev_err(dev, "invalid 'num-cs' in ACPI definition\n");
+ ret = NULL;
+ }
+ kfree(entry.key);
+ kfree(entry.value);
+ }
+ if (acpi_amba_dsm_lookup(ACPI_HANDLE(dev),
+ "autosuspend-delay", 0, &entry) == 0) {
+ if (kstrtoint(entry.value, 0, &pd->autosuspend_delay) != 0) {
+ dev_err(dev, "invalid 'autosuspend-delay' in ACPI definition\n");
+ ret = NULL;
+ }
+ kfree(entry.key);
+ kfree(entry.value);
+ }
+ if (acpi_amba_dsm_lookup(ACPI_HANDLE(dev), "rt", 0, &entry) == 0) {
+ pd->rt = (entry.value && strcmp(entry.value, "1") == 0);
+ kfree(entry.key);
+ kfree(entry.value);
+ }
+
+ return ret;
+}
+#endif
+
static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
@@ -2078,6 +2122,11 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
dev_info(&adev->dev,
"ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
+#ifdef CONFIG_ACPI
+ if (!platform_info && ACPI_HANDLE(dev))
+ platform_info = acpi_pl022_get_platform_data(dev);
+ else
+#endif
if (!platform_info && IS_ENABLED(CONFIG_OF))
platform_info = pl022_platform_data_dt_get(dev);