linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change
@ 2021-01-07  9:11 Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 1/4] PCI: dwc: Change to use an array to store the structure of functions Zhiqiang Hou
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Zhiqiang Hou @ 2021-01-07  9:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, linux-kernel, linux-omap,
	linux-arm-kernel, lorenzo.pieralisi, robh, bhelgaas
  Cc: kishon, minghuan.Lian, jesper.nilsson, jingoohan1,
	gustavo.pimentel, hayashi.kunihiko, Hou Zhiqiang

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

Tune the EP mode code slightly to make it more readable.

Hou Zhiqiang (4):
  PCI: dwc: Change to use an array to store the structure of functions
  PCI: dwc: Add CFG offset info into function's represented structure
  PCI: dwc: Rename callback function func_conf_select and its instance
  PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar()

 drivers/pci/controller/dwc/pci-dra7xx.c       |   2 +-
 .../pci/controller/dwc/pci-layerscape-ep.c    |   8 +-
 drivers/pci/controller/dwc/pcie-artpec6.c     |   2 +-
 .../pci/controller/dwc/pcie-designware-ep.c   | 192 ++++++++----------
 .../pci/controller/dwc/pcie-designware-plat.c |   3 +-
 drivers/pci/controller/dwc/pcie-designware.h  |  11 +-
 drivers/pci/controller/dwc/pcie-uniphier-ep.c |   3 +-
 7 files changed, 96 insertions(+), 125 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] PCI: dwc: Change to use an array to store the structure of functions
  2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
@ 2021-01-07  9:11 ` Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure Zhiqiang Hou
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Zhiqiang Hou @ 2021-01-07  9:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, linux-kernel, linux-omap,
	linux-arm-kernel, lorenzo.pieralisi, robh, bhelgaas
  Cc: kishon, minghuan.Lian, jesper.nilsson, jingoohan1,
	gustavo.pimentel, hayashi.kunihiko, Hou Zhiqiang

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

As there isn't dynamically adding and deleting a function's structure,
the list_head is not necessary for this case. Array is easier and
more efficient to search.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 .../pci/controller/dwc/pcie-designware-ep.c   | 33 ++++++++-----------
 drivers/pci/controller/dwc/pcie-designware.h  |  3 +-
 2 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index bcd1cd9ba8c8..e583700b5ba3 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -34,12 +34,8 @@ EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify);
 struct dw_pcie_ep_func *
 dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
 {
-	struct dw_pcie_ep_func *ep_func;
-
-	list_for_each_entry(ep_func, &ep->func_list, list) {
-		if (ep_func->func_no == func_no)
-			return ep_func;
-	}
+	if (func_no < ep->epc->max_functions)
+		return ep->funcs + func_no;
 
 	return NULL;
 }
@@ -675,9 +671,9 @@ EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
 
 int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
+	u8 i;
 	int ret;
 	void *addr;
-	u8 func_no;
 	struct resource *res;
 	struct pci_epc *epc;
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -685,9 +681,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
 	const struct pci_epc_features *epc_features;
-	struct dw_pcie_ep_func *ep_func;
-
-	INIT_LIST_HEAD(&ep->func_list);
+	struct dw_pcie_ep_func *funcs;
 
 	if (!pci->dbi_base) {
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
@@ -750,18 +744,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	if (ret < 0)
 		epc->max_functions = 1;
 
-	for (func_no = 0; func_no < epc->max_functions; func_no++) {
-		ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
-		if (!ep_func)
-			return -ENOMEM;
+	funcs = devm_kcalloc(dev, epc->max_functions, sizeof(*funcs),
+			     GFP_KERNEL);
+	if (!funcs)
+		return -ENOMEM;
+
+	ep->funcs = funcs;
 
-		ep_func->func_no = func_no;
-		ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
+	for (i = 0; i < epc->max_functions; i++) {
+		funcs[i].func_no = i;
+		funcs[i].msi_cap = dw_pcie_ep_find_capability(ep, i,
 							      PCI_CAP_ID_MSI);
-		ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
+		funcs[i].msix_cap = dw_pcie_ep_find_capability(ep, i,
 							       PCI_CAP_ID_MSIX);
-
-		list_add_tail(&ep_func->list, &ep->func_list);
 	}
 
 	if (ep->ops->ep_init)
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 98710bf5ab0e..16d239c4d09b 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -221,7 +221,6 @@ struct dw_pcie_ep_ops {
 };
 
 struct dw_pcie_ep_func {
-	struct list_head	list;
 	u8			func_no;
 	u8			msi_cap;	/* MSI capability offset */
 	u8			msix_cap;	/* MSI-X capability offset */
@@ -229,7 +228,7 @@ struct dw_pcie_ep_func {
 
 struct dw_pcie_ep {
 	struct pci_epc		*epc;
-	struct list_head	func_list;
+	struct dw_pcie_ep_func	*funcs;
 	const struct dw_pcie_ep_ops *ops;
 	phys_addr_t		phys_base;
 	size_t			addr_size;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure
  2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 1/4] PCI: dwc: Change to use an array to store the structure of functions Zhiqiang Hou
@ 2021-01-07  9:11 ` Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 3/4] PCI: dwc: Rename callback function func_conf_select and its instance Zhiqiang Hou
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Zhiqiang Hou @ 2021-01-07  9:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, linux-kernel, linux-omap,
	linux-arm-kernel, lorenzo.pieralisi, robh, bhelgaas
  Cc: kishon, minghuan.Lian, jesper.nilsson, jingoohan1,
	gustavo.pimentel, hayashi.kunihiko, Hou Zhiqiang

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

