Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f928a490 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-ec', 'acpi-dma', 'acpi-processor' and 'acpi-cppc'

* acpi-ec:
  ACPI / EC: Clean up EC GPE mask flag
  ACPI: EC: Fix possible issues related to EC initialization order

* acpi-dma:
  ACPI/IORT: Add IORT named component memory address limits
  ACPI: Make acpi_dma_configure() DMA regions aware
  ACPI: Introduce DMA ranges parsing
  ACPI: Make acpi_dev_get_resources() method agnostic

* acpi-processor:
  ACPI / processor: make function acpi_processor_check_duplicates() static
  ACPI: processor: use dev_dbg() instead of dev_warn() when CPPC probe failed

* acpi-cppc:
  mailbox: pcc: Drop uninformative output during boot
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -670,7 +670,7 @@ static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,

}

void __init acpi_processor_check_duplicates(void)
static void __init acpi_processor_check_duplicates(void)
{
	/* check the correctness for all processors in ACPI namespace */
	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+55 −2
Original line number Diff line number Diff line
@@ -680,13 +680,36 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
	return ret ? NULL : ops;
}

static int nc_dma_get_range(struct device *dev, u64 *size)
{
	struct acpi_iort_node *node;
	struct acpi_iort_named_component *ncomp;

	node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
			      iort_match_node_callback, dev);
	if (!node)
		return -ENODEV;

	ncomp = (struct acpi_iort_named_component *)node->node_data;

	*size = ncomp->memory_address_limit >= 64 ? U64_MAX :
			1ULL<<ncomp->memory_address_limit;

	return 0;
}

/**
 * iort_set_dma_mask - Set-up dma mask for a device.
 * iort_dma_setup() - Set-up device DMA parameters.
 *
 * @dev: device to configure
 * @dma_addr: device DMA address result pointer
 * @size: DMA range size result pointer
 */
void iort_set_dma_mask(struct device *dev)
void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
{
	u64 mask, dmaaddr = 0, size = 0, offset = 0;
	int ret, msb;

	/*
	 * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
	 * setup the correct supported mask.
@@ -700,6 +723,36 @@ void iort_set_dma_mask(struct device *dev)
	 */
	if (!dev->dma_mask)
		dev->dma_mask = &dev->coherent_dma_mask;

	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);

	if (dev_is_pci(dev))
		ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
	else
		ret = nc_dma_get_range(dev, &size);

	if (!ret) {
		msb = fls64(dmaaddr + size - 1);
		/*
		 * Round-up to the power-of-two mask or set
		 * the mask to the whole 64-bit address space
		 * in case the DMA region covers the full
		 * memory window.
		 */
		mask = msb == 64 ? U64_MAX : (1ULL << msb) - 1;
		/*
		 * Limit coherent and dma mask based on size
		 * retrieved from firmware.
		 */
		dev->coherent_dma_mask = mask;
		*dev->dma_mask = mask;
	}

	*dma_addr = dmaaddr;
	*dma_size = size;

	dev->dma_pfn_offset = PFN_DOWN(offset);
	dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset);
}

/**
+27 −21
Original line number Diff line number Diff line
@@ -112,8 +112,7 @@ enum {
	EC_FLAGS_EVT_HANDLER_INSTALLED, /* _Qxx handlers installed */
	EC_FLAGS_STARTED,		/* Driver is started */
	EC_FLAGS_STOPPED,		/* Driver is stopped */
	EC_FLAGS_COMMAND_STORM,		/* GPE storms occurred to the
					 * current command processing */
	EC_FLAGS_GPE_MASKED,		/* GPE masked */
};

#define ACPI_EC_COMMAND_POLL		0x01 /* Available for command byte */
@@ -425,19 +424,19 @@ static void acpi_ec_complete_request(struct acpi_ec *ec)
		wake_up(&ec->wait);
}

