aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpi_lpss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpi_lpss.c')
-rw-r--r--drivers/acpi/acpi_lpss.c167
1 files changed, 58 insertions, 109 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index b0ea767c8696..93d160661f4c 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -54,55 +54,58 @@ ACPI_MODULE_NAME("acpi_lpss");
54 54
55#define LPSS_PRV_REG_COUNT 9 55#define LPSS_PRV_REG_COUNT 9
56 56
57struct lpss_shared_clock { 57/* LPSS Flags */
58 const char *name; 58#define LPSS_CLK BIT(0)
59 unsigned long rate; 59#define LPSS_CLK_GATE BIT(1)
60 struct clk *clk; 60#define LPSS_CLK_DIVIDER BIT(2)
61}; 61#define LPSS_LTR BIT(3)
62#define LPSS_SAVE_CTX BIT(4)
62 63
63struct lpss_private_data; 64struct lpss_private_data;
64 65
65struct lpss_device_desc { 66struct lpss_device_desc {
66 bool clk_required; 67 unsigned int flags;
67 const char *clkdev_name;
68 bool ltr_required;
69 unsigned int prv_offset; 68 unsigned int prv_offset;
70 size_t prv_size_override; 69 size_t prv_size_override;
71 bool clk_divider;
72 bool clk_gate;
73 bool save_ctx;
74 struct lpss_shared_clock *shared_clock;
75 void (*setup)(struct lpss_private_data *pdata); 70 void (*setup)(struct lpss_private_data *pdata);
76}; 71};
77 72
78static struct lpss_device_desc lpss_dma_desc = { 73static struct lpss_device_desc lpss_dma_desc = {
79 .clk_required = true, 74 .flags = LPSS_CLK,
80 .clkdev_name = "hclk",
81}; 75};
82 76
83struct lpss_private_data { 77struct lpss_private_data {
84 void __iomem *mmio_base; 78 void __iomem *mmio_base;
85 resource_size_t mmio_size; 79 resource_size_t mmio_size;
80 unsigned int fixed_clk_rate;
86 struct clk *clk; 81 struct clk *clk;
87 const struct lpss_device_desc *dev_desc; 82 const struct lpss_device_desc *dev_desc;
88 u32 prv_reg_ctx[LPSS_PRV_REG_COUNT]; 83 u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
89}; 84};
90 85
86/* UART Component Parameter Register */
87#define LPSS_UART_CPR 0xF4
88#define LPSS_UART_CPR_AFCE BIT(4)
89
91static void lpss_uart_setup(struct lpss_private_data *pdata) 90static void lpss_uart_setup(struct lpss_private_data *pdata)
92{ 91{
93 unsigned int offset; 92 unsigned int offset;
94 u32 reg; 93 u32 val;
95 94
96 offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; 95 offset = pdata->dev_desc->prv_offset + LPSS_TX_INT;
97 reg = readl(pdata->mmio_base + offset); 96 val = readl(pdata->mmio_base + offset);
98 writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + offset); 97 writel(val | LPSS_TX_INT_MASK, pdata->mmio_base + offset);
99 98
100 offset = pdata->dev_desc->prv_offset + LPSS_GENERAL; 99 val = readl(pdata->mmio_base + LPSS_UART_CPR);
101 reg = readl(pdata->mmio_base + offset); 100 if (!(val & LPSS_UART_CPR_AFCE)) {
102 writel(reg | LPSS_GENERAL_UART_RTS_OVRD, pdata->mmio_base + offset); 101 offset = pdata->dev_desc->prv_offset + LPSS_GENERAL;
102 val = readl(pdata->mmio_base + offset);
103 val |= LPSS_GENERAL_UART_RTS_OVRD;
104 writel(val, pdata->mmio_base + offset);
105 }
103} 106}
104 107
105static void lpss_i2c_setup(struct lpss_private_data *pdata) 108static void byt_i2c_setup(struct lpss_private_data *pdata)
106{ 109{
107 unsigned int offset; 110 unsigned int offset;
108 u32 val; 111 u32 val;
@@ -111,100 +114,56 @@ static void lpss_i2c_setup(struct lpss_private_data *pdata)
111 val = readl(pdata->mmio_base + offset); 114 val = readl(pdata->mmio_base + offset);
112 val |= LPSS_RESETS_RESET_APB | LPSS_RESETS_RESET_FUNC; 115 val |= LPSS_RESETS_RESET_APB | LPSS_RESETS_RESET_FUNC;
113 writel(val, pdata->mmio_base + offset); 116 writel(val, pdata->mmio_base + offset);
114}
115 117
116static struct lpss_device_desc wpt_dev_desc = { 118 if (readl(pdata->mmio_base + pdata->dev_desc->prv_offset))
117 .clk_required = true, 119 pdata->fixed_clk_rate = 133000000;
118 .prv_offset = 0x800, 120}
119 .ltr_required = true,
120 .clk_divider = true,
121 .clk_gate = true,
122};
123 121
124static struct lpss_device_desc lpt_dev_desc = { 122static struct lpss_device_desc lpt_dev_desc = {
125 .clk_required = true, 123 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR,
126 .prv_offset = 0x800, 124 .prv_offset = 0x800,
127 .ltr_required = true,
128 .clk_divider = true,
129 .clk_gate = true,
130}; 125};
131 126
132static struct lpss_device_desc lpt_i2c_dev_desc = { 127static struct lpss_device_desc lpt_i2c_dev_desc = {
133 .clk_required = true, 128 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_LTR,
134 .prv_offset = 0x800, 129 .prv_offset = 0x800,
135 .ltr_required = true,
136 .clk_gate = true,
137}; 130};
138 131
139static struct lpss_device_desc lpt_uart_dev_desc = { 132static struct lpss_device_desc lpt_uart_dev_desc = {
140 .clk_required = true, 133 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR,
141 .prv_offset = 0x800, 134 .prv_offset = 0x800,
142 .ltr_required = true,
143 .clk_divider = true,
144 .clk_gate = true,
145 .setup = lpss_uart_setup, 135 .setup = lpss_uart_setup,
146}; 136};
147 137
148static struct lpss_device_desc lpt_sdio_dev_desc = { 138static struct lpss_device_desc lpt_sdio_dev_desc = {
139 .flags = LPSS_LTR,
149 .prv_offset = 0x1000, 140 .prv_offset = 0x1000,
150 .prv_size_override = 0x1018, 141 .prv_size_override = 0x1018,
151 .ltr_required = true,
152};
153
154static struct lpss_shared_clock pwm_clock = {
155 .name = "pwm_clk",
156 .rate = 25000000,
157}; 142};
158 143
159static struct lpss_device_desc byt_pwm_dev_desc = { 144static struct lpss_device_desc byt_pwm_dev_desc = {
160 .clk_required = true, 145 .flags = LPSS_SAVE_CTX,
161 .save_ctx = true,
162 .shared_clock = &pwm_clock,
163}; 146};
164 147
165static struct lpss_device_desc byt_uart_dev_desc = { 148static struct lpss_device_desc byt_uart_dev_desc = {
166 .clk_required = true, 149 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
167 .prv_offset = 0x800, 150 .prv_offset = 0x800,
168 .clk_divider = true,
169 .clk_gate = true,
170 .save_ctx = true,
171 .setup = lpss_uart_setup, 151 .setup = lpss_uart_setup,
172}; 152};
173 153
174static struct lpss_device_desc byt_spi_dev_desc = { 154static struct lpss_device_desc byt_spi_dev_desc = {
175 .clk_required = true, 155 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
176 .prv_offset = 0x400, 156 .prv_offset = 0x400,
177 .clk_divider = true,
178 .clk_gate = true,
179 .save_ctx = true,
180}; 157};
181 158
182static struct lpss_device_desc byt_sdio_dev_desc = { 159static struct lpss_device_desc byt_sdio_dev_desc = {
183 .clk_required = true, 160 .flags = LPSS_CLK,
184};
185
186static struct lpss_shared_clock i2c_clock = {
187 .name = "i2c_clk",
188 .rate = 100000000,
189}; 161};
190 162
191static struct lpss_device_desc byt_i2c_dev_desc = { 163static struct lpss_device_desc byt_i2c_dev_desc = {
192 .clk_required = true, 164 .flags = LPSS_CLK | LPSS_SAVE_CTX,
193 .prv_offset = 0x800, 165 .prv_offset = 0x800,
194 .save_ctx = true, 166 .setup = byt_i2c_setup,
195 .shared_clock = &i2c_clock,
196 .setup = lpss_i2c_setup,
197};
198
199static struct lpss_shared_clock bsw_pwm_clock = {
200 .name = "pwm_clk",
201 .rate = 19200000,
202};
203
204static struct lpss_device_desc bsw_pwm_dev_desc = {
205 .clk_required = true,
206 .save_ctx = true,
207 .shared_clock = &bsw_pwm_clock,
208}; 167};
209 168
210#else 169#else
@@ -237,7 +196,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
237 { "INT33FC", }, 196 { "INT33FC", },
238 197
239 /* Braswell LPSS devices */ 198 /* Braswell LPSS devices */
240 { "80862288", LPSS_ADDR(bsw_pwm_dev_desc) }, 199 { "80862288", LPSS_ADDR(byt_pwm_dev_desc) },
241 { "8086228A", LPSS_ADDR(byt_uart_dev_desc) }, 200 { "8086228A", LPSS_ADDR(byt_uart_dev_desc) },
242 { "8086228E", LPSS_ADDR(byt_spi_dev_desc) }, 201 { "8086228E", LPSS_ADDR(byt_spi_dev_desc) },
243 { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) }, 202 { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) },
@@ -251,7 +210,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
251 { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) }, 210 { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) },
252 { "INT3437", }, 211 { "INT3437", },
253 212
254 { "INT3438", LPSS_ADDR(wpt_dev_desc) }, 213 /* Wildcat Point LPSS devices */
214 { "INT3438", LPSS_ADDR(lpt_dev_desc) },
255 215
256 { } 216 { }
257}; 217};
@@ -276,7 +236,6 @@ static int register_device_clock(struct acpi_device *adev,
276 struct lpss_private_data *pdata) 236 struct lpss_private_data *pdata)
277{ 237{
278 const struct lpss_device_desc *dev_desc = pdata->dev_desc; 238 const struct lpss_device_desc *dev_desc = pdata->dev_desc;
279 struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
280 const char *devname = dev_name(&adev->dev); 239 const char *devname = dev_name(&adev->dev);
281 struct clk *clk = ERR_PTR(-ENODEV); 240 struct clk *clk = ERR_PTR(-ENODEV);
282 struct lpss_clk_data *clk_data; 241 struct lpss_clk_data *clk_data;
@@ -289,12 +248,7 @@ static int register_device_clock(struct acpi_device *adev,
289 clk_data = platform_get_drvdata(lpss_clk_dev); 248 clk_data = platform_get_drvdata(lpss_clk_dev);
290 if (!clk_data) 249 if (!clk_data)
291 return -ENODEV; 250 return -ENODEV;
292 251 clk = clk_data->clk;
293 if (dev_desc->clkdev_name) {
294 clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
295 devname);
296 return 0;
297 }
298 252
299 if (!pdata->mmio_base 253 if (!pdata->mmio_base
300 || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) 254 || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
@@ -303,24 +257,19 @@ static int register_device_clock(struct acpi_device *adev,
303 parent = clk_data->name; 257 parent = clk_data->name;
304 prv_base = pdata->mmio_base + dev_desc->prv_offset; 258 prv_base = pdata->mmio_base + dev_desc->prv_offset;
305 259
306 if (shared_clock) { 260 if (pdata->fixed_clk_rate) {
307 clk = shared_clock->clk; 261 clk = clk_register_fixed_rate(NULL, devname, parent, 0,
308 if (!clk) { 262 pdata->fixed_clk_rate);
309 clk = clk_register_fixed_rate(NULL, shared_clock->name, 263 goto out;
310 "lpss_clk", 0,
311 shared_clock->rate);
312 shared_clock->clk = clk;
313 }
314 parent = shared_clock->name;
315 } 264 }
316 265
317 if (dev_desc->clk_gate) { 266 if (dev_desc->flags & LPSS_CLK_GATE) {
318 clk = clk_register_gate(NULL, devname, parent, 0, 267 clk = clk_register_gate(NULL, devname, parent, 0,
319 prv_base, 0, 0, NULL); 268 prv_base, 0, 0, NULL);
320 parent = devname; 269 parent = devname;
321 } 270 }
322 271
323 if (dev_desc->clk_divider) { 272 if (dev_desc->flags & LPSS_CLK_DIVIDER) {
324 /* Prevent division by zero */ 273 /* Prevent division by zero */
325 if (!readl(prv_base)) 274 if (!readl(prv_base))
326 writel(LPSS_CLK_DIVIDER_DEF_MASK, prv_base); 275 writel(LPSS_CLK_DIVIDER_DEF_MASK, prv_base);
@@ -344,7 +293,7 @@ static int register_device_clock(struct acpi_device *adev,
344 kfree(parent); 293 kfree(parent);
345 kfree(clk_name); 294 kfree(clk_name);
346 } 295 }
347 296out:
348 if (IS_ERR(clk)) 297 if (IS_ERR(clk))
349 return PTR_ERR(clk); 298 return PTR_ERR(clk);
350 299
@@ -392,7 +341,10 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
392 341
393 pdata->dev_desc = dev_desc; 342 pdata->dev_desc = dev_desc;
394 343
395 if (dev_desc->clk_required) { 344 if (dev_desc->setup)
345 dev_desc->setup(pdata);
346
347 if (dev_desc->flags & LPSS_CLK) {
396 ret = register_device_clock(adev, pdata); 348 ret = register_device_clock(adev, pdata);
397 if (ret) { 349 if (ret) {
398 /* Skip the device, but continue the namespace scan. */ 350 /* Skip the device, but continue the namespace scan. */
@@ -413,9 +365,6 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
413 goto err_out; 365 goto err_out;
414 } 366 }
415 367
416 if (dev_desc->setup)
417 dev_desc->setup(pdata);
418
419 adev->driver_data = pdata; 368 adev->driver_data = pdata;
420 pdev = acpi_create_platform_device(adev); 369 pdev = acpi_create_platform_device(adev);
421 if (!IS_ERR_OR_NULL(pdev)) { 370 if (!IS_ERR_OR_NULL(pdev)) {
@@ -692,19 +641,19 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
692 641
693 switch (action) { 642 switch (action) {
694 case BUS_NOTIFY_BOUND_DRIVER: 643 case BUS_NOTIFY_BOUND_DRIVER:
695 if (pdata->dev_desc->save_ctx) 644 if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
696 pdev->dev.pm_domain = &acpi_lpss_pm_domain; 645 pdev->dev.pm_domain = &acpi_lpss_pm_domain;
697 break; 646 break;
698 case BUS_NOTIFY_UNBOUND_DRIVER: 647 case BUS_NOTIFY_UNBOUND_DRIVER:
699 if (pdata->dev_desc->save_ctx) 648 if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
700 pdev->dev.pm_domain = NULL; 649 pdev->dev.pm_domain = NULL;
701 break; 650 break;
702 case BUS_NOTIFY_ADD_DEVICE: 651 case BUS_NOTIFY_ADD_DEVICE:
703 if (pdata->dev_desc->ltr_required) 652 if (pdata->dev_desc->flags & LPSS_LTR)
704 return sysfs_create_group(&pdev->dev.kobj, 653 return sysfs_create_group(&pdev->dev.kobj,
705 &lpss_attr_group); 654 &lpss_attr_group);
706 case BUS_NOTIFY_DEL_DEVICE: 655 case BUS_NOTIFY_DEL_DEVICE:
707 if (pdata->dev_desc->ltr_required) 656 if (pdata->dev_desc->flags & LPSS_LTR)
708 sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); 657 sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
709 default: 658 default:
710 break; 659 break;
@@ -721,7 +670,7 @@ static void acpi_lpss_bind(struct device *dev)
721{ 670{
722 struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); 671 struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
723 672
724 if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required) 673 if (!pdata || !pdata->mmio_base || !(pdata->dev_desc->flags & LPSS_LTR))
725 return; 674 return;
726 675
727 if (pdata->mmio_size >= pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) 676 if (pdata->mmio_size >= pdata->dev_desc->prv_offset + LPSS_LTR_SIZE)