To avoid multiple calculating of the CFG offset for each function, store
the CFG offset info to the function's represented structure, and only do
one time calculation during the initialization.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 .../pci/controller/dwc/pcie-designware-ep.c   | 138 ++++++++----------
 drivers/pci/controller/dwc/pcie-designware.h  |   1 +
 2 files changed, 59 insertions(+), 80 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index e583700b5ba3..bc6ad1f96a48 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -42,24 +42,23 @@ dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
 
 static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8 func_no)
 {
-	unsigned int func_offset = 0;
-
 	if (ep->ops->func_conf_select)
-		func_offset = ep->ops->func_conf_select(ep, func_no);
+		return ep->ops->func_conf_select(ep, func_no);
 
-	return func_offset;
+	return 0;
 }
 
 static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
 				   enum pci_barno bar, int flags)
 {
 	u32 reg;
-	unsigned int func_offset = 0;
 	struct dw_pcie_ep *ep = &pci->ep;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return;
 
-	reg = func_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
+	reg = func->cfg_off + PCI_BASE_ADDRESS_0 + (4 * bar);
 	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writel_dbi2(pci, reg, 0x0);
 	dw_pcie_writel_dbi(pci, reg, 0x0);
@@ -83,17 +82,15 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
 static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
 		u8 cap_ptr, u8 cap)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
 	u8 cap_id, next_cap_ptr;
 	u16 reg;
 
-	if (!cap_ptr)
+	if (!cap_ptr || !func)
 		return 0;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = dw_pcie_readw_dbi(pci, func_offset + cap_ptr);
+	reg = dw_pcie_readw_dbi(pci, func->cfg_off + cap_ptr);
 	cap_id = (reg & 0x00ff);
 
 	if (cap_id > PCI_CAP_ID_MAX)
@@ -108,14 +105,15 @@ static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
 
 static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
 	u8 next_cap_ptr;
 	u16 reg;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return 0;
 
-	reg = dw_pcie_readw_dbi(pci, func_offset + PCI_CAPABILITY_LIST);
+	reg = dw_pcie_readw_dbi(pci, func->cfg_off + PCI_CAPABILITY_LIST);
 	next_cap_ptr = (reg & 0x00ff);
 
 	return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
@@ -126,23 +124,26 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	unsigned int func_offset = 0;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
+	u32 cfg_off;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return -EINVAL;
 
+	cfg_off = func->cfg_off;
 	dw_pcie_dbi_ro_wr_en(pci);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_VENDOR_ID, hdr->vendorid);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_DEVICE_ID, hdr->deviceid);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_REVISION_ID, hdr->revid);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_CLASS_PROG, hdr->progif_code);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_CLASS_DEVICE,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_VENDOR_ID, hdr->vendorid);
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_DEVICE_ID, hdr->deviceid);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_REVISION_ID, hdr->revid);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_CLASS_PROG, hdr->progif_code);
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_CLASS_DEVICE,
 			   hdr->subclass_code | hdr->baseclass_code << 8);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_CACHE_LINE_SIZE,
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_CACHE_LINE_SIZE,
 			   hdr->cache_line_size);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_VENDOR_ID,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_SUBSYSTEM_VENDOR_ID,
 			   hdr->subsys_vendor_id);
