[PATCH v1 05/21] PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip

2014-09-05 Thread Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index a77e7f7..539c11d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -29,9 +29,14 @@ static int pci_msi_enable = 1;
 
 /* Arch hooks */
 
+struct msi_chip * __weak arch_find_msi_chip(struct pci_dev *dev)
+{
+   return dev-bus-msi;
+}
+
 int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
-   struct msi_chip *chip = dev-bus-msi;
+   struct msi_chip *chip = arch_find_msi_chip(dev);
int err;
 
if (!chip || !chip-setup_irq)
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 03/21] MSI: Remove the redundant irq_set_chip_data()

2014-09-05 Thread Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f6cb317..d547f7f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,8 +41,6 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
if (err  0)
return err;
 
-   irq_set_chip_data(desc-irq, chip);
-
return 0;
 }
 
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 10/21] x86/MSI: Remove unused MSI weak arch functions

2014-09-05 Thread Yijing Wang
Now we can clean up MSI weak arch functions in x86.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/x86/include/asm/pci.h  |3 ---
 arch/x86/include/asm/x86_init.h |4 
 arch/x86/kernel/apic/io_apic.c  |2 +-
 arch/x86/kernel/x86_init.c  |   24 
 drivers/iommu/irq_remapping.c   |1 -
 5 files changed, 1 insertions(+), 33 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 878a06d..34f9676 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -96,14 +96,11 @@ extern void pci_iommu_alloc(void);
 #ifdef CONFIG_PCI_MSI
 /* implemented in arch/x86/kernel/apic/io_apic. */
 struct msi_desc;
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
 void native_teardown_msi_irq(unsigned int irq);
-void native_restore_msi_irqs(struct pci_dev *dev);
 int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
  unsigned int irq_base, unsigned int irq_offset);
 extern struct msi_chip *x86_msi_chip;
 #else
-#define native_setup_msi_irqs  NULL
 #define native_teardown_msi_irqNULL
 #endif
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f58a9c7..2514f67 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -174,13 +174,9 @@ struct pci_dev;
 struct msi_msg;
 
 struct x86_msi_ops {
-   int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
void (*compose_msi_msg)(struct pci_dev *dev, unsigned int irq,
unsigned int dest, struct msi_msg *msg,
   u8 hpet_id);
-   void (*teardown_msi_irq)(unsigned int irq);
-   void (*teardown_msi_irqs)(struct pci_dev *dev);
-   void (*restore_msi_irqs)(struct pci_dev *dev);
int  (*setup_hpet_msi)(unsigned int irq, unsigned int id);
 };
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 882b95e..f998192 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3200,7 +3200,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*msidesc,
return 0;
 }
 
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
struct msi_desc *msidesc;
unsigned int irq;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 234b072..cc32568 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -110,34 +110,10 @@ EXPORT_SYMBOL_GPL(x86_platform);
 
 #if defined(CONFIG_PCI_MSI)
 struct x86_msi_ops x86_msi = {
-   .setup_msi_irqs = native_setup_msi_irqs,
.compose_msi_msg= native_compose_msi_msg,
-   .teardown_msi_irq   = native_teardown_msi_irq,
-   .teardown_msi_irqs  = default_teardown_msi_irqs,
-   .restore_msi_irqs   = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
 };
 
-/* MSI arch specific hooks */
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
-   return x86_msi.setup_msi_irqs(dev, nvec, type);
-}
-
-void arch_teardown_msi_irqs(struct pci_dev *dev)
-{
-   x86_msi.teardown_msi_irqs(dev);
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-   x86_msi.teardown_msi_irq(irq);
-}
-
-void arch_restore_msi_irqs(struct pci_dev *dev)
-{
-   x86_msi.restore_msi_irqs(dev);
-}
 #endif
 
 struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index e75026e..99b1c0f 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -170,7 +170,6 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
-   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
x86_msi_chip = remap_msi_chip;
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 09/21] Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/irq_remapping.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..e75026e 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -148,6 +148,11 @@ static int irq_remapping_setup_msi_irqs(struct pci_dev 
*dev,
return do_setup_msix_irqs(dev, nvec);
 }
 
+static struct msi_chip remap_msi_chip = {
+   .setup_irqs = irq_remapping_setup_msi_irqs,
+   .teardown_irq = native_teardown_msi_irq,
+};
+
 static void eoi_ioapic_pin_remapped(int apic, int pin, int vector)
 {
/*
@@ -165,9 +170,10 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
-   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
+   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
+   x86_msi_chip = remap_msi_chip;
 }
 
 static __init int setup_nointremap(char *str)
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 08/21] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 arch/x86/pci/xen.c |   46 ++
 1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 84c2fce..e669ee4 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -376,6 +376,11 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev 
*dev)
 }
 #endif
 
+static void xen_teardown_msi_irq(unsigned int irq)
+{
+   xen_destroy_irq(irq);
+}
+
 static void xen_teardown_msi_irqs(struct pci_dev *dev)
 {
struct msi_desc *msidesc;
@@ -385,19 +390,26 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
xen_pci_frontend_disable_msix(dev);
else
xen_pci_frontend_disable_msi(dev);
-
-   /* Free the IRQ's and the msidesc using the generic code. */
-   default_teardown_msi_irqs(dev);
-}
-
-static void xen_teardown_msi_irq(unsigned int irq)
-{
-   xen_destroy_irq(irq);
+
+   list_for_each_entry(msidesc, dev-msi_list, list) {
+   int i, nvec;
+   if (msidesc-irq == 0)
+   continue;
+   if (msidesc-nvec_used)
+   nvec = msidesc-nvec_used;
+   else
+   nvec = 1  msidesc-msi_attrib.multiple;
+   for (i = 0; i  nvec; i++)
+   xen_teardown_msi_irq(msidesc-irq + i);
+   }
 }
 
 void xen_nop_msi_mask(struct irq_data *data)
 {
 }
+
+struct msi_chip xen_msi_chip;
+
 #endif
 
 int __init pci_xen_init(void)
@@ -418,9 +430,9 @@ int __init pci_xen_init(void)
 #endif
 
 #ifdef CONFIG_PCI_MSI
-   x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
-   x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
-   x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
+   xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
+   xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
+   x86_msi_chip = xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
 #endif
@@ -441,8 +453,9 @@ int __init pci_xen_hvm_init(void)
 #endif
 
 #ifdef CONFIG_PCI_MSI
-   x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
-   x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+   xen_msi_chip.setup_irqs = xen_hvm_setup_msi_irqs;
+   xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+   x86_msi_chip = xen_msi_chip;
 #endif
return 0;
 }
@@ -499,9 +512,10 @@ int __init pci_xen_initial_domain(void)
int irq;
 
 #ifdef CONFIG_PCI_MSI
-   x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
-   x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
-   x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
+   xen_msi_chip.setup_irqs = xen_initdom_setup_msi_irqs;
+   xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+   xen_msi_chip.restore_irqs = xen_initdom_restore_msi_irqs;
+   x86_msi_chip = xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
 #endif
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 17/21] arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/arm/mach-iop13xx/include/mach/pci.h |2 ++
 arch/arm/mach-iop13xx/iq81340mc.c|1 +
 arch/arm/mach-iop13xx/iq81340sc.c|1 +
 arch/arm/mach-iop13xx/msi.c  |9 +++--
 arch/arm/mach-iop13xx/pci.c  |6 ++
 5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h 
