aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-06-03 17:12:09 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-06-03 17:12:09 -0400
commit864e055f44a5701cb033bf3afa2b6cc37ddba678 (patch)
tree9843c97302482f2a5da16c3c89bdeceec280e8fb
parent6ad29246e3053085fdf28b5aa2a248ec787b3446 (diff)
parent3022f4de491c096650d55ae9d562a9c811830724 (diff)
Merge branch 'acpi-lpss'
* acpi-lpss: ACPI / LPSS: support for fractional divider clock ACPI / LPSS: custom power domain for LPSS
-rw-r--r--drivers/acpi/acpi_lpss.c232
1 files changed, 202 insertions, 30 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 0e9c0d38b85c..db362a96c38e 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/platform_data/clk-lpss.h> 20#include <linux/platform_data/clk-lpss.h>
21#include <linux/pm_runtime.h> 21#include <linux/pm_runtime.h>
22#include <linux/delay.h>
22 23
23#include "internal.h" 24#include "internal.h"
24 25
@@ -28,6 +29,7 @@ ACPI_MODULE_NAME("acpi_lpss");
28#define LPSS_LTR_SIZE 0x18 29#define LPSS_LTR_SIZE 0x18
29 30
30/* Offsets relative to LPSS_PRIVATE_OFFSET */ 31/* Offsets relative to LPSS_PRIVATE_OFFSET */
32#define LPSS_CLK_DIVIDER_DEF_MASK (BIT(1) | BIT(16))
31#define LPSS_GENERAL 0x08 33#define LPSS_GENERAL 0x08
32#define LPSS_GENERAL_LTR_MODE_SW BIT(2) 34#define LPSS_GENERAL_LTR_MODE_SW BIT(2)
33#define LPSS_GENERAL_UART_RTS_OVRD BIT(3) 35#define LPSS_GENERAL_UART_RTS_OVRD BIT(3)
@@ -43,6 +45,8 @@ ACPI_MODULE_NAME("acpi_lpss");
43#define LPSS_TX_INT 0x20 45#define LPSS_TX_INT 0x20
44#define LPSS_TX_INT_MASK BIT(1) 46#define LPSS_TX_INT_MASK BIT(1)
45 47
48#define LPSS_PRV_REG_COUNT 9
49
46struct lpss_shared_clock { 50struct lpss_shared_clock {
47 const char *name; 51 const char *name;
48 unsigned long rate; 52 unsigned long rate;
@@ -57,7 +61,9 @@ struct lpss_device_desc {
57 bool ltr_required; 61 bool ltr_required;
58 unsigned int prv_offset; 62 unsigned int prv_offset;
59 size_t prv_size_override; 63 size_t prv_size_override;
64 bool clk_divider;
60 bool clk_gate; 65 bool clk_gate;
66 bool save_ctx;
61 struct lpss_shared_clock *shared_clock; 67 struct lpss_shared_clock *shared_clock;
62 void (*setup)(struct lpss_private_data *pdata); 68 void (*setup)(struct lpss_private_data *pdata);
63}; 69};
@@ -72,6 +78,7 @@ struct lpss_private_data {
72 resource_size_t mmio_size; 78 resource_size_t mmio_size;
73 struct clk *clk; 79 struct clk *clk;
74 const struct lpss_device_desc *dev_desc; 80 const struct lpss_device_desc *dev_desc;
81 u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
75}; 82};
76 83
77static void lpss_uart_setup(struct lpss_private_data *pdata) 84static void lpss_uart_setup(struct lpss_private_data *pdata)
@@ -92,6 +99,14 @@ static struct lpss_device_desc lpt_dev_desc = {
92 .clk_required = true, 99 .clk_required = true,
93 .prv_offset = 0x800, 100 .prv_offset = 0x800,
94 .ltr_required = true, 101 .ltr_required = true,
102 .clk_divider = true,
103 .clk_gate = true,
104};
105
106static struct lpss_device_desc lpt_i2c_dev_desc = {
107 .clk_required = true,
108 .prv_offset = 0x800,
109 .ltr_required = true,
95 .clk_gate = true, 110 .clk_gate = true,
96}; 111};
97 112
@@ -99,6 +114,7 @@ static struct lpss_device_desc lpt_uart_dev_desc = {
99 .clk_required = true, 114 .clk_required = true,
100 .prv_offset = 0x800, 115 .prv_offset = 0x800,
101 .ltr_required = true, 116 .ltr_required = true,
117 .clk_divider = true,
102 .clk_gate = true, 118 .clk_gate = true,
103 .setup = lpss_uart_setup, 119 .setup = lpss_uart_setup,
104}; 120};
@@ -116,32 +132,25 @@ static struct lpss_shared_clock pwm_clock = {
116 132
117static struct lpss_device_desc byt_pwm_dev_desc = { 133static struct lpss_device_desc byt_pwm_dev_desc = {
118 .clk_required = true, 134 .clk_required = true,
135 .save_ctx = true,
119 .shared_clock = &pwm_clock, 136 .shared_clock = &pwm_clock,
120}; 137};
121 138
122static struct lpss_shared_clock uart_clock = {
123 .name = "uart_clk",
124 .rate = 44236800,
125};
126
127static struct lpss_device_desc byt_uart_dev_desc = { 139static struct lpss_device_desc byt_uart_dev_desc = {
128 .clk_required = true, 140 .clk_required = true,
129 .prv_offset = 0x800, 141 .prv_offset = 0x800,
142 .clk_divider = true,
130 .clk_gate = true, 143 .clk_gate = true,
131 .shared_clock = &uart_clock, 144 .save_ctx = true,
132 .setup = lpss_uart_setup, 145 .setup = lpss_uart_setup,
133}; 146};
134 147
135static struct lpss_shared_clock spi_clock = {
136 .name = "spi_clk",
137 .rate = 50000000,
138};
139
140static struct lpss_device_desc byt_spi_dev_desc = { 148static struct lpss_device_desc byt_spi_dev_desc = {
141 .clk_required = true, 149 .clk_required = true,
142 .prv_offset = 0x400, 150 .prv_offset = 0x400,
151 .clk_divider = true,
143 .clk_gate = true, 152 .clk_gate = true,
144 .shared_clock = &spi_clock, 153 .save_ctx = true,
145}; 154};
146 155
147static struct lpss_device_desc byt_sdio_dev_desc = { 156static struct lpss_device_desc byt_sdio_dev_desc = {
@@ -156,6 +165,7 @@ static struct lpss_shared_clock i2c_clock = {
156static struct lpss_device_desc byt_i2c_dev_desc = { 165static struct lpss_device_desc byt_i2c_dev_desc = {
157 .clk_required = true, 166 .clk_required = true,
158 .prv_offset = 0x800, 167 .prv_offset = 0x800,
168 .save_ctx = true,
159 .shared_clock = &i2c_clock, 169 .shared_clock = &i2c_clock,
160}; 170};
161 171
@@ -166,8 +176,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
166 /* Lynxpoint LPSS devices */ 176 /* Lynxpoint LPSS devices */
167 { "INT33C0", (unsigned long)&lpt_dev_desc }, 177 { "INT33C0", (unsigned long)&lpt_dev_desc },
168 { "INT33C1", (unsigned long)&lpt_dev_desc }, 178 { "INT33C1", (unsigned long)&lpt_dev_desc },
169 { "INT33C2", (unsigned long)&lpt_dev_desc }, 179 { "INT33C2", (unsigned long)&lpt_i2c_dev_desc },
170 { "INT33C3", (unsigned long)&lpt_dev_desc }, 180 { "INT33C3", (unsigned long)&lpt_i2c_dev_desc },
171 { "INT33C4", (unsigned long)&lpt_uart_dev_desc }, 181 { "INT33C4", (unsigned long)&lpt_uart_dev_desc },
172 { "INT33C5", (unsigned long)&lpt_uart_dev_desc }, 182 { "INT33C5", (unsigned long)&lpt_uart_dev_desc },
173 { "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, 183 { "INT33C6", (unsigned long)&lpt_sdio_dev_desc },
@@ -183,8 +193,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
183 193
184 { "INT3430", (unsigned long)&lpt_dev_desc }, 194 { "INT3430", (unsigned long)&lpt_dev_desc },
185 { "INT3431", (unsigned long)&lpt_dev_desc }, 195 { "INT3431", (unsigned long)&lpt_dev_desc },
186 { "INT3432", (unsigned long)&lpt_dev_desc }, 196 { "INT3432", (unsigned long)&lpt_i2c_dev_desc },
187 { "INT3433", (unsigned long)&lpt_dev_desc }, 197 { "INT3433", (unsigned long)&lpt_i2c_dev_desc },
188 { "INT3434", (unsigned long)&lpt_uart_dev_desc }, 198 { "INT3434", (unsigned long)&lpt_uart_dev_desc },
189 { "INT3435", (unsigned long)&lpt_uart_dev_desc }, 199 { "INT3435", (unsigned long)&lpt_uart_dev_desc },
190 { "INT3436", (unsigned long)&lpt_sdio_dev_desc }, 200 { "INT3436", (unsigned long)&lpt_sdio_dev_desc },
@@ -212,9 +222,11 @@ static int register_device_clock(struct acpi_device *adev,
212{ 222{
213 const struct lpss_device_desc *dev_desc = pdata->dev_desc; 223 const struct lpss_device_desc *dev_desc = pdata->dev_desc;
214 struct lpss_shared_clock *shared_clock = dev_desc->shared_clock; 224 struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
225 const char *devname = dev_name(&adev->dev);
215 struct clk *clk = ERR_PTR(-ENODEV); 226 struct clk *clk = ERR_PTR(-ENODEV);
216 struct lpss_clk_data *clk_data; 227 struct lpss_clk_data *clk_data;
217 const char *parent; 228 const char *parent, *clk_name;
229 void __iomem *prv_base;
218 230
219 if (!lpss_clk_dev) 231 if (!lpss_clk_dev)
220 lpt_register_clock_device(); 232 lpt_register_clock_device();
@@ -225,7 +237,7 @@ static int register_device_clock(struct acpi_device *adev,
225 237
226 if (dev_desc->clkdev_name) { 238 if (dev_desc->clkdev_name) {
227 clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name, 239 clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
228 dev_name(&adev->dev)); 240 devname);
229 return 0; 241 return 0;
230 } 242 }
231 243
@@ -234,6 +246,7 @@ static int register_device_clock(struct acpi_device *adev,
234 return -ENODATA; 246 return -ENODATA;
235 247
236 parent = clk_data->name; 248 parent = clk_data->name;
249 prv_base = pdata->mmio_base + dev_desc->prv_offset;
237 250
238 if (shared_clock) { 251 if (shared_clock) {
239 clk = shared_clock->clk; 252 clk = shared_clock->clk;
@@ -247,16 +260,41 @@ static int register_device_clock(struct acpi_device *adev,
247 } 260 }
248 261
249 if (dev_desc->clk_gate) { 262 if (dev_desc->clk_gate) {
250 clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0, 263 clk = clk_register_gate(NULL, devname, parent, 0,
251 pdata->mmio_base + dev_desc->prv_offset, 264 prv_base, 0, 0, NULL);
252 0, 0, NULL); 265 parent = devname;
253 pdata->clk = clk; 266 }
267
268 if (dev_desc->clk_divider) {
269 /* Prevent division by zero */
270 if (!readl(prv_base))
271 writel(LPSS_CLK_DIVIDER_DEF_MASK, prv_base);
272
273 clk_name = kasprintf(GFP_KERNEL, "%s-div", devname);
274 if (!clk_name)
275 return -ENOMEM;
276 clk = clk_register_fractional_divider(NULL, clk_name, parent,
277 0, prv_base,
278 1, 15, 16, 15, 0, NULL);
279 parent = clk_name;
280
281 clk_name = kasprintf(GFP_KERNEL, "%s-update", devname);
282 if (!clk_name) {
283 kfree(parent);
284 return -ENOMEM;
285 }
286 clk = clk_register_gate(NULL, clk_name, parent,
287 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
288 prv_base, 31, 0, NULL);
289 kfree(parent);
290 kfree(clk_name);
254 } 291 }
255 292
256 if (IS_ERR(clk)) 293 if (IS_ERR(clk))
257 return PTR_ERR(clk); 294 return PTR_ERR(clk);
258 295
259 clk_register_clkdev(clk, NULL, dev_name(&adev->dev)); 296 pdata->clk = clk;
297 clk_register_clkdev(clk, NULL, devname);
260 return 0; 298 return 0;
261} 299}
262 300
@@ -454,6 +492,126 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val)
454 } 492 }
455} 493}
456 494
495#ifdef CONFIG_PM
496/**
497 * acpi_lpss_save_ctx() - Save the private registers of LPSS device
498 * @dev: LPSS device
499 *
500 * Most LPSS devices have private registers which may loose their context when
501 * the device is powered down. acpi_lpss_save_ctx() saves those registers into
502 * prv_reg_ctx array.
503 */
504static void acpi_lpss_save_ctx(struct device *dev)
505{
506 struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
507 unsigned int i;
508
509 for (i = 0; i < LPSS_PRV_REG_COUNT; i++) {
510 unsigned long offset = i * sizeof(u32);
511
512 pdata->prv_reg_ctx[i] = __lpss_reg_read(pdata, offset);
513 dev_dbg(dev, "saving 0x%08x from LPSS reg at offset 0x%02lx\n",
514 pdata->prv_reg_ctx[i], offset);
515 }
516}
517
518/**
519 * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device
520 * @dev: LPSS device
521 *
522 * Restores the registers that were previously stored with acpi_lpss_save_ctx().
523 */
524static void acpi_lpss_restore_ctx(struct device *dev)
525{
526 struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
527 unsigned int i;
528
529 /*
530 * The following delay is needed or the subsequent write operations may
531 * fail. The LPSS devices are actually PCI devices and the PCI spec
532 * expects 10ms delay before the device can be accessed after D3 to D0
533 * transition.
534 */
535 msleep(10);
536
537 for (i = 0; i < LPSS_PRV_REG_COUNT; i++) {
538 unsigned long offset = i * sizeof(u32);
539
540 __lpss_reg_write(pdata->prv_reg_ctx[i], pdata, offset);
541 dev_dbg(dev, "restoring 0x%08x to LPSS reg at offset 0x%02lx\n",
542 pdata->prv_reg_ctx[i], offset);
543 }
544}
545
546#ifdef CONFIG_PM_SLEEP
547static int acpi_lpss_suspend_late(struct device *dev)
548{
549 int ret = pm_generic_suspend_late(dev);
550
551 if (ret)
552 return ret;
553
554 acpi_lpss_save_ctx(dev);
555 return acpi_dev_suspend_late(dev);
556}
557
558static int acpi_lpss_restore_early(struct device *dev)
559{
560 int ret = acpi_dev_resume_early(dev);
561
562 if (ret)
563 return ret;
564
565 acpi_lpss_restore_ctx(dev);
566 return pm_generic_resume_early(dev);
567}
568#endif /* CONFIG_PM_SLEEP */
569
570#ifdef CONFIG_PM_RUNTIME
571static int acpi_lpss_runtime_suspend(struct device *dev)
572{
573 int ret = pm_generic_runtime_suspend(dev);
574
575 if (ret)
576 return ret;
577
578 acpi_lpss_save_ctx(dev);
579 return acpi_dev_runtime_suspend(dev);
580}
581
582static int acpi_lpss_runtime_resume(struct device *dev)
583{
584 int ret = acpi_dev_runtime_resume(dev);
585
586 if (ret)
587 return ret;
588
589 acpi_lpss_restore_ctx(dev);
590 return pm_generic_runtime_resume(dev);
591}
592#endif /* CONFIG_PM_RUNTIME */
593#endif /* CONFIG_PM */
594
595static struct dev_pm_domain acpi_lpss_pm_domain = {
596 .ops = {
597#ifdef CONFIG_PM_SLEEP
598 .suspend_late = acpi_lpss_suspend_late,
599 .restore_early = acpi_lpss_restore_early,
600 .prepare = acpi_subsys_prepare,
601 .complete = acpi_subsys_complete,
602 .suspend = acpi_subsys_suspend,
603 .resume_early = acpi_subsys_resume_early,
604 .freeze = acpi_subsys_freeze,
605 .poweroff = acpi_subsys_suspend,
606 .poweroff_late = acpi_subsys_suspend_late,
607#endif
608#ifdef CONFIG_PM_RUNTIME
609 .runtime_suspend = acpi_lpss_runtime_suspend,
610 .runtime_resume = acpi_lpss_runtime_resume,
611#endif
612 },
613};
614
457static int acpi_lpss_platform_notify(struct notifier_block *nb, 615static int acpi_lpss_platform_notify(struct notifier_block *nb,
458 unsigned long action, void *data) 616 unsigned long action, void *data)
459{ 617{
@@ -461,7 +619,6 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
461 struct lpss_private_data *pdata; 619 struct lpss_private_data *pdata;
462 struct acpi_device *adev; 620 struct acpi_device *adev;
463 const struct acpi_device_id *id; 621 const struct acpi_device_id *id;
464 int ret = 0;
465 622
466 id = acpi_match_device(acpi_lpss_device_ids, &pdev->dev); 623 id = acpi_match_device(acpi_lpss_device_ids, &pdev->dev);
467 if (!id || !id->driver_data) 624 if (!id || !id->driver_data)
@@ -471,7 +628,7 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
471 return 0; 628 return 0;
472 629
473 pdata = acpi_driver_data(adev); 630 pdata = acpi_driver_data(adev);
474 if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required) 631 if (!pdata || !pdata->mmio_base)
475 return 0; 632 return 0;
476 633
477 if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { 634 if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
@@ -479,12 +636,27 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
479 return 0; 636 return 0;
480 } 637 }
481 638
482 if (action == BUS_NOTIFY_ADD_DEVICE) 639 switch (action) {
483 ret = sysfs_create_group(&pdev->dev.kobj, &lpss_attr_group); 640 case BUS_NOTIFY_BOUND_DRIVER:
484 else if (action == BUS_NOTIFY_DEL_DEVICE) 641 if (pdata->dev_desc->save_ctx)
485 sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); 642 pdev->dev.pm_domain = &acpi_lpss_pm_domain;
643 break;
644 case BUS_NOTIFY_UNBOUND_DRIVER:
645 if (pdata->dev_desc->save_ctx)
646 pdev->dev.pm_domain = NULL;
647 break;
648 case BUS_NOTIFY_ADD_DEVICE:
649 if (pdata->dev_desc->ltr_required)
650 return sysfs_create_group(&pdev->dev.kobj,
651 &lpss_attr_group);
652 case BUS_NOTIFY_DEL_DEVICE:
653 if (pdata->dev_desc->ltr_required)
654 sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
655 default:
656 break;
657 }
486 658
487 return ret; 659 return 0;
488} 660}
489 661
490static struct notifier_block acpi_lpss_nb = { 662static struct notifier_block acpi_lpss_nb = {