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()
Unified · Split
| @@ -105,7 +105,7 @@ static void lpss_uart_setup(struct lpss_private_data *pdata) · 104 unmodified lines | |||
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void byt_i2c_setup(struct lpss_private_data *pdata) | 108 | static void lpss_deassert_reset(struct lpss_private_data *pdata) |
| 109 | { | 109 | { |
| 110 | unsigned int offset; | 110 | unsigned int offset; |
| 111 | u32 val; | 111 | u32 val; |
| @@ -114,9 +114,18 @@ static void byt_i2c_setup(struct lpss_private_data *pdata) · 2 unmodified lines | |||
| 114 | val = readl(pdata->mmio_base + offset); | 114 | val = readl(pdata->mmio_base + offset); |
| 115 | val |= LPSS_RESETS_RESET_APB | LPSS_RESETS_RESET_FUNC; | 115 | val |= LPSS_RESETS_RESET_APB | LPSS_RESETS_RESET_FUNC; |
| 116 | writel(val, pdata->mmio_base + offset); | 116 | writel(val, pdata->mmio_base + offset); |
| 117 | } | ||
| 118 | |||
| 119 | #define LPSS_I2C_ENABLE 0x6c | ||
| 120 | |||
| 121 | static void byt_i2c_setup(struct lpss_private_data *pdata) | ||
| 122 | { | ||
| 123 | lpss_deassert_reset(pdata); | ||
| 117 | 124 | ||
| 118 | if (readl(pdata->mmio_base + pdata->dev_desc->prv_offset)) | 125 | if (readl(pdata->mmio_base + pdata->dev_desc->prv_offset)) |
| 119 | pdata->fixed_clk_rate = 133000000; | 126 | pdata->fixed_clk_rate = 133000000; |
| 127 | |||
| 128 | writel(0, pdata->mmio_base + LPSS_I2C_ENABLE); | ||
| 120 | } | 129 | } |
| 121 | 130 | ||
| 122 | static struct lpss_device_desc lpt_dev_desc = { | 131 | static struct lpss_device_desc lpt_dev_desc = { |
| @@ -125,7 +134,7 @@ static struct lpss_device_desc lpt_dev_desc = { · 2 unmodified lines | |||
| 125 | }; | 134 | }; |
| 126 | 135 | ||
| 127 | static struct lpss_device_desc lpt_i2c_dev_desc = { | 136 | static struct lpss_device_desc lpt_i2c_dev_desc = { |
| 128 | .flags = LPSS_CLK | LPSS_LTR, | 137 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_LTR, |
| 129 | .prv_offset = 0x800, | 138 | .prv_offset = 0x800, |
| 130 | }; | 139 | }; |
| 131 | 140 | ||
| @@ -166,6 +175,12 @@ static struct lpss_device_desc byt_i2c_dev_desc = { · 34 unmodified lines | |||
| 166 | .setup = byt_i2c_setup, | 175 | .setup = byt_i2c_setup, |
| 167 | }; | 176 | }; |
| 168 | 177 | ||
| 178 | static struct lpss_device_desc bsw_spi_dev_desc = { | ||
| 179 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, | ||
| 180 | .prv_offset = 0x400, | ||
| 181 | .setup = lpss_deassert_reset, | ||
| 182 | }; | ||
| 183 | |||
| 169 | #else | 184 | #else |
| 170 | 185 | ||
| 171 | #define LPSS_ADDR(desc) (0UL) | 186 | #define LPSS_ADDR(desc) (0UL) |
| @@ -198,7 +213,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { · 26 unmodified lines | |||
| 198 | /* Braswell LPSS devices */ | 213 | /* Braswell LPSS devices */ |
| 199 | { "80862288", LPSS_ADDR(byt_pwm_dev_desc) }, | 214 | { "80862288", LPSS_ADDR(byt_pwm_dev_desc) }, |
| 200 | { "8086228A", LPSS_ADDR(byt_uart_dev_desc) }, | 215 | { "8086228A", LPSS_ADDR(byt_uart_dev_desc) }, |
| 201 | { "8086228E", LPSS_ADDR(byt_spi_dev_desc) }, | 216 | { "8086228E", LPSS_ADDR(bsw_spi_dev_desc) }, |
| 202 | { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) }, | 217 | { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) }, |
| 203 | 218 | ||
| 204 | { "INT3430", LPSS_ADDR(lpt_dev_desc) }, | 219 | { "INT3430", LPSS_ADDR(lpt_dev_desc) }, |
| @@ -680,7 +680,7 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming) · 679 unmodified lines | |||
| 680 | /* Enable GPE for event processing (SCI_EVT=1) */ | 680 | /* Enable GPE for event processing (SCI_EVT=1) */ |
| 681 | if (!resuming) | 681 | if (!resuming) |
| 682 | acpi_ec_submit_request(ec); | 682 | acpi_ec_submit_request(ec); |
| 683 | pr_info("+++++ EC started +++++\n"); | 683 | pr_debug("EC started\n"); |
| 684 | } | 684 | } |
| 685 | spin_unlock_irqrestore(&ec->lock, flags); | 685 | spin_unlock_irqrestore(&ec->lock, flags); |
| 686 | } | 686 | } |
| @@ -712,7 +712,7 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) · 25 unmodified lines | |||
| 712 | acpi_ec_complete_request(ec); | 712 | acpi_ec_complete_request(ec); |
| 713 | clear_bit(EC_FLAGS_STARTED, &ec->flags); | 713 | clear_bit(EC_FLAGS_STARTED, &ec->flags); |
| 714 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); | 714 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); |
| 715 | pr_info("+++++ EC stopped +++++\n"); | 715 | pr_debug("EC stopped\n"); |
| 716 | } | 716 | } |
| 717 | spin_unlock_irqrestore(&ec->lock, flags); | 717 | spin_unlock_irqrestore(&ec->lock, flags); |
| 718 | } | 718 | } |
| @@ -46,7 +46,7 @@ static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io) · 45 unmodified lines | |||
| 46 | if (len && reslen && reslen == len && start <= end) | 46 | if (len && reslen && reslen == len && start <= end) |
| 47 | return true; | 47 | return true; |
| 48 | 48 | ||
| 49 | pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n", | 49 | pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n", |
| 50 | io ? "io" : "mem", start, end, len); | 50 | io ? "io" : "mem", start, end, len); |
| 51 | 51 | ||
| 52 | return false; | 52 | return false; |
| @@ -540,6 +540,15 @@ static struct dmi_system_id video_dmi_table[] __initdata = { · 539 unmodified lines | |||
| 540 | DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"), | 540 | DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"), |
| 541 | }, | 541 | }, |
| 542 | }, | 542 | }, |
| 543 | { | ||
| 544 | /* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */ | ||
| 545 | .callback = video_disable_native_backlight, | ||
| 546 | .ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D", | ||
| 547 | .matches = { | ||
| 548 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
| 549 | DMI_MATCH(DMI_PRODUCT_NAME, "900X3C/900X3D/900X3E/900X4C/900X4D"), | ||
| 550 | }, | ||
| 551 | }, | ||
| 543 | 552 | ||
| 544 | { | 553 | { |
| 545 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ | 554 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ |
| @@ -263,7 +263,7 @@ out: · 262 unmodified lines | |||
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | #ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE | 265 | #ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE |
| 266 | static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) | 266 | static void s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) |
| 267 | { | 267 | { |
| 268 | int count, v, i, found; | 268 | int count, v, i, found; |
| 269 | struct cpufreq_frequency_table *pos; | 269 | struct cpufreq_frequency_table *pos; |
| @@ -333,7 +333,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = { · 63 unmodified lines | |||
| 333 | .notifier_call = s3c2416_cpufreq_reboot_notifier_evt, | 333 | .notifier_call = s3c2416_cpufreq_reboot_notifier_evt, |
| 334 | }; | 334 | }; |
| 335 | 335 | ||
| 336 | static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) | 336 | static int s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) |
| 337 | { | 337 | { |
| 338 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; | 338 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; |
| 339 | struct cpufreq_frequency_table *pos; | 339 | struct cpufreq_frequency_table *pos; |
| @@ -144,11 +144,6 @@ static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg) · 143 unmodified lines | |||
| 144 | (cfg->info->set_fvco)(cfg); | 144 | (cfg->info->set_fvco)(cfg); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static inline void s3c_cpufreq_resume_clocks(void) | ||
| 148 | { | ||
| 149 | cpu_cur.info->resume_clocks(); | ||
| 150 | } | ||
| 151 | |||
| 152 | static inline void s3c_cpufreq_updateclk(struct clk *clk, | 147 | static inline void s3c_cpufreq_updateclk(struct clk *clk, |
| 153 | unsigned int freq) | 148 | unsigned int freq) |
| 154 | { | 149 | { |
| @@ -417,9 +412,6 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy) · 262 unmodified lines | |||
| 417 | 412 | ||
| 418 | last_target = ~0; /* invalidate last_target setting */ | 413 | last_target = ~0; /* invalidate last_target setting */ |
| 419 | 414 | ||
| 420 | /* first, find out what speed we resumed at. */ | ||
| 421 | s3c_cpufreq_resume_clocks(); | ||
| 422 | |||
| 423 | /* whilst we will be called later on, we try and re-set the | 415 | /* whilst we will be called later on, we try and re-set the |
| 424 | * cpu frequencies as soon as possible so that we do not end | 416 | * cpu frequencies as soon as possible so that we do not end |
| 425 | * up resuming devices and then immediately having to re-set | 417 | * up resuming devices and then immediately having to re-set |
| @@ -454,7 +446,7 @@ static struct cpufreq_driver s3c24xx_driver = { · 28 unmodified lines | |||
| 454 | }; | 446 | }; |
| 455 | 447 | ||
| 456 | 448 | ||
| 457 | int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info) | 449 | int s3c_cpufreq_register(struct s3c_cpufreq_info *info) |
| 458 | { | 450 | { |
| 459 | if (!info || !info->name) { | 451 | if (!info || !info->name) { |
| 460 | printk(KERN_ERR "%s: failed to pass valid information\n", | 452 | printk(KERN_ERR "%s: failed to pass valid information\n", |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/notifier.h> | 13 | #include <linux/notifier.h> |
| 14 | #include <linux/clockchips.h> | 14 | #include <linux/clockchips.h> |
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/slab.h> | ||
| 16 | 17 | ||
| 17 | #include <asm/machdep.h> | 18 | #include <asm/machdep.h> |
| 18 | #include <asm/firmware.h> | 19 | #include <asm/firmware.h> |
| @@ -158,70 +159,83 @@ static int powernv_add_idle_states(void) · 139 unmodified lines | |||
| 158 | struct device_node *power_mgt; | 159 | struct device_node *power_mgt; |
| 159 | int nr_idle_states = 1; /* Snooze */ | 160 | int nr_idle_states = 1; /* Snooze */ |
| 160 | int dt_idle_states; | 161 | int dt_idle_states; |
| 161 | const __be32 *idle_state_flags; | 162 | u32 *latency_ns, *residency_ns, *flags; |
| 162 | const __be32 *idle_state_latency; | 163 | int i, rc; |
| 163 | u32 len_flags, flags, latency_ns; | ||
| 164 | int i; | ||
| 165 | 164 | ||
| 166 | /* Currently we have snooze statically defined */ | 165 | /* Currently we have snooze statically defined */ |
| 167 | 166 | ||
| 168 | power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); | 167 | power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); |
| 169 | if (!power_mgt) { | 168 | if (!power_mgt) { |
| 170 | pr_warn("opal: PowerMgmt Node not found\n"); | 169 | pr_warn("opal: PowerMgmt Node not found\n"); |
| 171 | return nr_idle_states; | 170 | goto out; |
| 172 | } | 171 | } |
| 173 | 172 | ||
| 174 | idle_state_flags = of_get_property(power_mgt, "ibm,cpu-idle-state-flags", &len_flags); | 173 | /* Read values of any property to determine the num of idle states */ |
| 175 | if (!idle_state_flags) { | 174 | dt_idle_states = of_property_count_u32_elems(power_mgt, "ibm,cpu-idle-state-flags"); |
| 176 | pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n"); | 175 | if (dt_idle_states < 0) { |
| 177 | return nr_idle_states; | 176 | pr_warn("cpuidle-powernv: no idle states found in the DT\n"); |
| 177 | goto out; | ||
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | idle_state_latency = of_get_property(power_mgt, | 180 | flags = kzalloc(sizeof(*flags) * dt_idle_states, GFP_KERNEL); |
| 181 | "ibm,cpu-idle-state-latencies-ns", NULL); | 181 | if (of_property_read_u32_array(power_mgt, |
| 182 | if (!idle_state_latency) { | 182 | "ibm,cpu-idle-state-flags", flags, dt_idle_states)) { |
| 183 | pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-latencies-ns\n"); | 183 | pr_warn("cpuidle-powernv : missing ibm,cpu-idle-state-flags in DT\n"); |
| 184 | return nr_idle_states; | 184 | goto out_free_flags; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | dt_idle_states = len_flags / sizeof(u32); | 187 | latency_ns = kzalloc(sizeof(*latency_ns) * dt_idle_states, GFP_KERNEL); |
| 188 | rc = of_property_read_u32_array(power_mgt, | ||
| 189 | "ibm,cpu-idle-state-latencies-ns", latency_ns, dt_idle_states); | ||
| 190 | if (rc) { | ||
| 191 | pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n"); | ||
| 192 | goto out_free_latency; | ||
| 193 | } | ||
| 188 | 194 | ||
| 189 | for (i = 0; i < dt_idle_states; i++) { | 195 | residency_ns = kzalloc(sizeof(*residency_ns) * dt_idle_states, GFP_KERNEL); |
| 196 | rc = of_property_read_u32_array(power_mgt, | ||
| 197 | "ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states); | ||
| 190 | 198 | ||
| 191 | flags = be32_to_cpu(idle_state_flags[i]); | 199 | for (i = 0; i < dt_idle_states; i++) { |
| 192 | 200 | ||
| 193 | /* Cpuidle accepts exit_latency in us and we estimate | 201 | /* |
| 194 | * target residency to be 10x exit_latency | 202 | * Cpuidle accepts exit_latency and target_residency in us. |
| 203 | * Use default target_residency values if f/w does not expose it. | ||
| 195 | */ | 204 | */ |
| 196 | latency_ns = be32_to_cpu(idle_state_latency[i]); | 205 | if (flags[i] & OPAL_PM_NAP_ENABLED) { |
| 197 | if (flags & OPAL_PM_NAP_ENABLED) { | ||
| 198 | /* Add NAP state */ | 206 | /* Add NAP state */ |
| 199 | strcpy(powernv_states[nr_idle_states].name, "Nap"); | 207 | strcpy(powernv_states[nr_idle_states].name, "Nap"); |
| 200 | strcpy(powernv_states[nr_idle_states].desc, "Nap"); | 208 | strcpy(powernv_states[nr_idle_states].desc, "Nap"); |
| 201 | powernv_states[nr_idle_states].flags = 0; | 209 | powernv_states[nr_idle_states].flags = 0; |
| 202 | powernv_states[nr_idle_states].exit_latency = | 210 | powernv_states[nr_idle_states].target_residency = 100; |
| 203 | ((unsigned int)latency_ns) / 1000; | ||
| 204 | powernv_states[nr_idle_states].target_residency = | ||
| 205 | ((unsigned int)latency_ns / 100); | ||
| 206 | powernv_states[nr_idle_states].enter = &nap_loop; | 211 | powernv_states[nr_idle_states].enter = &nap_loop; |
| 207 | nr_idle_states++; | 212 | } else if (flags[i] & OPAL_PM_SLEEP_ENABLED || |
| 208 | } | 213 | flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) { |
| 209 | |||
| 210 | if (flags & OPAL_PM_SLEEP_ENABLED || | ||
| 211 | flags & OPAL_PM_SLEEP_ENABLED_ER1) { | ||
| 212 | /* Add FASTSLEEP state */ | 214 | /* Add FASTSLEEP state */ |
| 213 | strcpy(powernv_states[nr_idle_states].name, "FastSleep"); | 215 | strcpy(powernv_states[nr_idle_states].name, "FastSleep"); |
| 214 | strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); | 216 | strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); |
| 215 | powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP; | 217 | powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP; |
| 216 | powernv_states[nr_idle_states].exit_latency = | 218 | powernv_states[nr_idle_states].target_residency = 300000; |
| 217 | ((unsigned int)latency_ns) / 1000; | ||
| 218 | powernv_states[nr_idle_states].target_residency = | ||
| 219 | ((unsigned int)latency_ns / 100); | ||
| 220 | powernv_states[nr_idle_states].enter = &fastsleep_loop; | 219 | powernv_states[nr_idle_states].enter = &fastsleep_loop; |
| 221 | nr_idle_states++; | ||
| 222 | } | 220 | } |
| 221 | |||
| 222 | powernv_states[nr_idle_states].exit_latency = | ||
| 223 | ((unsigned int)latency_ns[i]) / 1000; | ||
| 224 | |||
| 225 | if (!rc) { | ||
| 226 | powernv_states[nr_idle_states].target_residency = | ||
| 227 | ((unsigned int)residency_ns[i]) / 1000; | ||
| 228 | } | ||
| 229 | |||
| 230 | nr_idle_states++; | ||
| 223 | } | 231 | } |
| 224 | 232 | ||
| 233 | kfree(residency_ns); | ||
| 234 | out_free_latency: | ||
| 235 | kfree(latency_ns); | ||
| 236 | out_free_flags: | ||
| 237 | kfree(flags); | ||
| 238 | out: | ||
| 225 | return nr_idle_states; | 239 | return nr_idle_states; |
| 226 | } | 240 | } |
| 227 | 241 | ||
| @@ -179,8 +179,9 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res) · 178 unmodified lines | |||
| 179 | /* check if the resource is already in use, skip if the | 179 | /* check if the resource is already in use, skip if the |
| 180 | * device is active because it itself may be in use */ | 180 | * device is active because it itself may be in use */ |
| 181 | if (!dev->active) { | 181 | if (!dev->active) { |
| 182 | if (__check_region(&ioport_resource, *port, length(port, end))) | 182 | if (!request_region(*port, length(port, end), "pnp")) |
| 183 | return 0; | 183 | return 0; |
| 184 | release_region(*port, length(port, end)); | ||
| 184 | } | 185 | } |
| 185 | 186 | ||
| 186 | /* check if the resource is reserved */ | 187 | /* check if the resource is reserved */ |
| @@ -241,8 +242,9 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res) · 54 unmodified lines | |||
| 241 | /* check if the resource is already in use, skip if the | 242 | /* check if the resource is already in use, skip if the |
| 242 | * device is active because it itself may be in use */ | 243 | * device is active because it itself may be in use */ |
| 243 | if (!dev->active) { | 244 | if (!dev->active) { |
| 244 | if (check_mem_region(*addr, length(addr, end))) | 245 | if (!request_mem_region(*addr, length(addr, end), "pnp")) |
| 245 | return 0; | 246 | return 0; |
| 247 | release_mem_region(*addr, length(addr, end)); | ||
| 246 | } | 248 | } |
| 247 | 249 | ||
| 248 | /* check if the resource is reserved */ | 250 | /* check if the resource is reserved */ |