b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..7a073cb 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -10,6 +10,8 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data 
*);
 void iop13xx_atu_select(struct hw_pci *plat_pci);
 void iop13xx_pci_init(void);
 void iop13xx_map_pci_memory(void);
+void iop13xx_add_bus(struct pci_bus *bus);
+extern struct msi_chip iop13xx_msi_chip;
 
 #define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |   \
   PCI_STATUS_SIG_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c 
b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..19d47cb 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,7 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq= iq81340mc_pcix_map_irq,
.scan   = iop13xx_scan_bus,
.preinit= iop13xx_pci_init,
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340mc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c 
b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..4d56993 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -61,6 +61,7 @@ static struct hw_pci iq81340sc_pci __initdata = {
.scan   = iop13xx_scan_bus,
.map_irq= iq81340sc_atux_map_irq,
.preinit= iop13xx_pci_init
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340sc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index e7730cf..1a8cb2f 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,7 @@ static struct irq_chip iop13xx_msi_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int iop13xx_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
struct msi_msg msg;
@@ -159,7 +159,12 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct 
msi_desc *desc)
return 0;
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+static void iop13xx_teardown_msi_irq(unsigned int irq)
 {
irq_free_desc(irq);
 }
+
+struct msi_chip iop13xx_chip = {
+   .setup_irq = iop13xx_setup_msi_irq,
+   .teardown_irq = iop13xx_teardown_msi_irq,
+};
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..f498800 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -962,6 +962,12 @@ void __init iop13xx_atu_select(struct hw_pci *plat_pci)
}
 }
 
+void iop13xx_add_bus(struct pci_bus *bus)
+{
+   if (IS_ENABLED(CONFIG_PCI_MSI))
+   bus-msi = iop13xx_msi_chip;
+}
+
 void __init iop13xx_pci_init(void)
 {
/* clear pre-existing south bridge errors */
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 16/21] s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/s390/pci/pci.c |   18 ++
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 2fa7b14..da5316e 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,7 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
 }
 
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int zpci_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
@@ -434,7 +434,7 @@ out:
return rc;
 }
 
-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct pci_dev *pdev)
 {
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -448,9 +448,9 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
/* Release MSI interrupts */
list_for_each_entry(msi, pdev-msi_list, list) {
if (msi-msi_attrib.is_msix)
-   default_msix_mask_irq(msi, 1);
+   __msix_mask_irq(msi, 1);
else
-   default_msi_mask_irq(msi, 1, 1);
+   __msi_mask_irq(msi, 1, 1);
irq_set_msi_desc(msi-irq, NULL);
irq_free_desc(msi-irq);
msi-msg.address_lo = 0;
@@ -464,6 +464,16 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
airq_iv_free_bit(zpci_aisb_iv, zdev-aisb);
 }
 
+static struct msi_chip zpci_msi_chip = {
+   .setup_irqs = zpci_setup_msi_irqs,
+   .teardown_irqs = zpci_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return zpci_msi_chip;
+}
+
 static void zpci_map_resources(struct zpci_dev *zdev)
 {
struct pci_dev *pdev = zdev-pdev;
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 13/21] MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/mips/pci/msi-xlp.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..6b791ef 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
 {
 }
 
@@ -450,7 +450,7 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int 
link,
return 0;
 }
 
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int xlp_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
struct pci_dev *lnkdev;
uint64_t lnkbase;
@@ -472,6 +472,16 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
return xlp_setup_msi(lnkbase, node, link, desc);
 }
 
+static struct msi_chip xlp_chip = {
+   .setup_irq = xlp_setup_msi_irq,
+   .teardown_irq = xlp_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return xlp_chip;
+}
+
 void __init xlp_init_node_msi_irqs(int node, int link)
 {
struct nlm_soc_info *nodep;
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 19/21] Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/sparc/kernel/pci.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b36365f..2a89ee2 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -905,7 +905,7 @@ int pci_domain_nr(struct pci_bus *pbus)
 EXPORT_SYMBOL(pci_domain_nr);
 
 #ifdef CONFIG_PCI_MSI
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int sparc_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 {
struct pci_pbm_info *pbm = pdev-dev.archdata.host_controller;
unsigned int irq;
@@ -916,7 +916,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct 
msi_desc *desc)
return pbm-setup_msi_irq(irq, pdev, desc);
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+void sparc_teardown_msi_irq(unsigned int irq)
 {
struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry-dev;
@@ -925,6 +925,16 @@ void arch_teardown_msi_irq(unsigned int irq)
if (pbm-teardown_msi_irq)
pbm-teardown_msi_irq(irq, pdev);
 }
+
+static struct msi_chip sparc_msi_chip = {
+   .setup_irq = sparc_setup_msi_irq,
+   .teardown_irq = sparc_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return sparc_msi_chip;
+}
 #endif /* !(CONFIG_PCI_MSI) */
 
 static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 15/21] Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/powerpc/kernel/msi.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 71bd161..01781a4 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,7 @@
 
 #include asm/machdep.h
 
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int ppc_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
pr_debug(msi: Platform doesn't provide MSI callbacks.\n);
@@ -27,7 +27,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int 
type)
return ppc_md.setup_msi_irqs(dev, nvec, type);
 }
 
-void arch_teardown_msi_irqs(struct pci_dev *dev)
+static void ppc_teardown_msi_irqs(struct pci_dev *dev)
 {
ppc_md.teardown_msi_irqs(dev);
 }
+
+static struct msi_chip ppc_msi_chip = {
+   .setup_irqs = ppc_setup_msi_irqs,
+   .teardown_irqs = ppc_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return ppc_msi_chip;
+}
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 20/21] tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/tile/kernel/pci_gx.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index e39f9c5..4912b75 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1485,7 +1485,7 @@ static struct irq_chip tilegx_msi_chip = {
/* TBD: support set_affinity. */
 };
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int tile_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 {
struct pci_controller *controller;
gxio_trio_context_t *trio_context;
@@ -1604,7 +1604,17 @@ is_64_failure:
return ret;
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+void tile_teardown_msi_irq(unsigned int irq)
 {
irq_free_hwirq(irq);
 }
+
+static struct msi_chip tile_msi_chip = {
+   .setup_irq = tile_setup_msi_irq,
+   .teardown_irq = tile_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return tile_msi_chip;
+}
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 21/21] PCI/MSI: Clean up unused MSI arch functions

2014-09-05 Thread Yijing Wang
Now we use struct msi_chip in all platforms to configure
MSI/MSI-X. We can clean up the unused arch functions.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/irq_remapping.c |2 +-
 drivers/pci/msi.c |   99 -
 include/linux/msi.h   |   14 --
 3 files changed, 39 insertions(+), 76 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 99b1c0f..6e645f0 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -92,7 +92,7 @@ error:
 
/*
 * Restore altered MSI descriptor fields and prevent just destroyed
-* IRQs from tearing down again in default_teardown_msi_irqs()
+* IRQs from tearing down again in teardown_msi_irqs()
 */
msidesc-irq = 0;
msidesc-nvec_used = 0;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d78d637..e3e7f4f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -34,50 +34,31 @@ struct msi_chip * __weak arch_find_msi_chip(struct pci_dev 
*dev)
return dev-bus-msi;
 }
 
