Skip to content

Commit

Permalink
Merge branches 'pm-pci', 'acpi-pm', 'pm-sleep' and 'pm-avs'
Browse files Browse the repository at this point in the history
* pm-pci:
  PCI / PM: Clean up outdated comments in pci_target_state()
  PCI / PM: Do not clear state_saved for devices that remain suspended

* acpi-pm:
  ACPI: EC: Dispatch the EC GPE directly on s2idle wake
  ACPICA: Introduce acpi_dispatch_gpe()

* pm-sleep:
  PM / hibernate: Fix oops at snapshot_write()
  PM / wakeup: Make s2idle_lock a RAW_SPINLOCK
  PM / s2idle: Make s2idle_wait_head swait based
  PM / wakeup: Make events_lock a RAW_SPINLOCK
  PM / suspend: Prevent might sleep splats

* pm-avs:
  PM / AVS: rockchip-io: add io selectors and supplies for PX30
  • Loading branch information
Rafael J. Wysocki committed Jun 4, 2018
5 parents 601ef1f + 60ee031 + 68e2201 + fc14eeb + b8281fa commit a24e16b
Showing 16 changed files with 171 additions and 26 deletions.
15 changes: 15 additions & 0 deletions Documentation/devicetree/bindings/power/rockchip-io-domain.txt
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@ SoC is on the same page.

Required properties:
- compatible: should be one of:
- "rockchip,px30-io-voltage-domain" for px30
- "rockchip,px30-pmu-io-voltage-domain" for px30 pmu-domains
- "rockchip,rk3188-io-voltage-domain" for rk3188
- "rockchip,rk3228-io-voltage-domain" for rk3228
- "rockchip,rk3288-io-voltage-domain" for rk3288
@@ -51,6 +53,19 @@ a phandle the relevant regulator. All specified supplies must be able
to report their voltage. The IO Voltage Domain for any non-specified
supplies will be not be touched.

Possible supplies for PX30:
- vccio6-supply: The supply connected to VCCIO6.
- vccio1-supply: The supply connected to VCCIO1.
- vccio2-supply: The supply connected to VCCIO2.
- vccio3-supply: The supply connected to VCCIO3.
- vccio4-supply: The supply connected to VCCIO4.
- vccio5-supply: The supply connected to VCCIO5.
- vccio-oscgpi-supply: The supply connected to VCCIO_OSCGPI.

Possible supplies for PX30 pmu-domains:
- pmuio1-supply: The supply connected to PMUIO1.
- pmuio2-supply: The supply connected to PMUIO2.

Possible supplies for rk3188:
- ap0-supply: The supply connected to AP0_VCC.
- ap1-supply: The supply connected to AP1_VCC.
6 changes: 6 additions & 0 deletions drivers/acpi/acpica/evgpe.c
Original file line number Diff line number Diff line change
@@ -634,6 +634,12 @@ acpi_ev_detect_gpe(struct acpi_namespace_node *gpe_device,

flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);

if (!gpe_event_info) {
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info)
goto error_exit;
}

/* Get the info block for the entire GPE register */

gpe_register_info = gpe_event_info->register_info;
22 changes: 22 additions & 0 deletions drivers/acpi/acpica/evxfgpe.c
Original file line number Diff line number Diff line change
@@ -637,6 +637,28 @@ acpi_get_gpe_status(acpi_handle gpe_device,

ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)

/*******************************************************************************
*
* FUNCTION: acpi_gispatch_gpe
*
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
* gpe_number - GPE level within the GPE block
*
* RETURN: None
*
* DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
* (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
*
******************************************************************************/
void acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number)
{
ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);

acpi_ev_detect_gpe(gpe_device, NULL, gpe_number);
}

ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe)

/*******************************************************************************
*
* FUNCTION: acpi_finish_gpe
6 changes: 6 additions & 0 deletions drivers/acpi/ec.c
Original file line number Diff line number Diff line change
@@ -1034,6 +1034,12 @@ void acpi_ec_unblock_transactions(void)
acpi_ec_start(first_ec, true);
}

void acpi_ec_dispatch_gpe(void)
{
if (first_ec)
acpi_dispatch_gpe(NULL, first_ec->gpe);
}

/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
1 change: 1 addition & 0 deletions drivers/acpi/internal.h
Original file line number Diff line number Diff line change
@@ -188,6 +188,7 @@ int acpi_ec_ecdt_probe(void);
int acpi_ec_dsdt_probe(void);
void acpi_ec_block_transactions(void);
void acpi_ec_unblock_transactions(void);
void acpi_ec_dispatch_gpe(void);
int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
acpi_handle handle, acpi_ec_query_func func,
void *data);
7 changes: 7 additions & 0 deletions drivers/acpi/sleep.c
Original file line number Diff line number Diff line change
@@ -989,6 +989,13 @@ static void acpi_s2idle_wake(void)
!irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) {
pm_system_cancel_wakeup();
s2idle_wakeup = true;
/*
* On some platforms with the LPS0 _DSM device noirq resume
* takes too much time for EC wakeup events to survive, so look
* for them now.
*/
if (lps0_device_handle)
acpi_ec_dispatch_gpe();
}
}

