Skip to content

Commit 4aa8c70

Browse files
committed
Merge branches 'acpi-pm', 'acpi-pci', 'acpi-sysfs' and 'acpi-tables'
Merge power management, PCI and sysfs-related material and changes related to handling ACPI tables for 5.19-rc1: - Improve debug messages in the ACPI device PM code (Rafael Wysocki). - Block ASUS B1400CEAE from suspend to idle by default (Mario Limonciello). - Improve handling of PCI devices that are in D3cold during system initialization (Rafael Wysocki). - Fix BERT error region memory mapping (Lorenzo Pieralisi). - Add support for NVIDIA 16550-compatible port subtype to the SPCR parsing code (Jeff Brasen). - Use static for BGRT_SHOW kobj_attribute defines (Tom Rix). - Fix missing prototype warning for acpi_agdi_init() (Ilkka Koskinen). * acpi-pm: ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default ACPI: PM: Always print final debug message in acpi_device_set_power() ACPI: PM: Unify debug messages in acpi_device_set_power() ACPI: PM: Change pr_fmt() in device_pm.c ACPI: PM: Convert debug message in acpi_device_get_power() * acpi-pci: ACPI: bus: Avoid non-ACPI device objects in walks over children PCI: ACPI: PM: Power up devices in D3cold before scanning them ACPI: PM: Introduce acpi_dev_power_up_children_with_adr() ACPI: bus: Introduce acpi_dev_for_each_child() * acpi-sysfs: ACPI: sysfs: Fix BERT error region memory mapping * acpi-tables: ACPI: AGDI: Fix missing prototype warning for acpi_agdi_init() ACPI: BGRT: use static for BGRT_SHOW kobj_attribute defines ACPI: SPCR: Add support for NVIDIA 16550-compatible port subtype
5 parents ec1ff61 + d528486 + 10fa1b2 + 1bbc217 + 988d7a1 commit 4aa8c70

File tree

10 files changed

+124
-34
lines changed

10 files changed

+124
-34
lines changed

drivers/acpi/arm64/agdi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define pr_fmt(fmt) "ACPI: AGDI: " fmt
1010

1111
#include <linux/acpi.h>
12+
#include <linux/acpi_agdi.h>
1213
#include <linux/arm_sdei.h>
1314
#include <linux/io.h>
1415
#include <linux/kernel.h>

drivers/acpi/bgrt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static struct kobject *bgrt_kobj;
2121
{ \
2222
return sysfs_emit(buf, "%d\n", bgrt_tab._member); \
2323
} \
24-
struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
24+
static struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
2525

2626
BGRT_SHOW(version, version);
2727
BGRT_SHOW(status, status);

drivers/acpi/bus.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,32 @@ int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data)
10701070
}
10711071
EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev);
10721072

1073+
struct acpi_dev_walk_context {
1074+
int (*fn)(struct acpi_device *, void *);
1075+
void *data;
1076+
};
1077+
1078+
static int acpi_dev_for_one_check(struct device *dev, void *context)
1079+
{
1080+
struct acpi_dev_walk_context *adwc = context;
1081+
1082+
if (dev->bus != &acpi_bus_type)
1083+
return 0;
1084+
1085+
return adwc->fn(to_acpi_device(dev), adwc->data);
1086+
}
1087+
1088+
int acpi_dev_for_each_child(struct acpi_device *adev,
1089+
int (*fn)(struct acpi_device *, void *), void *data)
1090+
{
1091+
struct acpi_dev_walk_context adwc = {
1092+
.fn = fn,
1093+
.data = data,
1094+
};
1095+
1096+
return device_for_each_child(&adev->dev, &adwc, acpi_dev_for_one_check);
1097+
}
1098+
10731099
/* --------------------------------------------------------------------------
10741100
Initialization/Cleanup
10751101
-------------------------------------------------------------------------- */

drivers/acpi/device_pm.c

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1111
*/
1212

13-
#define pr_fmt(fmt) "ACPI: PM: " fmt
13+
#define pr_fmt(fmt) "PM: " fmt
1414

1515
#include <linux/acpi.h>
1616
#include <linux/export.h>
@@ -130,8 +130,8 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
130130
*state = result;
131131

132132
out:
133-
dev_dbg(&device->dev, "Device power state is %s\n",
134-
acpi_power_state_string(*state));
133+
acpi_handle_debug(device->handle, "Power state: %s\n",
134+
acpi_power_state_string(*state));
135135

136136
return 0;
137137
}
@@ -173,11 +173,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
173173
/* Make sure this is a valid target state */
174174