-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
-   struct msi_chip *chip = arch_find_msi_chip(dev);
-   int err;
-
-   if (!chip || !chip-setup_irq)
-   return -EINVAL;
-
-   err = chip-setup_irq(dev, desc);
-   if (err  0)
-   return err;
-
-   return 0;
-}
-
-void __weak arch_teardown_msi_irq(unsigned int irq)
-{
-   struct msi_chip *chip = irq_get_chip_data(irq);
-
-   if (!chip || !chip-teardown_irq)
-   return;
-
-   chip-teardown_irq(irq);
-}
-
-int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
struct msi_desc *entry;
int ret;
struct msi_chip *chip;
 
chip = arch_find_msi_chip(dev);
-   if (chip  chip-setup_irqs)
+   if (!chip)
+   return -EINVAL;
+
+   if (chip-setup_irqs)
return chip-setup_irqs(dev, nvec, type);
 
/*
 * If an architecture wants to support multiple MSI, it needs to
-* override arch_setup_msi_irqs()
+* implement chip-setup_irqs().
 */
if (type == PCI_CAP_ID_MSI  nvec  1)
return 1;
 
+   if (!chip-setup_irq)
+   return -EINVAL;
+
list_for_each_entry(entry, dev-msi_list, list) {
-   ret = arch_setup_msi_irq(dev, entry);
+   ret = chip-setup_irq(dev, entry);
if (ret  0)
return ret;
if (ret  0)
@@ -87,13 +68,20 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
return 0;
 }
 
-/*
- * We have a default implementation available as a separate non-weak
- * function, as it is used by the Xen x86 PCI code
- */
-void default_teardown_msi_irqs(struct pci_dev *dev)
+static void teardown_msi_irqs(struct pci_dev *dev)
 {
struct msi_desc *entry;
+   struct msi_chip *chip;
+
+   chip = arch_find_msi_chip(dev);
+   if (!chip)
+   return;
+
+   if (chip-teardown_irqs)
+   return chip-teardown_irqs(dev);
+
+   if (!chip-teardown_irq)
+   return;
 
list_for_each_entry(entry, dev-msi_list, list) {
int i, nvec;
@@ -104,20 +92,10 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
else
nvec = 1  entry-msi_attrib.multiple;
for (i = 0; i  nvec; i++)
-   arch_teardown_msi_irq(entry-irq + i);
+   chip-teardown_irq(entry-irq + i);
}
 }
 
-void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
-{
-   struct msi_chip *chip = arch_find_msi_chip(dev);
-
-   if (chip  chip-teardown_irqs)
-   return chip-teardown_irqs(dev);
-
-   return default_teardown_msi_irqs(dev);
-}
-
 static void default_restore_msi_irq(struct pci_dev *dev, int irq)
 {
struct msi_desc *entry;
@@ -136,10 +114,18 @@ static void default_restore_msi_irq(struct pci_dev *dev, 
int irq)
write_msi_msg(irq, entry-msg);
 }
 
-void __weak arch_restore_msi_irqs(struct pci_dev *dev)
+static void default_restore_msi_irqs(struct pci_dev *dev)
 {
-   struct msi_chip *chip = arch_find_msi_chip(dev);
+   struct msi_desc *entry = NULL;
+
+   list_for_each_entry(entry, dev-msi_list, list) {
+   default_restore_msi_irq(dev, entry-irq);
+   }
+}
 
+static void restore_msi_irqs(struct pci_dev *dev)
+{
+   struct msi_chip *chip = arch_find_msi_chip(dev);
if (chip  chip-restore_irqs)
return chip-restore_irqs(dev);
 
@@ -248,15 +234,6 @@ void unmask_msi_irq(struct irq_data *data)
msi_set_mask_bit(data, 0);
 }
 
-void default_restore_msi_irqs(struct pci_dev *dev)
-{
-   struct msi_desc *entry;
-
-   

[PATCH v1 01/21] PCI/MSI: Clean up struct msi_chip argument

2014-09-05 Thread Yijing Wang
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument. We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@gmail.com
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/irqchip/irq-armada-370-xp.c |   12 +---
 drivers/pci/host/pci-tegra.c|8 +---
 drivers/pci/host/pcie-designware.c  |4 ++--
 drivers/pci/host/pcie-rcar.c|8 +---
 drivers/pci/msi.c   |4 ++--
 include/linux/msi.h |5 ++---
 6 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-armada-370-xp.c 
b/drivers/irqchip/irq-armada-370-xp.c
index 574aba0..658990c 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -129,9 +129,8 @@ static void armada_370_xp_free_msi(int hwirq)
mutex_unlock(msi_used_lock);
 }
 
-static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
-  struct pci_dev *pdev,
-  struct msi_desc *desc)
+static int armada_370_xp_setup_msi_irq(struct pci_dev *pdev,
+   struct msi_desc *desc)
 {
struct msi_msg msg;
int virq, hwirq;
@@ -156,8 +155,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip 
*chip,
return 0;
 }
 
-static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
-  unsigned int irq)
+static void armada_370_xp_teardown_msi_irq(unsigned int irq)
 {
struct irq_data *d = irq_get_irq_data(irq);
unsigned long hwirq = d-hwirq;
@@ -166,8 +164,8 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip 
*chip,
armada_370_xp_free_msi(hwirq);
 }
 
-static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct 
pci_dev *dev,
- int nvec, int type)
+static int armada_370_xp_check_msi_device(struct pci_dev *dev,
+   int nvec, int type)
 {
/* We support MSI, but not MSI-X */
if (type == PCI_CAP_ID_MSI)
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..edd4040 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1157,9 +1157,10 @@ static irqreturn_t tegra_pcie_msi_irq(int irq, void 
*data)
return processed  0 ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int tegra_msi_setup_irq(struct pci_dev *pdev,
   struct msi_desc *desc)
 {
+   struct msi_chip *chip = pdev-bus-msi;
struct tegra_msi *msi = to_tegra_msi(chip);
struct msi_msg msg;
unsigned int irq;
@@ -1185,10 +1186,11 @@ static int tegra_msi_setup_irq(struct msi_chip *chip, 
struct pci_dev *pdev,
return 0;
 }
 
-static void tegra_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void tegra_msi_teardown_irq(unsigned int irq)
 {
-   struct tegra_msi *msi = to_tegra_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+   struct msi_chip *chip = irq_get_chip_data(irq);
+   struct tegra_msi *msi = to_tegra_msi(chip);
 
tegra_msi_free(msi, d-hwirq);
 }
diff --git a/drivers/pci/host/pcie-designware.c 
b/drivers/pci/host/pcie-designware.c
index 52bd3a1..2204456 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -342,7 +342,7 @@ static void clear_irq(unsigned int irq)
msi-msi_attrib.multiple = 0;
 }
 
-static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int dw_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
 {
int irq, pos, msgvec;
@@ -384,7 +384,7 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct 
pci_dev *pdev,
return 0;
 }
 
-static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void dw_msi_teardown_irq(unsigned int irq)
 {
clear_irq(irq);
 }
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..647bc9f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -615,9 +615,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int rcar_msi_setup_irq(struct pci_dev *pdev,
  struct msi_desc *desc)
 {
+   struct msi_chip *chip = pdev-bus-msi;
struct rcar_msi *msi = to_rcar_msi(chip);
struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
struct msi_msg msg;
@@ -645,10 +646,11 @@ static int rcar_msi_setup_irq(struct msi_chip *chip, 
struct pci_dev *pdev,
return 0;
 }
 
-static void rcar_msi_teardown_irq(struct msi_chip *chip, 

[PATCH v1 02/21] PCI/MSI: Remove useless bus-msi assignment

2014-09-05 Thread Yijing Wang
Currently, PCI drivers will initialize bus-msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus-msi
assignment in pci_alloc_child_bus() is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@avionic-design.de
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/pci/probe.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..8296576 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -677,7 +677,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus 
*parent,
 
child-parent = parent;
child-ops = parent-ops;
-   child-msi = parent-msi;
child-sysdata = parent-sysdata;
child-bus_flags = parent-bus_flags;
 
-- 
1.7.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1 15/21] Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Sergei Shtylyov

Hello.

On 9/5/2014 2:10 PM, Yijing Wang wrote:


Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.



Signed-off-by: Yijing Wang wangyij...@huawei.com
---
  arch/powerpc/kernel/msi.c |   14 --
  1 files changed, 12 insertions(+), 2 deletions(-)



diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 71bd161..01781a4 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c

[...]

@@ -27,7 +27,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int 
type)
return ppc_md.setup_msi_irqs(dev, nvec, type);
  }

