aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGraeme Gregory <graeme.gregory@linaro.org>2014-06-27 18:08:49 +0100
committerGraeme Gregory <graeme.gregory@linaro.org>2014-07-30 13:19:18 +0100
commit7c8c13740bf8d06748970f956612829a765f8767 (patch)
treeb694480d08d661663251208fd2b664060f76b9cb /drivers
parent0959eddd5e16cfa640ceeb0fc57c5caf18c13de0 (diff)
acpi: amba: convert to using _PRP and fix _HID
Convert from the old _DSM indicated clocks to the newer _PRP method as a staging point for final conversion to _DSD Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/amba/acpi.c160
1 files changed, 31 insertions, 129 deletions
diff --git a/drivers/amba/acpi.c b/drivers/amba/acpi.c
index 9a97cd8ad433..ae180757f335 100644
--- a/drivers/amba/acpi.c
+++ b/drivers/amba/acpi.c
@@ -25,102 +25,6 @@ struct acpi_amba_bus_info {
char *clk_name;
};
-/* UUID: a706b112-bf0b-48d2-9fa3-95591a3c4c06 (randomly generated) */
-static const char acpi_amba_dsm_uuid[] = {
- 0xa7, 0x06, 0xb1, 0x12, 0xbf, 0x0b, 0x48, 0xd2,
- 0x9f, 0xa3, 0x95, 0x59, 0x1a, 0x3c, 0x4c, 0x06
-};
-
-/* acpi_amba_dsm_lookup()
- *
- * Helper to parse through ACPI _DSM object for a device. Each entry
- * has three fields.
- */
-int acpi_amba_dsm_lookup(acpi_handle handle,
- const char *tag, int index,
- struct acpi_amba_dsm_entry *entry)
-{
- acpi_status status;
- struct acpi_object_list input;
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object params[4];
- union acpi_object *obj;
- int len, match_count, i;
-
- /* invalidate output in case there's no entry to supply */
- entry->key = NULL;
- entry->value = NULL;
-
- if (!acpi_has_method(handle, "_DSM"))
- return -ENOENT;
-
- input.count = 4;
- params[0].type = ACPI_TYPE_BUFFER; /* UUID */
- params[0].buffer.length = sizeof(acpi_amba_dsm_uuid);
- params[0].buffer.pointer = (char *)acpi_amba_dsm_uuid;
- params[1].type = ACPI_TYPE_INTEGER; /* Revision */
- params[1].integer.value = 1;
- params[2].type = ACPI_TYPE_INTEGER; /* Function # */
- params[2].integer.value = 1;
- params[3].type = ACPI_TYPE_PACKAGE; /* Arguments */
- params[3].package.count = 0;
- params[3].package.elements = NULL;
- input.pointer = params;
-
- status = acpi_evaluate_object_typed(handle, "_DSM",
- &input, &output, ACPI_TYPE_PACKAGE);
- if (ACPI_FAILURE(status)) {
- pr_err("failed to get _DSM package for this device\n");
- return -ENOENT;
- }
-
- obj = (union acpi_object *)output.pointer;
-
- /* parse 2 objects per entry */
- match_count = 0;
- for (i = 0; (i + 2) <= obj->package.count; i += 2) {
- /* key must be a string */
- len = obj->package.elements[i].string.length;
- if (len <= 0)
- continue;
-
- /* check to see if this is the entry to return */
- if (strncmp(tag, obj->package.elements[i].string.pointer,
- len) != 0 ||
- match_count < index) {
- match_count++;
- continue;
- }
-
- /* copy the key */
- entry->key = kmalloc(len + 1, GFP_KERNEL);
- strncpy(entry->key,
- obj->package.elements[i].string.pointer,
- len);
- entry->key[len] = '\0';
-
- /* value is a string with space-delimited fields if necessary */
- len = obj->package.elements[i + 1].string.length;
- if (len > 0) {
- entry->value = kmalloc(len + 1, GFP_KERNEL);
- strncpy(entry->value,
- obj->package.elements[i+1].string.pointer,
- len);
- entry->value[len] = '\0';
- }
-
- break;
- }
-
- kfree(output.pointer);
-
- if (entry->key == NULL)
- return -ENOENT;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_amba_dsm_lookup);
-
static int acpi_amba_add_resource(struct acpi_resource *ares, void *data)
{
struct amba_device *dev = data;
@@ -157,43 +61,41 @@ static int acpi_amba_add_resource(struct acpi_resource *ares, void *data)
static struct clk *acpi_amba_get_clk(acpi_handle handle, int index,
char **clk_name)
{
- struct acpi_amba_dsm_entry entry;
acpi_handle clk_handle;
struct acpi_device *adev, *clk_adev;
- char *clk_path;
+ const char **clk_paths;
struct clk *clk = NULL;
- int len;
+ int ret;
if (acpi_bus_get_device(handle, &adev)) {
pr_err("cannot get device from handle\n");
return NULL;
}
- /* key=value format for clocks is:
- * "clock-name"="apb_pclk \\_SB.CLK0"
- */
- if (acpi_amba_dsm_lookup(handle, "clock-name", index, &entry) != 0)
+ /* Get number of entries */
+ ret = acpi_dev_get_property_array_string(adev, "clocks", NULL, 0);
+
+ if ((ret < 0) || (index >= ret))
return NULL;
+ clk_paths = kzalloc(sizeof(*clk_paths) * ret, GFP_KERNEL);
+
/* look under the clock device for the clock that matches the entry */
- *clk_name = NULL;
- len = strcspn(entry.value, " ");
- if (len > 0 && (len + 1) < strlen(entry.value)) {
- clk_path = entry.value + len + 1;
- *clk_name = kmalloc(len + 1, GFP_KERNEL);
- strncpy(*clk_name, entry.value, len);
- (*clk_name)[len] = '\0';
- if (ACPI_FAILURE(
- acpi_get_handle(NULL, clk_path, &clk_handle)) == 0 &&
- acpi_bus_get_device(clk_handle, &clk_adev) == 0)
- clk = clk_get_sys(dev_name(&clk_adev->dev), *clk_name);
- } else
- pr_err("Invalid clock-name value format '%s' for %s\n",
- entry.value, dev_name(&adev->dev));
-
- kfree(entry.key);
- kfree(entry.value);
+ ret = acpi_dev_get_property_array_string(adev, "clocks", clk_paths,
+ ret);
+
+ /* Locate the acpi_device from the device name */
+ acpi_get_handle(NULL, (acpi_string)clk_paths[index], &clk_handle);
+ if (!clk_handle)
+ goto error;
+ acpi_bus_get_device(clk_handle, &clk_adev);
+ if (!clk_adev)
+ goto error;
+ clk = clk_get_sys(dev_name(&clk_adev->dev), NULL);
+
+error:
+ kfree(clk_paths);
return clk;
}
@@ -204,14 +106,6 @@ static void acpi_amba_register_clocks(struct acpi_device *adev,
int i;
char *clk_name;
- if (default_clk) {
- /* for amba_get_enable_pclk() ... */
- clk_register_clkdev(default_clk, default_clk_name,
- dev_name(&adev->dev));
- /* for devm_clk_get() ... */
- clk_register_clkdev(default_clk, NULL, dev_name(&adev->dev));
- }
-
for (i = 0;; i++) {
clk_name = NULL;
clk = acpi_amba_get_clk(ACPI_HANDLE(&adev->dev), i, &clk_name);
@@ -222,6 +116,14 @@ static void acpi_amba_register_clocks(struct acpi_device *adev,
kfree(clk_name);
}
+
+ if (default_clk) {
+ /* for amba_get_enable_pclk() ... */
+ clk_register_clkdev(default_clk, default_clk_name,
+ dev_name(&adev->dev));
+ /* for devm_clk_get() ... */
+ clk_register_clkdev(default_clk, NULL, dev_name(&adev->dev));
+ }
}
/* acpi_amba_add_device()
@@ -309,7 +211,7 @@ static int acpi_amba_bus_probe(struct platform_device *pdev)
}
static const struct acpi_device_id amba_bus_acpi_match[] = {
- { "AMBA0000", 0 },
+ { "LNRO001A", 0 },
{ },
};