All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hanjun Guo <hanjun.guo@linaro.org>
To: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Hanjun Guo <guohanjun@huawei.com>
Cc: Robin Murphy <robin.murphy@arm.com>,
	Marc Zyngier <marc.zyngier@arm.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linuxarm@huawei.com
Subject: Re: [RFC PATCH v2 4/4] ACPI: IORT: SMMUv3 nodes MSI support
Date: Wed, 27 Sep 2017 08:34:20 +0800	[thread overview]
Message-ID: <59CAF20C.6050403@linaro.org> (raw)
In-Reply-To: <20170922130741.GD3475@red-moon>

On 09/22/2017 09:07 PM, Lorenzo Pieralisi wrote:
> On Thu, Sep 21, 2017 at 09:17:18PM +0800, Hanjun Guo wrote:
>> From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>
>> Since we make single mappings valid for SMMUv3 (and PMCG), also
>> we have a mapping index for SMMUv3 MSI, we can directly use that
>> index to get the map entry, then retrieve dev ID and ITS parent
>> to add SMMUv3 MSI support.
>>
>> Introduce a new API iort_set_device_domain() to find the MSI domain
>> for an SMMUv3 (or any other IORT table node) to reduce the complex
>> of doing that via acpi_configure_pmsi_domain(), then reuse the
>> iort_node_get_id() to get the dev id for SMMU MSI.
>>
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/arm64/iort.c | 99 ++++++++++++++++++++++++++++++++++++++---------
>>   1 file changed, 81 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 269959e..bbab2ab 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -357,7 +357,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
>>
>>   	if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
>>   		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
>> -		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
>> +		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
>> +		    node->type == ACPI_IORT_NODE_SMMU_V3) {
>>   			*id_out = map->output_base;
>>   			return parent;
>>   		}
>> @@ -366,8 +367,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
>>   	return NULL;
>>   }
>>
>> -static int iort_get_smmu_v3_id_mapping_index(struct acpi_iort_node *node,
>> -					     u32 *index)
>> +static int iort_get_id_mapping_index(struct acpi_iort_node *node,
>> +				     u32 *index)
>>   {
>>   	struct acpi_iort_smmu_v3 *smmu;
>>
>> @@ -378,20 +379,28 @@ static int iort_get_smmu_v3_id_mapping_index(struct acpi_iort_node *node,
>>   	if (node->revision < 1)
>>   		return -EINVAL;
>>
>> -	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
>> -	/* if any of the gsi for control interrupts is not 0, ignore the MSI */
>> -	if (smmu->event_gsiv || smmu->pri_gsiv || smmu->gerr_gsiv
>> -	    || smmu->sync_gsiv)
>> -		return -EINVAL;
>> +	switch (node->type) {
>> +	case ACPI_IORT_NODE_SMMU_V3:
>> +		smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
>> +		/*
>> +		 * if any of the gsi for control interrupts is not 0,
>> +		 * ignore the MSI
>> +		 */
>> +		if (smmu->event_gsiv || smmu->pri_gsiv || smmu->gerr_gsiv
>> +		    || smmu->sync_gsiv)
>> +			return -EINVAL;
>>
>> -	if (smmu->id_mapping_index >= node->mapping_count) {
>> -		pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n",
>> -		       node, node->type);
>> +		if (smmu->id_mapping_index >= node->mapping_count) {
>> +			pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n",
>> +			       node, node->type);
>> +			return -EINVAL;
>> +		}
>> +
>> +		*index = smmu->id_mapping_index;
>> +		return 0;
>> +	default:
>>   		return -EINVAL;
>>   	}
>> -
>> -	*index = smmu->id_mapping_index;
>> -	return 0;
>>   }
>>
>>   static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
>> @@ -431,7 +440,7 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
>>   		 *  associated ID map for single mapping cases.
>>   		 */
>>   		if (node->type == ACPI_IORT_NODE_SMMU_V3)
>
> I wanted to use:
>
> iort_get_id_mapping_index()
>
> so that the node type check is done *in* that function and you do
> not need to check it here.
>
>> -			ret = iort_get_smmu_v3_id_mapping_index(node, &index);
>> +			ret = iort_get_id_mapping_index(node, &index);
>>
>>   		/* Do the ID translation */
>>   		for (i = 0; i < node->mapping_count; i++, map++) {
>> @@ -555,9 +564,18 @@ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
>>   	if (!node)
>>   		return -ENODEV;
>>
>> -	for (i = 0; i < node->mapping_count; i++) {
>> -		if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
>> -			return 0;
>> +	if (node->type == ACPI_IORT_NODE_SMMU_V3) {
>
> Ditto.
>
>> +		u32 index;
>> +
>> +		if (!iort_get_id_mapping_index(node, &index)) {
>> +			if (iort_node_get_id(node, dev_id, index))
>> +				return 0;
>> +		}
>> +	} else {
>> +		for (i = 0; i < node->mapping_count; i++) {
>> +			if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
>> +				return 0;
>> +		}
>>   	}
>>
>>   	return -ENODEV;
>> @@ -620,6 +638,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>   	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>>   }
>
> All changes above can be squashed with patch 3.
>
>> +static void iort_set_device_domain(struct device *dev,
>> +				   struct acpi_iort_node *node)
>> +{
>> +	struct acpi_iort_its_group *its;
>> +	struct acpi_iort_node *msi_parent;
>> +	struct acpi_iort_id_mapping *map;
>> +	struct fwnode_handle *iort_fwnode;
>> +	struct irq_domain *domain;
>> +	int ret, index;
>> +
>> +	ret = iort_get_id_mapping_index(node, &index);
>> +	if (ret < 0)
>> +		return;
>> +
>> +	map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
>> +			   node->mapping_offset + index * sizeof(*map));
>> +
>> +	/* Firmware bug! */
>> +	if (!map->output_reference ||
>> +	    !(map->flags & ACPI_IORT_ID_SINGLE_MAPPING)) {
>> +		pr_err(FW_BUG "[node %p type %d] Invalid MSI mapping\n",
>> +		       node, node->type);
>> +		return;
>> +	}
>> +
>> +	msi_parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
>> +				  map->output_reference);
>> +
>> +	if (!msi_parent || msi_parent->type != ACPI_IORT_NODE_ITS_GROUP)
>> +		return;
>> +
>> +	/* Move to ITS specific data */
>> +	its = (struct acpi_iort_its_group *)msi_parent->node_data;
>> +
>> +	iort_fwnode = iort_find_domain_token(its->identifiers[0]);
>> +	if (!iort_fwnode)
>> +		return;
>> +
>> +	domain = irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
>> +	if (domain)
>> +		dev_set_msi_domain(dev, domain);
>> +}
>> +
>>   /**
>>    * iort_get_platform_device_domain() - Find MSI domain related to a
>>    * platform device
>> @@ -1246,6 +1307,8 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
>>   	/* Configure DMA for the page table walker */
>>   	acpi_dma_configure(&pdev->dev, attr);
>>
>> +	iort_set_device_domain(&pdev->dev, node);
>> +
>
> ..and then you introduce iort_set_device_domain() and use it in a
> separate patch.
>
> With these changes I think we are ready to queue the series.