-void arch_teardown_msi_irqs(struct pci_dev *dev)
+static void ppc_teardown_msi_irqs(struct pci_dev *dev)


   Shouldn't this function take IRQ # instead?


  {
ppc_md.teardown_msi_irqs(dev);
  }
+
+static struct msi_chip ppc_msi_chip = {
+   .setup_irqs = ppc_setup_msi_irqs,
+   .teardown_irqs = ppc_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return ppc_msi_chip;
+}


WBR, Sergei

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 03/12] iommu/amd: Convert to iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/amd_iommu.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index ecb0109..7de9276 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3384,20 +3384,20 @@ static phys_addr_t amd_iommu_iova_to_phys(struct 
iommu_domain *dom,
return paddr;
 }
 
-static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
-   unsigned long cap)
+static bool amd_iommu_capable(enum iommu_cap cap)
 {
switch (cap) {
case IOMMU_CAP_CACHE_COHERENCY:
-   return 1;
+   return true;
case IOMMU_CAP_INTR_REMAP:
-   return irq_remapping_enabled;
+   return (irq_remapping_enabled == 1);
}
 
-   return 0;
+   return false;
 }
 
 static const struct iommu_ops amd_iommu_ops = {
+   .capable = amd_iommu_capable,
.domain_init = amd_iommu_domain_init,
.domain_destroy = amd_iommu_domain_destroy,
.attach_dev = amd_iommu_attach_device,
@@ -3405,7 +3405,6 @@ static const struct iommu_ops amd_iommu_ops = {
.map = amd_iommu_map,
.unmap = amd_iommu_unmap,
.iova_to_phys = amd_iommu_iova_to_phys,
-   .domain_has_cap = amd_iommu_domain_has_cap,
.pgsize_bitmap  = AMD_IOMMU_PGSIZES,
 };
 
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 12/12] iommu: Remove iommu_domain_has_cap() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c | 13 -
 include/linux/iommu.h | 11 ---
 2 files changed, 24 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 319d40e..41c6a7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -954,19 +954,6 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain 
*domain, dma_addr_t iova)
 }
 EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
 
-int iommu_domain_has_cap(struct iommu_domain *domain,
-enum iommu_cap cap)
-{
-   if (domain-ops-domain_has_cap != NULL)
-   return domain-ops-domain_has_cap(domain, cap);
-
-   if (domain-ops-capable != NULL)
-   return domain-ops-capable(cap);
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
-
 static size_t iommu_pgsize(struct iommu_domain *domain,
   unsigned long addr_merge, size_t size)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d5534d5..379a617 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -97,7 +97,6 @@ enum iommu_attr {
  * @map: map a physically contiguous memory region to an iommu domain
  * @unmap: unmap a physically contiguous memory region from an iommu domain
  * @iova_to_phys: translate iova to physical address
- * @domain_has_cap: domain capabilities query
  * @add_device: add device to iommu grouping
  * @remove_device: remove device from iommu grouping
  * @domain_get_attr: Query domain attributes
@@ -115,8 +114,6 @@ struct iommu_ops {
size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
 size_t size);
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t 
iova);
-   int (*domain_has_cap)(struct iommu_domain *domain,
- unsigned long cap);
int (*add_device)(struct device *dev);
void (*remove_device)(struct device *dev);
int (*device_group)(struct device *dev, unsigned int *groupid);
@@ -159,8 +156,6 @@ extern int iommu_map(struct iommu_domain *domain, unsigned 
long iova,
 extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
   size_t size);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t 
iova);
-extern int iommu_domain_has_cap(struct iommu_domain *domain,
-   enum iommu_cap cap);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler, void *token);
 
@@ -314,12 +309,6 @@ static inline phys_addr_t iommu_iova_to_phys(struct 
iommu_domain *domain, dma_ad
return 0;
 }
 
-static inline int iommu_domain_has_cap(struct iommu_domain *domain,
-  enum iommu_cap cap)
-{
-   return 0;
-}
-
 static inline void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler, void *token)
 {
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 00/12] iommu: Convert iommu_domain_has_cap() to iommu_capable()

2014-09-05 Thread Joerg Roedel
Hi,

this patch-set removes the iommu_domain_has_cap() function
from the IOMMU-API and replaces it with the new
iommu_capable() function.

The capabilities that can be queried with the
iommu_domain_has_cap() function are not domain specific, but
specific to the IOMMUs in the system, so they are not a
function of the domain. This should be reflected in the
IOMMU-API. Please review.

Thanks,

Joerg

Joerg Roedel (12):
  iommu: Introduce iommu_capable API function
  iommu: Convert iommu-caps from define to enum
  iommu/amd: Convert to iommu_capable() API function
  iommu/arm-smmu: Convert to iommu_capable() API function
  iommu/fsl: Convert to iommu_capable() API function
  iommu/vt-d: Convert to iommu_capable() API function
  iommu/msm: Convert to iommu_capable() API function
  iommu/tegra: Convert to iommu_capable() API function
  kvm: iommu: Convert to use new iommu_capable() API function
  vfio: Convert to use new iommu_capable() API function
  IB/usnic: Convert to use new iommu_capable() API function
  iommu: Remove iommu_domain_has_cap() API function

 drivers/infiniband/hw/usnic/usnic_uiom.c |  2 +-
 drivers/iommu/amd_iommu.c| 11 +-
 drivers/iommu/arm-smmu.c | 35 
 drivers/iommu/fsl_pamu_domain.c  |  5 ++---
 drivers/iommu/intel-iommu.c  | 13 +---
 drivers/iommu/iommu.c| 19 -
 drivers/iommu/msm_iommu.c|  7 +++
 drivers/iommu/tegra-gart.c   |  7 +++
 drivers/iommu/tegra-smmu.c   |  7 +++
 drivers/vfio/vfio_iommu_type1.c  |  4 ++--
 include/linux/iommu.h| 25 +++
 virt/kvm/iommu.c |  6 ++
 12 files changed, 73 insertions(+), 68 deletions(-)

