Commit b59cc200 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Vinod Koul

ACPI / LPSS: register clock device for Lynxpoint DMA properly

The DMA controller in Lynxpoint is enumerated as a regular ACPI device now. To
work properly it is using the LPSS root clock as a functional clock. That's why
we have to register the clock device accordingly to the ACPI ID of the DMA
controller. The acpi_lpss.c module is responsible to do the job.

This patch also removes hardcoded name of the DMA device in clk-lpt.c and the
name of the root clock in acpi_lpss.c.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent ee8209fd
...@@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss"); ...@@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss");
struct lpss_device_desc { struct lpss_device_desc {
bool clk_required; bool clk_required;
const char *clk_parent; const char *clkdev_name;
bool ltr_required; bool ltr_required;
unsigned int prv_offset; unsigned int prv_offset;
}; };
static struct lpss_device_desc lpss_dma_desc = {
.clk_required = true,
.clkdev_name = "hclk",
};
struct lpss_private_data { struct lpss_private_data {
void __iomem *mmio_base; void __iomem *mmio_base;
resource_size_t mmio_size; resource_size_t mmio_size;
...@@ -49,7 +54,6 @@ struct lpss_private_data { ...@@ -49,7 +54,6 @@ struct lpss_private_data {
static struct lpss_device_desc lpt_dev_desc = { static struct lpss_device_desc lpt_dev_desc = {
.clk_required = true, .clk_required = true,
.clk_parent = "lpss_clk",
.prv_offset = 0x800, .prv_offset = 0x800,
.ltr_required = true, .ltr_required = true,
}; };
...@@ -60,6 +64,9 @@ static struct lpss_device_desc lpt_sdio_dev_desc = { ...@@ -60,6 +64,9 @@ static struct lpss_device_desc lpt_sdio_dev_desc = {
}; };
static const struct acpi_device_id acpi_lpss_device_ids[] = { static const struct acpi_device_id acpi_lpss_device_ids[] = {
/* Generic LPSS devices */
{ "INTL9C60", (unsigned long)&lpss_dma_desc },
/* Lynxpoint LPSS devices */ /* Lynxpoint LPSS devices */
{ "INT33C0", (unsigned long)&lpt_dev_desc }, { "INT33C0", (unsigned long)&lpt_dev_desc },
{ "INT33C1", (unsigned long)&lpt_dev_desc }, { "INT33C1", (unsigned long)&lpt_dev_desc },
...@@ -91,16 +98,27 @@ static int register_device_clock(struct acpi_device *adev, ...@@ -91,16 +98,27 @@ static int register_device_clock(struct acpi_device *adev,
struct lpss_private_data *pdata) struct lpss_private_data *pdata)
{ {
const struct lpss_device_desc *dev_desc = pdata->dev_desc; const struct lpss_device_desc *dev_desc = pdata->dev_desc;
struct lpss_clk_data *clk_data;
if (!lpss_clk_dev) if (!lpss_clk_dev)
lpt_register_clock_device(); lpt_register_clock_device();
if (!dev_desc->clk_parent || !pdata->mmio_base clk_data = platform_get_drvdata(lpss_clk_dev);
if (!clk_data)
return -ENODEV;
if (dev_desc->clkdev_name) {
clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
dev_name(&adev->dev));
return 0;
}
if (!pdata->mmio_base
|| pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
return -ENODATA; return -ENODATA;
pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev),
dev_desc->clk_parent, 0, clk_data->name, 0,
pdata->mmio_base + dev_desc->prv_offset, pdata->mmio_base + dev_desc->prv_offset,
0, 0, NULL); 0, 0, NULL);
if (IS_ERR(pdata->clk)) if (IS_ERR(pdata->clk))
......
...@@ -15,22 +15,29 @@ ...@@ -15,22 +15,29 @@
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_data/clk-lpss.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#define PRV_CLOCK_PARAMS 0x800 #define PRV_CLOCK_PARAMS 0x800
static int lpt_clk_probe(struct platform_device *pdev) static int lpt_clk_probe(struct platform_device *pdev)
{ {
struct lpss_clk_data *drvdata;
struct clk *clk; struct clk *clk;
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
/* LPSS free running clock */ /* LPSS free running clock */
clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT, drvdata->name = "lpss_clk";
100000000); clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL,
CLK_IS_ROOT, 100000000);
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
/* Shared DMA clock */ drvdata->clk = clk;
clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto"); platform_set_drvdata(pdev, drvdata);
return 0; return 0;
} }
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
#ifndef __CLK_LPSS_H #ifndef __CLK_LPSS_H
#define __CLK_LPSS_H #define __CLK_LPSS_H
struct lpss_clk_data {
const char *name;
struct clk *clk;
};
extern int lpt_clk_init(void); extern int lpt_clk_init(void);
#endif /* __CLK_LPSS_H */ #endif /* __CLK_LPSS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment