diff mbox

[RFCv2,1/2] acpi:iort: Add new helper function to retrieve ITS base addr from dev IORT node

Message ID 20170531143213.82100-2-shameerali.kolothum.thodi@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shameerali Kolothum Thodi May 31, 2017, 2:32 p.m. UTC
This provides a helper function to find and retrieve the ITS
base address from the ID mappings array reference of a device
IORT node(if any).

This is used in the subsequent patch to retrieve the ITS base 
address associated with a pci dev IORT node.

Signed-off-by: shameer <shameerali.kolothum.thodi@huawei.com>
---
 drivers/acpi/arm64/iort.c        | 47 +++++++++++++++++++++++++++++++++++++---
 drivers/irqchip/irq-gic-v3-its.c |  3 ++-
 include/linux/acpi_iort.h        |  8 ++++++-
 3 files changed, 53 insertions(+), 5 deletions(-)

Comments

Lorenzo Pieralisi June 6, 2017, 2:10 p.m. UTC | #1
On Wed, May 31, 2017 at 03:32:12PM +0100, shameer wrote:
> This provides a helper function to find and retrieve the ITS
> base address from the ID mappings array reference of a device
> IORT node(if any).
> 
> This is used in the subsequent patch to retrieve the ITS base 
> address associated with a pci dev IORT node.

"Add an IORT helper function to retrieve the ITS data through IORT
device<->ITS mappings".

> Signed-off-by: shameer <shameerali.kolothum.thodi@huawei.com>
> ---
>  drivers/acpi/arm64/iort.c        | 47 +++++++++++++++++++++++++++++++++++++---
>  drivers/irqchip/irq-gic-v3-its.c |  3 ++-
>  include/linux/acpi_iort.h        |  8 ++++++-
>  3 files changed, 53 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index c5fecf9..12d7347 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -34,6 +34,7 @@
>  struct iort_its_msi_chip {
>  	struct list_head	list;
>  	struct fwnode_handle	*fw_node;
> +	u64			base_addr;

phys_addr_t

>  	u32			translation_id;
>  };
>  
> @@ -132,13 +133,14 @@ typedef acpi_status (*iort_find_node_callback)
>  
>  /**
>   * iort_register_domain_token() - register domain token and related ITS ID
> - * to the list from where we can get it back later on.
> + * and base address to the list from where we can get it back later on.
>   * @trans_id: ITS ID.

Missing something here

>   * @fw_node: Domain token.
>   *
>   * Returns: 0 on success, -ENOMEM if no memory when allocating list element
>   */
> -int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
> +int iort_register_domain_token(int trans_id, u64 base,

phys_addr_t

> +			       struct fwnode_handle *fw_node)
>  {
>  	struct iort_its_msi_chip *its_msi_chip;
>  
> @@ -148,6 +150,7 @@ int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
>  
>  	its_msi_chip->fw_node = fw_node;
>  	its_msi_chip->translation_id = trans_id;
> +	its_msi_chip->base_addr = base;
>  
>  	spin_lock(&iort_msi_chip_lock);
>  	list_add(&its_msi_chip->list, &iort_msi_chip_list);
> @@ -370,7 +373,6 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
>  
>  		if (!node->mapping_offset || !node->mapping_count)
>  			goto fail_map;
> -

Unrelated change.

>  		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
>  				   node->mapping_offset);
>  
> @@ -491,6 +493,45 @@ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
>  	return -ENODEV;
>  }
>  
> +int iort_dev_find_its_base(struct device *dev, u32 req_id,
> +			   unsigned int idx, u64 *its_base)
> +{
> +	struct acpi_iort_its_group *its;
> +	struct acpi_iort_node *node;
> +	struct iort_its_msi_chip *its_msi_chip;
> +	u32  trans_id;
> +
> +	node = iort_find_dev_node(dev);
> +	if (!node)
> +		return -ENXIO;

-ENODEV, throughout

> +
> +	node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
> +	if (!node)
> +		return -ENXIO;
> +
> +	/* Move to ITS specific data */
> +	its = (struct acpi_iort_its_group *)node->node_data;
> +	if (idx > its->its_count) {
> +		dev_err(dev, "requested ITS ID index [%d] is greater than available [%d]\n",
> +			idx, its->its_count);
> +		return -ENXIO;
> +	}
> +
> +	trans_id = its->identifiers[idx];
> +
> +	spin_lock(&iort_msi_chip_lock);
> +	list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) {
> +		if (its_msi_chip->translation_id == trans_id) {
> +			*its_base = its_msi_chip->base_addr;
> +			spin_unlock(&iort_msi_chip_lock);
> +			return 0;
> +		}
> +	}
> +	spin_unlock(&iort_msi_chip_lock);
> +
> +	return -ENXIO;