-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 05/12] iommu/fsl: Convert to iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Cc: Varun Sethi varun.se...@freescale.com
Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/fsl_pamu_domain.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 61d1daf..f43a80d 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -411,8 +411,7 @@ static phys_addr_t fsl_pamu_iova_to_phys(struct 
iommu_domain *domain,
return get_phys_addr(dma_domain, iova);
 }
 
-static int fsl_pamu_domain_has_cap(struct iommu_domain *domain,
- unsigned long cap)
+static bool fsl_pamu_capable(enum iommu_cap cap)
 {
return cap == IOMMU_CAP_CACHE_COHERENCY;
 }
@@ -1074,6 +1073,7 @@ static u32 fsl_pamu_get_windows(struct iommu_domain 
*domain)
 }
 
 static const struct iommu_ops fsl_pamu_ops = {
+   .capable= fsl_pamu_capable,
.domain_init= fsl_pamu_domain_init,
.domain_destroy = fsl_pamu_domain_destroy,
.attach_dev = fsl_pamu_attach_device,
@@ -1083,7 +1083,6 @@ static const struct iommu_ops fsl_pamu_ops = {
.domain_get_windows = fsl_pamu_get_windows,
.domain_set_windows = fsl_pamu_set_windows,
.iova_to_phys   = fsl_pamu_iova_to_phys,
-   .domain_has_cap = fsl_pamu_domain_has_cap,
.domain_set_attr = fsl_pamu_set_domain_attr,
.domain_get_attr = fsl_pamu_get_domain_attr,
.add_device = fsl_pamu_add_device,
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 11/12] IB/usnic: Convert to use new iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Cc: Upinder Malhi uma...@cisco.com
Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/infiniband/hw/usnic/usnic_uiom.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c 
b/drivers/infiniband/hw/usnic/usnic_uiom.c
index 801a1d6..417de1f 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -507,7 +507,7 @@ int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, 
struct device *dev)
if (err)
goto out_free_dev;
 
-   if (!iommu_domain_has_cap(pd-domain, IOMMU_CAP_CACHE_COHERENCY)) {
+   if (!iommu_capable(dev-bus, IOMMU_CAP_CACHE_COHERENCY)) {
usnic_err(IOMMU of %s does not support cache coherency\n,
dev_name(dev));
err = -EINVAL;
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 09/12] kvm: iommu: Convert to use new iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Cc: Gleb Natapov g...@kernel.org
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Joerg Roedel jroe...@suse.de
---
 virt/kvm/iommu.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index 714b949..45ee080 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -191,8 +191,7 @@ int kvm_assign_device(struct kvm *kvm,
return r;
}
 
-   noncoherent = !iommu_domain_has_cap(kvm-arch.iommu_domain,
-   IOMMU_CAP_CACHE_COHERENCY);
+   noncoherent = !iommu_capable(pci_bus_type, IOMMU_CAP_CACHE_COHERENCY);
 
/* Check if need to update IOMMU page table for guest memory */
if (noncoherent != kvm-arch.iommu_noncoherent) {
@@ -254,8 +253,7 @@ int kvm_iommu_map_guest(struct kvm *kvm)
}
 
if (!allow_unsafe_assigned_interrupts 
-   !iommu_domain_has_cap(kvm-arch.iommu_domain,
- IOMMU_CAP_INTR_REMAP)) {
+   !iommu_capable(pci_bus_type, IOMMU_CAP_INTR_REMAP)) {
printk(KERN_WARNING %s: No interrupt remapping support,
disallowing device assignment.
Re-enble with \allow_unsafe_assigned_interrupts=1\
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 07/12] iommu/msm: Convert to iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/msm_iommu.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 49f41d6..6e3dcc28 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -603,10 +603,9 @@ fail:
return ret;
 }
 
-static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
-   unsigned long cap)
+static bool msm_iommu_capable(enum iommu_cap cap)
 {
-   return 0;
+   return false;
 }
 
 static void print_ctx_regs(void __iomem *base, int ctx)
@@ -675,6 +674,7 @@ fail:
 }
 
 static const struct iommu_ops msm_iommu_ops = {
+   .capable = msm_iommu_capable,
.domain_init = msm_iommu_domain_init,
.domain_destroy = msm_iommu_domain_destroy,
.attach_dev = msm_iommu_attach_dev,
@@ -682,7 +682,6 @@ static const struct iommu_ops msm_iommu_ops = {
.map = msm_iommu_map,
.unmap = msm_iommu_unmap,
.iova_to_phys = msm_iommu_iova_to_phys,
-   .domain_has_cap = msm_iommu_domain_has_cap,
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 };
 
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 01/12] iommu: Introduce iommu_capable API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

This function will replace the current iommu_domain_has_cap
function and clean up the interface while at it.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c | 18 +++---
 include/linux/iommu.h |  7 +++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ac4adb3..1bc882e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -815,6 +815,15 @@ bool iommu_present(struct bus_type *bus)
 }
 EXPORT_SYMBOL_GPL(iommu_present);
 
+bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
+{
+   if (!bus-iommu_ops || !bus-iommu_ops-capable)
+   return false;
+
+   return bus-iommu_ops-capable(cap);
+}
+EXPORT_SYMBOL_GPL(iommu_capable);
+
 /**
  * iommu_set_fault_handler() - set a fault handler for an iommu domain
  * @domain: iommu domain
@@ -948,10 +957,13 @@ EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
 int iommu_domain_has_cap(struct iommu_domain *domain,
 unsigned long cap)
 {
-   if (unlikely(domain-ops-domain_has_cap == NULL))
-   return 0;
+   if (domain-ops-domain_has_cap != NULL)
+   return domain-ops-domain_has_cap(domain, cap);
+
+   if (domain-ops-capable != NULL)
+   return domain-ops-capable(cap);
 
-   return domain-ops-domain_has_cap(domain, cap);
+   return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 20f9a52..d43146a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -102,6 +102,7 @@ enum iommu_attr {
  * @pgsize_bitmap: bitmap of supported page sizes
  */
 struct iommu_ops {
+   bool (*capable)(enum iommu_cap);
int (*domain_init)(struct iommu_domain *domain);
void (*domain_destroy)(struct iommu_domain *domain);
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
@@ -142,6 +143,7 @@ struct iommu_ops {
 
 extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
 extern bool iommu_present(struct bus_type *bus);
+extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap);
 extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
 extern struct iommu_group *iommu_group_get_by_id(int id);
 extern void iommu_domain_free(struct iommu_domain *domain);
@@ -250,6 +252,11 @@ static inline bool iommu_present(struct bus_type *bus)
return false;
 }
 
+static inline bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
+{
+   return false;
+}
+
 static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 {
return NULL;
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 10/12] vfio: Convert to use new iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/vfio/vfio_iommu_type1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 0734fbe..562f686 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -713,14 +713,14 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
list_add(group-next, domain-group_list);
 
if (!allow_unsafe_interrupts 
-   !iommu_domain_has_cap(domain-domain, IOMMU_CAP_INTR_REMAP)) {
+   !iommu_capable(bus, IOMMU_CAP_INTR_REMAP)) {
pr_warn(%s: No interrupt remapping support.  Use the module 
param \allow_unsafe_interrupts\ to enable VFIO IOMMU support on this 
platform\n,
   __func__);
ret = -EPERM;
goto out_detach;
}
 
