summaryrefslogtreecommitdiff
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-08-07 10:55:58 +0100
commitadf705f3c8e2174a5dfa03804ae403b69a17afe9 (patch)
treed78c40f812b8b44a5ebebc52528a13a7f31d2b3c
parentbcdf23da0c404274d823a724ebf7704af0186fa2 (diff)
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 66d2ae21e78e..a90f4b1228a4 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.
@@ -2059,6 +2060,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;
@@ -2071,6 +2115,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);