static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag)
static void acpi_ec_mask_gpe(struct acpi_ec *ec)
{
	if (!test_bit(flag, &ec->flags)) {
	if (!test_bit(EC_FLAGS_GPE_MASKED, &ec->flags)) {
		acpi_ec_disable_gpe(ec, false);
		ec_dbg_drv("Polling enabled");
		set_bit(flag, &ec->flags);
		set_bit(EC_FLAGS_GPE_MASKED, &ec->flags);
	}
}

static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag)
static void acpi_ec_unmask_gpe(struct acpi_ec *ec)
{
	if (test_bit(flag, &ec->flags)) {
		clear_bit(flag, &ec->flags);
	if (test_bit(EC_FLAGS_GPE_MASKED, &ec->flags)) {
		clear_bit(EC_FLAGS_GPE_MASKED, &ec->flags);
		acpi_ec_enable_gpe(ec, false);
		ec_dbg_drv("Polling disabled");
	}
@@ -464,7 +463,7 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec)

static void acpi_ec_submit_query(struct acpi_ec *ec)
{
	acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM);
	acpi_ec_mask_gpe(ec);
	if (!acpi_ec_event_enabled(ec))
		return;
	if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
@@ -480,7 +479,7 @@ static void acpi_ec_complete_query(struct acpi_ec *ec)
	if (test_and_clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
		ec_dbg_evt("Command(%s) unblocked",
			   acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
	acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM);
	acpi_ec_unmask_gpe(ec);
}

static inline void __acpi_ec_enable_event(struct acpi_ec *ec)
@@ -700,7 +699,7 @@ static void advance_transaction(struct acpi_ec *ec)
				++t->irq_count;
			/* Allow triggering on 0 threshold */
			if (t->irq_count == ec_storm_threshold)
				acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM);
				acpi_ec_mask_gpe(ec);
		}
	}
out:
@@ -798,7 +797,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,

	spin_lock_irqsave(&ec->lock, tmp);
	if (t->irq_count == ec_storm_threshold)
		acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM);
		acpi_ec_unmask_gpe(ec);
	ec_dbg_req("Command(%s) stopped", acpi_ec_cmd_string(t->command));
	ec->curr = NULL;
	/* Disable GPE for command processing (IBF=0/OBF=1) */
@@ -1586,9 +1585,7 @@ static bool acpi_is_boot_ec(struct acpi_ec *ec)
{
	if (!boot_ec)
		return false;
	if (ec->handle == boot_ec->handle &&
	    ec->gpe == boot_ec->gpe &&
	    ec->command_addr == boot_ec->command_addr &&
	if (ec->command_addr == boot_ec->command_addr &&
	    ec->data_addr == boot_ec->data_addr)
		return true;
	return false;
@@ -1613,6 +1610,13 @@ static int acpi_ec_add(struct acpi_device *device)

	if (acpi_is_boot_ec(ec)) {
		boot_ec_is_ecdt = false;
		/*
		 * Trust PNP0C09 namespace location rather than ECDT ID.
		 *
		 * But trust ECDT GPE rather than _GPE because of ASUS quirks,
		 * so do not change boot_ec->gpe to ec->gpe.
		 */
		boot_ec->handle = ec->handle;
		acpi_handle_debug(ec->handle, "duplicated.\n");
		acpi_ec_free(ec);
		ec = boot_ec;
@@ -1747,18 +1751,20 @@ static int __init acpi_ec_ecdt_start(void)

	if (!boot_ec)
		return -ENODEV;
	/*
	 * The DSDT EC should have already been started in
	 * acpi_ec_add().
	 */
	/* In case acpi_ec_ecdt_start() is called after acpi_ec_add() */
	if (!boot_ec_is_ecdt)
		return -ENODEV;

	/*
	 * At this point, the namespace and the GPE is initialized, so
	 * start to find the namespace objects and handle the events.
	 *
	 * Note: ec->handle can be valid if this function is called after
	 * acpi_ec_add(), hence the fast path.
	 */
	if (!acpi_ec_ecdt_get_handle(&handle))
	if (boot_ec->handle != ACPI_ROOT_OBJECT)
		handle = boot_ec->handle;
	else if (!acpi_ec_ecdt_get_handle(&handle))
		return -ENODEV;
	return acpi_config_boot_ec(boot_ec, handle, true, true);
}
@@ -2011,8 +2017,8 @@ int __init acpi_ec_init(void)
		return result;

	/* Drivers must be started after acpi_ec_query_init() */
	ecdt_fail = acpi_ec_ecdt_start();
	dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
	ecdt_fail = acpi_ec_ecdt_start();
	return ecdt_fail && dsdt_fail ? -ENODEV : 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ static int __acpi_processor_start(struct acpi_device *device)

	result = acpi_cppc_processor_probe(pr);
	if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS))
		dev_warn(&device->dev, "CPPC data invalid or not present\n");
		dev_dbg(&device->dev, "CPPC data invalid or not present\n");

	if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
		acpi_processor_power_init(pr);