Updated already, will send a new version soon.

Thanks
Hanjun

WARNING: multiple messages have this Message-ID (diff)
From: hanjun.guo@linaro.org (Hanjun Guo)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH v2 4/4] ACPI: IORT: SMMUv3 nodes MSI support
Date: Wed, 27 Sep 2017 08:34:20 +0800	[thread overview]
Message-ID: <59CAF20C.6050403@linaro.org> (raw)
In-Reply-To: <20170922130741.GD3475@red-moon>

On 09/22/2017 09:07 PM, Lorenzo Pieralisi wrote:
> On Thu, Sep 21, 2017 at 09:17:18PM +0800, Hanjun Guo wrote:
>> From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>
>> Since we make single mappings valid for SMMUv3 (and PMCG), also
>> we have a mapping index for SMMUv3 MSI, we can directly use that
>> index to get the map entry, then retrieve dev ID and ITS parent
>> to add SMMUv3 MSI support.
>>
>> Introduce a new API iort_set_device_domain() to find the MSI domain
>> for an SMMUv3 (or any other IORT table node) to reduce the complex
>> of doing that via acpi_configure_pmsi_domain(), then reuse the
>> iort_node_get_id() to get the dev id for SMMU MSI.
>>
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/arm64/iort.c | 99 ++++++++++++++++++++++++++++++++++++++---------
>>   1 file changed, 81 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 269959e..bbab2ab 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -357,7 +357,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
>>
>>   	if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
>>   		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
>> -		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
>> +		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
>> +		    node->type == ACPI_IORT_NODE_SMMU_V3) {
>>   			*id_out = map->output_base;
>>   			return parent;
>>   		}
>> @@ -366,8 +367,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
>>   	return NULL;
>>   }
>>
>> -static int iort_get_smmu_v3_id_mapping_index(struct acpi_iort_node *node,
>> -					     u32 *index)
>> +static int iort_get_id_mapping_index(struct acpi_iort_node *node,
>> +				     u32 *index)
>>   {
>>   	struct acpi_iort_smmu_v3 *smmu;
>>
>> @@ -378,20 +379,28 @@ static int iort_get_smmu_v3_id_mapping_index(struct acpi_iort_node *node,
>>   	if (node->revision < 1)
>>   		return -EINVAL;
>>
>> -	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
>> -	/* if any of the gsi for control interrupts is not 0, ignore the MSI */
>> -	if (smmu->event_gsiv || smmu->pri_gsiv || smmu->gerr_gsiv
>> -	    || smmu->sync_gsiv)
>> -		return -EINVAL;
>> +	switch (node->type) {
>> +	case ACPI_IORT_NODE_SMMU_V3:
>> +		smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
>> +		/*
>> +		 * if any of the gsi for control interrupts is not 0,
>> +		 * ignore the MSI
>> +		 */
>> +		if (smmu->event_gsiv || smmu->pri_gsiv || smmu->gerr_gsiv
>> +		    || smmu->sync_gsiv)
>> +			return -EINVAL;
>>
>> -	if (smmu->id_mapping_index >= node->mapping_count) {
>> -		pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n",
>> -		       node, node->type);
>> +		if (smmu->id_mapping_index >= node->mapping_count) {
>> +			pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n",
>> +			       node, node->type);
>> +			return -EINVAL;
>> +		}
>> +
>> +		*index = smmu->id_mapping_index;
>> +		return 0;
>> +	default:
>>   		return -EINVAL;
>>   	}
>> -
>> -	*index = smmu->id_mapping_index;
>> -	return 0;
>>   }
>>
>>   static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
>> @@ -431,7 +440,7 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
>>   		 *  associated ID map for single mapping cases.
>>   		 */
>>   		if (node->type == ACPI_IORT_NODE_SMMU_V3)
>
> I wanted to use:
>
> iort_get_id_mapping_index()
>
> so that the node type check is done *in* that function and you do
> not need to check it here.
>
>> -			ret = iort_get_smmu_v3_id_mapping_index(node, &index);
>> +			ret = iort_get_id_mapping_index(node, &index);
>>
>>   		/* Do the ID translation */
>>   		for (i = 0; i < node->mapping_count; i++, map++) {
>> @@ -555,9 +564,18 @@ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
>>   	if (!node)
>>   		return -ENODEV;
>>
>> -	for (i = 0; i < node->mapping_count; i++) {
>> -		if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
>> -			return 0;
>> +	if (node->type == ACPI_IORT_NODE_SMMU_V3) {
>
> Ditto.
>
>> +		u32 index;
>> +
>> +		if (!iort_get_id_mapping_index(node, &index)) {
>> +			if (iort_node_get_id(node, dev_id, index))
>> +				return 0;
>> +		}
>> +	} else {
>> +		for (i = 0; i < node->mapping_count; i++) {
>> +			if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
>> +				return 0;
>> +		}
>>   	}
>>
>>   	return -ENODEV;
>> @@ -620,6 +638,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>   	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>>   }
>
> All changes above can be squashed with patch 3.
>
>> +static void iort_set_device_domain(struct device *dev,
>> +				   struct acpi_iort_node *node)
>> +{
>> +	struct acpi_iort_its_group *its;
>> +	struct acpi_iort_node *msi_parent;
>> +	struct acpi_iort_id_mapping *map;
>> +	struct fwnode_handle *iort_fwnode;
>> +	struct irq_domain *domain;
>> +	int ret, index;
>> +
>> +	ret = iort_get_id_mapping_index(node, &index);
>> +	if (ret < 0)
>> +		return;
>> +
>> +	map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
>> +			   node->mapping_offset + index * sizeof(*map));
>> +
>> +	/* Firmware bug! */
>> +	if (!map->output_reference ||
>> +	    !(map->flags & ACPI_IORT_ID_SINGLE_MAPPING)) {
>> +		pr_err(FW_BUG "[node %p type %d] Invalid MSI mapping\n",
>> +		       node, node->type);
>> +		return;
>> +	}
>> +
>> +	msi_parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
>> +				  map->output_reference);
>> +
>> +	if (!msi_parent || msi_parent->type != ACPI_IORT_NODE_ITS_GROUP)
>> +		return;
>> +
>> +	/* Move to ITS specific data */
>> +	its = (struct acpi_iort_its_group *)msi_parent->node_data;
>> +
>> +	iort_fwnode = iort_find_domain_token(its->identifiers[0]);
>> +	if (!iort_fwnode)
>> +		return;
>> +
>> +	domain = irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
>> +	if (domain)
>> +		dev_set_msi_domain(dev, domain);
>> +}
>> +
>>   /**
>>    * iort_get_platform_device_domain() - Find MSI domain related to a
>>    * platform device
>> @@ -1246,6 +1307,8 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
>>   	/* Configure DMA for the page table walker */
>>   	acpi_dma_configure(&pdev->dev, attr);
>>
>> +	iort_set_device_domain(&pdev->dev, node);
>> +
>
> ..and then you introduce iort_set_device_domain() and use it in a
> separate patch.
>
> With these changes I think we are ready to queue the series.