-   if (iommu_domain_has_cap(domain-domain, IOMMU_CAP_CACHE_COHERENCY))
+   if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
domain-prot |= IOMMU_CACHE;
 
/*
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 02/12] iommu: Convert iommu-caps from define to enum

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Allow compile-time type-checking.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c |  2 +-
 include/linux/iommu.h | 11 +++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1bc882e..319d40e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -955,7 +955,7 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, 
dma_addr_t iova)
 EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
 
 int iommu_domain_has_cap(struct iommu_domain *domain,
-unsigned long cap)
+enum iommu_cap cap)
 {
if (domain-ops-domain_has_cap != NULL)
return domain-ops-domain_has_cap(domain, cap);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d43146a..d5534d5 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -57,8 +57,11 @@ struct iommu_domain {
struct iommu_domain_geometry geometry;
 };
 
-#define IOMMU_CAP_CACHE_COHERENCY  0x1
-#define IOMMU_CAP_INTR_REMAP   0x2 /* isolates device intrs */
+enum iommu_cap {
+   IOMMU_CAP_CACHE_COHERENCY,  /* IOMMU can enforce cache coherent DMA
+  transactions */
+   IOMMU_CAP_INTR_REMAP,   /* IOMMU supports interrupt isolation */
+};
 
 /*
  * Following constraints are specifc to FSL_PAMUV1:
@@ -157,7 +160,7 @@ extern size_t iommu_unmap(struct iommu_domain *domain, 
unsigned long iova,
   size_t size);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t 
iova);
 extern int iommu_domain_has_cap(struct iommu_domain *domain,
-   unsigned long cap);
+   enum iommu_cap cap);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler, void *token);
 
@@ -312,7 +315,7 @@ static inline phys_addr_t iommu_iova_to_phys(struct 
iommu_domain *domain, dma_ad
 }
 
 static inline int iommu_domain_has_cap(struct iommu_domain *domain,
-  unsigned long cap)
+  enum iommu_cap cap)
 {
return 0;
 }
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 04/12] iommu/arm-smmu: Convert to iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Cc: Will Deacon will.dea...@arm.com
Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/arm-smmu.c | 35 ++-
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index ca18d6d..47c2cb6 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1515,20 +1515,37 @@ static phys_addr_t arm_smmu_iova_to_phys(struct 
iommu_domain *domain,
return __pfn_to_phys(pte_pfn(pte)) | (iova  ~PAGE_MASK);
 }
 
-static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
-  unsigned long cap)
+static bool arm_smmu_capable(enum iommu_cap cap)
 {
-   struct arm_smmu_domain *smmu_domain = domain-priv;
-   struct arm_smmu_device *smmu = smmu_domain-smmu;
-   u32 features = smmu ? smmu-features : 0;
+   struct arm_smmu_device *smmu;
+   bool ret = false;
 
switch (cap) {
case IOMMU_CAP_CACHE_COHERENCY:
-   return features  ARM_SMMU_FEAT_COHERENT_WALK;
+   /*
+* Use ARM_SMMU_FEAT_COHERENT_WALK as an indicator on whether
+* the SMMU can force coherency on the DMA transaction. If it
+* supports COHERENT_WALK it must be behind a coherent
+* interconnect.
+* A domain can be attached to any SMMU, so to reliably support
+* IOMMU_CAP_CACHE_COHERENCY all SMMUs in the system need to be
+* behind a coherent interconnect.
+*/
+   spin_lock(arm_smmu_devices_lock);
+   list_for_each_entry(smmu, arm_smmu_devices, list) {
+   if (smmu-features  ARM_SMMU_FEAT_COHERENT_WALK) {
+   ret = true;
+   } else {
+   ret = false;
+   break;
+   }
+   }
+   spin_unlock(arm_smmu_devices_lock);
+   return ret;
case IOMMU_CAP_INTR_REMAP:
-   return 1; /* MSIs are just memory writes */
+   return true; /* MSIs are just memory writes */
default:
-   return 0;
+   return false;
}
 }
 