+63 −19
Original line number Diff line number Diff line
@@ -573,6 +573,35 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
	return AE_OK;
}

static int __acpi_dev_get_resources(struct acpi_device *adev,
				    struct list_head *list,
				    int (*preproc)(struct acpi_resource *, void *),
				    void *preproc_data, char *method)
{
	struct res_proc_context c;
	acpi_status status;

	if (!adev || !adev->handle || !list_empty(list))
		return -EINVAL;

	if (!acpi_has_method(adev->handle, method))
		return 0;

	c.list = list;
	c.preproc = preproc;
	c.preproc_data = preproc_data;
	c.count = 0;
	c.error = 0;
	status = acpi_walk_resources(adev->handle, method,
				     acpi_dev_process_resource, &c);
	if (ACPI_FAILURE(status)) {
		acpi_dev_free_resource_list(list);
		return c.error ? c.error : -EIO;
	}

	return c.count;
}

/**
 * acpi_dev_get_resources - Get current resources of a device.
 * @adev: ACPI device node to get the resources for.
@@ -601,30 +630,45 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
			   int (*preproc)(struct acpi_resource *, void *),
			   void *preproc_data)
{
	struct res_proc_context c;
	acpi_status status;
	return __acpi_dev_get_resources(adev, list, preproc, preproc_data,
					METHOD_NAME__CRS);
}
EXPORT_SYMBOL_GPL(acpi_dev_get_resources);

	if (!adev || !adev->handle || !list_empty(list))
		return -EINVAL;
static int is_memory(struct acpi_resource *ares, void *not_used)
{
	struct resource_win win;
	struct resource *res = &win.res;

	if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
		return 0;
	memset(&win, 0, sizeof(win));

	c.list = list;
	c.preproc = preproc;
	c.preproc_data = preproc_data;
	c.count = 0;
	c.error = 0;
	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
				     acpi_dev_process_resource, &c);
	if (ACPI_FAILURE(status)) {
		acpi_dev_free_resource_list(list);
		return c.error ? c.error : -EIO;
	return !(acpi_dev_resource_memory(ares, res)
	       || acpi_dev_resource_address_space(ares, &win)
	       || acpi_dev_resource_ext_address_space(ares, &win));
}

	return c.count;
/**
 * acpi_dev_get_dma_resources - Get current DMA resources of a device.
 * @adev: ACPI device node to get the resources for.
 * @list: Head of the resultant list of resources (must be empty).
 *
 * Evaluate the _DMA method for the given device node and process its
 * output.
 *
 * The resultant struct resource objects are put on the list pointed to
 * by @list, that must be empty initially, as members of struct
 * resource_entry objects.  Callers of this routine should use
 * %acpi_dev_free_resource_list() to free that list.
 *
 * The number of resources in the output list is returned on success,
 * an error code reflecting the error condition is returned otherwise.
 */
int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list)
{
	return __acpi_dev_get_resources(adev, list, is_memory, NULL,
					METHOD_NAME__DMA);
}
EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
EXPORT_SYMBOL_GPL(acpi_dev_get_dma_resources);

/**
 * acpi_dev_filter_resource_type - Filter ACPI resource according to resource
Loading