Updated already, will send a new version soon.

Thanks
Hanjun

  reply	other threads:[~2017-09-27  0:34 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-21 13:17 [RFC PATCH v2 0/4] IORT SMMUv3 MSI support Hanjun Guo
2017-09-21 13:17 ` Hanjun Guo
2017-09-21 13:17 ` [RFC PATCH v2 1/4] ACPICA: Add SMMUv3 device ID mapping index support Hanjun Guo
2017-09-21 13:17   ` Hanjun Guo
2017-09-22 11:25   ` Lorenzo Pieralisi
2017-09-22 11:25     ` Lorenzo Pieralisi
2017-09-21 13:17 ` [RFC PATCH v2 2/4] ACPI: IORT: lookup iort node via fwnode Hanjun Guo
2017-09-21 13:17   ` Hanjun Guo
2017-09-21 13:17 ` [RFC PATCH v2 3/4] ACPI: IORT: Skip SMMUv3 device ID map for two steps mappings Hanjun Guo
2017-09-21 13:17   ` Hanjun Guo
2017-09-22 12:53   ` Lorenzo Pieralisi
2017-09-22 12:53     ` Lorenzo Pieralisi
2017-09-26 21:39     ` Hanjun Guo
2017-09-26 21:39       ` Hanjun Guo
2017-09-22 13:21   ` Robin Murphy
2017-09-22 13:21     ` Robin Murphy
2017-09-26 19:04     ` Hanjun Guo
2017-09-26 19:04       ` Hanjun Guo
2017-09-21 13:17 ` [RFC PATCH v2 4/4] ACPI: IORT: SMMUv3 nodes MSI support Hanjun Guo
2017-09-21 13:17   ` Hanjun Guo
2017-09-22 13:07   ` Lorenzo Pieralisi
2017-09-22 13:07     ` Lorenzo Pieralisi
2017-09-27  0:34     ` Hanjun Guo [this message]
2017-09-27  0:34       ` Hanjun Guo
2017-09-22 11:22 ` [RFC PATCH v2 0/4] IORT SMMUv3 " Lorenzo Pieralisi
2017-09-22 11:22   ` Lorenzo Pieralisi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=59CAF20C.6050403@linaro.org \
    --to=hanjun.guo@linaro.org \
    --cc=guohanjun@huawei.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linuxarm@huawei.com \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=marc.zyngier@arm.com \
    --cc=rafael@kernel.org \
    --cc=robin.murphy@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.