-	dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_ID, hdr->subsys_id);
-	dw_pcie_writeb_dbi(pci, func_offset + PCI_INTERRUPT_PIN,
+	dw_pcie_writew_dbi(pci, cfg_off + PCI_SUBSYSTEM_ID, hdr->subsys_id);
+	dw_pcie_writeb_dbi(pci, cfg_off + PCI_INTERRUPT_PIN,
 			   hdr->interrupt_pin);
 	dw_pcie_dbi_ro_wr_dis(pci);
 
@@ -223,12 +224,13 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
 	size_t size = epf_bar->size;
 	int flags = epf_bar->flags;
 	enum dw_pcie_as_type as_type;
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 reg;
-	unsigned int func_offset = 0;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
+	if (!func)
+		return -EINVAL;
 
-	reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
+	reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func->cfg_off;
 
 	if (!(flags & PCI_BASE_ADDRESS_SPACE))
 		as_type = DW_PCIE_AS_MEM;
@@ -309,17 +311,13 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	if (!(val & PCI_MSI_FLAGS_ENABLE))
 		return -EINVAL;
@@ -333,17 +331,13 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	val &= ~PCI_MSI_FLAGS_QMASK;
 	val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
@@ -358,17 +352,13 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	if (!(val & PCI_MSIX_FLAGS_ENABLE))
 		return -EINVAL;
@@ -383,29 +373,25 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	u32 val, reg;
-	unsigned int func_offset = 0;
-	struct dw_pcie_ep_func *ep_func;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
 	dw_pcie_dbi_ro_wr_en(pci);
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_FLAGS;
 	val = dw_pcie_readw_dbi(pci, reg);
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
 	val |= interrupts;
 	dw_pcie_writew_dbi(pci, reg, val);
 
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_TABLE;
 	val = offset | bir;
 	dw_pcie_writel_dbi(pci, reg, val);
 
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_PBA;
+	reg = func->msi_cap + func->cfg_off + PCI_MSIX_PBA;
 	val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
 	dw_pcie_writel_dbi(pci, reg, val);
 
@@ -487,37 +473,33 @@ int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u8 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	struct pci_epc *epc = ep->epc;
 	unsigned int aligned_offset;
-	unsigned int func_offset = 0;
 	u16 msg_ctrl, msg_data;
 	u32 msg_addr_lower, msg_addr_upper, reg;
 	u64 msg_addr;
 	bool has_upper;
 	int ret;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msi_cap)
+	if (!func || !func->msi_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
 	/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_FLAGS;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_FLAGS;
 	msg_ctrl = dw_pcie_readw_dbi(pci, reg);
 	has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
-	reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_LO;
+	reg = func->msi_cap + func->cfg_off + PCI_MSI_ADDRESS_LO;
 	msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
 	if (has_upper) {
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_ADDRESS_HI;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_ADDRESS_HI;
 		msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_64;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_DATA_64;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	} else {
 		msg_addr_upper = 0;
-		reg = ep_func->msi_cap + func_offset + PCI_MSI_DATA_32;
+		reg = func->msi_cap + func->cfg_off + PCI_MSI_DATA_32;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	}
 	aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1);
@@ -538,12 +520,11 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 				       u16 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	u32 msg_data;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
 	msg_data = (func_no << PCIE_MSIX_DOORBELL_PF_SHIFT) |
