tangled
alpha
login
or
join now
tjh.dev
/
kernel
1
fork
atom
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge branch 'acpi-lpss' into pm-runtime
Rafael J. Wysocki
11 years ago
4bea2b4c
d30d819d
+76
-29
2 changed files
expand all
collapse all
unified
split
drivers
acpi
acpi_lpss.c
dma
dw
core.c
+65
-29
drivers/acpi/acpi_lpss.c
reviewed
···
1
1
/*
2
2
* ACPI support for Intel Lynxpoint LPSS.
3
3
*
4
4
-
* Copyright (C) 2013, Intel Corporation
4
4
+
* Copyright (C) 2013, 2014, Intel Corporation
5
5
* Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
6
6
* Rafael J. Wysocki <rafael.j.wysocki@intel.com>
7
7
*
···
60
60
#define LPSS_CLK_DIVIDER BIT(2)
61
61
#define LPSS_LTR BIT(3)
62
62
#define LPSS_SAVE_CTX BIT(4)
63
63
+
#define LPSS_DEV_PROXY BIT(5)
64
64
+
#define LPSS_PROXY_REQ BIT(6)
63
65
64
66
struct lpss_private_data;
65
67
···
72
70
void (*setup)(struct lpss_private_data *pdata);
73
71
};
74
72
73
73
+
static struct device *proxy_device;
74
74
+
75
75
static struct lpss_device_desc lpss_dma_desc = {
76
76
-
.flags = LPSS_CLK,
76
76
+
.flags = LPSS_CLK | LPSS_PROXY_REQ,
77
77
};
78
78
79
79
struct lpss_private_data {
···
150
146
};
151
147
152
148
static struct lpss_device_desc byt_uart_dev_desc = {
153
153
-
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
149
149
+
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX |
150
150
+
LPSS_DEV_PROXY,
154
151
.prv_offset = 0x800,
155
152
.setup = lpss_uart_setup,
156
153
};
157
154
158
155
static struct lpss_device_desc byt_spi_dev_desc = {
159
159
-
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
156
156
+
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX |
157
157
+
LPSS_DEV_PROXY,
160
158
.prv_offset = 0x400,
161
159
};
162
160
163
161
static struct lpss_device_desc byt_sdio_dev_desc = {
164
164
-
.flags = LPSS_CLK,
162
162
+
.flags = LPSS_CLK | LPSS_DEV_PROXY,
165
163
};
166
164
167
165
static struct lpss_device_desc byt_i2c_dev_desc = {
168
168
-
.flags = LPSS_CLK | LPSS_SAVE_CTX,
166
166
+
.flags = LPSS_CLK | LPSS_SAVE_CTX | LPSS_DEV_PROXY,
169
167
.prv_offset = 0x800,
170
168
.setup = byt_i2c_setup,
171
169
};
···
374
368
adev->driver_data = pdata;
375
369
pdev = acpi_create_platform_device(adev);
376
370
if (!IS_ERR_OR_NULL(pdev)) {
371
371
+
if (!proxy_device && dev_desc->flags & LPSS_DEV_PROXY)
372
372
+
proxy_device = &pdev->dev;
377
373
return 1;
378
374
}
379
375
···
507
499
/**
508
500
* acpi_lpss_save_ctx() - Save the private registers of LPSS device
509
501
* @dev: LPSS device
502
502
+
* @pdata: pointer to the private data of the LPSS device
510
503
*
511
504
* Most LPSS devices have private registers which may loose their context when
512
505
* the device is powered down. acpi_lpss_save_ctx() saves those registers into
513
506
* prv_reg_ctx array.
514
507
*/
515
515
-
static void acpi_lpss_save_ctx(struct device *dev)
508
508
+
static void acpi_lpss_save_ctx(struct device *dev,
509
509
+
struct lpss_private_data *pdata)
516
510
{
517
517
-
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
518
511
unsigned int i;
519
512
520
513
for (i = 0; i < LPSS_PRV_REG_COUNT; i++) {
···
530
521
/**
531
522
* acpi_lpss_restore_ctx() - Restore the private registers of LPSS device
532
523
* @dev: LPSS device
524
524
+
* @pdata: pointer to the private data of the LPSS device
533
525
*
534
526
* Restores the registers that were previously stored with acpi_lpss_save_ctx().
535
527
*/
536
536
-
static void acpi_lpss_restore_ctx(struct device *dev)
528
528
+
static void acpi_lpss_restore_ctx(struct device *dev,
529
529
+
struct lpss_private_data *pdata)
537
530
{
538
538
-
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
539
531
unsigned int i;
540
532
541
533
/*
···
559
549
#ifdef CONFIG_PM_SLEEP
560
550
static int acpi_lpss_suspend_late(struct device *dev)
561
551
{
562
562
-
int ret = pm_generic_suspend_late(dev);
552
552
+
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
553
553
+
int ret;
563
554
555
555
+
ret = pm_generic_suspend_late(dev);
564
556
if (ret)
565
557
return ret;
566
558
567
567
-
acpi_lpss_save_ctx(dev);
559
559
+
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
560
560
+
acpi_lpss_save_ctx(dev, pdata);
561
561
+
568
562
return acpi_dev_suspend_late(dev);
569
563
}
570
564
571
565
static int acpi_lpss_resume_early(struct device *dev)
572
566
{
573
573
-
int ret = acpi_dev_resume_early(dev);
567
567
+
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
568
568
+
int ret;
574
569
570
570
+
ret = acpi_dev_resume_early(dev);
575
571
if (ret)
576
572
return ret;
577
573
578
578
-
acpi_lpss_restore_ctx(dev);
574
574
+
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
575
575
+
acpi_lpss_restore_ctx(dev, pdata);
576
576
+
579
577
return pm_generic_resume_early(dev);
580
578
}
581
579
#endif /* CONFIG_PM_SLEEP */
···
591
573
#ifdef CONFIG_PM_RUNTIME
592
574
static int acpi_lpss_runtime_suspend(struct device *dev)
593
575
{
594
594
-
int ret = pm_generic_runtime_suspend(dev);
576
576
+
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
577
577
+
int ret;
595
578
579
579
+
ret = pm_generic_runtime_suspend(dev);
596
580
if (ret)
597
581
return ret;
598
582
599
599
-
acpi_lpss_save_ctx(dev);
600
600
-
return acpi_dev_runtime_suspend(dev);
583
583
+
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
584
584
+
acpi_lpss_save_ctx(dev, pdata);
585
585
+
586
586
+
ret = acpi_dev_runtime_suspend(dev);
587
587
+
if (ret)
588
588
+
return ret;
589
589
+
590
590
+
if (pdata->dev_desc->flags & LPSS_PROXY_REQ && proxy_device)
591
591
+
return pm_runtime_put_sync_suspend(proxy_device);
592
592
+
593
593
+
return 0;
601
594
}
602
595
603
596
static int acpi_lpss_runtime_resume(struct device *dev)
604
597
{
605
605
-
int ret = acpi_dev_runtime_resume(dev);
598
598
+
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
599
599
+
int ret;
606
600
601
601
+
if (pdata->dev_desc->flags & LPSS_PROXY_REQ && proxy_device) {
602
602
+
ret = pm_runtime_get_sync(proxy_device);
603
603
+
if (ret)
604
604
+
return ret;
605
605
+
}
606
606
+
607
607
+
ret = acpi_dev_runtime_resume(dev);
607
608
if (ret)
608
609
return ret;
609
610
610
610
-
acpi_lpss_restore_ctx(dev);
611
611
+
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
612
612
+
acpi_lpss_restore_ctx(dev, pdata);
613
613
+
611
614
return pm_generic_runtime_resume(dev);
612
615
}
613
616
#endif /* CONFIG_PM_RUNTIME */
···
670
631
return 0;
671
632
672
633
pdata = acpi_driver_data(adev);
673
673
-
if (!pdata || !pdata->mmio_base)
634
634
+
if (!pdata)
674
635
return 0;
675
636
676
676
-
if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
637
637
+
if (pdata->mmio_base &&
638
638
+
pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
677
639
dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n");
678
640
return 0;
679
641
}
680
642
681
643
switch (action) {
682
682
-
case BUS_NOTIFY_BOUND_DRIVER:
683
683
-
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
684
684
-
pdev->dev.pm_domain = &acpi_lpss_pm_domain;
685
685
-
break;
686
686
-
case BUS_NOTIFY_UNBOUND_DRIVER:
687
687
-
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
688
688
-
pdev->dev.pm_domain = NULL;
689
689
-
break;
690
644
case BUS_NOTIFY_ADD_DEVICE:
645
645
+
pdev->dev.pm_domain = &acpi_lpss_pm_domain;
691
646
if (pdata->dev_desc->flags & LPSS_LTR)
692
647
return sysfs_create_group(&pdev->dev.kobj,
693
648
&lpss_attr_group);
649
649
+
break;
694
650
case BUS_NOTIFY_DEL_DEVICE:
695
651
if (pdata->dev_desc->flags & LPSS_LTR)
696
652
sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
653
653
+
pdev->dev.pm_domain = NULL;
654
654
+
break;
697
655
default:
698
656
break;
699
657
}
+11
drivers/dma/dw/core.c
reviewed
···
22
22
#include <linux/mm.h>
23
23
#include <linux/module.h>
24
24
#include <linux/slab.h>
25
25
+
#include <linux/pm_runtime.h>
25
26
26
27
#include "../dmaengine.h"
27
28
#include "internal.h"
···
1505
1504
dw->regs = chip->regs;
1506
1505
chip->dw = dw;
1507
1506
1507
1507
+
pm_runtime_enable(chip->dev);
1508
1508
+
pm_runtime_get_sync(chip->dev);
1509
1509
+
1508
1510
dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
1509
1511
autocfg = dw_params >> DW_PARAMS_EN & 0x1;
1510
1512
···
1671
1667
dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
1672
1668
nr_channels);
1673
1669
1670
1670
+
pm_runtime_put_sync_suspend(chip->dev);
1671
1671
+
1674
1672
return 0;
1675
1673
1676
1674
err_dma_register:
1677
1675
free_irq(chip->irq, dw);
1678
1676
err_pdata:
1677
1677
+
pm_runtime_put_sync_suspend(chip->dev);
1679
1678
return err;
1680
1679
}
1681
1680
EXPORT_SYMBOL_GPL(dw_dma_probe);
···
1687
1680
{
1688
1681
struct dw_dma *dw = chip->dw;
1689
1682
struct dw_dma_chan *dwc, *_dwc;
1683
1683
+
1684
1684
+
pm_runtime_get_sync(chip->dev);
1690
1685
1691
1686
dw_dma_off(dw);
1692
1687
dma_async_device_unregister(&dw->dma);
···
1702
1693
channel_clear_bit(dw, CH_EN, dwc->mask);
1703
1694
}
1704
1695
1696
1696
+
pm_runtime_put_sync_suspend(chip->dev);
1697
1697
+
pm_runtime_disable(chip->dev);
1705
1698
return 0;
1706
1699
}
1707
1700
EXPORT_SYMBOL_GPL(dw_dma_remove);