* [PATCH 0/3] Add dma_set_mask to pci_controller_ops
@ 2015-04-28 5:12 Daniel Axtens
2015-04-28 5:12 ` [PATCH 1/3] powerpc/powernv: Specialise pci_controller_ops for each controller type Daniel Axtens
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Daniel Axtens @ 2015-04-28 5:12 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Daniel Axtens
This adds dma_set_mask to pci_controller_ops.
Currently it's only implemented on PowerNV, because it gets very messy
on systems that have more than just simple PCI busses.
On the plus side, this series massively simplifies the code path on
PowerNV (see patch #3).
It is based on my recent MSI patch series[0], although it doesn't
depend on it. It could easily be respun on top of -rc1 if required.
It does depend on a PowerNV bug fix[1].
Tested on PowerNV big-endian.
Regards,
Daniel
[0] http://lkml.kernel.org/r/1428985683-24767-1-git-send-email-dja@axtens.net
[1] http://patchwork.ozlabs.org/patch/464765/
Daniel Axtens (3):
powerpc/powernv: Specialise pci_controller_ops for each controller
type
powerpc/pci: add dma_set_mask to pci_controller_ops
powerpc/powernv: Move dma_set_mask from pnv_phb to pci_controller_ops
arch/powerpc/include/asm/pci-bridge.h | 2 ++
arch/powerpc/kernel/dma.c | 11 +++++++++++
arch/powerpc/platforms/powernv/pci-ioda.c | 25 ++++++++++++++++++-------
arch/powerpc/platforms/powernv/pci-p5ioc2.c | 12 +++++++++++-
arch/powerpc/platforms/powernv/pci.c | 23 +++--------------------
arch/powerpc/platforms/powernv/pci.h | 8 ++++++--
arch/powerpc/platforms/powernv/powernv.h | 8 --------
arch/powerpc/platforms/powernv/setup.c | 8 --------
8 files changed, 51 insertions(+), 46 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] powerpc/powernv: Specialise pci_controller_ops for each controller type
2015-04-28 5:12 [PATCH 0/3] Add dma_set_mask to pci_controller_ops Daniel Axtens
@ 2015-04-28 5:12 ` Daniel Axtens
2015-04-28 5:12 ` [PATCH 2/3] powerpc/pci: add dma_set_mask to pci_controller_ops Daniel Axtens
2015-04-28 5:12 ` [PATCH 3/3] powerpc/powernv: Move dma_set_mask from pnv_phb " Daniel Axtens
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Axtens @ 2015-04-28 5:12 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Daniel Axtens
Remove powernv generic PCI controller operations. Replace it with
controller ops for each of the two supported PHBs.
As an added bonus, make the two new structs const, which will help
guard against bugs such as the one introduced in 65ebf4b63
("powerpc/powernv: Move controller ops from ppc_md to controller_ops")
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 18 ++++++++++++++----
arch/powerpc/platforms/powernv/pci-p5ioc2.c | 12 +++++++++++-
arch/powerpc/platforms/powernv/pci.c | 13 +++----------
arch/powerpc/platforms/powernv/pci.h | 6 ++++++
arch/powerpc/platforms/powernv/powernv.h | 2 --
5 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 6ed76c6..c853b62 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -44,6 +44,8 @@
#include "powernv.h"
#include "pci.h"
+static const struct pci_controller_ops pnv_pci_ioda_controller_ops;
+
/* 256M DMA window, 4K TCE pages, 8 bytes TCE */
#define TCE32_TABLE_SIZE ((0x10000000 / 0x1000) * 8)
@@ -2808,10 +2810,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
* the child P2P bridges) can form individual PE.
*/
ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
- pnv_pci_controller_ops.enable_device_hook = pnv_pci_enable_device_hook;
- pnv_pci_controller_ops.window_alignment = pnv_pci_window_alignment;
- pnv_pci_controller_ops.reset_secondary_bus = pnv_pci_reset_secondary_bus;
- hose->controller_ops = pnv_pci_controller_ops;
+ hose->controller_ops = pnv_pci_ioda_controller_ops;
#ifdef CONFIG_PCI_IOV
ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
@@ -2868,3 +2867,14 @@ void __init pnv_pci_init_ioda_hub(struct device_node *np)
pnv_pci_init_ioda_phb(phbn, hub_id, PNV_PHB_IODA1);
}
}
+
+static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
+ .dma_dev_setup = pnv_pci_dma_dev_setup,
+#ifdef CONFIG_PCI_MSI
+ .setup_msi_irqs = pnv_setup_msi_irqs,
+ .teardown_msi_irqs = pnv_teardown_msi_irqs,
+#endif
+ .enable_device_hook = pnv_pci_enable_device_hook,
+ .window_alignment = pnv_pci_window_alignment,
+ .reset_secondary_bus = pnv_pci_reset_secondary_bus,
+};
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index 4729ca7..a83951b 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -35,6 +35,8 @@
#include "powernv.h"
#include "pci.h"
+static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops;
+
/* For now, use a fixed amount of TCE memory for each p5ioc2
* hub, 16M will do
*/
@@ -133,7 +135,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
phb->hose->first_busno = 0;
phb->hose->last_busno = 0xff;
phb->hose->private_data = phb;
- phb->hose->controller_ops = pnv_pci_controller_ops;
+ phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops;
phb->hub_id = hub_id;
phb->opal_id = phb_id;
phb->type = PNV_PHB_P5IOC2;
@@ -234,3 +236,11 @@ void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
}
}
}
+
+static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = {
+ .dma_dev_setup = pnv_pci_dma_dev_setup,
+#ifdef CONFIG_PCI_MSI
+ .setup_msi_irqs = pnv_setup_msi_irqs,
+ .teardown_msi_irqs = pnv_teardown_msi_irqs,
+#endif
+};
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 0f04940..d7e37d8 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -45,7 +45,7 @@
//#define cfg_dbg(fmt...) printk(fmt)
#ifdef CONFIG_PCI_MSI
-static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
@@ -94,7 +94,7 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return 0;
}
-static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
+void pnv_teardown_msi_irqs(struct pci_dev *pdev)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
@@ -662,7 +662,7 @@ void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
tbl->it_type = TCE_PCI;
}
-static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
+void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
@@ -772,10 +772,3 @@ void __init pnv_pci_init(void)
machine_subsys_initcall_sync(powernv, tce_iommu_bus_notifier_init);
-struct pci_controller_ops pnv_pci_controller_ops = {
- .dma_dev_setup = pnv_pci_dma_dev_setup,
-#ifdef CONFIG_PCI_MSI
- .setup_msi_irqs = pnv_setup_msi_irqs,
- .teardown_msi_irqs = pnv_teardown_msi_irqs,
-#endif
-};
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 070ee88..b6d1290 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -218,4 +218,10 @@ extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
+extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
+#ifdef CONFIG_PCI_MSI
+extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
+extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
+#endif
+
#endif /* __POWERNV_PCI_H */
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h
index 826d2c9..604c48e 100644
--- a/arch/powerpc/platforms/powernv/powernv.h
+++ b/arch/powerpc/platforms/powernv/powernv.h
@@ -29,8 +29,6 @@ static inline u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev)
}
#endif
-extern struct pci_controller_ops pnv_pci_controller_ops;
-
extern u32 pnv_get_supported_cpuidle_states(void);
extern void pnv_lpc_init(void);
--
2.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] powerpc/pci: add dma_set_mask to pci_controller_ops
2015-04-28 5:12 [PATCH 0/3] Add dma_set_mask to pci_controller_ops Daniel Axtens
2015-04-28 5:12 ` [PATCH 1/3] powerpc/powernv: Specialise pci_controller_ops for each controller type Daniel Axtens
@ 2015-04-28 5:12 ` Daniel Axtens
2015-04-28 5:12 ` [PATCH 3/3] powerpc/powernv: Move dma_set_mask from pnv_phb " Daniel Axtens
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Axtens @ 2015-04-28 5:12 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Daniel Axtens
Some systems only need to deal with DMA masks for PCI devices.
For these systems, we can avoid the need for a platform hook and
instead use a pci controller based hook.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/include/asm/pci-bridge.h | 2 ++
arch/powerpc/kernel/dma.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index a3b6252..6d17bb8 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -36,6 +36,8 @@ struct pci_controller_ops {
int nvec, int type);
void (*teardown_msi_irqs)(struct pci_dev *dev);
#endif
+
+ int (*dma_set_mask)(struct pci_dev *dev, u64 dma_mask);
};
/*
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 484b2d4..1acf19c 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -246,8 +246,19 @@ int __dma_set_mask(struct device *dev, u64 dma_mask)
int dma_set_mask(struct device *dev, u64 dma_mask)
{
+ struct pci_dev *pdev;
+ struct pci_controller *phb;
+
if (ppc_md.dma_set_mask)
return ppc_md.dma_set_mask(dev, dma_mask);
+
+ if (dev_is_pci(dev)) {
+ pdev = to_pci_dev(dev);
+ phb = pci_bus_to_host(pdev->bus);
+ if (phb->controller_ops.dma_set_mask)
+ return phb->controller_ops.dma_set_mask(pdev, dma_mask);
+ }
+
return __dma_set_mask(dev, dma_mask);
}
EXPORT_SYMBOL(dma_set_mask);
--
2.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] powerpc/powernv: Move dma_set_mask from pnv_phb to pci_controller_ops
2015-04-28 5:12 [PATCH 0/3] Add dma_set_mask to pci_controller_ops Daniel Axtens
2015-04-28 5:12 ` [PATCH 1/3] powerpc/powernv: Specialise pci_controller_ops for each controller type Daniel Axtens
2015-04-28 5:12 ` [PATCH 2/3] powerpc/pci: add dma_set_mask to pci_controller_ops Daniel Axtens
@ 2015-04-28 5:12 ` Daniel Axtens
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Axtens @ 2015-04-28 5:12 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Daniel Axtens
Previously, dma_set_mask on powernv was convoluted:
0) Call dma_set_mask (kernel/dma.c)
1) In dma_set_mask, ppc_md.dma_set_mask exists, so call it.
2) On powernv, that function pointer is pnv_dma_set_mask.
In pnv_dma_set_mask, the device is pci, so call pnv_pci_dma_set_mask.
3) In pnv_pci_dma_set_mask, call pnv_phb->set_dma_mask if it exists.
4) It only exists in the ioda case, where it points to
pnv_pci_ioda_dma_set_mask, which is the final function.
So the call chain is:
dma_set_mask ->
pnv_dma_set_mask ->
pnv_pci_dma_set_mask ->
pnv_pci_ioda_dma_set_mask
Both ppc_md and pnv_phb function pointers are used
Rip out the ppc_md call, pnv_dma_set_mask, pnv_pci_dma_set_mask.
Instead:
0) Call dma_set_mask (kernel/dma.c)
1) In dma_set_mask, the device is pci, and pci_controller_ops.dma_set_mask
exists, so call pci_controller_ops.dma_set_mask
2) In the ioda case, that points to pnv_pci_ioda_dma_set_mask.
The new call chain is
dma_set_mask ->
pnv_pci_ioda_dma_set_mask
Now only the pci_controller_ops function pointer is used.
The fallback paths for p5ioc2 are the same.
Previously, pnv_pci_dma_set_mask would find no pnv_phb->set_dma_mask
function, to it would call __set_dma_mask.
Now, dma_set_mask finds no ppc_md call or pci_controller_ops call,
so it calls __set_dma_mask.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 7 ++++---
arch/powerpc/platforms/powernv/pci.c | 10 ----------
arch/powerpc/platforms/powernv/pci.h | 2 --
arch/powerpc/platforms/powernv/powernv.h | 6 ------
arch/powerpc/platforms/powernv/setup.c | 8 --------
5 files changed, 4 insertions(+), 29 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index c853b62..1e77a50 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1603,9 +1603,10 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev
set_iommu_table_base_and_group(&pdev->dev, pe->tce32_table);
}
-static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
- struct pci_dev *pdev, u64 dma_mask)
+static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
{
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+ struct pnv_phb *phb = hose->private_data;
struct pci_dn *pdn = pci_get_pdn(pdev);
struct pnv_ioda_pe *pe;
uint64_t top;
@@ -2793,7 +2794,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
/* Setup TCEs */
phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
- phb->dma_set_mask = pnv_pci_ioda_dma_set_mask;
phb->dma_get_required_mask = pnv_pci_ioda_dma_get_required_mask;
/* Setup shutdown function for kexec */
@@ -2877,4 +2877,5 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
.enable_device_hook = pnv_pci_enable_device_hook,
.window_alignment = pnv_pci_window_alignment,
.reset_secondary_bus = pnv_pci_reset_secondary_bus,
+ .dma_set_mask = pnv_pci_ioda_dma_set_mask,
};
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index d7e37d8..acc0ced 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -689,16 +689,6 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
phb->dma_dev_setup(phb, pdev);
}
-int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
-{
- struct pci_controller *hose = pci_bus_to_host(pdev->bus);
- struct pnv_phb *phb = hose->private_data;
-
- if (phb && phb->dma_set_mask)
- return phb->dma_set_mask(phb, pdev, dma_mask);
- return __dma_set_mask(&pdev->dev, dma_mask);
-}
-
u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index b6d1290..60bb935 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -106,8 +106,6 @@ struct pnv_phb {
unsigned int hwirq, unsigned int virq,
unsigned int is_64, struct msi_msg *msg);
void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
- int (*dma_set_mask)(struct pnv_phb *phb, struct pci_dev *pdev,
- u64 dma_mask);
u64 (*dma_get_required_mask)(struct pnv_phb *phb,
struct pci_dev *pdev);
void (*fixup_phb)(struct pci_controller *hose);
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h
index 604c48e..1e56962 100644
--- a/arch/powerpc/platforms/powernv/powernv.h
+++ b/arch/powerpc/platforms/powernv/powernv.h
@@ -12,17 +12,11 @@ struct pci_dev;
#ifdef CONFIG_PCI
extern void pnv_pci_init(void);
extern void pnv_pci_shutdown(void);
-extern int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask);
extern u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev);
#else
static inline void pnv_pci_init(void) { }
static inline void pnv_pci_shutdown(void) { }
-static inline int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
-{
- return -ENODEV;
-}
-
static inline u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev)
{
return 0;
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 16fdcb2..92fcc04 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -169,13 +169,6 @@ static void pnv_progress(char *s, unsigned short hex)
{
}
-static int pnv_dma_set_mask(struct device *dev, u64 dma_mask)
-{
- if (dev_is_pci(dev))
- return pnv_pci_dma_set_mask(to_pci_dev(dev), dma_mask);
- return __dma_set_mask(dev, dma_mask);
-}
-
static u64 pnv_dma_get_required_mask(struct device *dev)
{
if (dev_is_pci(dev))
@@ -492,7 +485,6 @@ define_machine(powernv) {
.machine_shutdown = pnv_shutdown,
.power_save = power7_idle,
.calibrate_decr = generic_calibrate_decr,
- .dma_set_mask = pnv_dma_set_mask,
.dma_get_required_mask = pnv_dma_get_required_mask,
#ifdef CONFIG_KEXEC
.kexec_cpu_down = pnv_kexec_cpu_down,
--
2.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-04-28 5:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-28 5:12 [PATCH 0/3] Add dma_set_mask to pci_controller_ops Daniel Axtens
2015-04-28 5:12 ` [PATCH 1/3] powerpc/powernv: Specialise pci_controller_ops for each controller type Daniel Axtens
2015-04-28 5:12 ` [PATCH 2/3] powerpc/pci: add dma_set_mask to pci_controller_ops Daniel Axtens
2015-04-28 5:12 ` [PATCH 3/3] powerpc/powernv: Move dma_set_mask from pnv_phb " Daniel Axtens
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).