From fef6e26208879f76bada77c11c80d56ebacb32e4 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 6 Jul 2011 10:16:21 -0400 Subject: xen/pci: Shuffle code around. The file is hard to read. Move the code around so that the contents of it follows a uniform format: - setup GSIs - PV, HVM, and initial domain case - then MSI/MSI-x setup - PV, HVM and then initial domain case. - then MSI/MSI-x teardown - same order. - lastly, the __init functions in PV, HVM, and initial domain order. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 346 ++++++++++++++++++++++++++--------------------------- 1 file changed, 173 insertions(+), 173 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index f567965c0620..ba4077b73047 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -19,6 +19,43 @@ #include #include +static int xen_pcifront_enable_irq(struct pci_dev *dev) +{ + int rc; + int share = 1; + int pirq; + u8 gsi; + + rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); + if (rc < 0) { + dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", + rc); + return rc; + } + + rc = xen_allocate_pirq_gsi(gsi); + if (rc < 0) { + dev_warn(&dev->dev, "Xen PCI: failed to allocate a PIRQ for GSI%d: %d\n", + gsi, rc); + return rc; + } + pirq = rc; + + if (gsi < NR_IRQS_LEGACY) + share = 0; + + rc = xen_bind_pirq_gsi_to_irq(gsi, pirq, share, "pcifront"); + if (rc < 0) { + dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n", + gsi, pirq, rc); + return rc; + } + + dev->irq = rc; + dev_info(&dev->dev, "Xen PCI mapped GSI%d to IRQ%d\n", gsi, dev->irq); + return 0; +} + #ifdef CONFIG_ACPI static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, int trigger, int polarity) @@ -58,6 +95,87 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, } #endif +#ifdef CONFIG_XEN_DOM0 +static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) +{ + int rc, pirq, irq = -1; + struct physdev_map_pirq map_irq; + int shareable = 0; + char *name; + + if (!xen_pv_domain()) + return -1; + + if (triggering == ACPI_EDGE_SENSITIVE) { + shareable = 0; + name = "ioapic-edge"; + } else { + shareable = 1; + name = "ioapic-level"; + } + pirq = xen_allocate_pirq_gsi(gsi); + if (pirq < 0) + goto out; + + if (gsi_override >= 0) + irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); + else + irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + if (irq < 0) + goto out; + + printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); + + map_irq.domid = DOMID_SELF; + map_irq.type = MAP_PIRQ_TYPE_GSI; + map_irq.index = gsi; + map_irq.pirq = pirq; + + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); + if (rc) { + printk(KERN_WARNING "xen map irq failed %d\n", rc); + return -1; + } + +out: + return irq; +} + +static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) +{ + int rc, irq; + struct physdev_setup_gsi setup_gsi; + + if (!xen_pv_domain()) + return -1; + + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", + gsi, triggering, polarity); + + irq = xen_register_pirq(gsi, gsi_override, triggering); + + setup_gsi.gsi = gsi; + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); + setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); + + rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); + if (rc == -EEXIST) + printk(KERN_INFO "Already setup the GSI :%d\n", gsi); + else if (rc) { + printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", + gsi, rc); + } + + return irq; +} + +static int acpi_register_gsi_xen(struct device *dev, u32 gsi, + int trigger, int polarity) +{ + return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); +} +#endif + #if defined(CONFIG_PCI_MSI) #include #include @@ -65,6 +183,46 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, struct xen_pci_frontend_ops *xen_pci_frontend; EXPORT_SYMBOL_GPL(xen_pci_frontend); +/* + * For MSI interrupts we have to use drivers/xen/event.s functions to + * allocate an irq_desc and setup the right */ +static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +{ + int irq, ret, i; + struct msi_desc *msidesc; + int *v; + + v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL); + if (!v) + return -ENOMEM; + + if (type == PCI_CAP_ID_MSIX) + ret = xen_pci_frontend_enable_msix(dev, v, nvec); + else + ret = xen_pci_frontend_enable_msi(dev, v); + if (ret) + goto error; + i = 0; + list_for_each_entry(msidesc, &dev->msi_list, list) { + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, + (type == PCI_CAP_ID_MSIX) ? + "pcifront-msi-x" : + "pcifront-msi", + DOMID_SELF); + if (irq < 0) + goto free; + i++; + } + kfree(v); + return 0; + +error: + dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n"); +free: + kfree(v); + return ret; +} + #define XEN_PIRQ_MSI_DATA (MSI_DATA_TRIGGER_EDGE | \ MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0)) @@ -123,67 +281,6 @@ error: return -ENODEV; } -/* - * For MSI interrupts we have to use drivers/xen/event.s functions to - * allocate an irq_desc and setup the right */ - - -static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - int irq, ret, i; - struct msi_desc *msidesc; - int *v; - - v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL); - if (!v) - return -ENOMEM; - - if (type == PCI_CAP_ID_MSIX) - ret = xen_pci_frontend_enable_msix(dev, v, nvec); - else - ret = xen_pci_frontend_enable_msi(dev, v); - if (ret) - goto error; - i = 0; - list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, - (type == PCI_CAP_ID_MSIX) ? - "pcifront-msi-x" : - "pcifront-msi", - DOMID_SELF); - if (irq < 0) - goto free; - i++; - } - kfree(v); - return 0; - -error: - dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n"); -free: - kfree(v); - return ret; -} - -static void xen_teardown_msi_irqs(struct pci_dev *dev) -{ - struct msi_desc *msidesc; - - msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); - if (msidesc->msi_attrib.is_msix) - 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); -} - #ifdef CONFIG_XEN_DOM0 static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { @@ -242,44 +339,28 @@ out: return ret; } #endif -#endif -static int xen_pcifront_enable_irq(struct pci_dev *dev) +static void xen_teardown_msi_irqs(struct pci_dev *dev) { - int rc; - int share = 1; - int pirq; - u8 gsi; + struct msi_desc *msidesc; - rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); - if (rc < 0) { - dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", - rc); - return rc; - } + msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); + if (msidesc->msi_attrib.is_msix) + xen_pci_frontend_disable_msix(dev); + else + xen_pci_frontend_disable_msi(dev); - rc = xen_allocate_pirq_gsi(gsi); - if (rc < 0) { - dev_warn(&dev->dev, "Xen PCI: failed to allocate a PIRQ for GSI%d: %d\n", - gsi, rc); - return rc; - } - pirq = rc; + /* Free the IRQ's and the msidesc using the generic code. */ + default_teardown_msi_irqs(dev); +} - if (gsi < NR_IRQS_LEGACY) - share = 0; +static void xen_teardown_msi_irq(unsigned int irq) +{ + xen_destroy_irq(irq); +} - rc = xen_bind_pirq_gsi_to_irq(gsi, pirq, share, "pcifront"); - if (rc < 0) { - dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n", - gsi, pirq, rc); - return rc; - } +#endif - dev->irq = rc; - dev_info(&dev->dev, "Xen PCI mapped GSI%d to IRQ%d\n", gsi, dev->irq); - return 0; -} int __init pci_xen_init(void) { @@ -327,79 +408,6 @@ int __init pci_xen_hvm_init(void) } #ifdef CONFIG_XEN_DOM0 -static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) -{ - int rc, pirq, irq = -1; - struct physdev_map_pirq map_irq; - int shareable = 0; - char *name; - - if (!xen_pv_domain()) - return -1; - - if (triggering == ACPI_EDGE_SENSITIVE) { - shareable = 0; - name = "ioapic-edge"; - } else { - shareable = 1; - name = "ioapic-level"; - } - pirq = xen_allocate_pirq_gsi(gsi); - if (pirq < 0) - goto out; - - if (gsi_override >= 0) - irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); - else - irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); - if (irq < 0) - goto out; - - printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); - - map_irq.domid = DOMID_SELF; - map_irq.type = MAP_PIRQ_TYPE_GSI; - map_irq.index = gsi; - map_irq.pirq = pirq; - - rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); - if (rc) { - printk(KERN_WARNING "xen map irq failed %d\n", rc); - return -1; - } - -out: - return irq; -} - -static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) -{ - int rc, irq; - struct physdev_setup_gsi setup_gsi; - - if (!xen_pv_domain()) - return -1; - - printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", - gsi, triggering, polarity); - - irq = xen_register_pirq(gsi, gsi_override, triggering); - - setup_gsi.gsi = gsi; - setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); - setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); - - rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); - if (rc == -EEXIST) - printk(KERN_INFO "Already setup the GSI :%d\n", gsi); - else if (rc) { - printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", - gsi, rc); - } - - return irq; -} - static __init void xen_setup_acpi_sci(void) { int rc; @@ -447,12 +455,6 @@ static __init void xen_setup_acpi_sci(void) return; } -static int acpi_register_gsi_xen(struct device *dev, u32 gsi, - int trigger, int polarity) -{ - return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); -} - static int __init pci_xen_initial_domain(void) { #ifdef CONFIG_PCI_MSI @@ -493,9 +495,7 @@ void __init xen_setup_pirqs(void) trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); } } -#endif -#ifdef CONFIG_XEN_DOM0 struct xen_device_domain_owner { domid_t domain; struct pci_dev *dev; -- cgit v1.2.3 From 996c34aee3525c0ef91052af0e425e87d83ba6e0 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 6 Jun 2011 12:22:23 -0400 Subject: xen/pci: Update comments and fix empty spaces. Update the out-dated comment at the beginning of the file. Also provide the copyrights of folks who have been contributing to this code lately. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index ba4077b73047..76b39804413c 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -1,8 +1,13 @@ /* - * Xen PCI Frontend Stub - puts some "dummy" functions in to the Linux - * x86 PCI core to support the Xen PCI Frontend + * Xen PCI - handle PCI (INTx) and MSI infrastructure calls for PV, HVM and + * initial domain support. We also handle the DSDT _PRT callbacks for GSI's + * used in HVM and initial domain mode (PV does not parse ACPI, so it has no + * concept of GSIs). Under PV we hook under the pnbbios API for IRQs and + * 0xcf8 PCI configuration read/write. * * Author: Ryan Wilson + * Konrad Rzeszutek Wilk + * Stefano Stabellini */ #include #include @@ -183,9 +188,6 @@ static int acpi_register_gsi_xen(struct device *dev, u32 gsi, struct xen_pci_frontend_ops *xen_pci_frontend; EXPORT_SYMBOL_GPL(xen_pci_frontend); -/* - * For MSI interrupts we have to use drivers/xen/event.s functions to - * allocate an irq_desc and setup the right */ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { int irq, ret, i; @@ -361,7 +363,6 @@ static void xen_teardown_msi_irq(unsigned int irq) #endif - int __init pci_xen_init(void) { if (!xen_pv_domain() || xen_initial_domain()) @@ -427,7 +428,7 @@ static __init void xen_setup_acpi_sci(void) } trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - + printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " "polarity=%d\n", gsi, trigger, polarity); -- cgit v1.2.3 From d92edd814e3c9d9105de55b14c8958b1f8f20269 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 6 Jul 2011 10:41:47 -0400 Subject: xen/pci: Provide #ifdef CONFIG_ACPI to easy code squashing. In the past we would guard those code segments to be dependent on CONFIG_XEN_DOM0 (which depends on CONFIG_ACPI) so this patch is not stricly necessary. But the next patch will merge common HVM and initial domain code and we want to make sure the CONFIG_ACPI dependency is preserved - as HVM code does not depend on CONFIG_XEN_DOM0. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 76b39804413c..7ee39cc38a2d 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -101,6 +101,7 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, #endif #ifdef CONFIG_XEN_DOM0 +#ifdef CONFIG_ACPI static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) { int rc, pirq, irq = -1; @@ -180,6 +181,7 @@ static int acpi_register_gsi_xen(struct device *dev, u32 gsi, return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); } #endif +#endif #if defined(CONFIG_PCI_MSI) #include @@ -409,6 +411,7 @@ int __init pci_xen_hvm_init(void) } #ifdef CONFIG_XEN_DOM0 +#ifdef CONFIG_ACPI static __init void xen_setup_acpi_sci(void) { int rc; @@ -455,16 +458,17 @@ static __init void xen_setup_acpi_sci(void) return; } - +#endif static int __init pci_xen_initial_domain(void) { #ifdef CONFIG_PCI_MSI x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; x86_msi.teardown_msi_irq = xen_teardown_msi_irq; #endif +#ifdef CONFIG_ACPI xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; - +#endif return 0; } @@ -484,7 +488,7 @@ void __init xen_setup_pirqs(void) } return; } - +#ifdef CONFIG_ACPI /* Pre-allocate legacy irqs */ for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { int trigger, polarity; @@ -495,6 +499,7 @@ void __init xen_setup_pirqs(void) xen_register_pirq(irq, -1 /* no GSI override */, trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); } +#endif } struct xen_device_domain_owner { -- cgit v1.2.3 From 30bd35edfd5c82147bdcf0540c6bd3cf92d101f8 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 6 Jul 2011 10:48:22 -0400 Subject: xen/pci: In xen_register_pirq bind the GSI to the IRQ after the hypercall. Not before .. also that code segment starts looking like the HVM one. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 7ee39cc38a2d..6b7d849905c3 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -112,26 +112,10 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) if (!xen_pv_domain()) return -1; - if (triggering == ACPI_EDGE_SENSITIVE) { - shareable = 0; - name = "ioapic-edge"; - } else { - shareable = 1; - name = "ioapic-level"; - } pirq = xen_allocate_pirq_gsi(gsi); if (pirq < 0) goto out; - if (gsi_override >= 0) - irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); - else - irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); - if (irq < 0) - goto out; - - printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); - map_irq.domid = DOMID_SELF; map_irq.type = MAP_PIRQ_TYPE_GSI; map_irq.index = gsi; @@ -143,6 +127,22 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) return -1; } + if (triggering == ACPI_EDGE_SENSITIVE) { + shareable = 0; + name = "ioapic-edge"; + } else { + shareable = 1; + name = "ioapic-level"; + } + + if (gsi_override >= 0) + gsi = gsi_override; + + irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + if (irq < 0) + goto out; + + printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); out: return irq; } -- cgit v1.2.3 From ed89eb6396b3307bf9aaa4785f6a0914a68040cf Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 6 Jul 2011 12:42:43 -0400 Subject: xen/pci: Use the xen_register_pirq for HVM and initial domain users .. to cut down on the code duplicity. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 75 +++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 52 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 6b7d849905c3..55c8cc3647a7 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -62,60 +62,19 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev) } #ifdef CONFIG_ACPI -static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, - int trigger, int polarity) +static int xen_register_pirq(u32 gsi, int gsi_override, int triggering, + bool alloc_pirq) { - int rc, irq; + int rc, pirq = -1, irq = -1; struct physdev_map_pirq map_irq; int shareable = 0; char *name; - if (!xen_hvm_domain()) - return -1; - - map_irq.domid = DOMID_SELF; - map_irq.type = MAP_PIRQ_TYPE_GSI; - map_irq.index = gsi; - map_irq.pirq = -1; - - rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); - if (rc) { - printk(KERN_WARNING "xen map irq failed %d\n", rc); - return -1; - } - - if (trigger == ACPI_EDGE_SENSITIVE) { - shareable = 0; - name = "ioapic-edge"; - } else { - shareable = 1; - name = "ioapic-level"; + if (alloc_pirq) { + pirq = xen_allocate_pirq_gsi(gsi); + if (pirq < 0) + goto out; } - - irq = xen_bind_pirq_gsi_to_irq(gsi, map_irq.pirq, shareable, name); - - printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); - - return irq; -} -#endif - -#ifdef CONFIG_XEN_DOM0 -#ifdef CONFIG_ACPI -static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) -{ - int rc, pirq, irq = -1; - struct physdev_map_pirq map_irq; - int shareable = 0; - char *name; - - if (!xen_pv_domain()) - return -1; - - pirq = xen_allocate_pirq_gsi(gsi); - if (pirq < 0) - goto out; - map_irq.domid = DOMID_SELF; map_irq.type = MAP_PIRQ_TYPE_GSI; map_irq.index = gsi; @@ -138,15 +97,26 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) if (gsi_override >= 0) gsi = gsi_override; - irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + irq = xen_bind_pirq_gsi_to_irq(gsi, map_irq.pirq, shareable, name); if (irq < 0) goto out; - printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); + printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", map_irq.pirq, irq, gsi); out: return irq; } +static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, + int trigger, int polarity) +{ + if (!xen_hvm_domain()) + return -1; + + return xen_register_pirq(gsi, -1 /* no GSI override */, + trigger, false /* no PIRQ allocation */); +} + +#ifdef CONFIG_XEN_DOM0 static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) { int rc, irq; @@ -158,7 +128,7 @@ static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polar printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", gsi, triggering, polarity); - irq = xen_register_pirq(gsi, gsi_override, triggering); + irq = xen_register_pirq(gsi, gsi_override, triggering, true); setup_gsi.gsi = gsi; setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); @@ -497,7 +467,8 @@ void __init xen_setup_pirqs(void) continue; xen_register_pirq(irq, -1 /* no GSI override */, - trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); + trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE, + true /* allocate IRQ */); } #endif } -- cgit v1.2.3 From a0ee05670915006564962114d4211dd578a8b28a Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 9 Jun 2011 09:49:13 -0400 Subject: xen/pci: Squash pci_xen_initial_domain and xen_setup_pirqs together. Since they are only called once and the rest of the pci_xen_* functions follow the same pattern of setup. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/xen/pci.h | 5 +++-- arch/x86/pci/xen.c | 17 ++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h index 4fbda9a3f339..968d57dd54c9 100644 --- a/arch/x86/include/asm/xen/pci.h +++ b/arch/x86/include/asm/xen/pci.h @@ -14,13 +14,14 @@ static inline int pci_xen_hvm_init(void) } #endif #if defined(CONFIG_XEN_DOM0) -void __init xen_setup_pirqs(void); +int __init pci_xen_initial_domain(void); int xen_find_device_domain_owner(struct pci_dev *dev); int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain); int xen_unregister_device_domain_owner(struct pci_dev *dev); #else -static inline void __init xen_setup_pirqs(void) +static inline int __init pci_xen_initial_domain(void) { + return -1; } static inline int xen_find_device_domain_owner(struct pci_dev *dev) { diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 55c8cc3647a7..54d5f3131060 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -429,8 +429,11 @@ static __init void xen_setup_acpi_sci(void) return; } #endif -static int __init pci_xen_initial_domain(void) + +int __init pci_xen_initial_domain(void) { + int pirq, irq; + #ifdef CONFIG_PCI_MSI x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; x86_msi.teardown_msi_irq = xen_teardown_msi_irq; @@ -439,15 +442,6 @@ static int __init pci_xen_initial_domain(void) xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; #endif - return 0; -} - -void __init xen_setup_pirqs(void) -{ - int pirq, irq; - - pci_xen_initial_domain(); - if (0 == nr_ioapics) { for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { pirq = xen_allocate_pirq_gsi(irq); @@ -456,7 +450,7 @@ void __init xen_setup_pirqs(void) break; irq = xen_bind_pirq_gsi_to_irq(irq, pirq, 0, "xt-pic"); } - return; + return 0; } #ifdef CONFIG_ACPI /* Pre-allocate legacy irqs */ @@ -471,6 +465,7 @@ void __init xen_setup_pirqs(void) true /* allocate IRQ */); } #endif + return 0; } struct xen_device_domain_owner { -- cgit v1.2.3 From 9b6519db5e226c0c83acddf788b7091b751fbb75 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 6 Jun 2011 14:20:35 -0400 Subject: xen/pci: Move the allocation of IRQs when there are no IOAPIC's to the end .. which means we can preset of NR_IRQS_LEGACY interrupts using the 'acpi_get_override_irq' API before this loop. This means that we can get the IRQ's polarity (and trigger) from either the ACPI (or MP); or use the default values. This fixes a bug if we did not have an IOAPIC we would not been able to preset the IRQ's polarity if the MP table existed. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 54d5f3131060..e585bf5778ec 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -441,18 +441,6 @@ int __init pci_xen_initial_domain(void) #ifdef CONFIG_ACPI xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; -#endif - if (0 == nr_ioapics) { - for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { - pirq = xen_allocate_pirq_gsi(irq); - if (WARN(pirq < 0, - "Could not allocate PIRQ for legacy interrupt\n")) - break; - irq = xen_bind_pirq_gsi_to_irq(irq, pirq, 0, "xt-pic"); - } - return 0; - } -#ifdef CONFIG_ACPI /* Pre-allocate legacy irqs */ for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { int trigger, polarity; @@ -465,6 +453,15 @@ int __init pci_xen_initial_domain(void) true /* allocate IRQ */); } #endif + if (0 == nr_ioapics) { + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { + pirq = xen_allocate_pirq_gsi(irq); + if (WARN(pirq < 0, + "Could not allocate PIRQ for legacy interrupt\n")) + break; + irq = xen_bind_pirq_gsi_to_irq(irq, pirq, 0, "xt-pic"); + } + } return 0; } -- cgit v1.2.3 From 34b1d1269d9fdaa1558e3014c3cc03ac0967de95 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 15 Jun 2011 14:43:52 -0400 Subject: xen/pci: Retire unnecessary #ifdef CONFIG_ACPI As the code paths that are guarded by CONFIG_XEN_DOM0 already depend on CONFIG_ACPI so the extra #ifdef is not required. The earlier patch that added them in had done its job. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index e585bf5778ec..6eddc524603c 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -381,7 +381,6 @@ int __init pci_xen_hvm_init(void) } #ifdef CONFIG_XEN_DOM0 -#ifdef CONFIG_ACPI static __init void xen_setup_acpi_sci(void) { int rc; @@ -428,7 +427,6 @@ static __init void xen_setup_acpi_sci(void) return; } -#endif int __init pci_xen_initial_domain(void) { @@ -438,7 +436,6 @@ int __init pci_xen_initial_domain(void) x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; x86_msi.teardown_msi_irq = xen_teardown_msi_irq; #endif -#ifdef CONFIG_ACPI xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; /* Pre-allocate legacy irqs */ @@ -452,7 +449,6 @@ int __init pci_xen_initial_domain(void) trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE, true /* allocate IRQ */); } -#endif if (0 == nr_ioapics) { for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { pirq = xen_allocate_pirq_gsi(irq); -- cgit v1.2.3 From 78316ada2222b5e3abc043eea7644e12319042d6 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 6 Jul 2011 15:15:23 -0400 Subject: xen/pci: Remove 'xen_allocate_pirq_gsi'. In the past (2.6.38) the 'xen_allocate_pirq_gsi' would allocate an entry in a Linux IRQ -> {XEN_IRQ, type, event, ..} array. All of that has been removed in 2.6.39 and the Xen IRQ subsystem uses an linked list that is populated when the call to 'xen_allocate_irq_gsi' (universally done from any of the xen_bind_* calls) is done. The 'xen_allocate_pirq_gsi' is a NOP and there is no need for it anymore so lets remove it. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 6eddc524603c..f07c419a616c 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -37,14 +37,8 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev) rc); return rc; } - - rc = xen_allocate_pirq_gsi(gsi); - if (rc < 0) { - dev_warn(&dev->dev, "Xen PCI: failed to allocate a PIRQ for GSI%d: %d\n", - gsi, rc); - return rc; - } - pirq = rc; + /* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/ + pirq = gsi; if (gsi < NR_IRQS_LEGACY) share = 0; @@ -63,18 +57,16 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev) #ifdef CONFIG_ACPI static int xen_register_pirq(u32 gsi, int gsi_override, int triggering, - bool alloc_pirq) + bool set_pirq) { int rc, pirq = -1, irq = -1; struct physdev_map_pirq map_irq; int shareable = 0; char *name; - if (alloc_pirq) { - pirq = xen_allocate_pirq_gsi(gsi); - if (pirq < 0) - goto out; - } + if (set_pirq) + pirq = gsi; + map_irq.domid = DOMID_SELF; map_irq.type = MAP_PIRQ_TYPE_GSI; map_irq.index = gsi; @@ -112,8 +104,8 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, if (!xen_hvm_domain()) return -1; - return xen_register_pirq(gsi, -1 /* no GSI override */, - trigger, false /* no PIRQ allocation */); + return xen_register_pirq(gsi, -1 /* no GSI override */, trigger, + false /* no mapping of GSI to PIRQ */); } #ifdef CONFIG_XEN_DOM0 @@ -430,7 +422,7 @@ static __init void xen_setup_acpi_sci(void) int __init pci_xen_initial_domain(void) { - int pirq, irq; + int irq; #ifdef CONFIG_PCI_MSI x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; @@ -447,16 +439,11 @@ int __init pci_xen_initial_domain(void) xen_register_pirq(irq, -1 /* no GSI override */, trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE, - true /* allocate IRQ */); + true /* Map GSI to PIRQ */); } if (0 == nr_ioapics) { - for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { - pirq = xen_allocate_pirq_gsi(irq); - if (WARN(pirq < 0, - "Could not allocate PIRQ for legacy interrupt\n")) - break; - irq = xen_bind_pirq_gsi_to_irq(irq, pirq, 0, "xt-pic"); - } + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) + xen_bind_pirq_gsi_to_irq(irq, irq, 0, "xt-pic"); } return 0; } -- cgit v1.2.3 From 97ffab1f14638d2c95ad986ce735481d164a0bd2 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 6 Jul 2011 13:03:35 -0400 Subject: xen/pci: Use 'acpi_gsi_to_irq' value unconditionally. In the past we would only use the function's value if the returned value was not equal to 'acpi_sci_override_gsi'. Meaning that the INT_SRV_OVR values for global and source irq were different. But it is OK to use the function's value even when the global and source irq are the same. Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index f07c419a616c..1017c7bee388 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -407,10 +407,9 @@ static __init void xen_setup_acpi_sci(void) * the ACPI interpreter and keels over since IRQ 9 has not been * setup as we had setup IRQ 20 for it). */ - /* Check whether the GSI != IRQ */ if (acpi_gsi_to_irq(gsi, &irq) == 0) { - if (irq >= 0 && irq != gsi) - /* Bugger, we MUST have that IRQ. */ + /* Use the provided value if it's valid. */ + if (irq >= 0) gsi_override = irq; } -- cgit v1.2.3