Additional power management and ACPI updates for v3.20-rc1
- Revert a recent ACPI LPSS driver commit that prevented the touchpad driver from loading on Dell XPS13 (Jarkko Nikula). - Make the ACPI LPSS driver disable the I2C controllers and deassert SPI host controllers resets at startup on Intel BayTrail and Braswell SoCs in case they have been left in wrong states by the platform firmware which then may casuse fatal controller driver failures during resume from hibernation (Mika Westerberg). - Make two recently added ACPI EC messages look better (Scot Doyle). - Reduce the printk level of a recently added debug message related to ACPI resources that may become noisy in some cases (Rafael J Wysocki). - Add a new ACPI backlight blacklist entry for Samsung Series 9 (900X3C/900X3D/900X3E/900X4C/900X4D) laptops where the native backlight interface doesn't work while the ACPI based one does (Jens Reyer). - Make the PNP sybsystem's core code use __request_region() followed by __release_region() instead of __check_region() which then will allow us to get rid of the latter as it has no more users (Jakub Sitnicki). - Fix a build breakage and an issue with two __init functions that may be called after initialization in the s3c cpufreq driver (Arnd Bergmann). - Make the powernv cpuidle driver read target_residency values for idle states from a Device Tree (as we have the suitable DT bindings for that now) and improve the parsing of the powermgmt DT node in that driver (Preeti U Murthy). / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJU6Ak8AAoJEILEb/54YlRx1IIP/3AJFuLlgQ15rFAMV5c1Wel8 RhyD0JcucgtGu9bLoFj2wMpy/FDv+zpqp4vF5qrgcY3OcKoBYvM18HzDbFyiThqo 4aTZEeuv14ipstBqPwt8aABAjWZ9elEb0h3zuEgekoc9UUpMYzHhSUaKbWzNHfd9 Uba6+aS1haE9zWeVJw+30uWFy42SLgbu1qDWizq/Lg+jUMRJvNsPsDzeTF4mP5Vs aF4BD0Fo9X2spnSYK16dHq08lQ7UzkHCAj9aY8KCHVIWwOOMjM7/kpa0TRNNqIm0 7UIH+ZwX8gGBJ2WQ1vQXESI0veJdH5B+xXtsaxXz+5VEWBI9sf4QjM7bti+HaGSw wgB5bgV3gV9T9uNbmwTCBkC9qRt+6cvqxLvH+z85l/U2cDMr0UqP4YlStqupfWOW fXTUsL7pmy9tKtzeaKzoBxKooRSMZg/GmscHtHlb4Ps+Vu/3vHsw7fJ3cOylvcT1 3IFtTt2JWicKWr3zcDtcqRBSgCLwUgLS8Zh25O7UT9WfNjo897Rccdta1jWvZppQ SLZxBB+SZGWe8s/RucwmYEB4+gKP8dNIPFIuVTK6RkMAnL4Iv13cNR/1X1GyaLpF exvs9i0/bIYVDfRXlVaS3RRSDKKZkNJdddQUD27PrCKRffOezjzBV+gohadXFbbn tkou9vHrphL0Zql/y6Iw =us59 -----END PGP SIGNATURE----- Merge tag 'pm+acpi-3.20-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull one more batch of power management and ACPI updates from Rafael Wysocki: "These are mostly fixes on top of the previously merged recent PM and ACPI material. First, one commit that broke the ACPI LPSS (Low-Power Subsystem) driver on a Dell box is reverted and there are two stable-candidate fixes for that driver. Another fix cleans up two recently added ACPI EC messages that look odd and the printk level of a noisy debug message in the core ACPI resources handling code is reduced. In addition to that we have two stable-candidate fixes for the s3c cpufreq driver, two cpuidle powernv driver updates related to Device Trees and a PNP subsystem cleanup that will allow us to get rid of some old ugliness going forward. Also there is a new blacklist entry for the ACPI backlight code. Specifics: - Revert a recent ACPI LPSS driver commit that prevented the touchpad driver from loading on Dell XPS13 (Jarkko Nikula). - Make the ACPI LPSS driver disable the I2C controllers and deassert SPI host controllers resets at startup on Intel BayTrail and Braswell SoCs in case they have been left in wrong states by the platform firmware which then may casuse fatal controller driver failures during resume from hibernation (Mika Westerberg). - Make two recently added ACPI EC messages look better (Scot Doyle). - Reduce the printk level of a recently added debug message related to ACPI resources that may become noisy in some cases (Rafael J Wysocki). - Add a new ACPI backlight blacklist entry for Samsung Series 9 (900X3C/900X3D/900X3E/900X4C/900X4D) laptops where the native backlight interface doesn't work while the ACPI based one does (Jens Reyer). - Make the PNP sybsystem's core code use __request_region() followed by __release_region() instead of __check_region() which then will allow us to get rid of the latter as it has no more users (Jakub Sitnicki). - Fix a build breakage and an issue with two __init functions that may be called after initialization in the s3c cpufreq driver (Arnd Bergmann). - Make the powernv cpuidle driver read target_residency values for idle states from a Device Tree (as we have the suitable DT bindings for that now) and improve the parsing of the powermgmt DT node in that driver (Preeti U Murthy)" * tag 'pm+acpi-3.20-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpuidle: powernv: Avoid endianness conversions while parsing DT cpufreq: s3c: remove last use of resume_clocks callback cpufreq: s3c: remove incorrect __init annotations ACPI / LPSS: Deassert resets for SPI host controllers on Braswell ACPI / LPSS: Always disable I2C host controllers ACPI / resources: Change pr_info() to pr_debug() for debug information ACPI / video: Disable native backlight on Samsung Series 9 laptops cpuidle: powernv: Read target_residency value of idle states from DT if available Revert "ACPI / LPSS: Remove non-existing clock control from Intel Lynxpoint I2C" ACPI / EC: Remove non-standard log emphasis PNP: Switch from __check_region() to __request_region()
This commit is contained in:
commit
cd50b70ccd
|
@ -105,7 +105,7 @@ static void lpss_uart_setup(struct lpss_private_data *pdata)
|
|||
}
|
||||
}
|
||||
|
||||
static void byt_i2c_setup(struct lpss_private_data *pdata)
|
||||
static void lpss_deassert_reset(struct lpss_private_data *pdata)
|
||||
{
|
||||
unsigned int offset;
|
||||
u32 val;
|
||||
|
@ -114,9 +114,18 @@ static void byt_i2c_setup(struct lpss_private_data *pdata)
|
|||
val = readl(pdata->mmio_base + offset);
|
||||
val |= LPSS_RESETS_RESET_APB | LPSS_RESETS_RESET_FUNC;
|
||||
writel(val, pdata->mmio_base + offset);
|
||||
}
|
||||
|
||||
#define LPSS_I2C_ENABLE 0x6c
|
||||
|
||||
static void byt_i2c_setup(struct lpss_private_data *pdata)
|
||||
{
|
||||
lpss_deassert_reset(pdata);
|
||||
|
||||
if (readl(pdata->mmio_base + pdata->dev_desc->prv_offset))
|
||||
pdata->fixed_clk_rate = 133000000;
|
||||
|
||||
writel(0, pdata->mmio_base + LPSS_I2C_ENABLE);
|
||||
}
|
||||
|
||||
static struct lpss_device_desc lpt_dev_desc = {
|
||||
|
@ -125,7 +134,7 @@ static struct lpss_device_desc lpt_dev_desc = {
|
|||
};
|
||||
|
||||
static struct lpss_device_desc lpt_i2c_dev_desc = {
|
||||
.flags = LPSS_CLK | LPSS_LTR,
|
||||
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_LTR,
|
||||
.prv_offset = 0x800,
|
||||
};
|
||||
|
||||
|
@ -166,6 +175,12 @@ static struct lpss_device_desc byt_i2c_dev_desc = {
|
|||
.setup = byt_i2c_setup,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc bsw_spi_dev_desc = {
|
||||
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
|
||||
.prv_offset = 0x400,
|
||||
.setup = lpss_deassert_reset,
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define LPSS_ADDR(desc) (0UL)
|
||||
|
@ -198,7 +213,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
|||
/* Braswell LPSS devices */
|
||||
{ "80862288", LPSS_ADDR(byt_pwm_dev_desc) },
|
||||
{ "8086228A", LPSS_ADDR(byt_uart_dev_desc) },
|
||||
{ "8086228E", LPSS_ADDR(byt_spi_dev_desc) },
|
||||
{ "8086228E", LPSS_ADDR(bsw_spi_dev_desc) },
|
||||
{ "808622C1", LPSS_ADDR(byt_i2c_dev_desc) },
|
||||
|
||||
{ "INT3430", LPSS_ADDR(lpt_dev_desc) },
|
||||
|
|
|
@ -680,7 +680,7 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming)
|
|||
/* Enable GPE for event processing (SCI_EVT=1) */
|
||||
if (!resuming)
|
||||
acpi_ec_submit_request(ec);
|
||||
pr_info("+++++ EC started +++++\n");
|
||||
pr_debug("EC started\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
|
@ -712,7 +712,7 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
|
|||
acpi_ec_complete_request(ec);
|
||||
clear_bit(EC_FLAGS_STARTED, &ec->flags);
|
||||
clear_bit(EC_FLAGS_STOPPED, &ec->flags);
|
||||
pr_info("+++++ EC stopped +++++\n");
|
||||
pr_debug("EC stopped\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
|
|||
if (len && reslen && reslen == len && start <= end)
|
||||
return true;
|
||||
|
||||
pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
|
||||
pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
|
||||
io ? "io" : "mem", start, end, len);
|
||||
|
||||
return false;
|
||||
|
|
|
@ -540,6 +540,15 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */
|
||||
.callback = video_disable_native_backlight,
|
||||
.ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "900X3C/900X3D/900X3E/900X4C/900X4D"),
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
|
||||
|
|
|
@ -263,7 +263,7 @@ out:
|
|||
}
|
||||
|
||||
#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE
|
||||
static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
|
||||
static void s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
|
||||
{
|
||||
int count, v, i, found;
|
||||
struct cpufreq_frequency_table *pos;
|
||||
|
@ -333,7 +333,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = {
|
|||
.notifier_call = s3c2416_cpufreq_reboot_notifier_evt,
|
||||
};
|
||||
|
||||
static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
|
||||
static int s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
|
||||
struct cpufreq_frequency_table *pos;
|
||||
|
|
|
@ -144,11 +144,6 @@ static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
|
|||
(cfg->info->set_fvco)(cfg);
|
||||
}
|
||||
|
||||
static inline void s3c_cpufreq_resume_clocks(void)
|
||||
{
|
||||
cpu_cur.info->resume_clocks();
|
||||
}
|
||||
|
||||
static inline void s3c_cpufreq_updateclk(struct clk *clk,
|
||||
unsigned int freq)
|
||||
{
|
||||
|
@ -417,9 +412,6 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
|
|||
|
||||
last_target = ~0; /* invalidate last_target setting */
|
||||
|
||||
/* first, find out what speed we resumed at. */
|
||||
s3c_cpufreq_resume_clocks();
|
||||
|
||||
/* whilst we will be called later on, we try and re-set the
|
||||
* cpu frequencies as soon as possible so that we do not end
|
||||
* up resuming devices and then immediately having to re-set
|
||||
|
@ -454,7 +446,7 @@ static struct cpufreq_driver s3c24xx_driver = {
|
|||
};
|
||||
|
||||
|
||||
int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
|
||||
int s3c_cpufreq_register(struct s3c_cpufreq_info *info)
|
||||
{
|
||||
if (!info || !info->name) {
|
||||
printk(KERN_ERR "%s: failed to pass valid information\n",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/notifier.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/firmware.h>
|
||||
|
@ -158,70 +159,83 @@ static int powernv_add_idle_states(void)
|
|||
struct device_node *power_mgt;
|
||||
int nr_idle_states = 1; /* Snooze */
|
||||
int dt_idle_states;
|
||||
const __be32 *idle_state_flags;
|
||||
const __be32 *idle_state_latency;
|
||||
u32 len_flags, flags, latency_ns;
|
||||
int i;
|
||||
u32 *latency_ns, *residency_ns, *flags;
|
||||
int i, rc;
|
||||
|
||||
/* Currently we have snooze statically defined */
|
||||
|
||||
power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
|
||||
if (!power_mgt) {
|
||||
pr_warn("opal: PowerMgmt Node not found\n");
|
||||
return nr_idle_states;
|
||||
goto out;
|
||||
}
|
||||
|
||||
idle_state_flags = of_get_property(power_mgt, "ibm,cpu-idle-state-flags", &len_flags);
|
||||
if (!idle_state_flags) {
|
||||
pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
|
||||
return nr_idle_states;
|
||||
/* Read values of any property to determine the num of idle states */
|
||||
dt_idle_states = of_property_count_u32_elems(power_mgt, "ibm,cpu-idle-state-flags");
|
||||
if (dt_idle_states < 0) {
|
||||
pr_warn("cpuidle-powernv: no idle states found in the DT\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idle_state_latency = of_get_property(power_mgt,
|
||||
"ibm,cpu-idle-state-latencies-ns", NULL);
|
||||
if (!idle_state_latency) {
|
||||
pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-latencies-ns\n");
|
||||
return nr_idle_states;
|
||||
flags = kzalloc(sizeof(*flags) * dt_idle_states, GFP_KERNEL);
|
||||
if (of_property_read_u32_array(power_mgt,
|
||||
"ibm,cpu-idle-state-flags", flags, dt_idle_states)) {
|
||||
pr_warn("cpuidle-powernv : missing ibm,cpu-idle-state-flags in DT\n");
|
||||
goto out_free_flags;
|
||||
}
|
||||
|
||||
dt_idle_states = len_flags / sizeof(u32);
|
||||
latency_ns = kzalloc(sizeof(*latency_ns) * dt_idle_states, GFP_KERNEL);
|
||||
rc = of_property_read_u32_array(power_mgt,
|
||||
"ibm,cpu-idle-state-latencies-ns", latency_ns, dt_idle_states);
|
||||
if (rc) {
|
||||
pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n");
|
||||
goto out_free_latency;
|
||||
}
|
||||
|
||||
residency_ns = kzalloc(sizeof(*residency_ns) * dt_idle_states, GFP_KERNEL);
|
||||
rc = of_property_read_u32_array(power_mgt,
|
||||
"ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states);
|
||||
|
||||
for (i = 0; i < dt_idle_states; i++) {
|
||||
|
||||
flags = be32_to_cpu(idle_state_flags[i]);
|
||||
|
||||
/* Cpuidle accepts exit_latency in us and we estimate
|
||||
* target residency to be 10x exit_latency
|
||||
/*
|
||||
* Cpuidle accepts exit_latency and target_residency in us.
|
||||
* Use default target_residency values if f/w does not expose it.
|
||||
*/
|
||||
latency_ns = be32_to_cpu(idle_state_latency[i]);
|
||||
if (flags & OPAL_PM_NAP_ENABLED) {
|
||||
if (flags[i] & OPAL_PM_NAP_ENABLED) {
|
||||
/* Add NAP state */
|
||||
strcpy(powernv_states[nr_idle_states].name, "Nap");
|
||||
strcpy(powernv_states[nr_idle_states].desc, "Nap");
|
||||
powernv_states[nr_idle_states].flags = 0;
|
||||
powernv_states[nr_idle_states].exit_latency =
|
||||
((unsigned int)latency_ns) / 1000;
|
||||
powernv_states[nr_idle_states].target_residency =
|
||||
((unsigned int)latency_ns / 100);
|
||||
powernv_states[nr_idle_states].target_residency = 100;
|
||||
powernv_states[nr_idle_states].enter = &nap_loop;
|
||||
nr_idle_states++;
|
||||
}
|
||||
|
||||
if (flags & OPAL_PM_SLEEP_ENABLED ||
|
||||
flags & OPAL_PM_SLEEP_ENABLED_ER1) {
|
||||
} else if (flags[i] & OPAL_PM_SLEEP_ENABLED ||
|
||||
flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) {
|
||||
/* Add FASTSLEEP state */
|
||||
strcpy(powernv_states[nr_idle_states].name, "FastSleep");
|
||||
strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
|
||||
powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP;
|
||||
powernv_states[nr_idle_states].exit_latency =
|
||||
((unsigned int)latency_ns) / 1000;
|
||||
powernv_states[nr_idle_states].target_residency =
|
||||
((unsigned int)latency_ns / 100);
|
||||
powernv_states[nr_idle_states].target_residency = 300000;
|
||||
powernv_states[nr_idle_states].enter = &fastsleep_loop;
|
||||
nr_idle_states++;
|
||||
}
|
||||
|
||||
powernv_states[nr_idle_states].exit_latency =
|
||||
((unsigned int)latency_ns[i]) / 1000;
|
||||
|
||||
if (!rc) {
|
||||
powernv_states[nr_idle_states].target_residency =
|
||||
((unsigned int)residency_ns[i]) / 1000;
|
||||
}
|
||||
|
||||
nr_idle_states++;
|
||||
}
|
||||
|
||||
kfree(residency_ns);
|
||||
out_free_latency:
|
||||
kfree(latency_ns);
|
||||
out_free_flags:
|
||||
kfree(flags);
|
||||
out:
|
||||
return nr_idle_states;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,8 +179,9 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res)
|
|||
/* check if the resource is already in use, skip if the
|
||||
* device is active because it itself may be in use */
|
||||
if (!dev->active) {
|
||||
if (__check_region(&ioport_resource, *port, length(port, end)))
|
||||
if (!request_region(*port, length(port, end), "pnp"))
|
||||
return 0;
|
||||
release_region(*port, length(port, end));
|
||||
}
|
||||
|
||||
/* check if the resource is reserved */
|
||||
|
@ -241,8 +242,9 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
|
|||
/* check if the resource is already in use, skip if the
|
||||
* device is active because it itself may be in use */
|
||||
if (!dev->active) {
|
||||
if (check_mem_region(*addr, length(addr, end)))
|
||||
if (!request_mem_region(*addr, length(addr, end), "pnp"))
|
||||
return 0;
|
||||
release_mem_region(*addr, length(addr, end));
|
||||
}
|
||||
|
||||
/* check if the resource is reserved */
|
||||
|
|
Loading…
Reference in New Issue