175175
/* There is a special case for D0 addressed below. */
176-
if (state > ACPI_STATE_D0 && state == device->power.state) {
177-
dev_dbg(&device->dev, "Device already in %s\n",
178-
acpi_power_state_string(state));
179-
return 0;
180-
}
176+
if (state > ACPI_STATE_D0 && state == device->power.state)
177+
goto no_change;
181178

182179
if (state == ACPI_STATE_D3_COLD) {
183180
/*
@@ -189,17 +186,17 @@ int acpi_device_set_power(struct acpi_device *device, int state)
189186
if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
190187
target_state = state;
191188
} else if (!device->power.states[state].flags.valid) {
192-
dev_warn(&device->dev, "Power state %s not supported\n",
193-
acpi_power_state_string(state));
189+
acpi_handle_debug(device->handle, "Power state %s not supported\n",
190+
acpi_power_state_string(state));
194191
return -ENODEV;
195192
}
196193

197-
if (!device->power.flags.ignore_parent &&
198-
device->parent && (state < device->parent->power.state)) {
199-
dev_warn(&device->dev,
200-
"Cannot transition to power state %s for parent in %s\n",
201-
acpi_power_state_string(state),
202-
acpi_power_state_string(device->parent->power.state));
194+
if (!device->power.flags.ignore_parent && device->parent &&
195+
state < device->parent->power.state) {
196+
acpi_handle_debug(device->handle,
197+
"Cannot transition to %s for parent in %s\n",
198+
acpi_power_state_string(state),
199+
acpi_power_state_string(device->parent->power.state));
203200
return -ENODEV;
204201
}
205202

@@ -216,9 +213,10 @@ int acpi_device_set_power(struct acpi_device *device, int state)
216213
* (deeper) states to higher-power (shallower) states.
217214
*/
218215
if (state < device->power.state) {
219-
dev_warn(&device->dev, "Cannot transition from %s to %s\n",
220-
acpi_power_state_string(device->power.state),
221-
acpi_power_state_string(state));
216+
acpi_handle_debug(device->handle,
217+
"Cannot transition from %s to %s\n",
218+
acpi_power_state_string(device->power.state),
219+
acpi_power_state_string(state));
222220
return -ENODEV;
223221
}
224222

@@ -248,7 +246,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
248246

249247
/* Nothing to do here if _PSC is not present. */
250248
if (!device->power.flags.explicit_get)
251-
return 0;
249+
goto no_change;
252250

253251
/*
254252
* The power state of the device was set to D0 last
@@ -263,23 +261,29 @@ int acpi_device_set_power(struct acpi_device *device, int state)
263261
*/
264262
result = acpi_dev_pm_explicit_get(device, &psc);
265263
if (result || psc == ACPI_STATE_D0)
266-
return 0;
264+
goto no_change;
267265
}
268266

269267
result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);
270268
}
271269

272-
end:
270+
end:
273271
if (result) {
274-
dev_warn(&device->dev, "Failed to change power state to %s\n",
275-
acpi_power_state_string(target_state));
272+
acpi_handle_debug(device->handle,
273+
"Failed to change power state to %s\n",
274+
acpi_power_state_string(target_state));
276275
} else {
277276
device->power.state = target_state;
278-
dev_dbg(&device->dev, "Power state changed to %s\n",
279-
acpi_power_state_string(target_state));
277+
acpi_handle_debug(device->handle, "Power state changed to %s\n",
278+
acpi_power_state_string(target_state));
280279
}
281280

282281
return result;
282+
283+
no_change:
284+
acpi_handle_debug(device->handle, "Already in %s\n",
285+
acpi_power_state_string(state));
286+
return 0;
283287
}
284288
EXPORT_SYMBOL(acpi_device_set_power);
285289

@@ -425,6 +429,33 @@ bool acpi_bus_power_manageable(acpi_handle handle)
425429
}
426430
EXPORT_SYMBOL(acpi_bus_power_manageable);
427431

