mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge tag 'acpi-7.4-rc1' into loongarch-next
LoongArch architecture changes for 7.4 need the acpi changes to add new features, so merge 'acpi-7.4-rc1' to create a base.
This commit is contained in:
commit
15107b81b8
|
|
@ -180,8 +180,10 @@ function are specified using param1::
|
|||
| segment | bus | device | function | reserved |
|
||||
+-------------------------------------------------+
|
||||
|
||||
Anyway, you get the idea, if there's doubt just take a look at the code
|
||||
in drivers/acpi/apei/einj.c.
|
||||
Anyway, you get the idea, if there's doubt just take a look at the code:
|
||||
drivers/acpi/apei/einj-core.c holds the core logic, while CXL-specific
|
||||
handling lives in drivers/acpi/apei/einj-cxl.c and the shared plumbing
|
||||
in drivers/acpi/apei/apei-internal.h.
|
||||
|
||||
An ACPI 5.0 BIOS may also allow vendor-specific errors to be injected.
|
||||
In this case a file named vendor will contain identifying information
|
||||
|
|
|
|||
|
|
@ -134,22 +134,30 @@ static int print_extlog_rcd(const char *pfx,
|
|||
}
|
||||
|
||||
static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
|
||||
int severity)
|
||||
int severity, u32 len)
|
||||
{
|
||||
#ifdef ACPI_APEI_PCIEAER
|
||||
struct aer_capability_regs *aer;
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
struct aer_capability_regs aer_regs = {};
|
||||
struct pci_dev *pdev;
|
||||
unsigned int devfn;
|
||||
unsigned int bus;
|
||||
int aer_severity;
|
||||
int domain;
|
||||
|
||||
if (len < sizeof(*pcie_err)) {
|
||||
pr_warn_ratelimited(FW_WARN
|
||||
"PCIe error section too small (%u)\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
|
||||
pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO))
|
||||
return;
|
||||
|
||||
aer_severity = cper_severity_to_aer(severity);
|
||||
aer = (struct aer_capability_regs *)pcie_err->aer_info;
|
||||
|
||||
aer_cap_regs_unpack(&aer_regs, pcie_err->aer_info, sizeof(pcie_err->aer_info));
|
||||
|
||||
domain = pcie_err->device_id.segment;
|
||||
bus = pcie_err->device_id.bus;
|
||||
devfn = PCI_DEVFN(pcie_err->device_id.device,
|
||||
|
|
@ -158,28 +166,11 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
|
|||
if (!pdev)
|
||||
return;
|
||||
|
||||
pci_print_aer(pdev, aer_severity, aer);
|
||||
pci_print_aer(pdev, aer_severity, &aer_regs);
|
||||
pci_dev_put(pdev);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
extlog_cxl_cper_handle_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity)
|
||||
{
|
||||
#ifdef ACPI_APEI_PCIEAER
|
||||
struct cxl_cper_prot_err_work_data wd;
|
||||
|
||||
if (cxl_cper_sec_prot_err_valid(prot_err))
|
||||
return;
|
||||
|
||||
if (cxl_cper_setup_prot_err_work_data(&wd, prot_err, severity))
|
||||
return;
|
||||
|
||||
cxl_cper_handle_prot_err(&wd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int extlog_print(struct notifier_block *nb, unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
|
|
@ -208,6 +199,15 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
|
|||
|
||||
tmp = (struct acpi_hest_generic_status *)elog_buf;
|
||||
|
||||
/*
|
||||
* Bound the length before cper_estatus_check() walks the sections: it
|
||||
* iterates over data_length, which is not yet known to fit elog_buf.
|
||||
* cper_estatus_check_header() then rejects a length that wrapped, which
|
||||
* the bound cannot see.
|
||||
*/
|
||||
if (cper_estatus_len(tmp) > ELOG_ENTRY_LEN || cper_estatus_check(tmp))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (!ras_userspace_consumers()) {
|
||||
print_extlog_rcd(NULL, tmp, cpu);
|
||||
goto out;
|
||||
|
|
@ -235,12 +235,14 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
|
|||
struct cxl_cper_sec_prot_err *prot_err =
|
||||
acpi_hest_get_payload(gdata);
|
||||
|
||||
extlog_cxl_cper_handle_prot_err(prot_err,
|
||||
gdata->error_severity);
|
||||
cxl_cper_post_prot_err(prot_err,
|
||||
gdata->error_severity,
|
||||
gdata->error_data_length);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
|
||||
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
|
||||
|
||||
extlog_print_pcie(pcie_err, gdata->error_severity);
|
||||
extlog_print_pcie(pcie_err, gdata->error_severity,
|
||||
gdata->error_data_length);
|
||||
} else {
|
||||
void *err = acpi_hest_get_payload(gdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,17 +36,11 @@ static u32 mrrm_mem_entry_num;
|
|||
|
||||
static int get_node_num(struct mrrm_mem_range_entry *e)
|
||||
{
|
||||
unsigned int nid;
|
||||
struct zone *zone;
|
||||
|
||||
for_each_online_node(nid) {
|
||||
for (int z = 0; z < MAX_NR_ZONES; z++) {
|
||||
struct zone *zone = NODE_DATA(nid)->node_zones + z;
|
||||
|
||||
if (!populated_zone(zone))
|
||||
continue;
|
||||
if (zone_intersects(zone, PHYS_PFN(e->base), PHYS_PFN(e->length)))
|
||||
return zone_to_nid(zone);
|
||||
}
|
||||
for_each_populated_zone(zone) {
|
||||
if (zone_intersects(zone, PHYS_PFN(e->base), PHYS_PFN(e->length)))
|
||||
return zone_to_nid(zone);
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
* to PCC commands
|
||||
*/
|
||||
#define PCC_CMD_WAIT_RETRIES_NUM 500ULL
|
||||
#define PCC_SIGNATURE_SIZE sizeof(u32)
|
||||
|
||||
struct pcc_data {
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
|
|
@ -49,10 +50,24 @@ static acpi_status
|
|||
acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
||||
void *handler_context, void **region_context)
|
||||
{
|
||||
struct pcc_data *data;
|
||||
struct acpi_pcc_info *ctx = handler_context;
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
struct pcc_data *data;
|
||||
acpi_status ret;
|
||||
u64 usecs_lat;
|
||||
|
||||
if (function == ACPI_REGION_DEACTIVATE) {
|
||||
data = *region_context;
|
||||
if (data) {
|
||||
pcc_mbox_free_channel(data->pcc_chan);
|
||||
kfree(data);
|
||||
*region_context = NULL;
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
if (function != ACPI_REGION_ACTIVATE)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
data = kzalloc_obj(*data);
|
||||
if (!data)
|
||||
|
|
@ -74,6 +89,14 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
|||
}
|
||||
|
||||
pcc_chan = data->pcc_chan;
|
||||
if (pcc_chan->shmem_size < PCC_SIGNATURE_SIZE ||
|
||||
ctx->length > pcc_chan->shmem_size - PCC_SIGNATURE_SIZE) {
|
||||
pr_err("PCC channel-%d shared memory is too small.\n",
|
||||
ctx->subspace_id);
|
||||
ret = AE_AML_REGION_LIMIT;
|
||||
goto err_free_channel;
|
||||
}
|
||||
|
||||
if (!pcc_chan->mchan->mbox->txdone_irq) {
|
||||
pr_err("This channel-%d does not support interrupt.\n",
|
||||
ctx->subspace_id);
|
||||
|
|
@ -81,6 +104,16 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
|||
goto err_free_channel;
|
||||
}
|
||||
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * pcc_chan->latency;
|
||||
data->cl.tx_tout = DIV_ROUND_UP_ULL(usecs_lat, 1000);
|
||||
if (!data->cl.tx_tout)
|
||||
data->cl.tx_tout = 1;
|
||||
|
||||
*region_context = data;
|
||||
return AE_OK;
|
||||
|
||||
|
|
@ -97,27 +130,23 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
|
|||
u32 bits, acpi_integer *value,
|
||||
void *handler_context, void *region_context)
|
||||
{
|
||||
int ret;
|
||||
struct pcc_data *data = region_context;
|
||||
u64 usecs_lat;
|
||||
void __iomem *pcc_opregion;
|
||||
int ret;
|
||||
|
||||
pcc_opregion = data->pcc_chan->shmem + PCC_SIGNATURE_SIZE;
|
||||
|
||||
reinit_completion(&data->done);
|
||||
|
||||
/* Write to Shared Memory */
|
||||
memcpy_toio(data->pcc_chan->shmem, (void *)value, data->ctx.length);
|
||||
/* Write to the PCC OperationRegion after the shared memory signature. */
|
||||
memcpy_toio(pcc_opregion, (void *)value, data->ctx.length);
|
||||
|
||||
ret = mbox_send_message(data->pcc_chan->mchan, NULL);
|
||||
if (ret < 0)
|
||||
return AE_ERROR;
|
||||
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
|
||||
ret = wait_for_completion_timeout(&data->done,
|
||||
usecs_to_jiffies(usecs_lat));
|
||||
msecs_to_jiffies(data->cl.tx_tout));
|
||||
if (ret == 0) {
|
||||
pr_err("PCC command executed timeout!\n");
|
||||
return AE_TIME;
|
||||
|
|
@ -125,7 +154,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
|
|||
|
||||
mbox_chan_txdone(data->pcc_chan->mchan, ret);
|
||||
|
||||
memcpy_fromio(value, data->pcc_chan->shmem, data->ctx.length);
|
||||
memcpy_fromio(value, pcc_opregion, data->ctx.length);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1700,9 +1700,9 @@ static int acpi_video_resume(struct notifier_block *nb,
|
|||
|
||||
static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
|
||||
{
|
||||
struct device *phys_dev, *parent = NULL;
|
||||
struct backlight_properties props;
|
||||
struct pci_dev *pdev;
|
||||
struct device *parent = NULL;
|
||||
int result;
|
||||
static int count;
|
||||
char *name;
|
||||
|
|
@ -1729,11 +1729,10 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
|
|||
device,
|
||||
&acpi_backlight_ops,
|
||||
&props);
|
||||
put_device(parent);
|
||||
kfree(name);
|
||||
if (IS_ERR(device->backlight)) {
|
||||
device->backlight = NULL;
|
||||
return;
|
||||
goto put_parent;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1743,8 +1742,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
|
|||
device->backlight->props.brightness =
|
||||
acpi_video_get_brightness(device->backlight);
|
||||
|
||||
device->cooling_dev = thermal_cooling_device_register("LCD", device,
|
||||
&video_cooling_ops);
|
||||
phys_dev = acpi_bus_get_primary_device(device->dev);
|
||||
if (!phys_dev)
|
||||
phys_dev = get_device(parent);
|
||||
|
||||
device->cooling_dev = thermal_cooling_device_create(phys_dev, "LCD", device,
|
||||
&video_cooling_ops);
|
||||
if (IS_ERR(device->cooling_dev)) {
|
||||
/*
|
||||
* Set cooling_dev to NULL so we don't crash trying to free it.
|
||||
|
|
@ -1753,21 +1756,17 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
|
|||
* -- dtor
|
||||
*/
|
||||
device->cooling_dev = NULL;
|
||||
return;
|
||||
goto put_phys_dev;
|
||||
}
|
||||
|
||||
dev_info(&device->dev->dev, "registered as cooling_device%d\n",
|
||||
device->cooling_dev->id);
|
||||
result = sysfs_create_link(&device->dev->dev.kobj,
|
||||
&device->cooling_dev->device.kobj,
|
||||
"thermal_cooling");
|
||||
if (result)
|
||||
pr_info("sysfs link creation failed\n");
|
||||
dev_info(&device->cooling_dev->device, "Using ACPI device %s\n",
|
||||
acpi_dev_name(device->dev));
|
||||
|
||||
result = sysfs_create_link(&device->cooling_dev->device.kobj,
|
||||
&device->dev->dev.kobj, "device");
|
||||
if (result)
|
||||
pr_info("Reverse sysfs link creation failed\n");
|
||||
put_phys_dev:
|
||||
put_device(phys_dev);
|
||||
|
||||
put_parent:
|
||||
put_device(parent);
|
||||
}
|
||||
|
||||
static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video)
|
||||
|
|
@ -1825,6 +1824,10 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
|
|||
|
||||
static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device)
|
||||
{
|
||||
if (device->cooling_dev) {
|
||||
thermal_cooling_device_unregister(device->cooling_dev);
|
||||
device->cooling_dev = NULL;
|
||||
}
|
||||
if (device->backlight) {
|
||||
backlight_device_unregister(device->backlight);
|
||||
device->backlight = NULL;
|
||||
|
|
@ -1834,12 +1837,6 @@ static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device
|
|||
kfree(device->brightness);
|
||||
device->brightness = NULL;
|
||||
}
|
||||
if (device->cooling_dev) {
|
||||
sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&device->cooling_dev->device.kobj, "device");
|
||||
thermal_cooling_device_unregister(device->cooling_dev);
|
||||
device->cooling_dev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video)
|
||||
|
|
|
|||
|
|
@ -522,7 +522,8 @@ acpi_ds_create_field(union acpi_parse_object *op,
|
|||
}
|
||||
|
||||
if (info.region_node->object->region.space_id ==
|
||||
ACPI_ADR_SPACE_PLATFORM_COMM) {
|
||||
ACPI_ADR_SPACE_PLATFORM_COMM &&
|
||||
!region_node->object->field.internal_pcc_buffer) {
|
||||
region_node->object->field.internal_pcc_buffer =
|
||||
ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
|
||||
length);
|
||||
|
|
|
|||
|
|
@ -45,12 +45,13 @@ static const u8 acpi_protocol_lengths[] = {
|
|||
|
||||
/*
|
||||
* The following macros determine a given offset is a COMD field.
|
||||
* According to the specification, generic subspaces (types 0-2) contains a
|
||||
* 2-byte COMD field at offset 4 and master subspaces (type 3) contains a 4-byte
|
||||
* COMD field starting at offset 12.
|
||||
* According to the specification, the PCC OperationRegion begins after
|
||||
* the PCC signature. The raw shared memory COMD offsets of 4 for generic
|
||||
* subspaces (types 0-2) and 12 for master subspaces (type 3) therefore
|
||||
* appear at OperationRegion offsets 0 and 8.
|
||||
*/
|
||||
#define GENERIC_SUBSPACE_COMMAND(a) (4 == a || a == 5)
|
||||
#define MASTER_SUBSPACE_COMMAND(a) (12 <= a && a <= 15)
|
||||
#define GENERIC_SUBSPACE_COMMAND(a) (0 == a || a == 1)
|
||||
#define MASTER_SUBSPACE_COMMAND(a) (8 <= a && a <= 11)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,
|
|||
* and don't filter out 'corrected' error here.
|
||||
*/
|
||||
if (is_cache && has_pa) {
|
||||
queued = ghes_do_memory_failure(err_info->physical_fault_addr, flags);
|
||||
queued |= ghes_do_memory_failure(err_info->physical_fault_addr, flags);
|
||||
p += err_info->length;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -642,11 +642,14 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
|
|||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
|
||||
|
||||
if (gdata->error_data_length < sizeof(*pcie_err))
|
||||
return;
|
||||
|
||||
if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
|
||||
pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
|
||||
struct aer_capability_regs *aer_info;
|
||||
unsigned int devfn;
|
||||
int aer_severity;
|
||||
u8 *aer_info;
|
||||
|
||||
devfn = PCI_DEVFN(pcie_err->device_id.device,
|
||||
pcie_err->device_id.function);
|
||||
|
|
@ -664,13 +667,12 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
|
|||
sizeof(struct aer_capability_regs));
|
||||
if (!aer_info)
|
||||
return;
|
||||
memcpy(aer_info, pcie_err->aer_info, sizeof(struct aer_capability_regs));
|
||||
|
||||
aer_cap_regs_unpack(aer_info, pcie_err->aer_info, sizeof(pcie_err->aer_info));
|
||||
|
||||
aer_recover_queue(pcie_err->device_id.segment,
|
||||
pcie_err->device_id.bus,
|
||||
devfn, aer_severity,
|
||||
(struct aer_capability_regs *)
|
||||
aer_info);
|
||||
devfn, aer_severity, aer_info);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -752,13 +754,13 @@ static DEFINE_KFIFO(cxl_cper_prot_err_fifo, struct cxl_cper_prot_err_work_data,
|
|||
static DEFINE_RAW_SPINLOCK(cxl_cper_prot_err_work_lock);
|
||||
struct work_struct *cxl_cper_prot_err_work;
|
||||
|
||||
static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity)
|
||||
void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity, u32 len)
|
||||
{
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
struct cxl_cper_prot_err_work_data wd;
|
||||
|
||||
if (cxl_cper_sec_prot_err_valid(prot_err))
|
||||
if (cxl_cper_sec_prot_err_valid(prot_err, len))
|
||||
return;
|
||||
|
||||
guard(raw_spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
|
||||
|
|
@ -777,6 +779,7 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
|||
schedule_work(cxl_cper_prot_err_work);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_MODULES(cxl_cper_post_prot_err, "acpi_extlog");
|
||||
|
||||
void cxl_cper_register_prot_err_work(struct work_struct *work)
|
||||
{
|
||||
|
|
@ -823,10 +826,15 @@ static DEFINE_RAW_SPINLOCK(cxl_cper_work_lock);
|
|||
struct work_struct *cxl_cper_work;
|
||||
|
||||
static void cxl_cper_post_event(enum cxl_event_type event_type,
|
||||
struct cxl_cper_event_rec *rec)
|
||||
struct cxl_cper_event_rec *rec, u32 len)
|
||||
{
|
||||
struct cxl_cper_work_data wd;
|
||||
|
||||
if (len < sizeof(*rec)) {
|
||||
pr_err(FW_WARN "CXL CPER section too small (%u)\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rec->hdr.length <= sizeof(rec->hdr) ||
|
||||
rec->hdr.length > sizeof(*rec)) {
|
||||
pr_err(FW_WARN "CXL CPER Invalid section length (%u)\n",
|
||||
|
|
@ -923,6 +931,28 @@ static void ghes_log_hwerr(int sev, guid_t *sec_type)
|
|||
hwerr_log_error_type(HWERR_RECOV_OTHERS);
|
||||
}
|
||||
|
||||
/*
|
||||
* The fields from "extended" on are absent from the 73-byte UEFI 2.1/2.2
|
||||
* layout that older firmware still emits. Return the length needed for the
|
||||
* fields the validation bits claim, so over-claiming is rejected without
|
||||
* rejecting an honest short record.
|
||||
*/
|
||||
static u32 ghes_mem_err_min_len(u64 validation_bits)
|
||||
{
|
||||
u32 len = sizeof(struct cper_sec_mem_err_old);
|
||||
|
||||
if (validation_bits & (CPER_MEM_VALID_ROW_EXT | CPER_MEM_VALID_CHIP_ID))
|
||||
len = offsetof(struct cper_sec_mem_err, rank);
|
||||
if (validation_bits & CPER_MEM_VALID_RANK_NUMBER)
|
||||
len = offsetof(struct cper_sec_mem_err, mem_array_handle);
|
||||
if (validation_bits & CPER_MEM_VALID_CARD_HANDLE)
|
||||
len = offsetof(struct cper_sec_mem_err, mem_dev_handle);
|
||||
if (validation_bits & CPER_MEM_VALID_MODULE_HANDLE)
|
||||
len = sizeof(struct cper_sec_mem_err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void ghes_do_proc(struct ghes *ghes,
|
||||
const struct acpi_hest_generic_status *estatus)
|
||||
{
|
||||
|
|
@ -948,30 +978,53 @@ static void ghes_do_proc(struct ghes *ghes,
|
|||
if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
|
||||
struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
|
||||
|
||||
/*
|
||||
* Check once for all three consumers below. The 73-byte
|
||||
* UEFI 2.1/2.2 layout is the floor, matching
|
||||
* cper_estatus_print_section() and making
|
||||
* validation_bits safe to read.
|
||||
*/
|
||||
if (gdata->error_data_length <
|
||||
sizeof(struct cper_sec_mem_err_old))
|
||||
continue;
|
||||
|
||||
/* Then require what the claimed fields actually need. */
|
||||
if (gdata->error_data_length <
|
||||
ghes_mem_err_min_len(mem_err->validation_bits)) {
|
||||
pr_warn_ratelimited(FW_WARN GHES_PFX
|
||||
"memory error section too small (%u) for the fields it claims\n",
|
||||
gdata->error_data_length);
|
||||
continue;
|
||||
}
|
||||
|
||||
atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
|
||||
|
||||
arch_apei_report_mem_error(sev, mem_err);
|
||||
queued = ghes_handle_memory_failure(gdata, sev, sync);
|
||||
queued |= ghes_handle_memory_failure(gdata, sev, sync);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
|
||||
ghes_handle_aer(gdata);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
|
||||
queued = ghes_handle_arm_hw_error(gdata, sev, sync);
|
||||
queued |= ghes_handle_arm_hw_error(gdata, sev, sync);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
|
||||
struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
|
||||
|
||||
cxl_cper_post_prot_err(prot_err, gdata->error_severity);
|
||||
cxl_cper_post_prot_err(prot_err, gdata->error_severity,
|
||||
gdata->error_data_length);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID)) {
|
||||
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
|
||||
|
||||
cxl_cper_post_event(CXL_CPER_EVENT_GEN_MEDIA, rec);
|
||||
cxl_cper_post_event(CXL_CPER_EVENT_GEN_MEDIA, rec,
|
||||
gdata->error_data_length);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_CXL_DRAM_GUID)) {
|
||||
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
|
||||
|
||||
cxl_cper_post_event(CXL_CPER_EVENT_DRAM, rec);
|
||||
cxl_cper_post_event(CXL_CPER_EVENT_DRAM, rec,
|
||||
gdata->error_data_length);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_CXL_MEM_MODULE_GUID)) {
|
||||
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
|
||||
|
||||
cxl_cper_post_event(CXL_CPER_EVENT_MEM_MODULE, rec);
|
||||
cxl_cper_post_event(CXL_CPER_EVENT_MEM_MODULE, rec,
|
||||
gdata->error_data_length);
|
||||
} else {
|
||||
void *err = acpi_hest_get_payload(gdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,15 @@
|
|||
#include <linux/aer.h>
|
||||
#include <cxl/event.h>
|
||||
|
||||
int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
|
||||
int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len)
|
||||
{
|
||||
if (len < sizeof(*prot_err)) {
|
||||
pr_err_ratelimited(FW_WARN
|
||||
"CXL CPER prot err section too small (%u)\n",
|
||||
len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {
|
||||
pr_err_ratelimited("CXL CPER invalid agent type\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -23,6 +30,15 @@ int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The RAS Capability block sits after a firmware-sized DVSEC. */
|
||||
if (sizeof(*prot_err) + prot_err->dvsec_len +
|
||||
sizeof(struct cxl_ras_capability_regs) > len) {
|
||||
pr_err_ratelimited(FW_WARN
|
||||
"CXL CPER prot err DVSEC (%u) overruns section (%u)\n",
|
||||
prot_err->dvsec_len, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((prot_err->agent_type == RCD || prot_err->agent_type == DEVICE ||
|
||||
prot_err->agent_type == LD || prot_err->agent_type == FMLD) &&
|
||||
!(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
|
||||
|
|
|
|||
|
|
@ -87,11 +87,12 @@ static int amba_handler_attach(struct acpi_device *adev,
|
|||
* the amba device we are about to create.
|
||||
*/
|
||||
if (parent)
|
||||
dev->dev.parent = acpi_get_first_physical_node(parent);
|
||||
dev->dev.parent = acpi_bus_get_primary_device(parent);
|
||||
|
||||
device_set_node(&dev->dev, acpi_fwnode_handle(adev));
|
||||
|
||||
ret = amba_device_add(dev, &iomem_resource);
|
||||
put_device(dev->dev.parent);
|
||||
if (ret) {
|
||||
dev_err(&adev->dev, "%s(): amba_device_add() failed (%d)\n",
|
||||
__func__, ret);
|
||||
|
|
|
|||
|
|
@ -341,7 +341,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const enum power_supply_property charge_battery_props[] = {
|
||||
/* For devices supporting the _BIX ACPI control method */
|
||||
|
||||
static const enum power_supply_property charge_battery_extended_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
|
|
@ -359,7 +361,7 @@ static const enum power_supply_property charge_battery_props[] = {
|
|||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
static const enum power_supply_property charge_battery_full_cap_broken_props[] = {
|
||||
static const enum power_supply_property charge_battery_full_cap_broken_extended_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
|
|
@ -373,7 +375,7 @@ static const enum power_supply_property charge_battery_full_cap_broken_props[] =
|
|||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
static const enum power_supply_property energy_battery_props[] = {
|
||||
static const enum power_supply_property energy_battery_extended_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
|
|
@ -391,7 +393,7 @@ static const enum power_supply_property energy_battery_props[] = {
|
|||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
static const enum power_supply_property energy_battery_full_cap_broken_props[] = {
|
||||
static const enum power_supply_property energy_battery_full_cap_broken_extended_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
|
|
@ -405,6 +407,68 @@ static const enum power_supply_property energy_battery_full_cap_broken_props[] =
|
|||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
/* For devices supporting only the _BIF ACPI control method */
|
||||
|
||||
static const enum power_supply_property charge_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
|
||||
POWER_SUPPLY_PROP_CHARGE_FULL,
|
||||
POWER_SUPPLY_PROP_CHARGE_NOW,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
static const enum power_supply_property charge_battery_full_cap_broken_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CHARGE_NOW,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
static const enum power_supply_property energy_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_POWER_NOW,
|
||||
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
|
||||
POWER_SUPPLY_PROP_ENERGY_FULL,
|
||||
POWER_SUPPLY_PROP_ENERGY_NOW,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
static const enum power_supply_property energy_battery_full_cap_broken_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_POWER_NOW,
|
||||
POWER_SUPPLY_PROP_ENERGY_NOW,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
|
||||
/* Battery Management */
|
||||
struct acpi_offsets {
|
||||
size_t offset; /* offset inside struct acpi_sbs_battery */
|
||||
|
|
@ -904,6 +968,7 @@ static void __exit battery_hook_exit(void)
|
|||
|
||||
static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
{
|
||||
bool extended_info_available = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
||||
struct power_supply_config psy_cfg = {
|
||||
.drv_data = battery,
|
||||
.attr_grp = acpi_battery_groups,
|
||||
|
|
@ -922,25 +987,55 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
|||
|
||||
if (power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
|
||||
if (full_cap_broken) {
|
||||
battery->bat_desc.properties =
|
||||
charge_battery_full_cap_broken_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(charge_battery_full_cap_broken_props);
|
||||
if (extended_info_available) {
|
||||
battery->bat_desc.properties =
|
||||
charge_battery_full_cap_broken_extended_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(charge_battery_full_cap_broken_extended_props);
|
||||
} else {
|
||||
battery->bat_desc.properties =
|
||||
charge_battery_full_cap_broken_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(charge_battery_full_cap_broken_props);
|
||||
}
|
||||
} else {
|
||||
battery->bat_desc.properties = charge_battery_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(charge_battery_props);
|
||||
if (extended_info_available) {
|
||||
battery->bat_desc.properties =
|
||||
charge_battery_extended_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(charge_battery_extended_props);
|
||||
} else {
|
||||
battery->bat_desc.properties =
|
||||
charge_battery_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(charge_battery_props);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (full_cap_broken) {
|
||||
battery->bat_desc.properties =
|
||||
energy_battery_full_cap_broken_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(energy_battery_full_cap_broken_props);
|
||||
if (extended_info_available) {
|
||||
battery->bat_desc.properties =
|
||||
energy_battery_full_cap_broken_extended_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(energy_battery_full_cap_broken_extended_props);
|
||||
} else {
|
||||
battery->bat_desc.properties =
|
||||
energy_battery_full_cap_broken_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(energy_battery_full_cap_broken_props);
|
||||
}
|
||||
} else {
|
||||
battery->bat_desc.properties = energy_battery_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(energy_battery_props);
|
||||
if (extended_info_available) {
|
||||
battery->bat_desc.properties =
|
||||
energy_battery_extended_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(energy_battery_extended_props);
|
||||
} else {
|
||||
battery->bat_desc.properties =
|
||||
energy_battery_props;
|
||||
battery->bat_desc.num_properties =
|
||||
ARRAY_SIZE(energy_battery_props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -809,24 +809,14 @@ struct device *acpi_bus_get_primary_device(struct acpi_device *adev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_bus_get_primary_device);
|
||||
|
||||
/**
|
||||
* acpi_get_first_physical_node - Find first physical node of an ACPI device
|
||||
* @adev: ACPI device in question
|
||||
*
|
||||
* Return: First physical node of ACPI device @adev
|
||||
*/
|
||||
struct device *acpi_get_first_physical_node(struct acpi_device *adev)
|
||||
{
|
||||
guard(mutex)(&adev->physical_node_lock);
|
||||
|
||||
return primary_physical_device(adev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_get_first_physical_node);
|
||||
|
||||
static struct acpi_device *acpi_primary_dev_companion(struct acpi_device *adev,
|
||||
const struct device *dev)
|
||||
{
|
||||
const struct device *phys_dev = acpi_get_first_physical_node(adev);
|
||||
const struct device *phys_dev;
|
||||
|
||||
guard(mutex)(&adev->physical_node_lock);
|
||||
|
||||
phys_dev = primary_physical_device(adev);
|
||||
|
||||
return phys_dev && phys_dev == dev ? adev : NULL;
|
||||
}
|
||||
|
|
@ -1120,11 +1110,6 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_device);
|
|||
ACPI Bus operations
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
static int acpi_bus_match(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
|
||||
|
|
@ -1132,7 +1117,6 @@ static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *
|
|||
|
||||
const struct bus_type acpi_bus_type = {
|
||||
.name = "acpi",
|
||||
.match = acpi_bus_match,
|
||||
.uevent = acpi_device_uevent,
|
||||
};
|
||||
|
||||
|
|
@ -1451,7 +1435,7 @@ static int __init acpi_bus_init(void)
|
|||
*/
|
||||
acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
|
||||
|
||||
result = bus_register(&acpi_bus_type);
|
||||
result = companion_bus_register(&acpi_bus_type);
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,18 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
|
|||
},
|
||||
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Razer Blade Stealth 13 early 2020, when the lid is opened
|
||||
* while suspended the open notification is lost and _LID keeps
|
||||
* returning closed after resume, causing spurious re-suspends.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Blade Stealth 13 (Early 2020) - RZ09-0310"),
|
||||
},
|
||||
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Samsung galaxybook2 ,initial _LID device notification returns
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "fan.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define ACPI_D_STATE_INVALID ACPI_D_STATE_COUNT
|
||||
|
||||
/**
|
||||
* acpi_power_state_string - String representation of ACPI device power state.
|
||||
* @state: ACPI device power state to return the string representation of.
|
||||
|
|
@ -75,15 +77,14 @@ static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state)
|
|||
int acpi_device_get_power(struct acpi_device *device, int *state)
|
||||
{
|
||||
int result = ACPI_STATE_UNKNOWN;
|
||||
struct acpi_device *parent;
|
||||
int error;
|
||||
|
||||
if (!device || !state)
|
||||
return -EINVAL;
|
||||
|
||||
parent = acpi_dev_parent(device);
|
||||
|
||||
if (!device->flags.power_manageable) {
|
||||
struct acpi_device *parent = acpi_dev_parent(device);
|
||||
|
||||
/* TBD: Non-recursive algorithm for walking up hierarchy. */
|
||||
*state = parent ? parent->power.state : ACPI_STATE_D0;
|
||||
goto out;
|
||||
|
|
@ -119,16 +120,6 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
|
|||
result = psc > ACPI_STATE_D2 ? ACPI_STATE_D3_HOT : psc;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were unsure about the device parent's power state up to this
|
||||
* point, the fact that the device is in D0 implies that the parent has
|
||||
* to be in D0 too, except if ignore_parent is set.
|
||||
*/
|
||||
if (!device->power.flags.ignore_parent && parent &&
|
||||
parent->power.state == ACPI_STATE_UNKNOWN &&
|
||||
result == ACPI_STATE_D0)
|
||||
parent->power.state = ACPI_STATE_D0;
|
||||
|
||||
*state = result;
|
||||
|
||||
out:
|
||||
|
|
@ -304,24 +295,28 @@ int acpi_bus_set_power(acpi_handle handle, int state)
|
|||
}
|
||||
EXPORT_SYMBOL(acpi_bus_set_power);
|
||||
|
||||
int acpi_bus_init_power(struct acpi_device *device)
|
||||
static int acpi_device_init_power(struct acpi_device *device)
|
||||
{
|
||||
int state;
|
||||
int result;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
device->power.state = ACPI_STATE_UNKNOWN;
|
||||
if (!acpi_device_is_present(device)) {
|
||||
device->flags.initialized = false;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
result = acpi_device_get_power(device, &state);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/*
|
||||
* If the current power state of the device is D0 and it has a parent
|
||||
* whose power state is not ignored, and the parent's power state
|
||||
* initialization has failed, the parent's power state can be updated to
|
||||
* D0 for consistency.
|
||||
*/
|
||||
if (!device->power.flags.ignore_parent && state == ACPI_STATE_D0) {
|
||||
struct acpi_device *parent = acpi_dev_parent(device);
|
||||
|
||||
if (parent && parent->power.state == ACPI_D_STATE_INVALID)
|
||||
parent->power.state = ACPI_STATE_D0;
|
||||
}
|
||||
|
||||
if (state < ACPI_STATE_D3_COLD && device->power.flags.power_resources) {
|
||||
/* Reference count the power resources. */
|
||||
result = acpi_power_on_resources(device, state);
|
||||
|
|
@ -351,9 +346,36 @@ int acpi_bus_init_power(struct acpi_device *device)
|
|||
state = ACPI_STATE_D0;
|
||||
}
|
||||
device->power.state = state;
|
||||
|
||||
acpi_handle_debug(device->handle, "Initial power state: %s\n",
|
||||
acpi_power_state_string(state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_bus_init_power(struct acpi_device *device)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (device->power.state != ACPI_STATE_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The ACPI device power state can be only initialized once. If this
|
||||
* fails, ACPI power management will not be used for the device going
|
||||
* forward.
|
||||
*/
|
||||
result = acpi_device_init_power(device);
|
||||
if (result) {
|
||||
device->flags.power_manageable = 0;
|
||||
device->power.state = ACPI_D_STATE_INVALID;
|
||||
acpi_handle_info(device->handle,
|
||||
"Initial power state undetermined, ACPI PM disabled\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_device_fix_up_power - Force device with missing _PSC into D0.
|
||||
* @device: Device object whose power state is to be fixed up.
|
||||
|
|
@ -475,8 +497,13 @@ static int acpi_power_up_if_adr_present(struct acpi_device *adev, void *not_used
|
|||
if (!(adev->flags.power_manageable && adev->pnp.type.bus_address))
|
||||
return 0;
|
||||
|
||||
acpi_handle_debug(adev->handle, "Power state: %s\n",
|
||||
acpi_power_state_string(adev->power.state));
|
||||
/*
|
||||
* This is done during the PCI root initialization which occurs before
|
||||
* acpi_bus_attach() is called for the device, so the ACPI power state
|
||||
* of the device needs to be initialized here.
|
||||
*/
|
||||
if (acpi_bus_init_power(adev))
|
||||
return 0;
|
||||
|
||||
if (adev->power.state == ACPI_STATE_D3_COLD)
|
||||
return acpi_device_set_power(adev, ACPI_STATE_D0);
|
||||
|
|
|
|||
|
|
@ -445,6 +445,15 @@ int dock_notify(struct acpi_device *adev, u32 event)
|
|||
break;
|
||||
}
|
||||
hotplug_dock_devices(ds, event);
|
||||
/*
|
||||
* The dock platform device already exists when an empty battery
|
||||
* bay becomes occupied, but its driver may not have bound while
|
||||
* the battery was absent. Retry after the ACPI scan updates its
|
||||
* status, since the scan only attaches the ACPI device.
|
||||
*/
|
||||
if (ds->flags & DOCK_IS_BAT)
|
||||
device_initial_probe(&ds->dock_device->dev);
|
||||
|
||||
complete_dock(ds);
|
||||
dock_event(ds, event, DOCK_EVENT);
|
||||
acpi_evaluate_lck(ds->handle, 1);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ struct acpi_fan_fst {
|
|||
};
|
||||
|
||||
struct acpi_fan {
|
||||
acpi_handle handle;
|
||||
struct acpi_device *adev;
|
||||
bool acpi4;
|
||||
bool has_fst;
|
||||
struct acpi_fan_fif fif;
|
||||
|
|
|
|||
|
|
@ -54,8 +54,7 @@ MODULE_DEVICE_TABLE(acpi, fan_device_ids);
|
|||
static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
|
||||
*state)
|
||||
{
|
||||
struct acpi_device *device = cdev->devdata;
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_fan *fan = cdev->devdata;
|
||||
|
||||
if (fan->acpi4) {
|
||||
if (fan->fif.fine_grain_ctrl)
|
||||
|
|
@ -72,42 +71,34 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
|
|||
int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
int ret = 0;
|
||||
|
||||
status = acpi_evaluate_object(handle, "_FST", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
return -ENXIO;
|
||||
|
||||
obj = buffer.pointer;
|
||||
union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
|
||||
if (!obj)
|
||||
return -ENODATA;
|
||||
|
||||
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) {
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3)
|
||||
return -EPROTO;
|
||||
|
||||
if (obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
obj->package.elements[1].type != ACPI_TYPE_INTEGER ||
|
||||
obj->package.elements[2].type != ACPI_TYPE_INTEGER) {
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
obj->package.elements[2].type != ACPI_TYPE_INTEGER)
|
||||
return -EPROTO;
|
||||
|
||||
fst->revision = obj->package.elements[0].integer.value;
|
||||
fst->control = obj->package.elements[1].integer.value;
|
||||
fst->speed = obj->package.elements[2].integer.value;
|
||||
|
||||
err:
|
||||
kfree(obj);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
|
||||
static int fan_get_state_acpi4(struct acpi_fan *fan, unsigned long *state)
|
||||
{
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_device *device = fan->adev;
|
||||
struct acpi_fan_fst fst;
|
||||
int status, i;
|
||||
|
||||
|
|
@ -159,13 +150,12 @@ static int fan_get_state(struct acpi_device *device, unsigned long *state)
|
|||
static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
|
||||
*state)
|
||||
{
|
||||
struct acpi_device *device = cdev->devdata;
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_fan *fan = cdev->devdata;
|
||||
|
||||
if (fan->acpi4)
|
||||
return fan_get_state_acpi4(device, state);
|
||||
return fan_get_state_acpi4(fan, state);
|
||||
else
|
||||
return fan_get_state(device, state);
|
||||
return fan_get_state(fan->adev, state);
|
||||
}
|
||||
|
||||
static int fan_set_state(struct acpi_device *device, unsigned long state)
|
||||
|
|
@ -177,9 +167,9 @@ static int fan_set_state(struct acpi_device *device, unsigned long state)
|
|||
state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
|
||||
}
|
||||
|
||||
static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
|
||||
static int fan_set_state_acpi4(struct acpi_fan *fan, unsigned long state)
|
||||
{
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_device *device = fan->adev;
|
||||
acpi_status status;
|
||||
u64 value = state;
|
||||
int max_state;
|
||||
|
|
@ -213,13 +203,12 @@ static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
|
|||
static int
|
||||
fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
|
||||
{
|
||||
struct acpi_device *device = cdev->devdata;
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_fan *fan = cdev->devdata;
|
||||
|
||||
if (fan->acpi4)
|
||||
return fan_set_state_acpi4(device, state);
|
||||
return fan_set_state_acpi4(fan, state);
|
||||
else
|
||||
return fan_set_state(device, state);
|
||||
return fan_set_state(fan->adev, state);
|
||||
}
|
||||
|
||||
static const struct thermal_cooling_device_ops fan_cooling_ops = {
|
||||
|
|
@ -240,25 +229,22 @@ static int acpi_fan_get_fif(struct acpi_device *device)
|
|||
struct acpi_buffer format = { sizeof("NNNN"), "NNNN" };
|
||||
u64 fields[4];
|
||||
struct acpi_buffer fif = { sizeof(fields), fields };
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_object(device->handle, "_FIF", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
return -ENXIO;
|
||||
|
||||
obj = buffer.pointer;
|
||||
union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
|
||||
if (!obj || obj->type != ACPI_TYPE_PACKAGE) {
|
||||
dev_err(&device->dev, "Invalid _FIF data\n");
|
||||
status = -EINVAL;
|
||||
goto err;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
status = acpi_extract_package(obj, &format, &fif);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev, "Invalid _FIF element\n");
|
||||
status = -EINVAL;
|
||||
goto err;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
fan->fif.revision = fields[0];
|
||||
|
|
@ -272,9 +258,8 @@ static int acpi_fan_get_fif(struct acpi_device *device)
|
|||
/* If step size > 9, change to 9 (by spec valid values 1-9) */
|
||||
else if (fan->fif.step_size > 9)
|
||||
fan->fif.step_size = 9;
|
||||
err:
|
||||
kfree(obj);
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_speed_cmp(const void *a, const void *b)
|
||||
|
|
@ -284,34 +269,28 @@ static int acpi_fan_speed_cmp(const void *a, const void *b)
|
|||
return fps1->speed - fps2->speed;
|
||||
}
|
||||
|
||||
static int acpi_fan_get_fps(struct acpi_device *device)
|
||||
static int acpi_fan_get_fps(struct device *dev, struct acpi_device *device)
|
||||
{
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
int i;
|
||||
|
||||
status = acpi_evaluate_object(device->handle, "_FPS", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
return -ENXIO;
|
||||
|
||||
obj = buffer.pointer;
|
||||
union acpi_object *obj __free(acpi_object_free) = buffer.pointer;
|
||||
if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) {
|
||||
dev_err(&device->dev, "Invalid _FPS data\n");
|
||||
status = -EINVAL;
|
||||
goto err;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
fan->fps_count = obj->package.count - 1; /* minus revision field */
|
||||
fan->fps = devm_kcalloc(&device->dev,
|
||||
fan->fps_count, sizeof(struct acpi_fan_fps),
|
||||
GFP_KERNEL);
|
||||
if (!fan->fps) {
|
||||
dev_err(&device->dev, "Not enough memory\n");
|
||||
status = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
fan->fps = devm_kcalloc(dev, fan->fps_count, sizeof(*fan->fps), GFP_KERNEL);
|
||||
if (!fan->fps)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < fan->fps_count; i++) {
|
||||
struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
|
||||
struct acpi_buffer fps = { offsetof(struct acpi_fan_fps, name),
|
||||
|
|
@ -320,7 +299,7 @@ static int acpi_fan_get_fps(struct acpi_device *device)
|
|||
&format, &fps);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev, "Invalid _FPS element\n");
|
||||
goto err;
|
||||
return -ENODATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,9 +307,7 @@ static int acpi_fan_get_fps(struct acpi_device *device)
|
|||
sort(fan->fps, fan->fps_count, sizeof(*fan->fps),
|
||||
acpi_fan_speed_cmp, NULL);
|
||||
|
||||
err:
|
||||
kfree(obj);
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_dsm_init(struct device *dev)
|
||||
|
|
@ -343,30 +320,28 @@ static int acpi_fan_dsm_init(struct device *dev)
|
|||
},
|
||||
};
|
||||
struct acpi_fan *fan = dev_get_drvdata(dev);
|
||||
union acpi_object *obj;
|
||||
int ret = 0;
|
||||
acpi_handle fan_handle = fan->adev->handle;
|
||||
|
||||
if (!acpi_check_dsm(fan->handle, &acpi_fan_microsoft_guid, 0,
|
||||
if (!acpi_check_dsm(fan_handle, &acpi_fan_microsoft_guid, 0,
|
||||
BIT(ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY) |
|
||||
BIT(ACPI_FAN_DSM_SET_TRIP_POINTS)))
|
||||
return 0;
|
||||
|
||||
dev_info(dev, "Using Microsoft fan extensions\n");
|
||||
|
||||
obj = acpi_evaluate_dsm_typed(fan->handle, &acpi_fan_microsoft_guid, 0,
|
||||
ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY, &dummy,
|
||||
ACPI_TYPE_INTEGER);
|
||||
union acpi_object *obj __free(acpi_object_free) =
|
||||
acpi_evaluate_dsm_typed(fan_handle, &acpi_fan_microsoft_guid, 0,
|
||||
ACPI_FAN_DSM_GET_TRIP_POINT_GRANULARITY,
|
||||
&dummy, ACPI_TYPE_INTEGER);
|
||||
if (!obj)
|
||||
return -EIO;
|
||||
return -ENXIO;
|
||||
|
||||
if (obj->integer.value > U32_MAX)
|
||||
ret = -EOVERFLOW;
|
||||
else
|
||||
fan->fan_trip_granularity = obj->integer.value;
|
||||
return -EOVERFLOW;
|
||||
|
||||
kfree(obj);
|
||||
fan->fan_trip_granularity = obj->integer.value;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower)
|
||||
|
|
@ -395,9 +370,9 @@ static int acpi_fan_dsm_set_trip_points(struct device *dev, u64 upper, u64 lower
|
|||
};
|
||||
union acpi_object *obj;
|
||||
|
||||
obj = acpi_evaluate_dsm(fan->handle, &acpi_fan_microsoft_guid, 0,
|
||||
ACPI_FAN_DSM_SET_TRIP_POINTS, &in);
|
||||
kfree(obj);
|
||||
obj = acpi_evaluate_dsm(fan->adev->handle, &acpi_fan_microsoft_guid,
|
||||
0, ACPI_FAN_DSM_SET_TRIP_POINTS, &in);
|
||||
ACPI_FREE(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -506,7 +481,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fan->handle = device->handle;
|
||||
fan->adev = device;
|
||||
device->driver_data = fan;
|
||||
platform_set_drvdata(pdev, fan);
|
||||
|
||||
|
|
@ -522,7 +497,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
if (result)
|
||||
return result;
|
||||
|
||||
result = acpi_fan_get_fps(device);
|
||||
result = acpi_fan_get_fps(&pdev->dev, device);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
|
@ -567,8 +542,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
else
|
||||
name = acpi_device_bid(device);
|
||||
|
||||
cdev = thermal_cooling_device_register(name, device,
|
||||
&fan_cooling_ops);
|
||||
cdev = thermal_cooling_device_create(&pdev->dev, name, fan, &fan_cooling_ops);
|
||||
if (IS_ERR(cdev)) {
|
||||
result = PTR_ERR(cdev);
|
||||
goto err_end;
|
||||
|
|
@ -577,28 +551,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id);
|
||||
|
||||
fan->cdev = cdev;
|
||||
result = sysfs_create_link(&pdev->dev.kobj,
|
||||
&cdev->device.kobj,
|
||||
"thermal_cooling");
|
||||
if (result) {
|
||||
dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
|
||||
goto err_unregister;
|
||||
}
|
||||
|
||||
result = sysfs_create_link(&cdev->device.kobj,
|
||||
&pdev->dev.kobj,
|
||||
"device");
|
||||
if (result) {
|
||||
dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
|
||||
goto err_remove_link;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_link:
|
||||
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
|
||||
err_unregister:
|
||||
thermal_cooling_device_unregister(cdev);
|
||||
err_end:
|
||||
if (fan->has_fst)
|
||||
acpi_fan_delete_attributes(device);
|
||||
|
|
@ -615,8 +570,6 @@ static void acpi_fan_remove(struct platform_device *pdev)
|
|||
|
||||
acpi_fan_delete_attributes(device);
|
||||
}
|
||||
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&fan->cdev->device.kobj, "device");
|
||||
thermal_cooling_device_unregister(fan->cdev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
|||
struct acpi_fan_fst fst;
|
||||
int ret;
|
||||
|
||||
ret = acpi_fan_get_fst(fan->handle, &fst);
|
||||
ret = acpi_fan_get_fst(fan->adev->handle, &fst);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,19 +59,37 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);
|
||||
|
||||
static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
|
||||
static struct acpi_device *acpi_companion_lookup(struct device *dev)
|
||||
{
|
||||
struct acpi_bus_type *tmp, *ret = NULL;
|
||||
struct acpi_bus_type *type;
|
||||
|
||||
down_read(&bus_type_sem);
|
||||
list_for_each_entry(tmp, &bus_type_list, list) {
|
||||
if (tmp->match(dev)) {
|
||||
ret = tmp;
|
||||
break;
|
||||
if (!dev->type)
|
||||
return NULL;
|
||||
|
||||
guard(rwsem_read)(&bus_type_sem);
|
||||
|
||||
list_for_each_entry(type, &bus_type_list, list) {
|
||||
struct acpi_device *adev;
|
||||
|
||||
if (!type->match(dev))
|
||||
continue;
|
||||
|
||||
adev = type->find_companion(dev);
|
||||
if (!adev) {
|
||||
dev_dbg(dev, "ACPI companion not found\n");
|
||||
return NULL;
|
||||
}
|
||||
if (acpi_bind_one(dev, adev)) {
|
||||
dev_dbg(dev, "Binding to ACPI companion failed\n");
|
||||
return NULL;
|
||||
}
|
||||
if (type->setup)
|
||||
type->setup(dev);
|
||||
|
||||
return adev;
|
||||
}
|
||||
up_read(&bus_type_sem);
|
||||
return ret;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define FIND_CHILD_MIN_SCORE 1
|
||||
|
|
@ -228,31 +246,25 @@ static void acpi_physnode_link_name(char *buf, unsigned int node_id)
|
|||
int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
||||
{
|
||||
struct acpi_device_physical_node *physical_node, *pn;
|
||||
struct acpi_device *comp_dev = ACPI_COMPANION(dev);
|
||||
char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
|
||||
struct list_head *physnode_list;
|
||||
unsigned int node_id;
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (has_acpi_companion(dev)) {
|
||||
if (acpi_dev) {
|
||||
dev_warn(dev, "ACPI companion already set\n");
|
||||
if (!acpi_dev) {
|
||||
if (!comp_dev)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
acpi_dev = ACPI_COMPANION(dev);
|
||||
}
|
||||
}
|
||||
if (!acpi_dev)
|
||||
return -EINVAL;
|
||||
|
||||
acpi_dev_get(acpi_dev);
|
||||
get_device(dev);
|
||||
physical_node = kzalloc_obj(*physical_node);
|
||||
if (!physical_node) {
|
||||
retval = -ENOMEM;
|
||||
goto err;
|
||||
/* If the companion has been set upfront, pick it up. */
|
||||
acpi_dev = comp_dev;
|
||||
} else if (comp_dev && acpi_dev != comp_dev) {
|
||||
dev_warn(dev, "ACPI companion already set to %s which is not %s\n",
|
||||
acpi_dev_name(comp_dev), acpi_dev_name(acpi_dev));
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
mutex_lock(&acpi_dev->physical_node_lock);
|
||||
guard(mutex)(&acpi_dev->physical_node_lock);
|
||||
|
||||
/*
|
||||
* Keep the list sorted by node_id so that the IDs of removed nodes can
|
||||
|
|
@ -263,15 +275,12 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
|
||||
/* Sanity check. */
|
||||
if (pn->dev == dev) {
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
|
||||
dev_warn(dev, "Already associated with ACPI node\n");
|
||||
kfree(physical_node);
|
||||
if (ACPI_COMPANION(dev) != acpi_dev)
|
||||
goto err;
|
||||
|
||||
put_device(dev);
|
||||
acpi_dev_put(acpi_dev);
|
||||
if (!comp_dev) {
|
||||
/* Really unexpected. */
|
||||
ACPI_COMPANION_SET(dev, acpi_dev);
|
||||
dev_warn(&acpi_dev->dev,
|
||||
"Physical device list corruption fixed up\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (pn->node_id == node_id) {
|
||||
|
|
@ -280,12 +289,19 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
}
|
||||
}
|
||||
|
||||
physical_node = kzalloc_obj(*physical_node);
|
||||
if (!physical_node)
|
||||
return -ENOMEM;
|
||||
|
||||
acpi_dev_get(acpi_dev);
|
||||
get_device(dev);
|
||||
|
||||
physical_node->node_id = node_id;
|
||||
physical_node->dev = dev;
|
||||
list_add(&physical_node->node, physnode_list);
|
||||
acpi_dev->physical_node_count++;
|
||||
|
||||
if (!has_acpi_companion(dev))
|
||||
if (!comp_dev)
|
||||
ACPI_COMPANION_SET(dev, acpi_dev);
|
||||
|
||||
acpi_physnode_link_name(physical_node_name, node_id);
|
||||
|
|
@ -301,28 +317,20 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
dev_err(dev, "Failed to create link firmware_node (%d)\n",
|
||||
retval);
|
||||
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
|
||||
if (acpi_dev->wakeup.flags.valid)
|
||||
device_set_wakeup_capable(dev, true);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
ACPI_COMPANION_SET(dev, NULL);
|
||||
put_device(dev);
|
||||
acpi_dev_put(acpi_dev);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_bind_one);
|
||||
|
||||
int acpi_unbind_one(struct device *dev)
|
||||
void acpi_unbind_one(struct device *dev)
|
||||
{
|
||||
struct acpi_device *acpi_dev = ACPI_COMPANION(dev);
|
||||
struct acpi_device_physical_node *entry;
|
||||
|
||||
if (!acpi_dev)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
mutex_lock(&acpi_dev->physical_node_lock);
|
||||
|
||||
|
|
@ -337,15 +345,17 @@ int acpi_unbind_one(struct device *dev)
|
|||
sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);
|
||||
sysfs_remove_link(&dev->kobj, "firmware_node");
|
||||
ACPI_COMPANION_SET(dev, NULL);
|
||||
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
|
||||
/* Drop references taken by acpi_bind_one(). */
|
||||
put_device(dev);
|
||||
acpi_dev_put(acpi_dev);
|
||||
kfree(entry);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_unbind_one);
|
||||
|
||||
|
|
@ -354,48 +364,29 @@ void acpi_device_notify(struct device *dev)
|
|||
struct acpi_device *adev;
|
||||
int ret;
|
||||
|
||||
/* ACPI devices have no ACPI companions. */
|
||||
if (dev->bus == &acpi_bus_type)
|
||||
return;
|
||||
|
||||
ret = acpi_bind_one(dev, NULL);
|
||||
if (ret) {
|
||||
struct acpi_bus_type *type = acpi_get_bus_type(dev);
|
||||
|
||||
if (!type)
|
||||
goto err;
|
||||
|
||||
adev = type->find_companion(dev);
|
||||
if (!adev) {
|
||||
dev_dbg(dev, "ACPI companion not found\n");
|
||||
goto err;
|
||||
}
|
||||
ret = acpi_bind_one(dev, adev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (type->setup) {
|
||||
type->setup(dev);
|
||||
goto done;
|
||||
}
|
||||
adev = acpi_companion_lookup(dev);
|
||||
if (!adev)
|
||||
return;
|
||||
} else {
|
||||
adev = ACPI_COMPANION(dev);
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
pci_acpi_setup(dev, adev);
|
||||
goto done;
|
||||
} else if (dev_is_platform(dev)) {
|
||||
acpi_configure_pmsi_domain(dev);
|
||||
|
||||
if (adev->handler && adev->handler->bind)
|
||||
adev->handler->bind(dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (adev->handler && adev->handler->bind)
|
||||
adev->handler->bind(dev);
|
||||
|
||||
done:
|
||||
acpi_handle_debug(ACPI_HANDLE(dev), "Bound to device %s\n",
|
||||
dev_name(dev));
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
dev_dbg(dev, "No ACPI support\n");
|
||||
dev_dbg(dev, "Bound to ACPI device %s\n", acpi_dev_name(adev));
|
||||
}
|
||||
|
||||
void acpi_device_notify_remove(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ void acpi_turn_off_unused_power_resources(void);
|
|||
Device Power Management
|
||||
-------------------------------------------------------------------------- */
|
||||
int acpi_device_get_power(struct acpi_device *device, int *state);
|
||||
int acpi_bus_init_power(struct acpi_device *device);
|
||||
int acpi_wakeup_device_init(void);
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -995,7 +995,7 @@ static int hmat_calculate_adistance(struct notifier_block *self,
|
|||
return NOTIFY_STOP;
|
||||
}
|
||||
|
||||
static struct notifier_block hmat_adist_nb __meminitdata = {
|
||||
static struct notifier_block hmat_adist_nb = {
|
||||
.notifier_call = hmat_calculate_adistance,
|
||||
.priority = 100,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ int __init fix_pxm_node_maps(int max_nid)
|
|||
for (j = 0; j <= max_nid; j++) {
|
||||
if ((emu_nid_to_phys[j] == i) &&
|
||||
WARN(node_to_pxm_map_copy[j] != PXM_INVAL,
|
||||
"Node %d is already binded to PXM %d\n",
|
||||
"Node %d is already bound to PXM %d\n",
|
||||
j, node_to_pxm_map_copy[j]))
|
||||
return -1;
|
||||
if (emu_nid_to_phys[j] == i) {
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
|
|||
{
|
||||
static char buffer[512];
|
||||
|
||||
vsprintf(buffer, fmt, args);
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
|
||||
#ifdef ENABLE_DEBUGGER
|
||||
if (acpi_in_debugger) {
|
||||
|
|
|
|||
|
|
@ -787,6 +787,7 @@ static void acpi_pci_link_remove(struct acpi_device *device)
|
|||
list_del(&link->list);
|
||||
mutex_unlock(&acpi_link_lock);
|
||||
|
||||
device->driver_data = NULL;
|
||||
kfree(link);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ static int start_update(int action, struct pfru_device *pfru_dev)
|
|||
|
||||
static long pfru_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct pfru_update_cap_info cap_hdr;
|
||||
struct pfru_update_cap_info cap_hdr = {};
|
||||
struct pfru_device *pfru_dev = to_pfru_dev(file);
|
||||
void __user *p = (void __user *)arg;
|
||||
u32 rev;
|
||||
|
|
|
|||
|
|
@ -1121,6 +1121,44 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
|
|||
}
|
||||
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Acer Swift 3 SF314-56G with NVIDIA MX250 suffers from the
|
||||
* same ACPI power resource regression as the Thunderobot ZERO.
|
||||
* The power resource controlling the dGPU is incorrectly turned off
|
||||
* during initialization, causing the GPU to fall off the bus (D3cold).
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Swift SF314-56G"),
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
/*
|
||||
* CASPER EXCALIBUR G900 laptop: Keep unused ACPI power
|
||||
* resources on to prevent the NVIDIA dGPU and NVMe #2
|
||||
* from becoming inaccessible.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "CASPER BILGISAYAR SISTEMLERI"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "EXCALIBUR G900"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NLCC 001"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Acer Aspire A515-53G: Two SSDTs both define power resources
|
||||
* for the dGPU root port RP05 ('PC01' and 'PCRP'). Only PC01 ends
|
||||
* up in RP05's _PR0/_PR3, so 'PCRP' is shut down on
|
||||
* initialization, cutting power to the NVIDIA dGPU behind the
|
||||
* back of 'PC01' and making the dGPU unavailable.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A515-53G"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ static int __acpi_processor_start(struct acpi_device *device)
|
|||
|
||||
acpi_pss_perf_init(pr);
|
||||
|
||||
result = acpi_processor_thermal_init(pr, device);
|
||||
result = acpi_processor_thermal_init(pr);
|
||||
if (result)
|
||||
goto err_power_exit;
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ static int __acpi_processor_start(struct acpi_device *device)
|
|||
return 0;
|
||||
|
||||
err_thermal_exit:
|
||||
acpi_processor_thermal_exit(pr, device);
|
||||
acpi_processor_thermal_exit(pr);
|
||||
err_power_exit:
|
||||
acpi_processor_power_exit(pr);
|
||||
return result;
|
||||
|
|
@ -203,7 +203,7 @@ static int acpi_processor_stop(struct device *dev)
|
|||
|
||||
acpi_cppc_processor_exit(pr);
|
||||
|
||||
acpi_processor_thermal_exit(pr, device);
|
||||
acpi_processor_thermal_exit(pr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,15 +235,7 @@ static int
|
|||
processor_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct acpi_device *device = cdev->devdata;
|
||||
struct acpi_processor *pr;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
pr = acpi_driver_data(device);
|
||||
if (!pr)
|
||||
return -EINVAL;
|
||||
struct acpi_processor *pr = cdev->devdata;
|
||||
|
||||
*state = acpi_processor_max_state(pr);
|
||||
return 0;
|
||||
|
|
@ -253,15 +245,7 @@ static int
|
|||
processor_get_cur_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *cur_state)
|
||||
{
|
||||
struct acpi_device *device = cdev->devdata;
|
||||
struct acpi_processor *pr;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
pr = acpi_driver_data(device);
|
||||
if (!pr)
|
||||
return -EINVAL;
|
||||
struct acpi_processor *pr = cdev->devdata;
|
||||
|
||||
*cur_state = cpufreq_get_cur_state(pr->id);
|
||||
if (pr->flags.throttling)
|
||||
|
|
@ -273,18 +257,10 @@ static int
|
|||
processor_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long state)
|
||||
{
|
||||
struct acpi_device *device = cdev->devdata;
|
||||
struct acpi_processor *pr;
|
||||
struct acpi_processor *pr = cdev->devdata;
|
||||
int result = 0;
|
||||
int max_pstate;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
pr = acpi_driver_data(device);
|
||||
if (!pr)
|
||||
return -EINVAL;
|
||||
|
||||
max_pstate = cpufreq_get_max_state(pr->id);
|
||||
|
||||
if (state > acpi_processor_max_state(pr))
|
||||
|
|
@ -308,55 +284,21 @@ const struct thermal_cooling_device_ops processor_cooling_ops = {
|
|||
.set_cur_state = processor_set_cur_state,
|
||||
};
|
||||
|
||||
int acpi_processor_thermal_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
int acpi_processor_thermal_init(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
pr->cdev = thermal_cooling_device_create(pr->dev, "Processor", pr,
|
||||
&processor_cooling_ops);
|
||||
if (IS_ERR(pr->cdev))
|
||||
return PTR_ERR(pr->cdev);
|
||||
|
||||
pr->cdev = thermal_cooling_device_register("Processor", device,
|
||||
&processor_cooling_ops);
|
||||
if (IS_ERR(pr->cdev)) {
|
||||
result = PTR_ERR(pr->cdev);
|
||||
return result;
|
||||
}
|
||||
|
||||
dev_dbg(&device->dev, "registered as cooling_device%d\n",
|
||||
pr->cdev->id);
|
||||
|
||||
result = sysfs_create_link(&device->dev.kobj,
|
||||
&pr->cdev->device.kobj,
|
||||
"thermal_cooling");
|
||||
if (result) {
|
||||
dev_err(&device->dev,
|
||||
"Failed to create sysfs link 'thermal_cooling'\n");
|
||||
goto err_thermal_unregister;
|
||||
}
|
||||
|
||||
result = sysfs_create_link(&pr->cdev->device.kobj,
|
||||
&device->dev.kobj,
|
||||
"device");
|
||||
if (result) {
|
||||
dev_err(&pr->cdev->device,
|
||||
"Failed to create sysfs link 'device'\n");
|
||||
goto err_remove_sysfs_thermal;
|
||||
}
|
||||
dev_dbg(pr->dev, "registered as cooling_device%d\n", pr->cdev->id);
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_sysfs_thermal:
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
err_thermal_unregister:
|
||||
thermal_cooling_device_unregister(pr->cdev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void acpi_processor_thermal_exit(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
void acpi_processor_thermal_exit(struct acpi_processor *pr)
|
||||
{
|
||||
if (pr->cdev) {
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&pr->cdev->device.kobj, "device");
|
||||
if (!IS_ERR_OR_NULL(pr->cdev)) {
|
||||
thermal_cooling_device_unregister(pr->cdev);
|
||||
pr->cdev = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ static struct acpi_battery_reader state_readers[] = {
|
|||
{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
|
||||
{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
|
||||
{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
|
||||
{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
|
||||
{0x0d, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
|
||||
{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
|
||||
};
|
||||
|
||||
|
|
@ -639,10 +639,8 @@ static int acpi_sbs_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
|
||||
sbs = kzalloc_obj(struct acpi_sbs);
|
||||
if (!sbs) {
|
||||
result = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
if (!sbs)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&sbs->lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/kthread.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_data/x86/apple.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <linux/crc32.h>
|
||||
|
|
@ -637,10 +638,9 @@ static struct acpi_device *handle_to_device(acpi_handle handle,
|
|||
|
||||
status = acpi_get_data_full(handle, acpi_scan_drop_device,
|
||||
(void **)&adev, callback);
|
||||
if (ACPI_FAILURE(status) || !adev) {
|
||||
acpi_handle_debug(handle, "No context!\n");
|
||||
if (ACPI_FAILURE(status) || !adev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return adev;
|
||||
}
|
||||
|
||||
|
|
@ -1143,8 +1143,7 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
|
|||
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
|
||||
}
|
||||
|
||||
if (acpi_bus_init_power(device))
|
||||
device->flags.power_manageable = 0;
|
||||
device->power.state = ACPI_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static void acpi_bus_get_flags(struct acpi_device *device)
|
||||
|
|
@ -2338,50 +2337,57 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
|
|||
static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
|
||||
{
|
||||
bool skip = !first_pass && device->flags.visited;
|
||||
struct pci_dev *pci;
|
||||
acpi_handle ejd;
|
||||
int ret;
|
||||
|
||||
if (skip)
|
||||
goto ok;
|
||||
|
||||
device->flags.initialized = true;
|
||||
|
||||
if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd)))
|
||||
register_dock_dependent_device(device, ejd);
|
||||
|
||||
acpi_bus_get_status(device);
|
||||
/* Skip devices that are not ready for enumeration (e.g. not present) */
|
||||
if (!acpi_dev_ready_for_enumeration(device)) {
|
||||
device->flags.initialized = false;
|
||||
/*
|
||||
* If the given ACPI device object has been already associated with a
|
||||
* PCI device found on the bus, its status is effectively "present and
|
||||
* enabled", and dependencies are not tracked for PCI devices, so it is
|
||||
* not necessary or even useful to check the device's readiness in that
|
||||
* case.
|
||||
*/
|
||||
pci = acpi_dev_get_pci_dev(device);
|
||||
if (pci) {
|
||||
acpi_handle_debug(device->handle, "PCI companion %s found\n",
|
||||
pci_name(pci));
|
||||
|
||||
if (!acpi_device_is_present(device))
|
||||
pci_info(pci, FW_BUG "ACPI status differs from reality\n");
|
||||
|
||||
pci_dev_put(pci);
|
||||
} else if (!acpi_dev_ready_for_enumeration(device)) {
|
||||
/* The device is not ready (e.g. not present), so skip it. */
|
||||
acpi_device_clear_enumerated(device);
|
||||
device->flags.power_manageable = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (device->handler)
|
||||
goto ok;
|
||||
|
||||
acpi_ec_register_opregions(device);
|
||||
|
||||
if (!device->flags.initialized) {
|
||||
device->flags.power_manageable =
|
||||
device->power.states[ACPI_STATE_D0].flags.valid;
|
||||
if (acpi_bus_init_power(device))
|
||||
device->flags.power_manageable = 0;
|
||||
acpi_bus_init_power(device);
|
||||
|
||||
device->flags.initialized = true;
|
||||
} else if (device->flags.visited) {
|
||||
if (device->flags.visited)
|
||||
goto ok;
|
||||
}
|
||||
|
||||
ret = acpi_scan_attach_handler(device);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
if (ret > 0 && !device->flags.enumeration_by_parent) {
|
||||
acpi_device_set_enumerated(device);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (device->pnp.type.platform_id || device->pnp.type.backlight ||
|
||||
device->flags.enumeration_by_parent)
|
||||
if (device->flags.enumeration_by_parent ||
|
||||
(!ret && (device->pnp.type.platform_id || device->pnp.type.backlight)))
|
||||
acpi_default_enumeration(device);
|
||||
else
|
||||
acpi_device_set_enumerated(device);
|
||||
|
|
|
|||
|
|
@ -548,7 +548,6 @@ static void acpi_pm_end(void)
|
|||
acpi_sleep_tts_switch(acpi_target_sleep_state);
|
||||
}
|
||||
#else /* !CONFIG_ACPI_SLEEP */
|
||||
#define sleep_no_lps0 (1)
|
||||
#define acpi_target_sleep_state ACPI_STATE_S0
|
||||
#define acpi_sleep_default_s3 (1)
|
||||
static inline void acpi_sleep_dmi_check(void) {}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
|
@ -181,10 +182,10 @@ static int param_set_trace_method_name(const char *val,
|
|||
|
||||
/* This is a hack. We can't kmalloc in early boot. */
|
||||
if (is_abs_path)
|
||||
strcpy(trace_method_name, val);
|
||||
strscpy(trace_method_name, val, sizeof(trace_method_name));
|
||||
else {
|
||||
trace_method_name[0] = '\\';
|
||||
strcpy(trace_method_name+1, val);
|
||||
strscpy(trace_method_name + 1, val, sizeof(trace_method_name) - 1);
|
||||
}
|
||||
|
||||
/* Restore the original tracer state */
|
||||
|
|
|
|||
|
|
@ -560,6 +560,9 @@ acpi_table_initrd_override(struct acpi_table_header *existing_table,
|
|||
while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
|
||||
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
|
||||
ACPI_HEADER_SIZE);
|
||||
if (!table)
|
||||
return AE_NO_MEMORY;
|
||||
|
||||
if (table_offset + table->length > all_tables_size) {
|
||||
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||
WARN_ON(1);
|
||||
|
|
|
|||
|
|
@ -564,17 +564,20 @@ static bool acpi_thermal_should_bind_cdev(struct thermal_zone_device *thermal,
|
|||
struct cooling_spec *c)
|
||||
{
|
||||
struct acpi_thermal_trip *acpi_trip = trip->priv;
|
||||
struct acpi_device *cdev_adev = cdev->devdata;
|
||||
struct device *parent = cdev->device.parent;
|
||||
acpi_handle parent_handle;
|
||||
int i;
|
||||
|
||||
/* Skip critical and hot trips. */
|
||||
if (!acpi_trip)
|
||||
/* Skip critical and hot trips and parentless cooling devices. */
|
||||
if (!acpi_trip || !parent)
|
||||
return false;
|
||||
|
||||
parent_handle = ACPI_HANDLE(parent);
|
||||
if (!parent_handle)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < acpi_trip->devices.count; i++) {
|
||||
acpi_handle handle = acpi_trip->devices.handles[i];
|
||||
|
||||
if (acpi_fetch_acpi_dev(handle) == cdev_adev)
|
||||
if (acpi_trip->devices.handles[i] == parent_handle)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -738,7 +741,9 @@ static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
|
|||
*/
|
||||
static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp)
|
||||
{
|
||||
if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1)
|
||||
if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 0)
|
||||
tz->kelvin_offset = 273000;
|
||||
else if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1)
|
||||
tz->kelvin_offset = 273100;
|
||||
else
|
||||
tz->kelvin_offset = 273200;
|
||||
|
|
|
|||
|
|
@ -883,6 +883,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7770 AIO"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* Dell OptiPlex AIO 7410 35W */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex AIO 7410 35W"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Models which have nvidia-ec-wmi support, but should not use it.
|
||||
|
|
@ -929,6 +937,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN515-46"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* Acer Nitro AN515-58 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN515-58"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* x86 android tablets which directly control the backlight through
|
||||
|
|
|
|||
|
|
@ -24,6 +24,34 @@
|
|||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
|
||||
static void acpi_setup_ixx_gpes(void)
|
||||
{
|
||||
acpi_handle gpe_root;
|
||||
unsigned int i;
|
||||
char gpe_nr_str[5];
|
||||
|
||||
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_GPE", &gpe_root)))
|
||||
return;
|
||||
|
||||
for (i = 0; i <= 0xff; i++) {
|
||||
scnprintf(gpe_nr_str, sizeof(gpe_nr_str), "_I%02X", i);
|
||||
if (!acpi_has_method(gpe_root, gpe_nr_str))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Enable the GPE if it has a handler method because marking it
|
||||
* as wake-capable causes acpi_update_all_gpes() to skip it.
|
||||
*/
|
||||
if (ACPI_FAILURE(acpi_enable_gpe_cond(NULL, i, ACPI_GPE_DISPATCH_METHOD)))
|
||||
continue;
|
||||
|
||||
acpi_mark_gpe_for_wake(NULL, i);
|
||||
acpi_set_gpe_wake_mask(NULL, i, ACPI_GPE_ENABLE);
|
||||
|
||||
pm_pr_dbg("ACPI: GPE0x%02x armed for wake via %s\n", i, gpe_nr_str);
|
||||
}
|
||||
}
|
||||
|
||||
static bool sleep_no_lps0 __read_mostly;
|
||||
module_param(sleep_no_lps0, bool, 0644);
|
||||
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
|
||||
|
|
@ -649,6 +677,7 @@ void __init acpi_s2idle_setup(void)
|
|||
{
|
||||
acpi_scan_add_handler(&lps0_handler);
|
||||
s2idle_set_ops(&acpi_s2idle_ops_lps0);
|
||||
acpi_setup_ixx_gpes();
|
||||
}
|
||||
|
||||
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
* @drivers_autoprobe: gate whether new devices are automatically attached to
|
||||
* registered drivers, or new drivers automatically attach
|
||||
* to existing devices.
|
||||
* @no_drivers: gate whether drivers can be registered.
|
||||
* @bus: pointer back to the struct bus_type that this structure is associated
|
||||
* with.
|
||||
* @dev_root: Default device to use as the parent.
|
||||
|
|
@ -51,6 +52,7 @@ struct subsys_private {
|
|||
struct klist klist_drivers;
|
||||
struct blocking_notifier_head bus_notifier;
|
||||
unsigned int drivers_autoprobe:1;
|
||||
unsigned int no_drivers:1;
|
||||
const struct bus_type *bus;
|
||||
struct device *dev_root;
|
||||
|
||||
|
|
|
|||
|
|
@ -738,6 +738,11 @@ int bus_add_driver(struct device_driver *drv)
|
|||
if (!sp)
|
||||
return -EINVAL;
|
||||
|
||||
if (sp->no_drivers) {
|
||||
error = -ENXIO;
|
||||
goto out_put_bus;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reference in sp is now incremented and will be dropped when
|
||||
* the driver is removed from the bus
|
||||
|
|
@ -930,15 +935,7 @@ static ssize_t bus_uevent_store(const struct bus_type *bus,
|
|||
static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL,
|
||||
bus_uevent_store);
|
||||
|
||||
/**
|
||||
* bus_register - register a driver-core subsystem
|
||||
* @bus: bus to register
|
||||
*
|
||||
* Once we have that, we register the bus with the kobject
|
||||
* infrastructure, then register the children subsystems it has:
|
||||
* the devices and drivers that belong to the subsystem.
|
||||
*/
|
||||
int bus_register(const struct bus_type *bus)
|
||||
static int bus_register_internal(const struct bus_type *bus, bool use_drivers)
|
||||
{
|
||||
int retval;
|
||||
struct subsys_private *priv;
|
||||
|
|
@ -960,7 +957,8 @@ int bus_register(const struct bus_type *bus)
|
|||
|
||||
bus_kobj->kset = bus_kset;
|
||||
bus_kobj->ktype = &bus_ktype;
|
||||
priv->drivers_autoprobe = 1;
|
||||
priv->drivers_autoprobe = use_drivers;
|
||||
priv->no_drivers = !use_drivers;
|
||||
|
||||
retval = kset_register(&priv->subsys);
|
||||
if (retval)
|
||||
|
|
@ -976,6 +974,10 @@ int bus_register(const struct bus_type *bus)
|
|||
goto bus_devices_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the drivers kset even if use_drivers is unset to prevent some
|
||||
* older versions of systemd from failing.
|
||||
*/
|
||||
priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
|
||||
if (!priv->drivers_kset) {
|
||||
retval = -ENOMEM;
|
||||
|
|
@ -989,9 +991,11 @@ int bus_register(const struct bus_type *bus)
|
|||
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
|
||||
klist_init(&priv->klist_drivers, NULL, NULL);
|
||||
|
||||
retval = add_probe_files(bus);
|
||||
if (retval)
|
||||
goto bus_probe_files_fail;
|
||||
if (use_drivers) {
|
||||
retval = add_probe_files(bus);
|
||||
if (retval)
|
||||
goto bus_probe_files_fail;
|
||||
}
|
||||
|
||||
retval = sysfs_create_groups(bus_kobj, bus->bus_groups);
|
||||
if (retval)
|
||||
|
|
@ -1016,8 +1020,40 @@ int bus_register(const struct bus_type *bus)
|
|||
kfree(priv);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* bus_register - register a driver-core subsystem
|
||||
* @bus: bus to register
|
||||
*
|
||||
* Once we have that, we register the bus with the kobject
|
||||
* infrastructure, then register the children subsystems it has:
|
||||
* the devices and drivers that belong to the subsystem.
|
||||
*/
|
||||
int bus_register(const struct bus_type *bus)
|
||||
{
|
||||
return bus_register_internal(bus, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bus_register);
|
||||
|
||||
/**
|
||||
* companion_bus_register - register a companion bus type
|
||||
* @bus: companion bus to register
|
||||
*
|
||||
* A companion bus is a bus without drivers. Devices that belong to it can be
|
||||
* bound to other devices as their "companions" and represent interfaces that
|
||||
* can be used by the drivers of those other devices. They may also be used for
|
||||
* the enumeration of those other devices.
|
||||
*
|
||||
* The ACPI bus is a specific example of a companion bus.
|
||||
*
|
||||
* Registering a companion bus is like registering a regular bus except that it
|
||||
* skips the creation of sysfs interfaces related to drivers for @bus.
|
||||
*/
|
||||
int companion_bus_register(const struct bus_type *bus)
|
||||
{
|
||||
return bus_register_internal(bus, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* bus_unregister - remove a bus from the system
|
||||
* @bus: bus.
|
||||
|
|
@ -1415,6 +1451,11 @@ struct device_driver *driver_find(const char *name, const struct bus_type *bus)
|
|||
if (!sp)
|
||||
return NULL;
|
||||
|
||||
if (sp->no_drivers) {
|
||||
subsys_put(sp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
k = kset_find_obj(sp->drivers_kset, name);
|
||||
subsys_put(sp);
|
||||
if (!k)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ static int match_memdev_by_parent(struct device *dev, const void *uport)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
|
||||
static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
|
||||
{
|
||||
unsigned int devfn = PCI_DEVFN(data->prot_err.agent_addr.device,
|
||||
data->prot_err.agent_addr.function);
|
||||
|
|
@ -118,7 +118,6 @@ void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
|
|||
else
|
||||
cxl_cper_trace_uncorr_prot_err(cxlmd, data->ras_cap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxl_cper_handle_prot_err);
|
||||
|
||||
static void cxl_cper_prot_err_work_fn(struct work_struct *work)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ void cxl_dport_map_rch_aer(struct cxl_dport *dport)
|
|||
aer_phys = aer_cap + dport->rcrb.base;
|
||||
dport->regs.dport_aer =
|
||||
devm_cxl_iomap_block(host, aer_phys,
|
||||
sizeof(struct aer_capability_regs));
|
||||
PCIE_AER_CAP_HW_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,31 +58,20 @@ void cxl_disable_rch_root_ints(struct cxl_dport *dport)
|
|||
static bool cxl_rch_get_aer_info(void __iomem *aer_base,
|
||||
struct aer_capability_regs *aer_regs)
|
||||
{
|
||||
/*
|
||||
* Bound the copy to the physically-defined AER registers (header
|
||||
* through the 16-byte Header Log). struct aer_capability_regs is a
|
||||
* software layout whose embedded struct pcie_tlp_log is larger than
|
||||
* the on-wire AER capability; copying sizeof(*aer_regs) would
|
||||
* over-read the RCRB-mapped MMIO block.
|
||||
*/
|
||||
int read_cnt = (PCI_ERR_HEADER_LOG + 16) / sizeof(u32);
|
||||
u32 *aer_regs_buf = (u32 *)aer_regs;
|
||||
int n;
|
||||
/* A flat copy cannot fill the struct; aer_cap_regs_unpack() places it. */
|
||||
__le32 raw[PCIE_AER_CAP_HW_SIZE / sizeof(__le32)];
|
||||
|
||||
if (!aer_base)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Zero the destination so the software-only tail fields
|
||||
* (e.g. header_log.header_len) are deterministic rather than
|
||||
* left as uninitialized stack, which could drive a bogus loop
|
||||
* length in pcie_print_tlp_log().
|
||||
* Use readl() to guarantee 32-bit accesses; it returns host order, so
|
||||
* put the registers back little-endian for aer_cap_regs_unpack().
|
||||
*/
|
||||
memset(aer_regs, 0, sizeof(*aer_regs));
|
||||
for (int n = 0; n < ARRAY_SIZE(raw); n++)
|
||||
raw[n] = cpu_to_le32(readl(aer_base + n * sizeof(u32)));
|
||||
|
||||
/* Use readl() to guarantee 32-bit accesses */
|
||||
for (n = 0; n < read_cnt; n++)
|
||||
aer_regs_buf[n] = readl(aer_base + n * sizeof(u32));
|
||||
aer_cap_regs_unpack(aer_regs, raw, sizeof(raw));
|
||||
|
||||
writel(aer_regs->uncor_status, aer_base + PCI_ERR_UNCOR_STATUS);
|
||||
writel(aer_regs->cor_status, aer_base + PCI_ERR_COR_STATUS);
|
||||
|
|
|
|||
|
|
@ -389,10 +389,28 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
|
|||
cmem->requestor_id = mem->requestor_id;
|
||||
cmem->responder_id = mem->responder_id;
|
||||
cmem->target_id = mem->target_id;
|
||||
cmem->extended = mem->extended;
|
||||
cmem->rank = mem->rank;
|
||||
cmem->mem_array_handle = mem->mem_array_handle;
|
||||
cmem->mem_dev_handle = mem->mem_dev_handle;
|
||||
|
||||
/*
|
||||
* These four sit past the end of the UEFI 2.1/2.2 layout, which older
|
||||
* firmware still emits, so reading them unconditionally runs off a
|
||||
* short record. Every consumer of the compact record gates them on the
|
||||
* same validation bits, so leave them zero when firmware does not
|
||||
* claim them.
|
||||
*/
|
||||
cmem->extended = 0;
|
||||
cmem->rank = 0;
|
||||
cmem->mem_array_handle = 0;
|
||||
cmem->mem_dev_handle = 0;
|
||||
|
||||
if (mem->validation_bits &
|
||||
(CPER_MEM_VALID_ROW_EXT | CPER_MEM_VALID_CHIP_ID))
|
||||
cmem->extended = mem->extended;
|
||||
if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
|
||||
cmem->rank = mem->rank;
|
||||
if (mem->validation_bits & CPER_MEM_VALID_CARD_HANDLE)
|
||||
cmem->mem_array_handle = mem->mem_array_handle;
|
||||
if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)
|
||||
cmem->mem_dev_handle = mem->mem_dev_handle;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cper_mem_err_pack);
|
||||
|
||||
|
|
@ -745,6 +763,17 @@ int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
|
|||
estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* cper_estatus_len() sums these into a u32, and a wrapped sum reads
|
||||
* back smaller than the record. Reject a length that cannot be
|
||||
* expressed so no caller is handed the short value.
|
||||
*/
|
||||
if ((u64)sizeof(*estatus) + estatus->data_length > U32_MAX)
|
||||
return -EINVAL;
|
||||
if (estatus->raw_data_length &&
|
||||
(u64)estatus->raw_data_offset + estatus->raw_data_length > U32_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cper_estatus_check_header);
|
||||
|
|
@ -752,7 +781,7 @@ EXPORT_SYMBOL_GPL(cper_estatus_check_header);
|
|||
int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
|
||||
{
|
||||
struct acpi_hest_generic_data *gdata;
|
||||
unsigned int data_len, record_size;
|
||||
unsigned int data_len;
|
||||
int rc;
|
||||
|
||||
rc = cper_estatus_check_header(estatus);
|
||||
|
|
@ -762,10 +791,18 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
|
|||
data_len = estatus->data_length;
|
||||
|
||||
apei_estatus_for_each_section(estatus, gdata) {
|
||||
if (acpi_hest_get_size(gdata) > data_len)
|
||||
int record_size;
|
||||
|
||||
/*
|
||||
* The <acpi/ghes.h> helpers sum these as a signed int, so a
|
||||
* huge error_data_length wraps small rather than large and the
|
||||
* walk then advances by that wrapped value. Reject a size an
|
||||
* int cannot carry.
|
||||
*/
|
||||
if (check_add_overflow(acpi_hest_get_size(gdata),
|
||||
gdata->error_data_length, &record_size))
|
||||
return -EINVAL;
|
||||
|
||||
record_size = acpi_hest_get_record_size(gdata);
|
||||
if (record_size > data_len)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ static long __init parse_acpi_path(const struct efi_dev_path *node,
|
|||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
phys_dev = acpi_get_first_physical_node(adev);
|
||||
phys_dev = acpi_bus_get_primary_device(adev);
|
||||
if (phys_dev) {
|
||||
*child = get_device(phys_dev);
|
||||
*child = phys_dev;
|
||||
acpi_dev_put(adev);
|
||||
} else
|
||||
*child = &adev->dev;
|
||||
|
|
|
|||
|
|
@ -5307,7 +5307,7 @@ static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
|
|||
adev = acpi_dev_get_first_match_dev("NVDA200C", uid, -1);
|
||||
if (adev) {
|
||||
/* Tegra241 CMDQV driver is responsible for put_device() */
|
||||
smmu->impl_dev = get_device(acpi_get_first_physical_node(adev));
|
||||
smmu->impl_dev = acpi_bus_get_primary_device(adev);
|
||||
smmu->options |= ARM_SMMU_OPT_TEGRA241_CMDQV;
|
||||
dev_info(smmu->dev, "found companion CMDQV device: %s\n",
|
||||
dev_name(smmu->impl_dev));
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@
|
|||
#include <linux/aer.h>
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include "../pci.h"
|
||||
|
||||
|
|
@ -92,6 +95,91 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* The Prefix Log registers hold dw[4..13] in Flit mode. */
|
||||
static_assert((PCI_ERR_PREFIX_LOG +
|
||||
(PCIE_STD_MAX_TLP_HEADERLOG - PCIE_STD_NUM_TLP_HEADERLOG) *
|
||||
sizeof(u32)) == PCIE_AER_CAP_HW_SIZE);
|
||||
|
||||
/**
|
||||
* aer_cap_regs_unpack - Convert a raw AER Capability image to the kernel layout
|
||||
* @regs: Destination, fully initialised
|
||||
* @raw: AER Capability register block in hardware order, little-endian
|
||||
* @raw_len: Bytes readable at @raw
|
||||
*
|
||||
* struct aer_capability_regs is not the hardware layout: struct pcie_tlp_log
|
||||
* spans 60 bytes where the Header Log it stands in for is 16, so a flat copy
|
||||
* misplaces everything behind it. Map the registers one by one instead,
|
||||
* taking the TLP Log layout from the Flit bit as pcie_read_tlp_log() does.
|
||||
*
|
||||
* @raw is not necessarily aligned. Registers past @raw_len are left zero, so
|
||||
* a short image cannot be read past.
|
||||
*/
|
||||
void aer_cap_regs_unpack(struct aer_capability_regs *regs, const void *raw,
|
||||
size_t raw_len)
|
||||
{
|
||||
unsigned int i, tlp_len;
|
||||
bool flit;
|
||||
|
||||
memset(regs, 0, sizeof(*regs));
|
||||
|
||||
if (raw_len < PCI_ERR_HEADER_LOG)
|
||||
return;
|
||||
|
||||
/* The Extended Capability Header, at offset 0, has no define */
|
||||
regs->header = get_unaligned_le32(raw);
|
||||
regs->uncor_status = get_unaligned_le32(raw + PCI_ERR_UNCOR_STATUS);
|
||||
regs->uncor_mask = get_unaligned_le32(raw + PCI_ERR_UNCOR_MASK);
|
||||
regs->uncor_severity = get_unaligned_le32(raw + PCI_ERR_UNCOR_SEVER);
|
||||
regs->cor_status = get_unaligned_le32(raw + PCI_ERR_COR_STATUS);
|
||||
regs->cor_mask = get_unaligned_le32(raw + PCI_ERR_COR_MASK);
|
||||
regs->cap_control = get_unaligned_le32(raw + PCI_ERR_CAP);
|
||||
|
||||
flit = FIELD_GET(PCI_ERR_CAP_TLP_LOG_FLIT, regs->cap_control);
|
||||
if (flit) {
|
||||
tlp_len = FIELD_GET(PCI_ERR_CAP_TLP_LOG_SIZE, regs->cap_control);
|
||||
} else {
|
||||
/*
|
||||
* dw[4..7] alias the Prefix Log. Take all four whatever
|
||||
* eetlp_prefix_max says; pcie_print_tlp_log() stops at the
|
||||
* first zero one.
|
||||
*/
|
||||
tlp_len = PCIE_STD_NUM_TLP_HEADERLOG + PCIE_STD_MAX_TLP_PREFIXLOG;
|
||||
}
|
||||
|
||||
tlp_len = min(tlp_len, ARRAY_SIZE(regs->header_log.dw));
|
||||
|
||||
for (i = 0; i < tlp_len; i++) {
|
||||
unsigned int off;
|
||||
|
||||
if (i < PCIE_STD_NUM_TLP_HEADERLOG)
|
||||
off = PCI_ERR_HEADER_LOG + i * sizeof(u32);
|
||||
else
|
||||
off = PCI_ERR_PREFIX_LOG +
|
||||
(i - PCIE_STD_NUM_TLP_HEADERLOG) * sizeof(u32);
|
||||
|
||||
if (off + sizeof(u32) > raw_len)
|
||||
break;
|
||||
regs->header_log.dw[i] = get_unaligned_le32(raw + off);
|
||||
}
|
||||
|
||||
/* @i may be short of tlp_len; non-Flit needs the TLP parsed, so cap at 4 */
|
||||
regs->header_log.header_len = flit ? i : min(i, PCIE_STD_NUM_TLP_HEADERLOG);
|
||||
regs->header_log.flit = flit;
|
||||
|
||||
if (raw_len >= PCI_ERR_ROOT_COMMAND + sizeof(u32))
|
||||
regs->root_command = get_unaligned_le32(raw + PCI_ERR_ROOT_COMMAND);
|
||||
if (raw_len >= PCI_ERR_ROOT_STATUS + sizeof(u32))
|
||||
regs->root_status = get_unaligned_le32(raw + PCI_ERR_ROOT_STATUS);
|
||||
if (raw_len >= PCI_ERR_ROOT_ERR_SRC + sizeof(u32)) {
|
||||
u32 src = get_unaligned_le32(raw + PCI_ERR_ROOT_ERR_SRC);
|
||||
|
||||
/* One register: ERR_COR in 15:0, ERR_FATAL/NONFATAL in 31:16 */
|
||||
regs->cor_err_source = src;
|
||||
regs->uncor_err_source = src >> 16;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aer_cap_regs_unpack);
|
||||
|
||||
#define EE_PREFIX_STR " E-E Prefixes:"
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -353,13 +353,13 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context)
|
|||
goto error_put_devs;
|
||||
}
|
||||
|
||||
data->kbd_dev = get_device(acpi_get_first_physical_node(data->kbd_adev));
|
||||
data->kbd_dev = acpi_bus_get_primary_device(data->kbd_adev);
|
||||
if (!data->kbd_dev || !data->kbd_dev->driver) {
|
||||
r = -EPROBE_DEFER;
|
||||
goto error_put_devs;
|
||||
}
|
||||
|
||||
data->dig_dev = get_device(acpi_get_first_physical_node(data->dig_adev));
|
||||
data->dig_dev = acpi_bus_get_primary_device(data->dig_adev);
|
||||
if (!data->dig_dev || !data->dig_dev->driver) {
|
||||
r = -EPROBE_DEFER;
|
||||
goto error_put_devs;
|
||||
|
|
|
|||
|
|
@ -74,8 +74,7 @@ get_serdev_controller(const char *serial_ctrl_hid,
|
|||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
/* get_first_physical_node() returns a weak ref */
|
||||
parent = get_device(acpi_get_first_physical_node(adev));
|
||||
parent = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!parent) {
|
||||
pr_err("error could not get %s/%s serial-ctrl physical node\n",
|
||||
|
|
|
|||
|
|
@ -390,7 +390,6 @@ static int gpio_secondary_fwnode_init(struct device *parent,
|
|||
{
|
||||
const struct software_node *const *swnode;
|
||||
struct fwnode_handle *fwnode;
|
||||
struct device *phys_dev;
|
||||
int ret;
|
||||
|
||||
if (!node_group)
|
||||
|
|
@ -418,7 +417,8 @@ static int gpio_secondary_fwnode_init(struct device *parent,
|
|||
if (WARN_ON(!fwnode))
|
||||
return -ENOENT;
|
||||
|
||||
phys_dev = acpi_get_first_physical_node(to_acpi_device(dev));
|
||||
struct device *phys_dev __free(put_device) =
|
||||
acpi_bus_get_primary_device(to_acpi_device(dev));
|
||||
if (!phys_dev)
|
||||
return dev_err_probe(parent, -ENODEV,
|
||||
"No physical device for ACPI GPIO dev: %pfwP\n",
|
||||
|
|
|
|||
|
|
@ -96,13 +96,13 @@ static int pnp_device_probe(struct device *dev)
|
|||
if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
|
||||
error = pnp_activate_dev(pnp_dev);
|
||||
if (error < 0)
|
||||
return error;
|
||||
goto fail;
|
||||
}
|
||||
} else if ((pnp_drv->flags & PNP_DRIVER_RES_DISABLE)
|
||||
== PNP_DRIVER_RES_DISABLE) {
|
||||
error = pnp_disable_dev(pnp_dev);
|
||||
if (error < 0)
|
||||
return error;
|
||||
goto fail;
|
||||
}
|
||||
error = 0;
|
||||
if (pnp_drv->probe) {
|
||||
|
|
|
|||
|
|
@ -1005,7 +1005,8 @@ thermal_cooling_device_alloc(const char *type, const struct thermal_cooling_devi
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdata)
|
||||
int thermal_cooling_device_add(struct thermal_cooling_device *cdev,
|
||||
struct device *parent, void *devdata)
|
||||
{
|
||||
unsigned long current_state;
|
||||
int ret;
|
||||
|
|
@ -1013,6 +1014,7 @@ int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdat
|
|||
mutex_init(&cdev->lock);
|
||||
INIT_LIST_HEAD(&cdev->thermal_instances);
|
||||
cdev->updated = false;
|
||||
cdev->device.parent = parent;
|
||||
cdev->device.class = &thermal_class;
|
||||
cdev->device.release = thermal_cdev_release;
|
||||
device_initialize(&cdev->device);
|
||||
|
|
@ -1062,21 +1064,23 @@ int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdat
|
|||
}
|
||||
|
||||
/**
|
||||
* thermal_cooling_device_register() - register a new thermal cooling device
|
||||
* thermal_cooling_device_create() - register a new thermal cooling device
|
||||
* @parent: parent device (optional).
|
||||
* @type: the thermal cooling device type.
|
||||
* @devdata: device private data.
|
||||
* @ops: standard thermal cooling devices callbacks.
|
||||
*
|
||||
* This interface function adds a new thermal cooling device (fan/processor/...)
|
||||
* to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
|
||||
* to all the thermal zone devices registered at the same time.
|
||||
* Allocate and register a new thermal cooling device under the given parent (if
|
||||
* not NULL) and with the given type, device data, and operations. During the
|
||||
* registration, it will be matched against all of the registered thermal zones
|
||||
* and it will be bound to the matching ones.
|
||||
*
|
||||
* Return: a pointer to the created struct thermal_cooling_device or an
|
||||
* ERR_PTR. Caller must check return value with IS_ERR*() helpers.
|
||||
* Return: A pointer to the created struct thermal_cooling_device or an ERR_PTR.
|
||||
* Callers must use IS_ERR*() helpers to check the return value.
|
||||
*/
|
||||
struct thermal_cooling_device *
|
||||
thermal_cooling_device_register(const char *type, void *devdata,
|
||||
const struct thermal_cooling_device_ops *ops)
|
||||
struct thermal_cooling_device *thermal_cooling_device_create(
|
||||
struct device *parent, const char *type, void *devdata,
|
||||
const struct thermal_cooling_device_ops *ops)
|
||||
{
|
||||
struct thermal_cooling_device *cdev;
|
||||
int ret;
|
||||
|
|
@ -1085,13 +1089,13 @@ thermal_cooling_device_register(const char *type, void *devdata,
|
|||
if (IS_ERR(cdev))
|
||||
return cdev;
|
||||
|
||||
ret = thermal_cooling_device_add(cdev, devdata);
|
||||
ret = thermal_cooling_device_add(cdev, parent, devdata);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return cdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_cooling_device_register);
|
||||
EXPORT_SYMBOL_GPL(thermal_cooling_device_create);
|
||||
|
||||
static void thermal_cooling_device_release(void *data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -270,7 +270,8 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
|
|||
struct thermal_cooling_device *
|
||||
thermal_cooling_device_alloc(const char *type, const struct thermal_cooling_device_ops *ops);
|
||||
|
||||
int thermal_cooling_device_add(struct thermal_cooling_device *cdev, void *devdata);
|
||||
int thermal_cooling_device_add(struct thermal_cooling_device *cdev,
|
||||
struct device *parent, void *devdata);
|
||||
|
||||
/* Helpers */
|
||||
#define for_each_trip_desc(__tz, __td) \
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ thermal_of_cooling_device_register(struct device_node *np, u32 cdev_id,
|
|||
cdev->np = np;
|
||||
cdev->cdev_id = cdev_id;
|
||||
|
||||
ret = thermal_cooling_device_add(cdev, devdata);
|
||||
ret = thermal_cooling_device_add(cdev, NULL, devdata);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
|
|||
struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
|
||||
struct fwnode_handle *fwnode;
|
||||
struct tb_nhi *nhi = data;
|
||||
struct device *dev = NULL;
|
||||
struct pci_dev *pdev;
|
||||
struct device *dev;
|
||||
|
||||
if (!adev)
|
||||
return AE_OK;
|
||||
|
|
@ -37,7 +37,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
|
|||
* USB3 ports might not even have a physical device yet if xHCI driver
|
||||
* isn't bound yet.
|
||||
*/
|
||||
dev = acpi_get_first_physical_node(adev);
|
||||
dev = acpi_bus_get_primary_device(adev);
|
||||
if (!dev || !dev_is_pci(dev))
|
||||
goto out_put;
|
||||
|
||||
|
|
@ -74,6 +74,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
|
|||
}
|
||||
|
||||
out_put:
|
||||
put_device(dev);
|
||||
fwnode_handle_put(fwnode);
|
||||
return AE_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef __ACPI_BUS_H__
|
||||
#define __ACPI_BUS_H__
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/device.h>
|
||||
|
|
@ -58,7 +60,6 @@ bool acpi_dock_match(acpi_handle handle);
|
|||
bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs);
|
||||
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid,
|
||||
u64 rev, u64 func, union acpi_object *argv4);
|
||||
#ifdef CONFIG_ACPI
|
||||
bool
|
||||
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
|
||||
|
||||
|
|
@ -77,7 +78,6 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
|
|||
|
||||
return obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ACPI_INIT_DSM_ARGV4(cnt, eles) \
|
||||
{ \
|
||||
|
|
@ -90,8 +90,6 @@ bool acpi_dev_found(const char *hid);
|
|||
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
|
||||
bool acpi_reduced_hardware(void);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
struct proc_dir_entry;
|
||||
|
||||
#define ACPI_BUS_FILE_ROOT "acpi"
|
||||
|
|
@ -435,9 +433,9 @@ struct acpi_device_software_nodes {
|
|||
|
||||
/* Device */
|
||||
struct acpi_device {
|
||||
acpi_handle handle; /* no handle for fixed hardware */
|
||||
u32 pld_crc;
|
||||
int device_type;
|
||||
acpi_handle handle; /* no handle for fixed hardware */
|
||||
struct fwnode_handle fwnode;
|
||||
struct list_head wakeup_list;
|
||||
struct list_head del_list;
|
||||
|
|
@ -613,7 +611,6 @@ int acpi_bus_get_status(struct acpi_device *device);
|
|||
int acpi_bus_set_power(acpi_handle handle, int state);
|
||||
const char *acpi_power_state_string(int state);
|
||||
int acpi_device_set_power(struct acpi_device *device, int state);
|
||||
int acpi_bus_init_power(struct acpi_device *device);
|
||||
int acpi_device_fix_up_power(struct acpi_device *device);
|
||||
void acpi_device_fix_up_power_extended(struct acpi_device *adev);
|
||||
void acpi_device_fix_up_power_children(struct acpi_device *adev);
|
||||
|
|
@ -665,7 +662,7 @@ struct acpi_bus_type {
|
|||
int register_acpi_bus_type(struct acpi_bus_type *);
|
||||
int unregister_acpi_bus_type(struct acpi_bus_type *);
|
||||
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
|
||||
int acpi_unbind_one(struct device *dev);
|
||||
void acpi_unbind_one(struct device *dev);
|
||||
|
||||
enum acpi_bridge_type {
|
||||
ACPI_BRIDGE_TYPE_PCIE = 1,
|
||||
|
|
@ -830,7 +827,15 @@ static inline bool acpi_str_uid_match(struct acpi_device *adev, const char *uid2
|
|||
{
|
||||
const char *uid1 = acpi_device_uid(adev);
|
||||
|
||||
return uid1 && uid2 && !strcmp(uid1, uid2);
|
||||
if (!uid1 || !uid2)
|
||||
return false;
|
||||
|
||||
if (*uid1 == '\\' && uid1[1])
|
||||
uid1++;
|
||||
if (*uid2 == '\\' && uid2[1])
|
||||
uid2++;
|
||||
|
||||
return !strcmp(uid1, uid2);
|
||||
}
|
||||
|
||||
static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
|
||||
|
|
@ -857,6 +862,10 @@ static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
|
|||
*
|
||||
* Matches UID in @adev with given @uid2.
|
||||
*
|
||||
* If both the UID in @adev and @uid2 are strings, they are compared
|
||||
* after optionally skipping a leading backslash ('\') if the given
|
||||
* string contains additional characters.
|
||||
*
|
||||
* Returns: %true if matches, %false otherwise.
|
||||
*/
|
||||
#define acpi_dev_uid_match(adev, uid2) \
|
||||
|
|
@ -942,8 +951,21 @@ int acpi_wait_for_acpi_ipmi(void);
|
|||
|
||||
int acpi_scan_add_dep(acpi_handle handle, struct acpi_handle_list *dep_devices);
|
||||
u32 arch_acpi_add_auto_dep(acpi_handle handle);
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
|
||||
static inline struct acpi_device *
|
||||
acpi_find_child_device(struct acpi_device *parent, u64 address,
|
||||
bool check_children)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool acpi_has_method(acpi_handle handle, char *name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct device *acpi_bus_get_primary_device(struct acpi_device *adev)
|
||||
{
|
||||
return NULL;
|
||||
|
|
@ -959,6 +981,11 @@ static inline const char *acpi_device_hid(struct acpi_device *device)
|
|||
return "";
|
||||
}
|
||||
|
||||
static inline char *acpi_device_uid(struct acpi_device *device)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -919,6 +919,13 @@ struct acpi_iovt_iommu {
|
|||
u32 device_entry_offset;
|
||||
};
|
||||
|
||||
/* Masks for Flags field above */
|
||||
#define ACPI_IOVT_IOMMU_PCI_DEVICE (1<<0)
|
||||
#define ACPI_IOVT_IOMMU_PXM_VALID (1<<1)
|
||||
#define ACPI_IOVT_IOMMU_MAGAGE_BY_SEGMENT (1<<2)
|
||||
#define ACPI_IOVT_IOMMU_HW_CAP_SUPPORT (1<<3)
|
||||
#define ACPI_IOVT_IOMMU_MSI_INT_BYPASS (1<<4)
|
||||
|
||||
struct acpi_iovt_device_entry {
|
||||
u8 type;
|
||||
u8 length;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ int devm_ghes_register_vendor_record_notifier(struct device *dev,
|
|||
struct list_head *ghes_get_devices(void);
|
||||
|
||||
void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
|
||||
|
||||
struct cxl_cper_sec_prot_err;
|
||||
void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity, u32 len);
|
||||
#else
|
||||
static inline struct list_head *ghes_get_devices(void) { return NULL; }
|
||||
|
||||
|
|
|
|||
|
|
@ -427,10 +427,8 @@ int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi);
|
|||
#endif /* CONFIG_ACPI_PROCESSOR_IDLE */
|
||||
|
||||
/* in processor_thermal.c */
|
||||
int acpi_processor_thermal_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device);
|
||||
void acpi_processor_thermal_exit(struct acpi_processor *pr,
|
||||
struct acpi_device *device);
|
||||
int acpi_processor_thermal_init(struct acpi_processor *pr);
|
||||
void acpi_processor_thermal_exit(struct acpi_processor *pr);
|
||||
extern const struct thermal_cooling_device_ops processor_cooling_ops;
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy);
|
||||
|
|
|
|||
|
|
@ -312,13 +312,13 @@ static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err);
|
||||
int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len);
|
||||
int cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
|
||||
struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity);
|
||||
#else
|
||||
static inline int
|
||||
cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
|
||||
cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
@ -331,6 +331,4 @@ cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
|
|||
}
|
||||
#endif
|
||||
|
||||
void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *wd);
|
||||
|
||||
#endif /* _LINUX_CXL_EVENT_H */
|
||||
|
|
|
|||
|
|
@ -25,17 +25,19 @@ struct irq_domain_ops;
|
|||
#define _LINUX
|
||||
#endif
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_numa.h>
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
DEFINE_FREE(acpi_object_free, union acpi_object *, if (_T) ACPI_FREE(_T));
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/dynamic_debug.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/fw_table.h>
|
||||
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <acpi/acpi_io.h>
|
||||
#include <asm/acpi.h>
|
||||
|
|
@ -105,8 +107,6 @@ static inline const char *acpi_dev_name(struct acpi_device *adev)
|
|||
return dev_name(&adev->dev);
|
||||
}
|
||||
|
||||
struct device *acpi_get_first_physical_node(struct acpi_device *adev);
|
||||
|
||||
enum acpi_irq_model_id {
|
||||
ACPI_IRQ_MODEL_PIC = 0,
|
||||
ACPI_IRQ_MODEL_IOAPIC,
|
||||
|
|
@ -434,7 +434,7 @@ extern acpi_handle ec_get_handle(void);
|
|||
|
||||
extern bool acpi_is_pnp_device(struct acpi_device *);
|
||||
|
||||
#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
|
||||
#if IS_ENABLED(CONFIG_ACPI_WMI)
|
||||
|
||||
typedef void (*wmi_notify_handler) (union acpi_object *data, void *context);
|
||||
|
||||
|
|
@ -938,11 +938,6 @@ static inline const char *acpi_dev_name(struct acpi_device *adev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct device *acpi_get_first_physical_node(struct acpi_device *adev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void acpi_early_init(void) { }
|
||||
static inline void acpi_subsystem_init(void) { }
|
||||
|
||||
|
|
@ -1305,34 +1300,34 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
|
|||
#endif
|
||||
|
||||
/*
|
||||
* acpi_handle_<level>: Print message with ACPI prefix and object path
|
||||
* acpi_handle_<level> - Print a message with ACPI prefix and object path
|
||||
*
|
||||
* These interfaces acquire the global namespace mutex to obtain an object
|
||||
* path. In interrupt context, it shows the object path as <n/a>.
|
||||
* In thread context, the global namespace mutex is acquired to obtain the
|
||||
* object path. In interrupt context, the object path is shown as <n/a>.
|
||||
*/
|
||||
#define acpi_handle_emerg(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_EMERG, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#define acpi_handle_alert(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_ALERT, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#define acpi_handle_crit(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_CRIT, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#define acpi_handle_err(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_ERR, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#define acpi_handle_warn(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_WARNING, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#define acpi_handle_notice(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_NOTICE, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#define acpi_handle_info(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_INFO, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define acpi_handle_debug(handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
|
||||
acpi_handle_printk(KERN_DEBUG, handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#else
|
||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
#define acpi_handle_debug(handle, fmt, ...) \
|
||||
_dynamic_func_call(fmt, __acpi_handle_debug, \
|
||||
handle, pr_fmt(fmt), ##__VA_ARGS__)
|
||||
handle, dev_fmt(fmt), ##__VA_ARGS__)
|
||||
#else
|
||||
#define acpi_handle_debug(handle, fmt, ...) \
|
||||
({ \
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@
|
|||
#define PCIE_STD_MAX_TLP_PREFIXLOG 4
|
||||
#define PCIE_STD_MAX_TLP_HEADERLOG (PCIE_STD_NUM_TLP_HEADERLOG + 10)
|
||||
|
||||
/*
|
||||
* Size of the AER Capability register block in hardware, long enough for the
|
||||
* longest Flit mode TLP Log. struct aer_capability_regs below is larger and
|
||||
* laid out differently; use aer_cap_regs_unpack() to convert.
|
||||
*/
|
||||
#define PCIE_AER_CAP_HW_SIZE 96
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
struct pcie_tlp_log {
|
||||
|
|
@ -68,6 +75,8 @@ static inline void pci_aer_unmask_internal_errors(struct pci_dev *dev) { }
|
|||
|
||||
void pci_print_aer(struct pci_dev *dev, int aer_severity,
|
||||
struct aer_capability_regs *aer);
|
||||
void aer_cap_regs_unpack(struct aer_capability_regs *regs, const void *raw,
|
||||
size_t raw_len);
|
||||
int cper_severity_to_aer(int cper_severity);
|
||||
void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
|
||||
int severity, struct aer_capability_regs *aer_regs);
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty
|
|||
if (!adev)
|
||||
return false;
|
||||
|
||||
dev = get_device(acpi_get_first_physical_node(adev));
|
||||
dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!dev)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ struct bus_type {
|
|||
bool need_parent_lock;
|
||||
};
|
||||
|
||||
int __must_check companion_bus_register(const struct bus_type *bus);
|
||||
int __must_check bus_register(const struct bus_type *bus);
|
||||
|
||||
void bus_unregister(const struct bus_type *bus);
|
||||
|
|
|
|||
|
|
@ -293,8 +293,9 @@ struct device *thermal_zone_device(struct thermal_zone_device *tzd);
|
|||
void thermal_zone_device_update(struct thermal_zone_device *,
|
||||
enum thermal_notify_event);
|
||||
|
||||
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
|
||||
void *, const struct thermal_cooling_device_ops *);
|
||||
struct thermal_cooling_device *thermal_cooling_device_create(
|
||||
struct device *parent, const char *type, void *devdata,
|
||||
const struct thermal_cooling_device_ops *ops);
|
||||
|
||||
struct thermal_cooling_device *
|
||||
devm_thermal_cooling_device_register(struct device *dev, const char *type, void *devdata,
|
||||
|
|
@ -340,9 +341,9 @@ static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
|
|||
enum thermal_notify_event event)
|
||||
{ }
|
||||
|
||||
static inline struct thermal_cooling_device *
|
||||
thermal_cooling_device_register(const char *type, void *devdata,
|
||||
const struct thermal_cooling_device_ops *ops)
|
||||
static inline struct thermal_cooling_device *thermal_cooling_device_create(
|
||||
struct device *parent, const char *type, void *devdata,
|
||||
const struct thermal_cooling_device_ops *ops)
|
||||
{ return ERR_PTR(-ENODEV); }
|
||||
|
||||
static inline struct thermal_cooling_device *
|
||||
|
|
@ -391,4 +392,12 @@ static inline void thermal_pm_prepare(void) {}
|
|||
static inline void thermal_pm_complete(void) {}
|
||||
#endif /* CONFIG_THERMAL */
|
||||
|
||||
static inline struct thermal_cooling_device *thermal_cooling_device_register(
|
||||
const char *type, void *devdata,
|
||||
const struct thermal_cooling_device_ops *ops)
|
||||
{
|
||||
return thermal_cooling_device_create(NULL, type, devdata, ops);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __THERMAL_H__ */
|
||||
|
|
|
|||
|
|
@ -209,8 +209,7 @@ static int aw88399_hda_acpi_probe(struct aw88399_hda *aw88399)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct device *physdev __free(put_device) =
|
||||
get_device(acpi_get_first_physical_node(adev));
|
||||
struct device *physdev __free(put_device) = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!physdev)
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -1926,8 +1926,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
|
|||
}
|
||||
|
||||
cs35l41->dacpi = adev;
|
||||
struct device *physdev __free(put_device) =
|
||||
get_device(acpi_get_first_physical_node(adev));
|
||||
struct device *physdev __free(put_device) = acpi_bus_get_primary_device(adev);
|
||||
if (!physdev) {
|
||||
acpi_dev_put(adev);
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -100,8 +100,7 @@ static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct device *physdev __free(put_device) =
|
||||
get_device(acpi_get_first_physical_node(adev));
|
||||
struct device *physdev __free(put_device) = acpi_bus_get_primary_device(adev);
|
||||
ret = acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p);
|
||||
if (ret < 0) {
|
||||
dev_err(p->dev, "Failed to get ACPI resource.\n");
|
||||
|
|
|
|||
|
|
@ -341,8 +341,7 @@ static int tas2781_read_acpi(struct tas2781_hda *tas_hda,
|
|||
|
||||
strscpy(p->dev_name, hid, sizeof(p->dev_name));
|
||||
|
||||
struct device *physdev __free(put_device) =
|
||||
get_device(acpi_get_first_physical_node(adev));
|
||||
struct device *physdev __free(put_device) = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!physdev)
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ static int st_es8336_late_probe(struct snd_soc_card *card)
|
|||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
codec_dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!codec_dev) {
|
||||
dev_err(card->dev, "can not find codec dev\n");
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@ static int acp3x_es83xx_probe(struct snd_soc_card *card)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
codec_dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!codec_dev) {
|
||||
dev_warn(dev, "Error cannot find codec device, will defer probe\n");
|
||||
|
|
|
|||
|
|
@ -601,11 +601,11 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
codec_dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!codec_dev)
|
||||
return -EPROBE_DEFER;
|
||||
priv->codec_dev = get_device(codec_dev);
|
||||
priv->codec_dev = codec_dev;
|
||||
|
||||
/* override platform name, if required */
|
||||
byt_cht_es8316_card.dev = dev;
|
||||
|
|
|
|||
|
|
@ -1744,11 +1744,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
codec_dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
|
||||
if (codec_dev) {
|
||||
priv->codec_dev = get_device(codec_dev);
|
||||
priv->codec_dev = codec_dev;
|
||||
} else {
|
||||
/*
|
||||
* Special case for Android tablets where the codec i2c_client
|
||||
|
|
|
|||
|
|
@ -960,11 +960,11 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
codec_dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!codec_dev)
|
||||
return -EPROBE_DEFER;
|
||||
priv->codec_dev = get_device(codec_dev);
|
||||
priv->codec_dev = codec_dev;
|
||||
|
||||
/*
|
||||
* swap SSP0 if bytcr is detected
|
||||
|
|
|
|||
|
|
@ -529,7 +529,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
|||
const char *platform_name;
|
||||
struct cht_mc_private *drv;
|
||||
struct acpi_device *adev;
|
||||
struct device *codec_dev;
|
||||
bool sof_parent;
|
||||
bool found = false;
|
||||
bool is_bytcr = false;
|
||||
|
|
@ -583,8 +582,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* acpi_get_first_physical_node() returns a borrowed ref, no need to deref */
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
struct device *codec_dev __free(put_device) = acpi_bus_get_primary_device(adev);
|
||||
|
||||
acpi_dev_put(adev);
|
||||
if (!codec_dev)
|
||||
return -EPROBE_DEFER;
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ static int cs35l41_compute_codec_conf(void)
|
|||
cs35l41_name_prefixes[uid]);
|
||||
continue;
|
||||
}
|
||||
physdev = get_device(acpi_get_first_physical_node(adev));
|
||||
physdev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!physdev) {
|
||||
pr_devel("Cannot find physical node for HID %s UID %u (%s)\n", CS35L41_HID,
|
||||
|
|
|
|||
|
|
@ -702,11 +702,11 @@ static int sof_es8336_probe(struct platform_device *pdev)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
codec_dev = acpi_get_first_physical_node(adev);
|
||||
codec_dev = acpi_bus_get_primary_device(adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!codec_dev)
|
||||
return -EPROBE_DEFER;
|
||||
priv->codec_dev = get_device(codec_dev);
|
||||
priv->codec_dev = codec_dev;
|
||||
|
||||
ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card,
|
||||
mach->mach_params.platform);
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ static int loongson_card_parse_acpi(struct loongson_card_data *data)
|
|||
struct snd_soc_card *card = &data->snd_card;
|
||||
const char *codec_dai_name;
|
||||
struct acpi_device *adev;
|
||||
struct device *phy_dev;
|
||||
int i, ret;
|
||||
|
||||
/* fixup platform name based on reference node */
|
||||
|
|
@ -204,7 +203,7 @@ static int loongson_card_parse_acpi(struct loongson_card_data *data)
|
|||
if (!adev)
|
||||
return -ENOENT;
|
||||
|
||||
phy_dev = acpi_get_first_physical_node(adev);
|
||||
struct device *phy_dev __free(put_device) = acpi_bus_get_primary_device(adev);
|
||||
if (!phy_dev)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user