18 changes: 9 additions & 9 deletions drivers/base/power/wakeup.c
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ static void split_counters(unsigned int *cnt, unsigned int *inpr)
/* A preserved old value of the events counter. */
static unsigned int saved_count;

static DEFINE_SPINLOCK(events_lock);
static DEFINE_RAW_SPINLOCK(events_lock);

static void pm_wakeup_timer_fn(struct timer_list *t);

@@ -184,9 +184,9 @@ void wakeup_source_add(struct wakeup_source *ws)
timer_setup(&ws->timer, pm_wakeup_timer_fn, 0);
ws->active = false;

spin_lock_irqsave(&events_lock, flags);
raw_spin_lock_irqsave(&events_lock, flags);
list_add_rcu(&ws->entry, &wakeup_sources);
spin_unlock_irqrestore(&events_lock, flags);
raw_spin_unlock_irqrestore(&events_lock, flags);
}
EXPORT_SYMBOL_GPL(wakeup_source_add);

@@ -201,9 +201,9 @@ void wakeup_source_remove(struct wakeup_source *ws)
if (WARN_ON(!ws))
return;

spin_lock_irqsave(&events_lock, flags);
raw_spin_lock_irqsave(&events_lock, flags);
list_del_rcu(&ws->entry);
spin_unlock_irqrestore(&events_lock, flags);
raw_spin_unlock_irqrestore(&events_lock, flags);
synchronize_srcu(&wakeup_srcu);
}
EXPORT_SYMBOL_GPL(wakeup_source_remove);
@@ -842,15 +842,15 @@ bool pm_wakeup_pending(void)
unsigned long flags;
bool ret = false;

spin_lock_irqsave(&events_lock, flags);
raw_spin_lock_irqsave(&events_lock, flags);
if (events_check_enabled) {
unsigned int cnt, inpr;

split_counters(&cnt, &inpr);
ret = (cnt != saved_count || inpr > 0);
events_check_enabled = !ret;
}
spin_unlock_irqrestore(&events_lock, flags);
raw_spin_unlock_irqrestore(&events_lock, flags);

if (ret) {
pr_debug("PM: Wakeup pending, aborting suspend\n");
@@ -939,13 +939,13 @@ bool pm_save_wakeup_count(unsigned int count)
unsigned long flags;

events_check_enabled = false;
spin_lock_irqsave(&events_lock, flags);
raw_spin_lock_irqsave(&events_lock, flags);
split_counters(&cnt, &inpr);
if (cnt == count && inpr == 0) {
saved_count = count;
events_check_enabled = true;
}
spin_unlock_irqrestore(&events_lock, flags);
raw_spin_unlock_irqrestore(&events_lock, flags);
return events_check_enabled;
}

5 changes: 3 additions & 2 deletions drivers/pci/pci-driver.c
Original file line number Diff line number Diff line change
@@ -753,10 +753,11 @@ static int pci_pm_suspend(struct device *dev)
* better to resume the device from runtime suspend here.
*/
if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
!pci_dev_keep_suspended(pci_dev))
!pci_dev_keep_suspended(pci_dev)) {
pm_runtime_resume(dev);
pci_dev->state_saved = false;
}

pci_dev->state_saved = false;
if (pm->suspend) {
pci_power_t prev = pci_dev->current_state;
int error;
6 changes: 2 additions & 4 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
@@ -2025,8 +2025,7 @@ static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup)

