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: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
parent
ee8209fd02
commit
b59cc200ac
|
@ -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 {
|
||||||
|
|
||||||
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 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in New Issue