lkml.org 
[lkml]   [2016]   [Jan]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2/6] ACPI: create setup_quirk in acpi_apd
Date
The post_setup hook of AMD0020 device will create an amba device as
the child of a previously created platform device.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
drivers/acpi/acpi_apd.c | 131 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 121 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index a450e7a..9520daf 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -3,7 +3,8 @@
*
* Copyright (c) 2014,2015 AMD Corporation.
* Authors: Ken Xue <Ken.Xue@amd.com>
- * Wu, Jeff <Jeff.Wu@amd.com>
+ * Jeff Wu <15618388108@163.com>
+ * Wang Hongcheng <Annie.Wang@amd.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,6 +18,8 @@
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/pm.h>
+#include <linux/amba/bus.h>
+#include <linux/dma-mapping.h>

#include "internal.h"

@@ -36,19 +39,23 @@ struct apd_private_data;
* @fixed_clk_rate: fixed rate input clock source for acpi device;
* 0 means no fixed rate input clock source
* @setup: a hook routine to set device resource during create platform device
- *
+ * @post_setup: an additional hook routine
* Device description defined as acpi_device_id.driver_data
*/
struct apd_device_desc {
unsigned int flags;
unsigned int fixed_clk_rate;
+ unsigned int base_offset;
+ unsigned int periphid;
int (*setup)(struct apd_private_data *pdata);
+ int (*post_setup)(struct apd_private_data *pdata);
};

struct apd_private_data {
struct clk *clk;
struct acpi_device *adev;
const struct apd_device_desc *dev_desc;
+ struct platform_device *pdev;
};

#ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
@@ -71,6 +78,100 @@ static int acpi_apd_setup(struct apd_private_data *pdata)
return 0;
}

+#ifdef CONFIG_SERIAL_8250_AMD
+static int acpi_apd_setup_quirks(struct apd_private_data *pdata)
+{
+ struct amba_device *amba_dev = NULL;
+ struct platform_device *pdev = pdata->pdev;
+ struct resource *presource, *resource = NULL;
+ int count = 0;
+ int ret = 0;
+ unsigned int i;
+ unsigned int irq[AMBA_NR_IRQS];
+ struct clk *clk = ERR_PTR(-ENODEV);
+ char amba_devname[100];
+
+ resource = kzalloc(sizeof(*resource), GFP_KERNEL);
+ if (!resource)
+ goto resource_alloc_err;
+
+ presource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ resource->parent = presource;
+
+ /*
+ * The memory address of AMD pl330 has an offset of ACPI
+ * mem resource.
+ */
+ resource->start += presource->start + pdata->dev_desc->base_offset;
+ resource->end = presource->end;
+
+ presource = pdev->resource;
+ for (i = 0; i < resource_size(presource); i++) {
+ if (presource[i].flags & IORESOURCE_IRQ)
+ irq[count++] = presource[i].start;
+ }
+
+ sprintf(amba_devname, "%s%s", dev_name(&pdev->dev), "DMA");
+
+ amba_dev = amba_device_alloc(amba_devname,
+ resource->start,
+ resource_size(resource));
+
+ if (!amba_dev)
+ goto amba_alloc_err;
+
+ amba_dev->dev.coherent_dma_mask
+ = acpi_dma_supported(ACPI_COMPANION(&pdev->dev)) ? DMA_BIT_MASK(64) : 0;
+ amba_dev->dev.fwnode = acpi_fwnode_handle(ACPI_COMPANION(&pdev->dev));
+
+ amba_dev->dev.parent = &pdev->dev;
+ amba_dev->periphid = pdata->dev_desc->periphid;
+
+ WARN_ON_ONCE(count > AMBA_NR_IRQS);
+
+ for (i = 0; i < count; i++)
+ amba_dev->irq[i] = irq[i];
+
+ clk = clk_register_fixed_rate(&amba_dev->dev,
+ dev_name(&amba_dev->dev),
+ NULL, CLK_IS_ROOT,
+ pdata->dev_desc->fixed_clk_rate);
+ if (IS_ERR_OR_NULL(clk))
+ goto amba_register_err;
+
+ ret = clk_register_clkdev(clk, "apb_pclk",
+ dev_name(&amba_dev->dev));
+ if (ret)
+ goto amba_register_err;
+
+ amba_dev->dev.init_name = NULL;
+ ret = amba_device_add(amba_dev, resource);
+ if (ret)
+ goto amba_register_err;
+
+ kfree(resource);
+ return 0;
+
+amba_register_err:
+ amba_device_put(amba_dev);
+
+amba_alloc_err:
+ kfree(resource);
+
+resource_alloc_err:
+ dev_info(&pdev->dev, "AMBA device created failed.\n");
+ return 0;
+}
+
+#else
+
+static int acpi_apd_setup_quirks(struct apd_private_data *pdata)
+{
+ return 0;
+}
+
+#endif
+
static struct apd_device_desc cz_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 133000000,
@@ -78,7 +179,10 @@ static struct apd_device_desc cz_i2c_desc = {

static struct apd_device_desc cz_uart_desc = {
.setup = acpi_apd_setup,
+ .post_setup = acpi_apd_setup_quirks,
.fixed_clk_rate = 48000000,
+ .periphid = 0x00041330,
+ .base_offset = SZ_4K,
};

#else
@@ -88,11 +192,11 @@ static struct apd_device_desc cz_uart_desc = {
#endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */

/**
-* Create platform device during acpi scan attach handle.
-* Return value > 0 on success of creating device.
-*/
+ * Create platform device during acpi scan attach handle.
+ * Return value > 0 on success of creating device.
+ */
static int acpi_apd_create_device(struct acpi_device *adev,
- const struct acpi_device_id *id)
+ const struct acpi_device_id *id)
{
const struct apd_device_desc *dev_desc = (void *)id->driver_data;
struct apd_private_data *pdata;
@@ -118,14 +222,21 @@ static int acpi_apd_create_device(struct acpi_device *adev,
}

adev->driver_data = pdata;
- pdev = acpi_create_platform_device(adev);
- if (!IS_ERR_OR_NULL(pdev))
- return 1;

+ pdev = acpi_create_platform_device(adev);
ret = PTR_ERR(pdev);
- adev->driver_data = NULL;
+ if (IS_ERR_OR_NULL(pdev))
+ goto err_out;
+
+ if (dev_desc->post_setup) {
+ pdata->pdev = pdev;
+ dev_desc->post_setup(pdata);
+ }
+
+ return ret;

err_out:
+ adev->driver_data = NULL;
kfree(pdata);
return ret;
}
--
1.9.1


\
 
 \ /
  Last update: 2016-01-04 07:01    [W:0.167 / U:0.492 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site