Cosmetics:

	bool match = false;

	[...]

	spin_lock(&iort_msi_chip_lock);
	list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) {
		if (its_msi_chip->translation_id == trans_id) {
			*its_base = its_msi_chip->base_addr;
			match = true;
			break;
		}
	}
	spin_unlock(&iort_msi_chip_lock);

	return match ? 0 : -ENODEV;

}

>  /**
>   * iort_dev_find_its_id() - Find the ITS identifier for a device
>   * @dev: The device.
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 45ea1933..c45a2ad 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1854,7 +1854,8 @@ static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
>  		return -ENOMEM;
>  	}
>  
> -	err = iort_register_domain_token(its_entry->translation_id, dom_handle);
> +	err = iort_register_domain_token(its_entry->translation_id, res.start,
> +					 dom_handle);
>  	if (err) {
>  		pr_err("ITS@%pa: Unable to register GICv3 ITS domain token (ITS ID %d) to IORT\n",
>  		       &res.start, its_entry->translation_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 3ff9ace..bf7b53d 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -26,7 +26,8 @@
>  #define IORT_IRQ_MASK(irq)		(irq & 0xffffffffULL)
>  #define IORT_IRQ_TRIGGER_MASK(irq)	((irq >> 32) & 0xffffffffULL)
>  
> -int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
> +int iort_register_domain_token(int trans_id, u64 base,
> +			       struct fwnode_handle *fw_node);
>  void iort_deregister_domain_token(int trans_id);
>  struct fwnode_handle *iort_find_domain_token(int trans_id);
>  #ifdef CONFIG_ACPI_IORT
> @@ -36,6 +37,8 @@
>  struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
>  void acpi_configure_pmsi_domain(struct device *dev);
>  int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
> +int iort_dev_find_its_base(struct device *dev, u32 req_id,
> +			   unsigned int idx, u64 *its_base);
>  /* IOMMU interface */
>  void iort_set_dma_mask(struct device *dev);
>  const struct iommu_ops *iort_iommu_configure(struct device *dev);
> @@ -48,6 +51,9 @@ static inline struct irq_domain *iort_get_device_domain(struct device *dev,
>  							u32 req_id)
>  { return NULL; }
>  static inline void acpi_configure_pmsi_domain(struct device *dev) { }
> +int iort_dev_find_its_base(struct device *dev, u32 req_id,
> +			   unsigned int idx, u64 *its_base)
> +{ return -ENOSYS; }

-ENODEV

Thanks,
Lorenzo
Jacob Pan June 6, 2017, 2:36 p.m. UTC | #2
On Tue, 6 Jun 2017 13:25:00 +0800
"若翾" <eva6688@vip.qq.com> wrote:

> Hi,Jacob,
> Thank you for your reply,
> alibaba in  San Mateo ,
> Do you have a WeChat? You can add me
> WeChat15900779704
> 
I see, I am not planning to relocate at the moment but I will keep it
in mind.

