Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss");

struct lpss_device_desc {
	bool clk_required;
	const char *clk_parent;
	const char *clkdev_name;
	bool ltr_required;
	unsigned int prv_offset;
};

static struct lpss_device_desc lpss_dma_desc = {
	.clk_required = true,
	.clkdev_name = "hclk",
};

struct lpss_private_data {
	void __iomem *mmio_base;
	resource_size_t mmio_size;
@@ -49,7 +54,6 @@ struct lpss_private_data {

static struct lpss_device_desc lpt_dev_desc = {
	.clk_required = true,
	.clk_parent = "lpss_clk",
	.prv_offset = 0x800,
	.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[] = {
	/* Generic LPSS devices */
	{ "INTL9C60", (unsigned long)&lpss_dma_desc },

	/* Lynxpoint LPSS devices */
	{ "INT33C0", (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)
{
	const struct lpss_device_desc *dev_desc = pdata->dev_desc;
	struct lpss_clk_data *clk_data;

	if (!lpss_clk_dev)
		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)
		return -ENODATA;

	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,
				       0, 0, NULL);
	if (IS_ERR(pdata->clk))
+11 −4
Original line number Diff line number Diff line
@@ -15,22 +15,29 @@
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_data/clk-lpss.h>
#include <linux/platform_device.h>

#define PRV_CLOCK_PARAMS 0x800

static int lpt_clk_probe(struct platform_device *pdev)
{
	struct lpss_clk_data *drvdata;
	struct clk *clk;

	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	/* LPSS free running clock */
	clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT,
				      100000000);
	drvdata->name = "lpss_clk";
	clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL,
				      CLK_IS_ROOT, 100000000);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	/* Shared DMA clock */
	clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto");
	drvdata->clk = clk;
	platform_set_drvdata(pdev, drvdata);
	return 0;
}

+5 −0
Original line number Diff line number Diff line
@@ -13,6 +13,11 @@
#ifndef __CLK_LPSS_H
#define __CLK_LPSS_H

struct lpss_clk_data {
	const char *name;
	struct clk *clk;
};

extern int lpt_clk_init(void);

#endif /* __CLK_LPSS_H */