if (platform_pci_power_manageable(dev)) {
/*
* Call the platform to choose the target state of the device
* and enable wake-up from this state if supported.
* Call the platform to find the target state for the device.
*/
pci_power_t state = platform_pci_choose_state(dev);

@@ -2059,8 +2058,7 @@ static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup)
if (wakeup) {
/*
* Find the deepest state from which the device can generate
* wake-up events, make it the target state and enable device
* to generate PME#.
* PME#.
*/
if (dev->pme_support) {
while (target_state
68 changes: 68 additions & 0 deletions drivers/power/avs/rockchip-io-domain.c
Original file line number Diff line number Diff line change
@@ -39,6 +39,10 @@
#define MAX_VOLTAGE_1_8 1980000
#define MAX_VOLTAGE_3_3 3600000

#define PX30_IO_VSEL 0x180
#define PX30_IO_VSEL_VCCIO6_SRC BIT(0)
#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1

#define RK3288_SOC_CON2 0x24c
#define RK3288_SOC_CON2_FLASH0 BIT(7)
#define RK3288_SOC_FLASH_SUPPLY_NUM 2
@@ -151,6 +155,25 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
return NOTIFY_OK;
}

static void px30_iodomain_init(struct rockchip_iodomain *iod)
{
int ret;
u32 val;

/* if no VCCIO0 supply we should leave things alone */
if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
return;

/*
* set vccio0 iodomain to also use this framework
* instead of a special gpio.
*/
val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
if (ret < 0)
dev_warn(iod->dev, "couldn't update vccio0 ctrl\n");
}

static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
{
int ret;
@@ -227,6 +250,43 @@ static void rk3399_pmu_iodomain_init(struct rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
}

static const struct rockchip_iodomain_soc_data soc_data_px30 = {
.grf_offset = 0x180,
.supply_names = {
NULL,
"vccio6",
"vccio1",
"vccio2",
"vccio3",
"vccio4",
"vccio5",
"vccio-oscgpi",
},
.init = px30_iodomain_init,
};

static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
.grf_offset = 0x100,
.supply_names = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"pmuio1",
"pmuio2",
},
};

/*
* On the rk3188 the io-domains are handled by a shared register with the
* lower 8 bits being still being continuing drive-strength settings.
@@ -380,6 +440,14 @@ static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
};

static const struct of_device_id rockchip_iodomain_match[] = {
{
.compatible = "rockchip,px30-io-voltage-domain",
.data = (void *)&soc_data_px30
},
{
.compatible = "rockchip,px30-pmu-io-voltage-domain",
.data = (void *)&soc_data_px30_pmu
},
{
.compatible = "rockchip,rk3188-io-voltage-domain",
.data = &soc_data_rk3188
1 change: 1 addition & 0 deletions include/acpi/acpixf.h
Original file line number Diff line number Diff line change
@@ -753,6 +753,7 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
u32 gpe_number,
acpi_event_status
*event_status))
ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number))
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void))
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void))
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void))
1 change: 1 addition & 0 deletions include/linux/kernel.h
Original file line number Diff line number Diff line change
@@ -542,6 +542,7 @@ extern enum system_states {
SYSTEM_HALT,
SYSTEM_POWER_OFF,
SYSTEM_RESTART,
SYSTEM_SUSPEND,
} system_state;

/* This cannot be an enum because some may be used in assembly source. */
7 changes: 7 additions & 0 deletions kernel/power/hibernate.c
Original file line number Diff line number Diff line change
@@ -287,6 +287,8 @@ static int create_image(int platform_mode)

local_irq_disable();

system_state = SYSTEM_SUSPEND;

error = syscore_suspend();
if (error) {
pr_err("Some system devices failed to power down, aborting hibernation\n");
@@ -317,6 +319,7 @@ static int create_image(int platform_mode)
syscore_resume();

Enable_irqs:
system_state = SYSTEM_RUNNING;
local_irq_enable();

Enable_cpus:
@@ -445,6 +448,7 @@ static int resume_target_kernel(bool platform_mode)
goto Enable_cpus;

local_irq_disable();
system_state = SYSTEM_SUSPEND;

error = syscore_suspend();
if (error)
@@ -478,6 +482,7 @@ static int resume_target_kernel(bool platform_mode)
syscore_resume();

Enable_irqs:
system_state = SYSTEM_RUNNING;
local_irq_enable();

Enable_cpus:
@@ -563,6 +568,7 @@ int hibernation_platform_enter(void)
goto Enable_cpus;

local_irq_disable();
system_state = SYSTEM_SUSPEND;
syscore_suspend();
if (pm_wakeup_pending()) {
error = -EAGAIN;
@@ -575,6 +581,7 @@ int hibernation_platform_enter(void)

Power_up:
syscore_resume();
system_state = SYSTEM_RUNNING;
local_irq_enable();

Enable_cpus:
Loading

0 comments on commit a24e16b

Please sign in to comment.