Thanks,
> 
> 
> 
> 
> ------------------
> 
> Eva wang  
> 中国 上海郊区 | BAT高科技公司高端技术类岗位招聘
> 互联网 | 某知名公司
> 
> 
> 
>  
> 
> 
> 
> 
> ------------------ 原始邮件 ------------------
> 发件人: "jacob.jun.pan";<jacob.jun.pan@linux.intel.com>;
> 发送时间: 2017年6月6日(星期二) 中午1:06
> 收件人: "若翾"<eva6688@vip.qq.com>; 
> 抄送: "jacob.jun.pan"<jacob.jun.pan@linux.intel.com>; 
> 主题: Re: Alibaba-kernel
> 
> 
> 
> On Mon, 5 Jun 2017 18:35:27 +0800
> "若翾" <eva6688@vip.qq.com> wrote:
> 
> > 您好,我是猎头eva。
> >  
> > 很冒昧的打扰您,想和您聊一下阿里的机会。  
> >  
> >  
> >  阿里巴巴首席技术官,行癫发出通知:阿里整合9个事业部加原有的中间件技术部组成新的基础设施事业群,携手共同打造具备全球竞争力的阿里巴巴经济体软硬件基础设施。                                
> >   
> >  成立系统软件事业部
> >  由平台架构部团队、AIS的JVM、Kernel团队共同组成,向毕玄汇报。
> >   
> >  目前我们需要高端的技术管理型leader/技术型资深研发专家和高级专家/
> > 行业的标杆和领军人物 1)虚拟化领域:对xen/KVM/Vmware熟悉的。
> > 2)OS内核领域:熟悉Linux内核机制:内存、调度、文件系统、网络等;熟练使用多种Linux内核调试分析工具(kgdb,
> > crash等);性能分析工具(gcover, blktrace, ftrace)等经验;
> > 
> >  
> > 
> >  事业部介绍:
> >  阿里巴巴操作系统研发团队负责全集团的服务器操作系统以及Linux内核的研发与产品化。
> >  团队针对阿里巴巴各业务的需求,新技术的发展,新硬件的引入,在内核与操作系统等基础领域进行研究创新。
> >  目前已经形成alios与alikernel等多个产品。加入我们,你可以跟传说中的多隆大神一起工作,你可以不断挑战基础软件领域的新技术,你可以向社区提Patch,你的工作可以应用到阿里巴巴的数十万台服务器上。阿里巴巴操作系统研发团队,期待你的加入。 
> >   Team Introduction; 
> >  The Operation System R&D Team of Alibaba Group is responsible for
> > research & development and production of the server operation system
> > and linux kernel . If you are interested in challenging and
> > edge-cutting technologies in foundational software domain, please
> > don't hesitate to join us. 
> >   
> Hi Eva,
> 
> Thanks for reaching out, sounds like great opportunity. What are the
> US locations? I am based in Portland Oregon.
> 
> Jacob
> >  
> > 
> >  地点:美国、北京、深圳、杭州
> > 
> >  JD参考介绍
> >  系统软件事业部-Linux内核研发专家
> >  Responsibilities: 
> >  1·Responsible for Linux kernel development 
> >  2·Responsible for Linux kernel related tools development 
> >  3·Responsible for Linux kernel security patching 
> >  4·Linux kernel debugging
> >  岗位要求
> >  1·Expertise in at least one kernel sub-system, for examples,
> > network, file system (ext4, xfs), memory management, process
> > scheduler 2·Five years or more of Linux kernel development
> > experiences 3·Knowledgeable about x86 or arm 4·Experienced with
> > kernel debugging 5·Kernel community contributor as a plus
> > 
> >  Linux内核测试专家
> >  具体职责: 
> >  1.
> > 根据业务需求制定测试方案,测试执行和结果分析,保证操作系统的高质量部署交付。
> > 2. 负责linux内核测试系统、测试工具和测试集的开发。 3.
> > 对内核各子模块性能数据采集和量化分析,发现性能瓶颈,提出解决方案。岗位要求
> >  1. 五年以上软件开发或测试软件开发经验。 
> >  2.熟悉linux操作系统各组件原理,了解内核开发工具和调试工具的运用,有内核开发或调优经验的优先。 
> >  3. 精通至少一到两种脚本语言和C语言的开发。 
> >  4. 具备复杂需求及技术的研究能力,善于进行任务分解,抓住关键点。 
> >  5. 良好的沟通协调能力和团队合作意识,能承受大的工作压力。
> >  
> >  
> >  
> >   
> >  Eva Wang
> >  consultant - Shanghai
> >  Mobile:15900779704
> >  Weixin:15900779704
> >   
> >  ------------------
> >   
> > 
> >  Eva wang  
> >  中国 上海郊区 | BAT高端技术类岗位招聘
> >  互联网 | 知名互联网公司  
> [Jacob Pan]
[Jacob Pan]
Shameerali Kolothum Thodi June 6, 2017, 3:17 p.m. UTC | #3
> -----Original Message-----
> From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi@arm.com]
> Sent: Tuesday, June 06, 2017 3:10 PM
> To: Shameerali Kolothum Thodi
> Cc: marc.zyngier@arm.com; sudeep.holla@arm.com; will.deacon@arm.com;
> robin.murphy@arm.com; hanjun.guo@linaro.org; Gabriele Paoloni; John
> Garry; iommu@lists.linux-foundation.org; linux-arm-
> kernel@lists.infradead.org; linux-acpi@vger.kernel.org; devel@acpica.org;
> Linuxarm; Wangzhou (B); Guohanjun (Hanjun Guo)
> Subject: Re: [RFCv2 1/2] acpi:iort: Add new helper function to retrieve ITS
> base addr from dev IORT node
> 
> On Wed, May 31, 2017 at 03:32:12PM +0100, shameer wrote:
> > This provides a helper function to find and retrieve the ITS base
> > address from the ID mappings array reference of a device IORT node(if
> > any).
> >
> > This is used in the subsequent patch to retrieve the ITS base address
> > associated with a pci dev IORT node.
> 
> "Add an IORT helper function to retrieve the ITS data through IORT device<-
> >ITS mappings".
> 
> > Signed-off-by: shameer <shameerali.kolothum.thodi@huawei.com>
> > ---
> >  drivers/acpi/arm64/iort.c        | 47
> +++++++++++++++++++++++++++++++++++++---
> >  drivers/irqchip/irq-gic-v3-its.c |  3 ++-
> >  include/linux/acpi_iort.h        |  8 ++++++-
> >  3 files changed, 53 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> > index c5fecf9..12d7347 100644
> > --- a/drivers/acpi/arm64/iort.c
> > +++ b/drivers/acpi/arm64/iort.c
> > @@ -34,6 +34,7 @@
> >  struct iort_its_msi_chip {
> >  	struct list_head	list;
> >  	struct fwnode_handle	*fw_node;
> > +	u64			base_addr;
> 
> phys_addr_t
> 
> >  	u32			translation_id;
> >  };
> >
> > @@ -132,13 +133,14 @@ typedef acpi_status (*iort_find_node_callback)
> >
> >  /**
> >   * iort_register_domain_token() - register domain token and related
> > ITS ID
> > - * to the list from where we can get it back later on.
> > + * and base address to the list from where we can get it back later on.
> >   * @trans_id: ITS ID.
> 
> Missing something here
> 
> >   * @fw_node: Domain token.
> >   *
> >   * Returns: 0 on success, -ENOMEM if no memory when allocating list
> element
> >   */
> > -int iort_register_domain_token(int trans_id, struct fwnode_handle
> > *fw_node)
> > +int iort_register_domain_token(int trans_id, u64 base,
> 
> phys_addr_t
> 
> > +			       struct fwnode_handle *fw_node)
> >  {
> >  	struct iort_its_msi_chip *its_msi_chip;
> >
> > @@ -148,6 +150,7 @@ int iort_register_domain_token(int trans_id,
> > struct fwnode_handle *fw_node)
> >
> >  	its_msi_chip->fw_node = fw_node;
> >  	its_msi_chip->translation_id = trans_id;
> > +	its_msi_chip->base_addr = base;
> >
> >  	spin_lock(&iort_msi_chip_lock);
> >  	list_add(&its_msi_chip->list, &iort_msi_chip_list); @@ -370,7 +373,6
> > @@ static struct acpi_iort_node *iort_node_map_id(struct
> > acpi_iort_node *node,
> >
> >  		if (!node->mapping_offset || !node->mapping_count)
> >  			goto fail_map;
> > -
> 
> Unrelated change.
> 
> >  		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
> >  				   node->mapping_offset);
> >
> > @@ -491,6 +493,45 @@ int iort_pmsi_get_dev_id(struct device *dev, u32
> *dev_id)
> >  	return -ENODEV;
> >  }
> >
> > +int iort_dev_find_its_base(struct device *dev, u32 req_id,
> > +			   unsigned int idx, u64 *its_base) {
> > +	struct acpi_iort_its_group *its;
> > +	struct acpi_iort_node *node;
> > +	struct iort_its_msi_chip *its_msi_chip;
> > +	u32  trans_id;
> > +
> > +	node = iort_find_dev_node(dev);
> > +	if (!node)
> > +		return -ENXIO;
> 
> -ENODEV, throughout

Ok. The reason for -ENXIO use is that this function is based on the existing
iort_dev_find_its_id() and it returns -ENXIO for those error cases.

I will incorporate all the other comments in the next revision.

Many thanks,
Shameer
diff mbox

Patch

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..12d7347 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -34,6 +34,7 @@ 
 struct iort_its_msi_chip {
 	struct list_head	list;
 	struct fwnode_handle	*fw_node;
+	u64			base_addr;
 	u32			translation_id;
 };
 
@@ -132,13 +133,14 @@  typedef acpi_status (*iort_find_node_callback)
 
 /**
  * iort_register_domain_token() - register domain token and related ITS ID
- * to the list from where we can get it back later on.
+ * and base address to the list from where we can get it back later on.
  * @trans_id: ITS ID.
  * @fw_node: Domain token.
  *
  * Returns: 0 on success, -ENOMEM if no memory when allocating list element
  */
-int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
+int iort_register_domain_token(int trans_id, u64 base,
+			       struct fwnode_handle *fw_node)
 {
 	struct iort_its_msi_chip *its_msi_chip;
 
@@ -148,6 +150,7 @@  int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
 
 	its_msi_chip->fw_node = fw_node;
 	its_msi_chip->translation_id = trans_id;
+	its_msi_chip->base_addr = base;
 
 	spin_lock(&iort_msi_chip_lock);
 	list_add(&its_msi_chip->list, &iort_msi_chip_list);
@@ -370,7 +373,6 @@  static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
 
 		if (!node->mapping_offset || !node->mapping_count)
 			goto fail_map;
-
 		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
 				   node->mapping_offset);
 
@@ -491,6 +493,45 @@  int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
 	return -ENODEV;
 }
 