@@ -557,11 +538,10 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 			      u16 interrupt_num)
 {
+	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct dw_pcie_ep_func *ep_func;
 	struct pci_epf_msix_tbl *msix_tbl;
 	struct pci_epc *epc = ep->epc;
-	unsigned int func_offset = 0;
 	u32 reg, msg_data, vec_ctrl;
 	unsigned int aligned_offset;
 	u32 tbl_offset;
@@ -569,13 +549,10 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	int ret;
 	u8 bir;
 
-	ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
-	if (!ep_func || !ep_func->msix_cap)
+	if (!func || !func->msix_cap)
 		return -EINVAL;
 
-	func_offset = dw_pcie_ep_func_select(ep, func_no);
-
-	reg = ep_func->msix_cap + func_offset + PCI_MSIX_TABLE;
+	reg = func->msix_cap + func->cfg_off + PCI_MSIX_TABLE;
 	tbl_offset = dw_pcie_readl_dbi(pci, reg);
 	bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
 	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
@@ -753,6 +730,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 
 	for (i = 0; i < epc->max_functions; i++) {
 		funcs[i].func_no = i;
+		funcs[i].cfg_off = dw_pcie_ep_func_select(ep, i);
 		funcs[i].msi_cap = dw_pcie_ep_find_capability(ep, i,
 							      PCI_CAP_ID_MSI);
 		funcs[i].msix_cap = dw_pcie_ep_find_capability(ep, i,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 16d239c4d09b..8ee67d4b8109 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -224,6 +224,7 @@ struct dw_pcie_ep_func {
 	u8			func_no;
 	u8			msi_cap;	/* MSI capability offset */
 	u8			msix_cap;	/* MSI-X capability offset */
+	u32			cfg_off;	/* CFG offset from DBI base */
 };
 
 struct dw_pcie_ep {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] PCI: dwc: Rename callback function func_conf_select and its instance
  2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 1/4] PCI: dwc: Change to use an array to store the structure of functions Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure Zhiqiang Hou
@ 2021-01-07  9:11 ` Zhiqiang Hou
  2021-01-07  9:11 ` [PATCH 4/4] PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar() Zhiqiang Hou
  2021-04-06  9:03 ` [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Z.q. Hou
  4 siblings, 0 replies; 6+ messages in thread
From: Zhiqiang Hou @ 2021-01-07  9:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, linux-kernel, linux-omap,
	linux-arm-kernel, lorenzo.pieralisi, robh, bhelgaas
  Cc: kishon, minghuan.Lian, jesper.nilsson, jingoohan1,
	gustavo.pimentel, hayashi.kunihiko, Hou Zhiqiang

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

Rename the callback func_conf_select() and its instance and wrapper
to *get_func_cfg_addr(), such that the code becomes more readable.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 drivers/pci/controller/dwc/pci-layerscape-ep.c  | 6 +++---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 9 +++++----
 drivers/pci/controller/dwc/pcie-designware.h    | 2 +-
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 4d12efdacd2f..0f5e4104c06c 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -87,8 +87,8 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
 	}
 }
 
-static unsigned int ls_pcie_ep_func_conf_select(struct dw_pcie_ep *ep,
-						u8 func_no)
+static unsigned int ls_pcie_ep_get_func_cfg_addr(struct dw_pcie_ep *ep,
+						 u8 func_no)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
@@ -101,7 +101,7 @@ static const struct dw_pcie_ep_ops ls_pcie_ep_ops = {
 	.ep_init = ls_pcie_ep_init,
 	.raise_irq = ls_pcie_ep_raise_irq,
 	.get_features = ls_pcie_ep_get_features,
-	.func_conf_select = ls_pcie_ep_func_conf_select,
+	.get_func_cfg_addr = ls_pcie_ep_get_func_cfg_addr,
 };
 
 static const struct ls_pcie_ep_drvdata ls1_ep_drvdata = {
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index bc6ad1f96a48..d8eb9a984547 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -40,10 +40,11 @@ dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
 	return NULL;
 }
 
-static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8 func_no)
+static unsigned int dw_pcie_ep_get_func_cfg_addr(struct dw_pcie_ep *ep,
+						 u8 func_no)
 {
-	if (ep->ops->func_conf_select)
-		return ep->ops->func_conf_select(ep, func_no);
+	if (ep->ops->get_func_cfg_addr)
+		return ep->ops->get_func_cfg_addr(ep, func_no);
 
 	return 0;
 }
@@ -730,7 +731,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 
 	for (i = 0; i < epc->max_functions; i++) {
 		funcs[i].func_no = i;
-		funcs[i].cfg_off = dw_pcie_ep_func_select(ep, i);
+		funcs[i].cfg_off = dw_pcie_ep_get_func_cfg_addr(ep, i);
 		funcs[i].msi_cap = dw_pcie_ep_find_capability(ep, i,
 							      PCI_CAP_ID_MSI);
 		funcs[i].msix_cap = dw_pcie_ep_find_capability(ep, i,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 8ee67d4b8109..b8cbe266e01c 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -217,7 +217,7 @@ struct dw_pcie_ep_ops {
 	 * return a 0, and implement code in callback function of platform
 	 * driver.
 	 */
-	unsigned int (*func_conf_select)(struct dw_pcie_ep *ep, u8 func_no);
+	unsigned int (*get_func_cfg_addr)(struct dw_pcie_ep *ep, u8 func_no);
 };
 
 struct dw_pcie_ep_func {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar()
  2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
                   ` (2 preceding siblings ...)
  2021-01-07  9:11 ` [PATCH 3/4] PCI: dwc: Rename callback function func_conf_select and its instance Zhiqiang Hou
@ 2021-01-07  9:11 ` Zhiqiang Hou
  2021-04-06  9:03 ` [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Z.q. Hou
  4 siblings, 0 replies; 6+ messages in thread
From: Zhiqiang Hou @ 2021-01-07  9:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, linux-kernel, linux-omap,
	linux-arm-kernel, lorenzo.pieralisi, robh, bhelgaas
  Cc: kishon, minghuan.Lian, jesper.nilsson, jingoohan1,
	gustavo.pimentel, hayashi.kunihiko, Hou Zhiqiang

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

This helper is endpoint mode specific, so change to use a pointer of
'struct dw_pcie_ep' as the parameter.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 drivers/pci/controller/dwc/pci-dra7xx.c          |  2 +-
 drivers/pci/controller/dwc/pci-layerscape-ep.c   |  2 +-
 drivers/pci/controller/dwc/pcie-artpec6.c        |  2 +-
 drivers/pci/controller/dwc/pcie-designware-ep.c  | 16 +++++++---------
 .../pci/controller/dwc/pcie-designware-plat.c    |  3 +--
 drivers/pci/controller/dwc/pcie-designware.h     |  5 +++--
 drivers/pci/controller/dwc/pcie-uniphier-ep.c    |  3 +--
 7 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index b105af63854a..12726c63366f 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -383,7 +383,7 @@ static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
 	enum pci_barno bar;
 
 	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-		dw_pcie_ep_reset_bar(pci, bar);
+		dw_pcie_ep_reset_bar(ep, bar);
 
 	dra7xx_pcie_enable_wrapper_interrupts(dra7xx);
 }
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 0f5e4104c06c..dcee95e16139 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -62,7 +62,7 @@ static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
 		return;
 
 	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-		dw_pcie_ep_reset_bar(pci, bar);
+		dw_pcie_ep_reset_bar(ep, bar);
 
 	pcie->ls_epc->msi_capable = ep_func->msi_cap ? true : false;
 	pcie->ls_epc->msix_capable = ep_func->msix_cap ? true : false;
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index 597c282f586c..f833daf6d422 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -348,7 +348,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
 	artpec6_pcie_wait_for_phy(artpec6_pcie);
 
 	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-		dw_pcie_ep_reset_bar(pci, bar);
+		dw_pcie_ep_reset_bar(ep, bar);
 }
 
 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index d8eb9a984547..2dc960e74fd0 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -49,11 +49,11 @@ static unsigned int dw_pcie_ep_get_func_cfg_addr(struct dw_pcie_ep *ep,
 	return 0;
 }
 
-static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
+static void __dw_pcie_ep_reset_bar(struct dw_pcie_ep *ep, u8 func_no,
 				   enum pci_barno bar, int flags)
 {
 	u32 reg;
-	struct dw_pcie_ep *ep = &pci->ep;
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	struct dw_pcie_ep_func *func = dw_pcie_ep_get_func_from_ep(ep, func_no);
 
 	if (!func)
@@ -70,14 +70,12 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
 	dw_pcie_dbi_ro_wr_dis(pci);
 }
 
-void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
+void dw_pcie_ep_reset_bar(struct dw_pcie_ep *ep, enum pci_barno bar)
 {
-	u8 func_no, funcs;
-
-	funcs = pci->ep.epc->max_functions;
+	u8 func_no;
 
-	for (func_no = 0; func_no < funcs; func_no++)
-		__dw_pcie_ep_reset_bar(pci, func_no, bar, 0);
+	for (func_no = 0; func_no < ep->epc->max_functions; func_no++)
+		__dw_pcie_ep_reset_bar(ep, func_no, bar, 0);
 }
 
 static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
@@ -208,7 +206,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
 	enum pci_barno bar = epf_bar->barno;
 	u32 atu_index = ep->bar_to_atu[bar];
 
-	__dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags);
+	__dw_pcie_ep_reset_bar(ep, func_no, bar, epf_bar->flags);
 
 	dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
 	clear_bit(atu_index, ep->ib_window_map);
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index 9b397c807261..49d51584a547 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -47,11 +47,10 @@ static const struct dw_pcie_ops dw_pcie_ops = {
 
 static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep)
 {
-	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	enum pci_barno bar;
 
 	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-		dw_pcie_ep_reset_bar(pci, bar);
+		dw_pcie_ep_reset_bar(ep, bar);
 }
 
 static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index b8cbe266e01c..10ba09237def 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -415,7 +415,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u16 interrupt_num);
 int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 				       u16 interrupt_num);
-void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
+void dw_pcie_ep_reset_bar(struct dw_pcie_ep *ep, enum pci_barno bar);
 struct dw_pcie_ep_func *
 dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no);
 #else
@@ -465,7 +465,8 @@ static inline int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep,
 	return 0;
 }
 
-static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
+static inline void dw_pcie_ep_reset_bar(struct dw_pcie_ep *ep,
+					enum pci_barno bar)
 {
 }
 
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 69810c6b0d58..21e185bf90d6 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -134,11 +134,10 @@ static void uniphier_pcie_stop_link(struct dw_pcie *pci)
 
 static void uniphier_pcie_ep_init(struct dw_pcie_ep *ep)
 {
-	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	enum pci_barno bar;
 
 	for (bar = BAR_0; bar <= BAR_5; bar++)
-		dw_pcie_ep_reset_bar(pci, bar);
+		dw_pcie_ep_reset_bar(ep, bar);
 }
 
 static int uniphier_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change
  2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
                   ` (3 preceding siblings ...)
  2021-01-07  9:11 ` [PATCH 4/4] PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar() Zhiqiang Hou
@ 2021-04-06  9:03 ` Z.q. Hou
  4 siblings, 0 replies; 6+ messages in thread
From: Z.q. Hou @ 2021-04-06  9:03 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, linux-kernel, linux-omap,
	linux-arm-kernel, lorenzo.pieralisi, robh, bhelgaas
  Cc: kishon, M.h. Lian, jesper.nilsson, jingoohan1, gustavo.pimentel,
	hayashi.kunihiko

Hi Lorenzo, Rob and Bjorn,

Any comments on this series?

Thanks,
Zhiqiang

> -----Original Message-----
> From: Z.q. Hou <zhiqiang.hou@nxp.com>
> Sent: 2021年1月7日 17:11
> To: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org; linux-omap@vger.kernel.org;
> linux-arm-kernel@axis.com; lorenzo.pieralisi@arm.com; robh@kernel.org;
> bhelgaas@google.com
> Cc: kishon@ti.com; M.h. Lian <minghuan.lian@nxp.com>;
> jesper.nilsson@axis.com; jingoohan1@gmail.com;
> gustavo.pimentel@synopsys.com; hayashi.kunihiko@socionext.com; Z.q.
> Hou <zhiqiang.hou@nxp.com>
> Subject: [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change
> 
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> Tune the EP mode code slightly to make it more readable.
> 
> Hou Zhiqiang (4):
>   PCI: dwc: Change to use an array to store the structure of functions
>   PCI: dwc: Add CFG offset info into function's represented structure
>   PCI: dwc: Rename callback function func_conf_select and its instance
>   PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar()
> 
>  drivers/pci/controller/dwc/pci-dra7xx.c       |   2 +-
>  .../pci/controller/dwc/pci-layerscape-ep.c    |   8 +-
>  drivers/pci/controller/dwc/pcie-artpec6.c     |   2 +-
>  .../pci/controller/dwc/pcie-designware-ep.c   | 192 ++++++++----------
>  .../pci/controller/dwc/pcie-designware-plat.c |   3 +-
>  drivers/pci/controller/dwc/pcie-designware.h  |  11 +-
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c |   3 +-
>  7 files changed, 96 insertions(+), 125 deletions(-)
> 
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-04-06  9:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-07  9:11 [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 1/4] PCI: dwc: Change to use an array to store the structure of functions Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 2/4] PCI: dwc: Add CFG offset info into function's represented structure Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 3/4] PCI: dwc: Rename callback function func_conf_select and its instance Zhiqiang Hou
2021-01-07  9:11 ` [PATCH 4/4] PCI: dwc: Change the parameter of function dw_pcie_ep_reset_bar() Zhiqiang Hou
2021-04-06  9:03 ` [PATCH 0/4] PCI: dwc: Refine the EP code no functionality change Z.q. Hou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).