@@ -1598,6 +1615,7 @@ static void arm_smmu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops arm_smmu_ops = {
+   .capable= arm_smmu_capable,
.domain_init= arm_smmu_domain_init,
.domain_destroy = arm_smmu_domain_destroy,
.attach_dev = arm_smmu_attach_dev,
@@ -1605,7 +1623,6 @@ static const struct iommu_ops arm_smmu_ops = {
.map= arm_smmu_map,
.unmap  = arm_smmu_unmap,
.iova_to_phys   = arm_smmu_iova_to_phys,
-   .domain_has_cap = arm_smmu_domain_has_cap,
.add_device = arm_smmu_add_device,
.remove_device  = arm_smmu_remove_device,
.pgsize_bitmap  = (SECTION_SIZE |
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 08/12] iommu/tegra: Convert to iommu_capable() API function

2014-09-05 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Cc: Hiroshi Doyu hd...@nvidia.com
Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/tegra-gart.c | 7 +++
 drivers/iommu/tegra-smmu.c | 7 +++
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index b10a8ec..6f44ebb 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -303,13 +303,13 @@ static phys_addr_t gart_iommu_iova_to_phys(struct 
iommu_domain *domain,
return pa;
 }
 
-static int gart_iommu_domain_has_cap(struct iommu_domain *domain,
-unsigned long cap)
+static bool gart_iommu_capable(enum iommu_cap cap)
 {
-   return 0;
+   return false;
 }
 
 static const struct iommu_ops gart_iommu_ops = {
+   .capable= gart_iommu_capable,
.domain_init= gart_iommu_domain_init,
.domain_destroy = gart_iommu_domain_destroy,
.attach_dev = gart_iommu_attach_dev,
@@ -317,7 +317,6 @@ static const struct iommu_ops gart_iommu_ops = {
.map= gart_iommu_map,
.unmap  = gart_iommu_unmap,
.iova_to_phys   = gart_iommu_iova_to_phys,
-   .domain_has_cap = gart_iommu_domain_has_cap,
.pgsize_bitmap  = GART_IOMMU_PGSIZES,
 };
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 3ded389..05d14e1 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -780,10 +780,9 @@ static phys_addr_t smmu_iommu_iova_to_phys(struct 
iommu_domain *domain,
return PFN_PHYS(pfn);
 }
 
-static int smmu_iommu_domain_has_cap(struct iommu_domain *domain,
-unsigned long cap)
+static bool smmu_iommu_capable(enum iommu_cap cap)
 {
-   return 0;
+   return false;
 }
 
 static int smmu_iommu_attach_dev(struct iommu_domain *domain,
@@ -949,6 +948,7 @@ static void smmu_iommu_domain_destroy(struct iommu_domain 
*domain)
 }
 
 static const struct iommu_ops smmu_iommu_ops = {
+   .capable= smmu_iommu_capable,
.domain_init= smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
.attach_dev = smmu_iommu_attach_dev,
@@ -956,7 +956,6 @@ static const struct iommu_ops smmu_iommu_ops = {
.map= smmu_iommu_map,
.unmap  = smmu_iommu_unmap,
.iova_to_phys   = smmu_iommu_iova_to_phys,
-   .domain_has_cap = smmu_iommu_domain_has_cap,
.pgsize_bitmap  = SMMU_IOMMU_PGSIZES,
 };
 
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/2] iommu/omap: Fix iommu archdata name for DT-based devices

2014-09-05 Thread Laurent Pinchart
Hi Suman,

On Thursday 04 September 2014 16:17:53 Suman Anna wrote:
 Hi Laurent,
 
  On Wednesday 03 September 2014 18:58:32 Suman Anna wrote:
  A device is tied to an iommu through its archdata field. The archdata
  is allocated on the fly for DT-based devices automatically through the
  .add_device iommu ops. The current logic incorrectly assigned the name
  of the IOMMU user device, instead of the name of the IOMMU device as
  required by the attach logic. Fix this issue so that DT-based devices
  can attach successfully to an IOMMU domain.
  
  Signed-off-by: Suman Anna s-a...@ti.com
  ---
  
   drivers/iommu/omap-iommu.c | 10 +-
   1 file changed, 9 insertions(+), 1 deletion(-)
  
  diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
  index f245d51..f47ac03 100644
  --- a/drivers/iommu/omap-iommu.c
  +++ b/drivers/iommu/omap-iommu.c
  @@ -26,6 +26,7 @@
   #include linux/of.h
   #include linux/of_iommu.h
   #include linux/of_irq.h
  +#include linux/of_platform.h
  
   #include asm/cacheflush.h
  
  @@ -1244,6 +1245,7 @@ static int omap_iommu_add_device(struct device
  *dev)
   {
 struct omap_iommu_arch_data *arch_data;
 struct device_node *np;
  +  struct platform_device *pdev;
  
 /*
  * Allocate the archdata iommu structure for DT-based devices.
  @@ -1258,13 +1260,19 @@ static int omap_iommu_add_device(struct device
  *dev)
 if (!np)
 return 0;
  
  +  pdev = of_find_device_by_node(np);
  +  if (WARN_ON(!pdev)) {
  +  of_node_put(np);
  +  return -EINVAL;
  +  }
  
  I might be wrong, but I don't think there's a guarantee at this point that
  the IOMMU device is already instantiated :-/
 
 The omap_iommu_init which registers the iommu_ops is a subsys_initcall,
 so the platform devices are guaranteed to be created by this point.

OK, no worries then.

 My test on OMAP4 in fact has the dsp node created before the IOMMU node,
 and this is not an issue. I have added the WARN_ON in case some one has
 the IOMMU node disabled, but try to use it.
 
  Will Deacon has posted patches that rework the IOMMU core for better DT
  integration, have you seen them ?
 
 Can you point out the thread? Are you talking about
 http://marc.info/?l=linux-arm-kernelm=140968072117851w=2?

Yes that's the one.

-- 
Regards,

Laurent Pinchart

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv2 2/2] iommu/omap: Fix iommu archdata name for DT-based devices

2014-09-05 Thread Laurent Pinchart
Hi Suman,

Thank you for the patch.

On Thursday 04 September 2014 17:27:30 Suman Anna wrote:
 A device is tied to an iommu through its archdata field. The archdata
 is allocated on the fly for DT-based devices automatically through the
 .add_device iommu ops. The current logic incorrectly assigned the name
 of the IOMMU user device, instead of the name of the IOMMU device as
 required by the attach logic. Fix this issue so that DT-based devices
 can attach successfully to an IOMMU domain.
 
 Signed-off-by: Suman Anna s-a...@ti.com

Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com

 ---
  drivers/iommu/omap-iommu.c | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)
 
 diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
 index ea6e59d..8cf8bf1 100644
 --- a/drivers/iommu/omap-iommu.c
 +++ b/drivers/iommu/omap-iommu.c
 @@ -26,6 +26,7 @@
  #include linux/of.h
  #include linux/of_iommu.h
  #include linux/of_irq.h
 +#include linux/of_platform.h
 
  #include asm/cacheflush.h
 
 @@ -1243,6 +1244,7 @@ static int omap_iommu_add_device(struct device *dev)
  {
   struct omap_iommu_arch_data *arch_data;
   struct device_node *np;
 + struct platform_device *pdev;
 
   /*
* Allocate the archdata iommu structure for DT-based devices.
 @@ -1257,13 +1259,19 @@ static int omap_iommu_add_device(struct device *dev)
 if (!np)
   return 0;
 
 + pdev = of_find_device_by_node(np);
 + if (WARN_ON(!pdev)) {
 + of_node_put(np);
 + return -EINVAL;
 + }
 +
   arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL);
   if (!arch_data) {
   of_node_put(np);
   return -ENOMEM;
   }
 
 - arch_data-name = kstrdup(dev_name(dev), GFP_KERNEL);
 + arch_data-name = kstrdup(dev_name(pdev-dev), GFP_KERNEL);
   dev-archdata.iommu = arch_data;
 
   of_node_put(np);

-- 
Regards,

Laurent Pinchart

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH v1 1/1] iommu/amd: set iommu for early mapped ioapic/hpet

2014-09-05 Thread Su, Friendy
Hi, Joerg,

 -Original Message-
 From: j...@8bytes.org [mailto:j...@8bytes.org]
 Sent: Wednesday, September 03, 2014 11:06 PM
 To: Su, Friendy
 Cc: iommu@lists.linux-foundation.org; linux-ker...@vger.kernel.org
 Subject: Re: [PATCH v1 1/1] iommu/amd: set iommu for early mapped
 ioapic/hpet
 
 On Mon, Sep 01, 2014 at 02:17:44PM +0800, Su, Friendy wrote:
  diff --git a/drivers/iommu/amd_iommu_init.c
 b/drivers/iommu/amd_iommu_init.c
  index 3783e0b..148ab61 100644
  --- a/drivers/iommu/amd_iommu_init.c
  +++ b/drivers/iommu/amd_iommu_init.c
  @@ -747,7 +747,7 @@ static int __init add_special_device(u8 type, u8 id,
 u16 devid, bool cmd_line)
  return 0;
   }
 
  -static int __init add_early_maps(void)
  +static int __init add_early_maps(struct amd_iommu *iommu)
   {
  int i, ret;
 
  @@ -758,6 +758,11 @@ static int __init add_early_maps(void)
   early_ioapic_map[i].cmd_line);
  if (ret)
  return ret;
  +   /*
  +* early mapped ioapci overrides ACPI IVRS,
  +* they should be always controlled by iommu.
  +*/
  +   set_iommu_for_device(iommu, early_ioapic_map[i].devid);
  }
 
  for (i = 0; i  early_hpet_map_size; ++i) {
  @@ -767,6 +772,11 @@ static int __init add_early_maps(void)
   early_hpet_map[i].cmd_line);
  if (ret)
  return ret;
  +   /*
  +* early mapped hpet overrides ACPI IVRS,
  +* they should be always controlled by iommu.
  +*/
  +   set_iommu_for_device(iommu, early_hpet_map[i].devid);
 
 This doesn't work on machines with multiple IOMMUs in it. Also the
 problem only exists if there is no IVHD entry in the IVRS table for the
 device containing IOAPIC and HPET.
 
 But if this IVHD entry is not present we can't reliably know which IOMMU
 is responsible for a given IOAPIC/HPET.
 
 
   Joerg
 
Thanks. You are correct, we should handle early mapped inside IOMMU whose IVHD 
reports the same ID. I will update.

Friendy
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 1/1] iommu/amd: set iommu for early mapped ioapic/hpet

2014-09-05 Thread Su, Friendy

From: Su Friendy friendy...@sony.com.cn

Subject: iommu/amd: make early mapped ioapic/hpet override IVHD

The early mapped ioapic/hpet specified by kernel boot parameter
ivrs_ioapic[ID]/ivrs_hpet[ID] always override the ioapic/hpet with
same ID reported by ACPI IVHD table.

Current driver still uses devid in IVHD to set dte entry, not devid
in early mapped. This patch fixed to use devid in early mapped.

This issue is found on a mother board whose BIOS reports wrong
IOAPIC devid in IVHD table. Without this fix, the early mapped
does not really override IVHD. So that the wrong reported IOAPIC
does not work.

Signed-off-by: Su Friendy friendy...@sony.com.cn
Signed-off-by: Saeki Shusuke shusuke.sa...@jp.sony.com
Signed-off-by: Tamori Masahiro masahiro.tam...@jp.sony.com
---
 drivers/iommu/amd_iommu_init.c |   40 +---
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 3c06183..83cb31b 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -715,7 +715,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu 
*iommu,
set_iommu_for_device(iommu, devid);
 }
 
-static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line)
+static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line, 
u16 *early_mapped_devid)
 {
struct devid_map *entry;
struct list_head *list;
@@ -734,6 +734,19 @@ static int __init add_special_device(u8 type, u8 id, u16 
devid, bool cmd_line)
pr_info(AMD-Vi: Command-line override present for %s id %d - 
ignoring\n,
type == IVHD_SPECIAL_IOAPIC ? IOAPIC : HPET, id);
 
+   /*
+* if this special device is added from IVHD and
+* its devid in IVHD != devid in early mapped, then
+* record early mapped devid.
+*/
+   if (!cmd_line  devid != entry-devid) {
+   if (early_mapped_devid == NULL)
+   return -EINVAL;
+
+   *early_mapped_devid = entry-devid;
+   return -EEXIST;
+   }
+
return 0;
}
 