+int iort_dev_find_its_base(struct device *dev, u32 req_id,
+			   unsigned int idx, u64 *its_base)
+{
+	struct acpi_iort_its_group *its;
+	struct acpi_iort_node *node;
+	struct iort_its_msi_chip *its_msi_chip;
+	u32  trans_id;
+
+	node = iort_find_dev_node(dev);
+	if (!node)
+		return -ENXIO;
+
+	node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
+	if (!node)
+		return -ENXIO;
+
+	/* Move to ITS specific data */
+	its = (struct acpi_iort_its_group *)node->node_data;
+	if (idx > its->its_count) {
+		dev_err(dev, "requested ITS ID index [%d] is greater than available [%d]\n",
+			idx, its->its_count);
+		return -ENXIO;
+	}
+
+	trans_id = its->identifiers[idx];
+
+	spin_lock(&iort_msi_chip_lock);
+	list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) {
+		if (its_msi_chip->translation_id == trans_id) {
+			*its_base = its_msi_chip->base_addr;
+			spin_unlock(&iort_msi_chip_lock);
+			return 0;
+		}
+	}
+	spin_unlock(&iort_msi_chip_lock);
+
+	return -ENXIO;
+}
+
 /**
  * iort_dev_find_its_id() - Find the ITS identifier for a device
  * @dev: The device.
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 45ea1933..c45a2ad 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1854,7 +1854,8 @@  static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
 		return -ENOMEM;
 	}
 
-	err = iort_register_domain_token(its_entry->translation_id, dom_handle);
+	err = iort_register_domain_token(its_entry->translation_id, res.start,
+					 dom_handle);
 	if (err) {
 		pr_err("ITS@%pa: Unable to register GICv3 ITS domain token (ITS ID %d) to IORT\n",
 		       &res.start, its_entry->translation_id);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 3ff9ace..bf7b53d 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -26,7 +26,8 @@ 
 #define IORT_IRQ_MASK(irq)		(irq & 0xffffffffULL)
 #define IORT_IRQ_TRIGGER_MASK(irq)	((irq >> 32) & 0xffffffffULL)
 
-int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
+int iort_register_domain_token(int trans_id, u64 base,
+			       struct fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
 struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_ACPI_IORT
@@ -36,6 +37,8 @@ 
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
 void acpi_configure_pmsi_domain(struct device *dev);
 int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
+int iort_dev_find_its_base(struct device *dev, u32 req_id,
+			   unsigned int idx, u64 *its_base);
 /* IOMMU interface */
 void iort_set_dma_mask(struct device *dev);
 const struct iommu_ops *iort_iommu_configure(struct device *dev);
@@ -48,6 +51,9 @@  static inline struct irq_domain *iort_get_device_domain(struct device *dev,
 							u32 req_id)
 { return NULL; }
 static inline void acpi_configure_pmsi_domain(struct device *dev) { }
+int iort_dev_find_its_base(struct device *dev, u32 req_id,
+			   unsigned int idx, u64 *its_base)
+{ return -ENOSYS; }
 /* IOMMU interface */
 static inline void iort_set_dma_mask(struct device *dev) { }
 static inline