432+
static int acpi_power_up_if_adr_present(struct acpi_device *adev, void *not_used)
433+
{
434+
if (!(adev->flags.power_manageable && adev->pnp.type.bus_address))
435+
return 0;
436+
437+
acpi_handle_debug(adev->handle, "Power state: %s\n",
438+
acpi_power_state_string(adev->power.state));
439+
440+
if (adev->power.state == ACPI_STATE_D3_COLD)
441+
return acpi_device_set_power(adev, ACPI_STATE_D0);
442+
443+
return 0;
444+
}
445+
446+
/**
447+
* acpi_dev_power_up_children_with_adr - Power up childres with valid _ADR
448+
* @adev: Parent ACPI device object.
449+
*
450+
* Change the power states of the direct children of @adev that are in D3cold
451+
* and hold valid _ADR objects to D0 in order to allow bus (e.g. PCI)
452+
* enumeration code to access them.
453+
*/
454+
void acpi_dev_power_up_children_with_adr(struct acpi_device *adev)
455+
{
456+
acpi_dev_for_each_child(adev, acpi_power_up_if_adr_present, NULL);
457+
}
458+
428459
#ifdef CONFIG_PM
429460
static DEFINE_MUTEX(acpi_pm_notifier_lock);
430461
static DEFINE_MUTEX(acpi_pm_notifier_install_lock);

drivers/acpi/pci_root.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,8 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
927927
host_bridge->preserve_config = 1;
928928
ACPI_FREE(obj);
929929

930+
acpi_dev_power_up_children_with_adr(device);
931+
930932
pci_scan_child_bus(bus);
931933
pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info,
932934
info);

drivers/acpi/sleep.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,18 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
373373
DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"),
374374
},
375375
},
376+
/*
377+
* ASUS B1400CEAE hangs on resume from suspend (see
378+
* https://bugzilla.kernel.org/show_bug.cgi?id=215742).
379+
*/
380+
{
381+
.callback = init_default_s3,
382+
.ident = "ASUS B1400CEAE",
383+
.matches = {
384+
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
385+
DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK B1400CEAE"),
386+
},
387+
},
376388
{},
377389
};
378390

drivers/acpi/spcr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
142142
case ACPI_DBG2_16550_COMPATIBLE:
143143
case ACPI_DBG2_16550_SUBSET:
144144
case ACPI_DBG2_16550_WITH_GAS:
145+
case ACPI_DBG2_16550_NVIDIA:
145146
uart = "uart";
146147
break;
147148
default:

drivers/acpi/sysfs.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,19 +415,30 @@ static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
415415
loff_t offset, size_t count)
416416
{
417417
struct acpi_data_attr *data_attr;
418-
void *base;
419-
ssize_t rc;
418+
void __iomem *base;
419+
ssize_t size;
420420

421421
data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
422+
size = data_attr->attr.size;
423+
424+
if (offset < 0)
425+
return -EINVAL;
426+
427+
if (offset >= size)
428+
return 0;
422429

423-
base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size);
430+
if (count > size - offset)
431+
count = size - offset;
432+
433+
base = acpi_os_map_iomem(data_attr->addr, size);
424434
if (!base)
425435
return -ENOMEM;
426-
rc = memory_read_from_buffer(buf, count, &offset, base,
427-
data_attr->attr.size);
428-
acpi_os_unmap_memory(base, data_attr->attr.size);
429436

430-
return rc;
437+
memcpy_fromio(buf, base + offset, count);
438+
439+
acpi_os_unmap_iomem(base, size);
440+
441+
return count;
431442
}
432443

433444
static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)

drivers/pci/pci-acpi.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,9 @@ void pci_acpi_setup(struct device *dev, struct acpi_device *adev)
13741374

13751375
acpi_pci_wakeup(pci_dev, false);
13761376
acpi_device_power_add_dependent(adev, dev);
1377+
1378+
if (pci_is_bridge(pci_dev))
1379+
acpi_dev_power_up_children_with_adr(adev);
13771380
}
13781381

13791382
void pci_acpi_cleanup(struct device *dev, struct acpi_device *adev)

include/acpi/acpi_bus.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@ void acpi_initialize_hp_context(struct acpi_device *adev,
481481
extern struct bus_type acpi_bus_type;
482482

483483
int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data);
484+
int acpi_dev_for_each_child(struct acpi_device *adev,
485+
int (*fn)(struct acpi_device *, void *), void *data);
484486

485487
/*
486488
* Events
@@ -522,6 +524,7 @@ int acpi_device_fix_up_power(struct acpi_device *device);
522524
int acpi_bus_update_power(acpi_handle handle, int *state_p);
523525
int acpi_device_update_power(struct acpi_device *device, int *state_p);
524526
bool acpi_bus_power_manageable(acpi_handle handle);
527+
void acpi_dev_power_up_children_with_adr(struct acpi_device *adev);
525528
int acpi_device_power_add_dependent(struct acpi_device *adev,
526529
struct device *dev);
527530
void acpi_device_power_remove_dependent(struct acpi_device *adev,

0 commit comments

Comments
 (0)