@@ -758,7 +771,8 @@ static int __init add_early_maps(void)
ret = add_special_device(IVHD_SPECIAL_IOAPIC,
 early_ioapic_map[i].id,
 early_ioapic_map[i].devid,
-early_ioapic_map[i].cmd_line);
+early_ioapic_map[i].cmd_line,
+NULL);
if (ret)
return ret;
}
@@ -767,7 +781,8 @@ static int __init add_early_maps(void)
ret = add_special_device(IVHD_SPECIAL_HPET,
 early_hpet_map[i].id,
 early_hpet_map[i].devid,
-early_hpet_map[i].cmd_line);
+early_hpet_map[i].cmd_line,
+NULL);
if (ret)
return ret;
}
@@ -961,7 +976,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu 
*iommu,
case IVHD_DEV_SPECIAL: {
u8 handle, type;
const char *var;
-   u16 devid;
+   u16 devid, early_mapped_devid;
int ret;
 
handle = e-ext  0xff;
@@ -981,10 +996,21 @@ static int __init init_iommu_from_acpi(struct amd_iommu 
*iommu,
PCI_SLOT(devid),
PCI_FUNC(devid));
 
-   set_dev_entry_from_acpi(iommu, devid, e-flags, 0);
-   ret = add_special_device(type, handle, devid, false);
-   if (ret)
+   ret = add_special_device(type, handle, devid, false, 
early_mapped_devid);
+
+   /*
+* if the special device is already early mapped,
+* let the early mapped devid override IVHD.
+*/
+   if (ret == -EEXIST) {
+   devid = early_mapped_devid;
+   ret = 0;
+   }
+
+   if (ret  0)
return ret;
+
+   set_dev_entry_from_acpi(iommu, devid, e-flags, 0);
break;
}
default:
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv2 0/2] OMAP IOMMU Fixes for DT-clients

2014-09-05 Thread Joerg Roedel
On Thu, Sep 04, 2014 at 05:27:28PM -0500, Suman Anna wrote:
 Suman Anna (2):
   iommu/omap: Check for valid archdata in attach_dev
   iommu/omap: Fix iommu archdata name for DT-based devices
 
  drivers/iommu/omap-iommu.c | 15 ++-
  1 file changed, 14 insertions(+), 1 deletion(-)

Applied, thanks.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2] iommu/fsl: Fix warning resulting from adding PCI device twice

2014-09-05 Thread Joerg Roedel
On Thu, Sep 04, 2014 at 05:08:45PM +0530, Varun Sethi wrote:
 iommu_group_get_for_dev determines the iommu group for the PCI device and adds
 the device to the group.
 
 In the PAMU driver we were again adding the device to the same group without 
 checking
 if the device already had an iommu group. This resulted in the following 
 warning.

 [...]
 
 Signed-off-by: Varun Sethi varun.se...@freescale.com
 ---
 v2 changes
 - directly check for the device iommu_group
 
  drivers/iommu/fsl_pamu_domain.c |   10 --
  1 file changed, 8 insertions(+), 2 deletions(-)

Applied to iommu/fixes and added stable tag, thanks.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [Xen-devel] [PATCH v1 08/21] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread David Vrabel
On 05/09/14 11:09, Yijing Wang wrote:
 Use MSI chip framework instead of arch MSI functions to configure
 MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
[...]
 --- a/arch/x86/pci/xen.c
 +++ b/arch/x86/pci/xen.c
[...]
 @@ -418,9 +430,9 @@ int __init pci_xen_init(void)
  #endif
  
  #ifdef CONFIG_PCI_MSI
 - x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
 - x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
 - x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
 + xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
 + xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
 + x86_msi_chip = xen_msi_chip;
   msi_chip.irq_mask = xen_nop_msi_mask;
   msi_chip.irq_unmask = xen_nop_msi_mask;

Why have these not been changed to set the x86_msi_chip.mask/unmask
fields instead?

David
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: ath9k and AMD IOMMU alias breakage on 3.16?

2014-09-05 Thread Alex Williamson
On Fri, 2014-09-05 at 20:00 -0700, Jason Newton wrote:
 Hi,
 
 I have an AR9462 connected over minipcie, it came with the ASRock
 FM2A88x-itx motherboard and I'm using an AMD A10-7850K cpu with it.  When I
 have IOMMU enabled, and this is desirable for opencl related things, the
 AR9462 malfunctions with these two errors occurring:
 
 AMD-Vi: Event logged [INVALID_DEVICE_REQUEST device=00:00.1
 address=0x00fdf8080020 flags=0x0a00]
 
 Followed by this  looping error, which reoccurs shortly after associating
 and obtaining an IP.  I've attached a large snippet from dmesg, due to it's
 length.
 
 I'm not sure where the error is coming from but I did see that Alex
 Williamson posted a patch that dealt with aliased devices (like pci
 bridges) and AMD's IOMMU issues, see
 e028a9e6b8a637af09ac4114083280df4a7045f1 for reference.
 
 I then disable IOMMU in the bios, and immediately the ath9k/AR9462 pair is
 working without flaw or retries.  Bios is up to date btw, updated it after
 building the machine last friday.
 
 So anyone have a clue what's going on here?

Please boot with amd_iommu_dump on the kernel boot line and send the
full dmesg log and 'sudo lspci -vvv' output.  Thanks,

Alex

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu