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:3.605 / U:0.656 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site