mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	Merge branch 'acpi-lpss'
* acpi-lpss:
  ACPI / LPSS: override SDIO private register space size from ACPI tables
  ACPI / LPSS: mask the UART TX completion interrupt
  ACPI / LPSS: add support for Intel BayTrail
Conflicts:
	drivers/acpi/acpi_lpss.c (with commit b9e95fc)
			
			
This commit is contained in:
		
						commit
						f4c9f40238
					
				
					 2 changed files with 116 additions and 13 deletions
				
			
		|  | @ -32,12 +32,26 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
| #define LPSS_GENERAL_LTR_MODE_SW	BIT(2) | ||||
| #define LPSS_SW_LTR			0x10 | ||||
| #define LPSS_AUTO_LTR			0x14 | ||||
| #define LPSS_TX_INT			0x20 | ||||
| #define LPSS_TX_INT_MASK		BIT(1) | ||||
| 
 | ||||
| struct lpss_shared_clock { | ||||
| 	const char *name; | ||||
| 	unsigned long rate; | ||||
| 	struct clk *clk; | ||||
| }; | ||||
| 
 | ||||
| struct lpss_private_data; | ||||
| 
 | ||||
| struct lpss_device_desc { | ||||
| 	bool clk_required; | ||||
| 	const char *clkdev_name; | ||||
| 	bool ltr_required; | ||||
| 	unsigned int prv_offset; | ||||
| 	size_t prv_size_override; | ||||
| 	bool clk_gate; | ||||
| 	struct lpss_shared_clock *shared_clock; | ||||
| 	void (*setup)(struct lpss_private_data *pdata); | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc lpss_dma_desc = { | ||||
|  | @ -52,17 +66,76 @@ struct lpss_private_data { | |||
| 	const struct lpss_device_desc *dev_desc; | ||||
| }; | ||||
| 
 | ||||
| static void lpss_uart_setup(struct lpss_private_data *pdata) | ||||
| { | ||||
| 	unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; | ||||
| 	u32 reg; | ||||
| 
 | ||||
| 	reg = readl(pdata->mmio_base + tx_int_offset); | ||||
| 	writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset); | ||||
| } | ||||
| 
 | ||||
| static struct lpss_device_desc lpt_dev_desc = { | ||||
| 	.clk_required = true, | ||||
| 	.prv_offset = 0x800, | ||||
| 	.ltr_required = true, | ||||
| 	.clk_gate = true, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc lpt_uart_dev_desc = { | ||||
| 	.clk_required = true, | ||||
| 	.prv_offset = 0x800, | ||||
| 	.ltr_required = true, | ||||
| 	.clk_gate = true, | ||||
| 	.setup = lpss_uart_setup, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc lpt_sdio_dev_desc = { | ||||
| 	.prv_offset = 0x1000, | ||||
| 	.prv_size_override = 0x1018, | ||||
| 	.ltr_required = true, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_shared_clock uart_clock = { | ||||
| 	.name = "uart_clk", | ||||
| 	.rate = 44236800, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc byt_uart_dev_desc = { | ||||
| 	.clk_required = true, | ||||
| 	.prv_offset = 0x800, | ||||
| 	.clk_gate = true, | ||||
| 	.shared_clock = &uart_clock, | ||||
| 	.setup = lpss_uart_setup, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_shared_clock spi_clock = { | ||||
| 	.name = "spi_clk", | ||||
| 	.rate = 50000000, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc byt_spi_dev_desc = { | ||||
| 	.clk_required = true, | ||||
| 	.prv_offset = 0x400, | ||||
| 	.clk_gate = true, | ||||
| 	.shared_clock = &spi_clock, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc byt_sdio_dev_desc = { | ||||
| 	.clk_required = true, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_shared_clock i2c_clock = { | ||||
| 	.name = "i2c_clk", | ||||
| 	.rate = 100000000, | ||||
| }; | ||||
| 
 | ||||
| static struct lpss_device_desc byt_i2c_dev_desc = { | ||||
| 	.clk_required = true, | ||||
| 	.prv_offset = 0x800, | ||||
| 	.shared_clock = &i2c_clock, | ||||
| }; | ||||
| 
 | ||||
| static const struct acpi_device_id acpi_lpss_device_ids[] = { | ||||
| 	/* Generic LPSS devices */ | ||||
| 	{ "INTL9C60", (unsigned long)&lpss_dma_desc }, | ||||
|  | @ -72,11 +145,18 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { | |||
| 	{ "INT33C1", (unsigned long)&lpt_dev_desc }, | ||||
| 	{ "INT33C2", (unsigned long)&lpt_dev_desc }, | ||||
| 	{ "INT33C3", (unsigned long)&lpt_dev_desc }, | ||||
| 	{ "INT33C4", (unsigned long)&lpt_dev_desc }, | ||||
| 	{ "INT33C5", (unsigned long)&lpt_dev_desc }, | ||||
| 	{ "INT33C4", (unsigned long)&lpt_uart_dev_desc }, | ||||
| 	{ "INT33C5", (unsigned long)&lpt_uart_dev_desc }, | ||||
| 	{ "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, | ||||
| 	{ "INT33C7", }, | ||||
| 
 | ||||
| 	/* BayTrail LPSS devices */ | ||||
| 	{ "80860F0A", (unsigned long)&byt_uart_dev_desc }, | ||||
| 	{ "80860F0E", (unsigned long)&byt_spi_dev_desc }, | ||||
| 	{ "80860F14", (unsigned long)&byt_sdio_dev_desc }, | ||||
| 	{ "80860F41", (unsigned long)&byt_i2c_dev_desc }, | ||||
| 	{ "INT33B2", }, | ||||
| 
 | ||||
| 	{ } | ||||
| }; | ||||
| 
 | ||||
|  | @ -98,7 +178,10 @@ 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_shared_clock *shared_clock = dev_desc->shared_clock; | ||||
| 	struct clk *clk = ERR_PTR(-ENODEV); | ||||
| 	struct lpss_clk_data *clk_data; | ||||
| 	const char *parent; | ||||
| 
 | ||||
| 	if (!lpss_clk_dev) | ||||
| 		lpt_register_clock_device(); | ||||
|  | @ -117,14 +200,30 @@ static int register_device_clock(struct acpi_device *adev, | |||
| 	    || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) | ||||
| 		return -ENODATA; | ||||
| 
 | ||||
| 	pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), | ||||
| 				       clk_data->name, 0, | ||||
| 				       pdata->mmio_base + dev_desc->prv_offset, | ||||
| 				       0, 0, NULL); | ||||
| 	if (IS_ERR(pdata->clk)) | ||||
| 		return PTR_ERR(pdata->clk); | ||||
| 	parent = clk_data->name; | ||||
| 
 | ||||
| 	clk_register_clkdev(pdata->clk, NULL, dev_name(&adev->dev)); | ||||
| 	if (shared_clock) { | ||||
| 		clk = shared_clock->clk; | ||||
| 		if (!clk) { | ||||
| 			clk = clk_register_fixed_rate(NULL, shared_clock->name, | ||||
| 						      "lpss_clk", 0, | ||||
| 						      shared_clock->rate); | ||||
| 			shared_clock->clk = clk; | ||||
| 		} | ||||
| 		parent = shared_clock->name; | ||||
| 	} | ||||
| 
 | ||||
| 	if (dev_desc->clk_gate) { | ||||
| 		clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0, | ||||
| 					pdata->mmio_base + dev_desc->prv_offset, | ||||
| 					0, 0, NULL); | ||||
| 		pdata->clk = clk; | ||||
| 	} | ||||
| 
 | ||||
| 	if (IS_ERR(clk)) | ||||
| 		return PTR_ERR(clk); | ||||
| 
 | ||||
| 	clk_register_clkdev(clk, NULL, dev_name(&adev->dev)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -152,7 +251,10 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
| 
 | ||||
| 	list_for_each_entry(rentry, &resource_list, node) | ||||
| 		if (resource_type(&rentry->res) == IORESOURCE_MEM) { | ||||
| 			pdata->mmio_size = resource_size(&rentry->res); | ||||
| 			if (dev_desc->prv_size_override) | ||||
| 				pdata->mmio_size = dev_desc->prv_size_override; | ||||
| 			else | ||||
| 				pdata->mmio_size = resource_size(&rentry->res); | ||||
| 			pdata->mmio_base = ioremap(rentry->res.start, | ||||
| 						   pdata->mmio_size); | ||||
| 			pdata->dev_desc = dev_desc; | ||||
|  | @ -182,6 +284,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
| 		goto err_out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (dev_desc->setup) | ||||
| 		dev_desc->setup(pdata); | ||||
| 
 | ||||
| 	adev->driver_data = pdata; | ||||
| 	ret = acpi_create_platform_device(adev, id); | ||||
| 	if (ret > 0) | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /*
 | ||||
|  * Intel Lynxpoint LPSS clocks. | ||||
|  * Intel Low Power Subsystem clocks. | ||||
|  * | ||||
|  * Copyright (C) 2013, Intel Corporation | ||||
|  * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> | ||||
|  | @ -18,8 +18,6 @@ | |||
| #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; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Rafael J. Wysocki
						Rafael J. Wysocki