aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-05-13 08:42:44 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-06-18 19:08:47 -0400
commitf627217064dbef1eef53ceb01edb9c94203991e0 (patch)
tree8a8f1caba1b430fe2c7506f32f10a9a3188e27a4 /drivers
parent7d132055814ef17a6c7b69f342244c410a5e000f (diff)
ACPI / LPSS: add support for Intel BayTrail
Intel BayTrail has almost the same Low Power Subsystem than Lynxpoint with few differences. Peripherals are clocked with different speeds (typically lower) and the clock is not always gated. To support this we add possibility to share a common fixed rate clock and make clock gating optional. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Mike Turquette <mturquette@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpi_lpss.c88
-rw-r--r--drivers/clk/x86/clk-lpt.c4
2 files changed, 82 insertions, 10 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 652fd5ce303c..f6d760581faa 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -33,11 +33,19 @@ ACPI_MODULE_NAME("acpi_lpss");
33#define LPSS_SW_LTR 0x10 33#define LPSS_SW_LTR 0x10
34#define LPSS_AUTO_LTR 0x14 34#define LPSS_AUTO_LTR 0x14
35 35
36struct lpss_shared_clock {
37 const char *name;
38 unsigned long rate;
39 struct clk *clk;
40};
41
36struct lpss_device_desc { 42struct lpss_device_desc {
37 bool clk_required; 43 bool clk_required;
38 const char *clkdev_name; 44 const char *clkdev_name;
39 bool ltr_required; 45 bool ltr_required;
40 unsigned int prv_offset; 46 unsigned int prv_offset;
47 bool clk_gate;
48 struct lpss_shared_clock *shared_clock;
41}; 49};
42 50
43static struct lpss_device_desc lpss_dma_desc = { 51static struct lpss_device_desc lpss_dma_desc = {
@@ -56,6 +64,7 @@ static struct lpss_device_desc lpt_dev_desc = {
56 .clk_required = true, 64 .clk_required = true,
57 .prv_offset = 0x800, 65 .prv_offset = 0x800,
58 .ltr_required = true, 66 .ltr_required = true,
67 .clk_gate = true,
59}; 68};
60 69
61static struct lpss_device_desc lpt_sdio_dev_desc = { 70static struct lpss_device_desc lpt_sdio_dev_desc = {
@@ -63,6 +72,45 @@ static struct lpss_device_desc lpt_sdio_dev_desc = {
63 .ltr_required = true, 72 .ltr_required = true,
64}; 73};
65 74
75static struct lpss_shared_clock uart_clock = {
76 .name = "uart_clk",
77 .rate = 44236800,
78};
79
80static struct lpss_device_desc byt_uart_dev_desc = {
81 .clk_required = true,
82 .prv_offset = 0x800,
83 .clk_gate = true,
84 .shared_clock = &uart_clock,
85};
86
87static struct lpss_shared_clock spi_clock = {
88 .name = "spi_clk",
89 .rate = 50000000,
90};
91
92static struct lpss_device_desc byt_spi_dev_desc = {
93 .clk_required = true,
94 .prv_offset = 0x400,
95 .clk_gate = true,
96 .shared_clock = &spi_clock,
97};
98
99static struct lpss_device_desc byt_sdio_dev_desc = {
100 .clk_required = true,
101};
102
103static struct lpss_shared_clock i2c_clock = {
104 .name = "i2c_clk",
105 .rate = 100000000,
106};
107
108static struct lpss_device_desc byt_i2c_dev_desc = {
109 .clk_required = true,
110 .prv_offset = 0x800,
111 .shared_clock = &i2c_clock,
112};
113
66static const struct acpi_device_id acpi_lpss_device_ids[] = { 114static const struct acpi_device_id acpi_lpss_device_ids[] = {
67 /* Generic LPSS devices */ 115 /* Generic LPSS devices */
68 { "INTL9C60", (unsigned long)&lpss_dma_desc }, 116 { "INTL9C60", (unsigned long)&lpss_dma_desc },
@@ -77,6 +125,13 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
77 { "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, 125 { "INT33C6", (unsigned long)&lpt_sdio_dev_desc },
78 { "INT33C7", }, 126 { "INT33C7", },
79 127
128 /* BayTrail LPSS devices */
129 { "80860F0A", (unsigned long)&byt_uart_dev_desc },
130 { "80860F0E", (unsigned long)&byt_spi_dev_desc },
131 { "80860F14", (unsigned long)&byt_sdio_dev_desc },
132 { "80860F41", (unsigned long)&byt_i2c_dev_desc },
133 { "INT33B2", },
134
80 { } 135 { }
81}; 136};
82 137
@@ -98,7 +153,10 @@ static int register_device_clock(struct acpi_device *adev,
98 struct lpss_private_data *pdata) 153 struct lpss_private_data *pdata)
99{ 154{
100 const struct lpss_device_desc *dev_desc = pdata->dev_desc; 155 const struct lpss_device_desc *dev_desc = pdata->dev_desc;
156 struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
157 struct clk *clk = ERR_PTR(-ENODEV);
101 struct lpss_clk_data *clk_data; 158 struct lpss_clk_data *clk_data;
159 const char *parent;
102 160
103 if (!lpss_clk_dev) 161 if (!lpss_clk_dev)
104 lpt_register_clock_device(); 162 lpt_register_clock_device();
@@ -117,14 +175,30 @@ static int register_device_clock(struct acpi_device *adev,
117 || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) 175 || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
118 return -ENODATA; 176 return -ENODATA;
119 177
120 pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), 178 parent = clk_data->name;
121 clk_data->name, 0, 179
122 pdata->mmio_base + dev_desc->prv_offset, 180 if (shared_clock) {
123 0, 0, NULL); 181 clk = shared_clock->clk;
124 if (IS_ERR(pdata->clk)) 182 if (!clk) {
125 return PTR_ERR(pdata->clk); 183 clk = clk_register_fixed_rate(NULL, shared_clock->name,
184 "lpss_clk", 0,
185 shared_clock->rate);
186 shared_clock->clk = clk;
187 }
188 parent = shared_clock->name;
189 }
190
191 if (dev_desc->clk_gate) {
192 clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0,
193 pdata->mmio_base + dev_desc->prv_offset,
194 0, 0, NULL);
195 pdata->clk = clk;
196 }
197
198 if (IS_ERR(clk))
199 return PTR_ERR(clk);
126 200
127 clk_register_clkdev(pdata->clk, NULL, dev_name(&adev->dev)); 201 clk_register_clkdev(clk, NULL, dev_name(&adev->dev));
128 return 0; 202 return 0;
129} 203}
130 204
diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c
index 4f45eee9e33b..812f83f8b0c6 100644
--- a/drivers/clk/x86/clk-lpt.c
+++ b/drivers/clk/x86/clk-lpt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Intel Lynxpoint LPSS clocks. 2 * Intel Low Power Subsystem clocks.
3 * 3 *
4 * Copyright (C) 2013, Intel Corporation 4 * Copyright (C) 2013, Intel Corporation
5 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> 5 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
@@ -18,8 +18,6 @@
18#include <linux/platform_data/clk-lpss.h> 18#include <linux/platform_data/clk-lpss.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#define PRV_CLOCK_PARAMS 0x800
22
23static int lpt_clk_probe(struct platform_device *pdev) 21static int lpt_clk_probe(struct platform_device *pdev)
24{ 22{
25 struct lpss_clk_data *drvdata; 23 struct lpss_clk_data *drvdata;