Re: [PATCH 2/6] ACPI: create setup_quirk in acpi_apd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jan 4, 2016 at 7:31 AM, Wang Hongcheng <annie.wang@xxxxxxx> wrote:
> 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@xxxxxxx>
> ---
>  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@xxxxxxx>
> - *     Wu, Jeff <Jeff.Wu@xxxxxxx>
> + *          Jeff Wu <15618388108@xxxxxxx>
> + *          Wang Hongcheng <Annie.Wang@xxxxxxx>
>   *
>   * 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;
> +

struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);

?

> +       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];

memcpy() ?

> +
> +       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));

clkdev_create()?

Or mention that driver shall not be unloaded, otherwise it will leak resources.

> +       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");

dev_err();

> +       return 0;

return ret;

> +}
> +
> +#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.
> + */

Separate change, doesn't belong to the topic.

>  static int acpi_apd_create_device(struct acpi_device *adev,
> -                                  const struct acpi_device_id *id)
> +                                 const struct acpi_device_id *id)

Ditto

>  {
>         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
>



-- 
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux