Commit bf25400e authored by Len Brown's avatar Len Brown
Browse files

Merge branch 'bugzilla-13620' into release

parents 762caf0b a5fe1a03
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -215,6 +215,12 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "***** Region %p\n", object));

		/* Invalidate the region address/length via the host OS */

		acpi_os_invalidate_address(object->region.space_id,
					  object->region.address,
					  (acpi_size) object->region.length);

		second_desc = acpi_ns_get_secondary_object(object);
		if (second_desc) {
			/*
+91 −3
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ struct acpi_res_list {
	char name[5];   /* only can have a length of 4 chars, make use of this
			   one instead of res->name, no need to kalloc then */
	struct list_head resource_list;
	int count;
};

static LIST_HEAD(resource_list_head);
@@ -1358,6 +1359,89 @@ acpi_os_validate_interface (char *interface)
	return AE_SUPPORT;
}

static inline int acpi_res_list_add(struct acpi_res_list *res)
{
	struct acpi_res_list *res_list_elem;

	list_for_each_entry(res_list_elem, &resource_list_head,
			    resource_list) {

		if (res->resource_type == res_list_elem->resource_type &&
		    res->start == res_list_elem->start &&
		    res->end == res_list_elem->end) {

			/*
			 * The Region(addr,len) already exist in the list,
			 * just increase the count
			 */

			res_list_elem->count++;
			return 0;
		}
	}

	res->count = 1;
	list_add(&res->resource_list, &resource_list_head);
	return 1;
}

static inline void acpi_res_list_del(struct acpi_res_list *res)
{
	struct acpi_res_list *res_list_elem;

	list_for_each_entry(res_list_elem, &resource_list_head,
			    resource_list) {

		if (res->resource_type == res_list_elem->resource_type &&
		    res->start == res_list_elem->start &&
		    res->end == res_list_elem->end) {

			/*
			 * If the res count is decreased to 0,
			 * remove and free it
			 */

			if (--res_list_elem->count == 0) {
				list_del(&res_list_elem->resource_list);
				kfree(res_list_elem);
			}
			return;
		}
	}
}

acpi_status
acpi_os_invalidate_address(
    u8                   space_id,
    acpi_physical_address   address,
    acpi_size               length)
{
	struct acpi_res_list res;

	switch (space_id) {
	case ACPI_ADR_SPACE_SYSTEM_IO:
	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
		/* Only interference checks against SystemIO and SytemMemory
		   are needed */
		res.start = address;
		res.end = address + length - 1;
		res.resource_type = space_id;
		spin_lock(&acpi_res_lock);
		acpi_res_list_del(&res);
		spin_unlock(&acpi_res_lock);
		break;
	case ACPI_ADR_SPACE_PCI_CONFIG:
	case ACPI_ADR_SPACE_EC:
	case ACPI_ADR_SPACE_SMBUS:
	case ACPI_ADR_SPACE_CMOS:
	case ACPI_ADR_SPACE_PCI_BAR_TARGET:
	case ACPI_ADR_SPACE_DATA_TABLE:
	case ACPI_ADR_SPACE_FIXED_HARDWARE:
		break;
	}
	return AE_OK;
}

/******************************************************************************
 *
 * FUNCTION:    acpi_os_validate_address
@@ -1382,6 +1466,7 @@ acpi_os_validate_address (
    char *name)
{
	struct acpi_res_list *res;
	int added;
	if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
		return AE_OK;

@@ -1399,14 +1484,17 @@ acpi_os_validate_address (
		res->end = address + length - 1;
		res->resource_type = space_id;
		spin_lock(&acpi_res_lock);
		list_add(&res->resource_list, &resource_list_head);
		added = acpi_res_list_add(res);
		spin_unlock(&acpi_res_lock);
		pr_debug("Added %s resource: start: 0x%llx, end: 0x%llx, "
			 "name: %s\n", (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
		pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, "
			 "name: %s\n", added ? "Added" : "Already exist",
			 (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
			 ? "SystemIO" : "System Memory",
			 (unsigned long long)res->start,
			 (unsigned long long)res->end,
			 res->name);
		if (!added)
			kfree(res);
		break;
	case ACPI_ADR_SPACE_PCI_CONFIG:
	case ACPI_ADR_SPACE_EC:
+3 −0
Original line number Diff line number Diff line
@@ -245,6 +245,9 @@ acpi_status acpi_osi_invalidate(char* interface);
acpi_status
acpi_os_validate_address(u8 space_id, acpi_physical_address address,
			 acpi_size length, char *name);
acpi_status
acpi_os_invalidate_address(u8 space_id, acpi_physical_address address,
			 acpi_size length);

u64 acpi_os_get_timer(void);