mirror of https://gitee.com/openkylin/linux.git
Merge branches 'acpi-sysfs', 'acpi-pci' and 'acpi-tables'
* acpi-sysfs: ACPI / sysfs: Update sysfs signature handling code ACPI / sysfs: Fix an issue for LoadTable opcode ACPI / sysfs: Use new GPE masking mechanism in GPE interface * acpi-pci: ACPI / platform: Pay attention to parent device's resources PCI: Add pci_find_resource() ACPI / PCI: fix GIC irq model default PCI IRQ polarity * acpi-tables: ACPI / tables: Remove duplicated include from tables.c ACPI / tables: do not report the number of entries ignored by acpi_parse_entries() ACPI / tables: fix acpi_parse_entries_array() so it traverses all subtables ACPI / tables: fix incorrect counts returned by acpi_parse_entries_array()
This commit is contained in:
commit
84a78c724b
|
@ -17,6 +17,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
@ -30,6 +31,22 @@ static const struct acpi_device_id forbidden_id_list[] = {
|
|||
{"", 0},
|
||||
};
|
||||
|
||||
static void acpi_platform_fill_resource(struct acpi_device *adev,
|
||||
const struct resource *src, struct resource *dest)
|
||||
{
|
||||
struct device *parent;
|
||||
|
||||
*dest = *src;
|
||||
|
||||
/*
|
||||
* If the device has parent we need to take its resources into
|
||||
* account as well because this device might consume part of those.
|
||||
*/
|
||||
parent = acpi_get_first_physical_node(adev->parent);
|
||||
if (parent && dev_is_pci(parent))
|
||||
dest->parent = pci_find_resource(to_pci_dev(parent), dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_create_platform_device - Create platform device for ACPI device node
|
||||
* @adev: ACPI device node to create a platform device for.
|
||||
|
@ -70,7 +87,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
|
|||
}
|
||||
count = 0;
|
||||
list_for_each_entry(rentry, &resource_list, node)
|
||||
resources[count++] = *rentry->res;
|
||||
acpi_platform_fill_resource(adev, rentry->res,
|
||||
&resources[count++]);
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
}
|
||||
|
|
|
@ -411,7 +411,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
|
|||
int gsi;
|
||||
u8 pin;
|
||||
int triggering = ACPI_LEVEL_SENSITIVE;
|
||||
int polarity = ACPI_ACTIVE_LOW;
|
||||
/*
|
||||
* On ARM systems with the GIC interrupt model, level interrupts
|
||||
* are always polarity high by specification; PCI legacy
|
||||
* IRQs lines are inverted before reaching the interrupt
|
||||
* controller and must therefore be considered active high
|
||||
* as default.
|
||||
*/
|
||||
int polarity = acpi_irq_model == ACPI_IRQ_MODEL_GIC ?
|
||||
ACPI_ACTIVE_HIGH : ACPI_ACTIVE_LOW;
|
||||
char *link = NULL;
|
||||
char link_desc[16];
|
||||
int rc;
|
||||
|
|
|
@ -572,7 +572,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||
|
||||
acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status);
|
||||
|
||||
if (pwr_btn_status & ACPI_EVENT_FLAG_SET) {
|
||||
if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET) {
|
||||
acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
|
||||
/* Flag for later */
|
||||
pwr_btn_event_pending = true;
|
||||
|
|
|
@ -314,10 +314,14 @@ static struct kobject *tables_kobj;
|
|||
static struct kobject *dynamic_tables_kobj;
|
||||
static struct kobject *hotplug_kobj;
|
||||
|
||||
#define ACPI_MAX_TABLE_INSTANCES 999
|
||||
#define ACPI_INST_SIZE 4 /* including trailing 0 */
|
||||
|
||||
struct acpi_table_attr {
|
||||
struct bin_attribute attr;
|
||||
char name[8];
|
||||
char name[ACPI_NAME_SIZE];
|
||||
int instance;
|
||||
char filename[ACPI_NAME_SIZE+ACPI_INST_SIZE];
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
|
@ -329,14 +333,9 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj,
|
|||
container_of(bin_attr, struct acpi_table_attr, attr);
|
||||
struct acpi_table_header *table_header = NULL;
|
||||
acpi_status status;
|
||||
char name[ACPI_NAME_SIZE];
|
||||
|
||||
if (strncmp(table_attr->name, "NULL", 4))
|
||||
memcpy(name, table_attr->name, ACPI_NAME_SIZE);
|
||||
else
|
||||
memcpy(name, "\0\0\0\0", 4);
|
||||
|
||||
status = acpi_get_table(name, table_attr->instance, &table_header);
|
||||
status = acpi_get_table(table_attr->name, table_attr->instance,
|
||||
&table_header);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -344,38 +343,45 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj,
|
|||
table_header, table_header->length);
|
||||
}
|
||||
|
||||
static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
|
||||
struct acpi_table_header *table_header)
|
||||
static int acpi_table_attr_init(struct kobject *tables_obj,
|
||||
struct acpi_table_attr *table_attr,
|
||||
struct acpi_table_header *table_header)
|
||||
{
|
||||
struct acpi_table_header *header = NULL;
|
||||
struct acpi_table_attr *attr = NULL;
|
||||
char instance_str[ACPI_INST_SIZE];
|
||||
|
||||
sysfs_attr_init(&table_attr->attr.attr);
|
||||
if (table_header->signature[0] != '\0')
|
||||
memcpy(table_attr->name, table_header->signature,
|
||||
ACPI_NAME_SIZE);
|
||||
else
|
||||
memcpy(table_attr->name, "NULL", 4);
|
||||
ACPI_MOVE_NAME(table_attr->name, table_header->signature);
|
||||
|
||||
list_for_each_entry(attr, &acpi_table_attr_list, node) {
|
||||
if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
|
||||
if (ACPI_COMPARE_NAME(table_attr->name, attr->name))
|
||||
if (table_attr->instance < attr->instance)
|
||||
table_attr->instance = attr->instance;
|
||||
}
|
||||
table_attr->instance++;
|
||||
if (table_attr->instance > ACPI_MAX_TABLE_INSTANCES) {
|
||||
pr_warn("%4.4s: too many table instances\n",
|
||||
table_attr->name);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
ACPI_MOVE_NAME(table_attr->filename, table_header->signature);
|
||||
table_attr->filename[ACPI_NAME_SIZE] = '\0';
|
||||
if (table_attr->instance > 1 || (table_attr->instance == 1 &&
|
||||
!acpi_get_table
|
||||
(table_header->signature, 2, &header)))
|
||||
sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
|
||||
table_attr->instance);
|
||||
(table_header->signature, 2, &header))) {
|
||||
snprintf(instance_str, sizeof(instance_str), "%u",
|
||||
table_attr->instance);
|
||||
strcat(table_attr->filename, instance_str);
|
||||
}
|
||||
|
||||
table_attr->attr.size = table_header->length;
|
||||
table_attr->attr.read = acpi_table_show;
|
||||
table_attr->attr.attr.name = table_attr->name;
|
||||
table_attr->attr.attr.name = table_attr->filename;
|
||||
table_attr->attr.attr.mode = 0400;
|
||||
|
||||
return;
|
||||
return sysfs_create_bin_file(tables_obj, &table_attr->attr);
|
||||
}
|
||||
|
||||
acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
|
||||
|
@ -383,21 +389,22 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
|
|||
struct acpi_table_attr *table_attr;
|
||||
|
||||
switch (event) {
|
||||
case ACPI_TABLE_EVENT_LOAD:
|
||||
case ACPI_TABLE_EVENT_INSTALL:
|
||||
table_attr =
|
||||
kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
|
||||
if (!table_attr)
|
||||
return AE_NO_MEMORY;
|
||||
|
||||
acpi_table_attr_init(table_attr, table);
|
||||
if (sysfs_create_bin_file(dynamic_tables_kobj,
|
||||
&table_attr->attr)) {
|
||||
if (acpi_table_attr_init(dynamic_tables_kobj,
|
||||
table_attr, table)) {
|
||||
kfree(table_attr);
|
||||
return AE_ERROR;
|
||||
} else
|
||||
list_add_tail(&table_attr->node, &acpi_table_attr_list);
|
||||
}
|
||||
list_add_tail(&table_attr->node, &acpi_table_attr_list);
|
||||
break;
|
||||
case ACPI_TABLE_EVENT_LOAD:
|
||||
case ACPI_TABLE_EVENT_UNLOAD:
|
||||
case ACPI_TABLE_EVENT_UNINSTALL:
|
||||
/*
|
||||
* we do not need to do anything right now
|
||||
* because the table is not deleted from the
|
||||
|
@ -435,13 +442,12 @@ static int acpi_tables_sysfs_init(void)
|
|||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
|
||||
table_attr = NULL;
|
||||
table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
|
||||
if (!table_attr)
|
||||
return -ENOMEM;
|
||||
|
||||
acpi_table_attr_init(table_attr, table_header);
|
||||
ret = sysfs_create_bin_file(tables_kobj, &table_attr->attr);
|
||||
ret = acpi_table_attr_init(tables_kobj,
|
||||
table_attr, table_header);
|
||||
if (ret) {
|
||||
kfree(table_attr);
|
||||
return ret;
|
||||
|
@ -597,14 +603,27 @@ static ssize_t counter_show(struct kobject *kobj,
|
|||
if (result)
|
||||
goto end;
|
||||
|
||||
if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER))
|
||||
size += sprintf(buf + size, " invalid");
|
||||
else if (status & ACPI_EVENT_FLAG_ENABLED)
|
||||
size += sprintf(buf + size, " enabled");
|
||||
else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
|
||||
size += sprintf(buf + size, " wake_enabled");
|
||||
if (status & ACPI_EVENT_FLAG_ENABLE_SET)
|
||||
size += sprintf(buf + size, " EN");
|
||||
else
|
||||
size += sprintf(buf + size, " disabled");
|
||||
size += sprintf(buf + size, " ");
|
||||
if (status & ACPI_EVENT_FLAG_STATUS_SET)
|
||||
size += sprintf(buf + size, " STS");
|
||||
else
|
||||
size += sprintf(buf + size, " ");
|
||||
|
||||
if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER))
|
||||
size += sprintf(buf + size, " invalid ");
|
||||
else if (status & ACPI_EVENT_FLAG_ENABLED)
|
||||
size += sprintf(buf + size, " enabled ");
|
||||
else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
|
||||
size += sprintf(buf + size, " wake_enabled");
|
||||
else
|
||||
size += sprintf(buf + size, " disabled ");
|
||||
if (status & ACPI_EVENT_FLAG_MASKED)
|
||||
size += sprintf(buf + size, " masked ");
|
||||
else
|
||||
size += sprintf(buf + size, " unmasked");
|
||||
|
||||
end:
|
||||
size += sprintf(buf + size, "\n");
|
||||
|
@ -655,8 +674,12 @@ static ssize_t counter_set(struct kobject *kobj,
|
|||
!(status & ACPI_EVENT_FLAG_ENABLED))
|
||||
result = acpi_enable_gpe(handle, index);
|
||||
else if (!strcmp(buf, "clear\n") &&
|
||||
(status & ACPI_EVENT_FLAG_SET))
|
||||
(status & ACPI_EVENT_FLAG_STATUS_SET))
|
||||
result = acpi_clear_gpe(handle, index);
|
||||
else if (!strcmp(buf, "mask\n"))
|
||||
result = acpi_mask_gpe(handle, index, TRUE);
|
||||
else if (!strcmp(buf, "unmask\n"))
|
||||
result = acpi_mask_gpe(handle, index, FALSE);
|
||||
else if (!kstrtoul(buf, 0, &tmp))
|
||||
all_counters[index].count = tmp;
|
||||
else
|
||||
|
@ -664,13 +687,13 @@ static ssize_t counter_set(struct kobject *kobj,
|
|||
} else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
|
||||
int event = index - num_gpes;
|
||||
if (!strcmp(buf, "disable\n") &&
|
||||
(status & ACPI_EVENT_FLAG_ENABLED))
|
||||
(status & ACPI_EVENT_FLAG_ENABLE_SET))
|
||||
result = acpi_disable_event(event, ACPI_NOT_ISR);
|
||||
else if (!strcmp(buf, "enable\n") &&
|
||||
!(status & ACPI_EVENT_FLAG_ENABLED))
|
||||
!(status & ACPI_EVENT_FLAG_ENABLE_SET))
|
||||
result = acpi_enable_event(event, ACPI_NOT_ISR);
|
||||
else if (!strcmp(buf, "clear\n") &&
|
||||
(status & ACPI_EVENT_FLAG_SET))
|
||||
(status & ACPI_EVENT_FLAG_STATUS_SET))
|
||||
result = acpi_clear_event(event);
|
||||
else if (!kstrtoul(buf, 0, &tmp))
|
||||
all_counters[index].count = tmp;
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <linux/earlycpio.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/acpi.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT
|
||||
|
@ -246,6 +245,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
|
|||
struct acpi_subtable_header *entry;
|
||||
unsigned long table_end;
|
||||
int count = 0;
|
||||
int errs = 0;
|
||||
int i;
|
||||
|
||||
if (acpi_disabled)
|
||||
|
@ -278,10 +278,12 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
|
|||
if (entry->type != proc[i].id)
|
||||
continue;
|
||||
if (!proc[i].handler ||
|
||||
proc[i].handler(entry, table_end))
|
||||
return -EINVAL;
|
||||
(!errs && proc[i].handler(entry, table_end))) {
|
||||
errs++;
|
||||
continue;
|
||||
}
|
||||
|
||||
proc->count++;
|
||||
proc[i].count++;
|
||||
break;
|
||||
}
|
||||
if (i != proc_num)
|
||||
|
@ -301,11 +303,11 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
|
|||
}
|
||||
|
||||
if (max_entries && count > max_entries) {
|
||||
pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
|
||||
id, proc->id, count - max_entries, count);
|
||||
pr_warn("[%4.4s:0x%02x] found the maximum %i entries\n",
|
||||
id, proc->id, count);
|
||||
}
|
||||
|
||||
return count;
|
||||
return errs ? -EINVAL : count;
|
||||
}
|
||||
|
||||
int __init
|
||||
|
|
|
@ -479,6 +479,30 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev,
|
|||
}
|
||||
EXPORT_SYMBOL(pci_find_parent_resource);
|
||||
|
||||
/**
|
||||
* pci_find_resource - Return matching PCI device resource
|
||||
* @dev: PCI device to query
|
||||
* @res: Resource to look for
|
||||
*
|
||||
* Goes over standard PCI resources (BARs) and checks if the given resource
|
||||
* is partially or fully contained in any of them. In that case the
|
||||
* matching resource is returned, %NULL otherwise.
|
||||
*/
|
||||
struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_ROM_RESOURCE; i++) {
|
||||
struct resource *r = &dev->resource[i];
|
||||
|
||||
if (r->start && resource_contains(r, res))
|
||||
return r;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_find_resource);
|
||||
|
||||
/**
|
||||
* pci_find_pcie_root_port - return PCIe Root Port
|
||||
* @dev: PCI device to query
|
||||
|
|
|
@ -1126,6 +1126,7 @@ void pdev_enable_device(struct pci_dev *);
|
|||
int pci_enable_resources(struct pci_dev *, int mask);
|
||||
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
|
||||
int (*)(const struct pci_dev *, u8, u8));
|
||||
struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res);
|
||||
#define HAVE_PCI_REQ_REGIONS 2
|
||||
int __must_check pci_request_regions(struct pci_dev *, const char *);
|
||||
int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *);
|
||||
|
@ -1542,6 +1543,9 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
|
|||
int enable)
|
||||
{ return 0; }
|
||||
|
||||
static inline struct resource *pci_find_resource(struct pci_dev *dev,
|
||||
struct resource *res)
|
||||
{ return NULL; }
|
||||
static inline int pci_request_regions(struct pci_dev *dev, const char *res_name)
|
||||
{ return -EIO; }
|
||||
static inline void pci_release_regions(struct pci_dev *dev) { }
|
||||
|
|
Loading…
Reference in New Issue