summaryrefslogtreecommitdiffstats
path: root/kernel/arch/powerpc/sysdev
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/arch/powerpc/sysdev')
-rw-r--r--kernel/arch/powerpc/sysdev/Makefile2
-rw-r--r--kernel/arch/powerpc/sysdev/axonram.c14
-rw-r--r--kernel/arch/powerpc/sysdev/cpm2_pic.c4
-rw-r--r--kernel/arch/powerpc/sysdev/cpm_common.c3
-rw-r--r--kernel/arch/powerpc/sysdev/dart_iommu.c28
-rw-r--r--kernel/arch/powerpc/sysdev/ehv_pic.c6
-rw-r--r--kernel/arch/powerpc/sysdev/fsl_lbc.c2
-rw-r--r--kernel/arch/powerpc/sysdev/fsl_msi.c34
-rw-r--r--kernel/arch/powerpc/sysdev/fsl_pci.c90
-rw-r--r--kernel/arch/powerpc/sysdev/ge/ge_pic.c2
-rw-r--r--kernel/arch/powerpc/sysdev/ge/ge_pic.h2
-rw-r--r--kernel/arch/powerpc/sysdev/i8259.c8
-rw-r--r--kernel/arch/powerpc/sysdev/ipic.c12
-rw-r--r--kernel/arch/powerpc/sysdev/mpc5xxx_clocks.c5
-rw-r--r--kernel/arch/powerpc/sysdev/mpc8xx_pic.c6
-rw-r--r--kernel/arch/powerpc/sysdev/mpic.c33
-rw-r--r--kernel/arch/powerpc/sysdev/mpic.h10
-rw-r--r--kernel/arch/powerpc/sysdev/mpic_msi.c2
-rw-r--r--kernel/arch/powerpc/sysdev/mpic_pasemi_msi.c167
-rw-r--r--kernel/arch/powerpc/sysdev/mpic_u3msi.c18
-rw-r--r--kernel/arch/powerpc/sysdev/msi_bitmap.c18
-rw-r--r--kernel/arch/powerpc/sysdev/mv64x60_pic.c2
-rw-r--r--kernel/arch/powerpc/sysdev/ppc4xx_hsta_msi.c16
-rw-r--r--kernel/arch/powerpc/sysdev/ppc4xx_msi.c16
-rw-r--r--kernel/arch/powerpc/sysdev/qe_lib/qe_ic.c12
-rw-r--r--kernel/arch/powerpc/sysdev/tsi108_pci.c4
-rw-r--r--kernel/arch/powerpc/sysdev/uic.c6
-rw-r--r--kernel/arch/powerpc/sysdev/xics/icp-native.c14
-rw-r--r--kernel/arch/powerpc/sysdev/xics/ics-opal.c4
-rw-r--r--kernel/arch/powerpc/sysdev/xics/ics-rtas.c4
-rw-r--r--kernel/arch/powerpc/sysdev/xics/xics-common.c7
-rw-r--r--kernel/arch/powerpc/sysdev/xilinx_intc.c4
32 files changed, 222 insertions, 333 deletions
diff --git a/kernel/arch/powerpc/sysdev/Makefile b/kernel/arch/powerpc/sysdev/Makefile
index f7cb2a1b0..5b492a643 100644
--- a/kernel/arch/powerpc/sysdev/Makefile
+++ b/kernel/arch/powerpc/sysdev/Makefile
@@ -2,7 +2,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
+mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o
obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
obj-$(CONFIG_MPIC_TIMER) += mpic_timer.o
obj-$(CONFIG_FSL_MPIC_TIMER_WAKEUP) += fsl_mpic_timer_wakeup.o
diff --git a/kernel/arch/powerpc/sysdev/axonram.c b/kernel/arch/powerpc/sysdev/axonram.c
index ee90db17b..7a399b4d6 100644
--- a/kernel/arch/powerpc/sysdev/axonram.c
+++ b/kernel/arch/powerpc/sysdev/axonram.c
@@ -103,7 +103,7 @@ axon_ram_irq_handler(int irq, void *dev)
* axon_ram_make_request - make_request() method for block device
* @queue, @bio: see blk_queue_make_request()
*/
-static void
+static blk_qc_t
axon_ram_make_request(struct request_queue *queue, struct bio *bio)
{
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
@@ -120,7 +120,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
bio_for_each_segment(vec, bio, iter) {
if (unlikely(phys_mem + vec.bv_len > phys_end)) {
bio_io_error(bio);
- return;
+ return BLK_QC_T_NONE;
}
user_mem = page_address(vec.bv_page) + vec.bv_offset;
@@ -132,7 +132,8 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
phys_mem += vec.bv_len;
transfered += vec.bv_len;
}
- bio_endio(bio, 0);
+ bio_endio(bio);
+ return BLK_QC_T_NONE;
}
/**
@@ -141,13 +142,14 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
*/
static long
axon_ram_direct_access(struct block_device *device, sector_t sector,
- void **kaddr, unsigned long *pfn, long size)
+ void __pmem **kaddr, unsigned long *pfn)
{
struct axon_ram_bank *bank = device->bd_disk->private_data;
loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
+ void *addr = (void *)(bank->ph_addr + offset);
- *kaddr = (void *)(bank->ph_addr + offset);
- *pfn = virt_to_phys(*kaddr) >> PAGE_SHIFT;
+ *kaddr = (void __pmem *)addr;
+ *pfn = virt_to_phys(addr) >> PAGE_SHIFT;
return bank->size - offset;
}
diff --git a/kernel/arch/powerpc/sysdev/cpm2_pic.c b/kernel/arch/powerpc/sysdev/cpm2_pic.c
index a11bd1d43..9e8607471 100644
--- a/kernel/arch/powerpc/sysdev/cpm2_pic.c
+++ b/kernel/arch/powerpc/sysdev/cpm2_pic.c
@@ -155,9 +155,9 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
irqd_set_trigger_type(d, flow_type);
if (flow_type & IRQ_TYPE_LEVEL_LOW)
- __irq_set_handler_locked(d->irq, handle_level_irq);
+ irq_set_handler_locked(d, handle_level_irq);
else
- __irq_set_handler_locked(d->irq, handle_edge_irq);
+ irq_set_handler_locked(d, handle_edge_irq);
/* internal IRQ senses are LEVEL_LOW
* EXT IRQ and Port C IRQ senses are programmable
diff --git a/kernel/arch/powerpc/sysdev/cpm_common.c b/kernel/arch/powerpc/sysdev/cpm_common.c
index 4f7869571..e00a5ee58 100644
--- a/kernel/arch/powerpc/sysdev/cpm_common.c
+++ b/kernel/arch/powerpc/sysdev/cpm_common.c
@@ -147,7 +147,8 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
spin_lock_irqsave(&cpm_muram_lock, flags);
cpm_muram_info.alignment = align;
start = rh_alloc(&cpm_muram_info, size, "commproc");
- memset(cpm_muram_addr(start), 0, size);
+ if (!IS_ERR_VALUE(start))
+ memset_io(cpm_muram_addr(start), 0, size);
spin_unlock_irqrestore(&cpm_muram_lock, flags);
return start;
diff --git a/kernel/arch/powerpc/sysdev/dart_iommu.c b/kernel/arch/powerpc/sysdev/dart_iommu.c
index d00a5663e..b7348637e 100644
--- a/kernel/arch/powerpc/sysdev/dart_iommu.c
+++ b/kernel/arch/powerpc/sysdev/dart_iommu.c
@@ -286,6 +286,12 @@ static int __init dart_init(struct device_node *dart_node)
return 0;
}
+static struct iommu_table_ops iommu_dart_ops = {
+ .set = dart_build,
+ .clear = dart_free,
+ .flush = dart_flush,
+};
+
static void iommu_table_dart_setup(void)
{
iommu_table_dart.it_busno = 0;
@@ -298,6 +304,7 @@ static void iommu_table_dart_setup(void)
iommu_table_dart.it_base = (unsigned long)dart_vbase;
iommu_table_dart.it_index = 0;
iommu_table_dart.it_blocksize = 1;
+ iommu_table_dart.it_ops = &iommu_dart_ops;
iommu_init_table(&iommu_table_dart, -1);
/* Reserve the last page of the DART to avoid possible prefetch
@@ -306,20 +313,11 @@ static void iommu_table_dart_setup(void)
set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
}
-static void dma_dev_setup_dart(struct device *dev)
-{
- /* We only have one iommu table on the mac for now, which makes
- * things simple. Setup all PCI devices to point to this table
- */
- if (get_dma_ops(dev) == &dma_direct_ops)
- set_dma_offset(dev, DART_U4_BYPASS_BASE);
- else
- set_iommu_table_base(dev, &iommu_table_dart);
-}
-
static void pci_dma_dev_setup_dart(struct pci_dev *dev)
{
- dma_dev_setup_dart(&dev->dev);
+ if (dart_is_u4)
+ set_dma_offset(&dev->dev, DART_U4_BYPASS_BASE);
+ set_iommu_table_base(&dev->dev, &iommu_table_dart);
}
static void pci_dma_bus_setup_dart(struct pci_bus *bus)
@@ -363,7 +361,6 @@ static int dart_dma_set_mask(struct device *dev, u64 dma_mask)
dev_info(dev, "Using 32-bit DMA via iommu\n");
set_dma_ops(dev, &dma_iommu_ops);
}
- dma_dev_setup_dart(dev);
*dev->dma_mask = dma_mask;
return 0;
@@ -386,11 +383,6 @@ void __init iommu_init_early_dart(struct pci_controller_ops *controller_ops)
if (dart_init(dn) != 0)
goto bail;
- /* Setup low level TCE operations for the core IOMMU code */
- ppc_md.tce_build = dart_build;
- ppc_md.tce_free = dart_free;
- ppc_md.tce_flush = dart_flush;
-
/* Setup bypass if supported */
if (dart_is_u4)
ppc_md.dma_set_mask = dart_dma_set_mask;
diff --git a/kernel/arch/powerpc/sysdev/ehv_pic.c b/kernel/arch/powerpc/sysdev/ehv_pic.c
index 2d20f10a4..bffcc7a48 100644
--- a/kernel/arch/powerpc/sysdev/ehv_pic.c
+++ b/kernel/arch/powerpc/sysdev/ehv_pic.c
@@ -177,10 +177,12 @@ unsigned int ehv_pic_get_irq(void)
return irq_linear_revmap(global_ehv_pic->irqhost, irq);
}
-static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node)
+static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node,
+ enum irq_domain_bus_token bus_token)
{
/* Exact match, unless ehv_pic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq,
diff --git a/kernel/arch/powerpc/sysdev/fsl_lbc.c b/kernel/arch/powerpc/sysdev/fsl_lbc.c
index d631022ff..38138cf8d 100644
--- a/kernel/arch/powerpc/sysdev/fsl_lbc.c
+++ b/kernel/arch/powerpc/sysdev/fsl_lbc.c
@@ -407,4 +407,4 @@ static int __init fsl_lbc_init(void)
{
return platform_driver_register(&fsl_lbc_ctrl_driver);
}
-module_init(fsl_lbc_init);
+subsys_initcall(fsl_lbc_init);
diff --git a/kernel/arch/powerpc/sysdev/fsl_msi.c b/kernel/arch/powerpc/sysdev/fsl_msi.c
index f086c6f22..3a2be3676 100644
--- a/kernel/arch/powerpc/sysdev/fsl_msi.c
+++ b/kernel/arch/powerpc/sysdev/fsl_msi.c
@@ -110,7 +110,7 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
int rc, hwirq;
rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS_MAX,
- msi_data->irqhost->of_node);
+ irq_domain_get_of_node(msi_data->irqhost));
if (rc)
return rc;
@@ -128,15 +128,16 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;
struct fsl_msi *msi_data;
+ irq_hw_number_t hwirq;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
+ hwirq = virq_to_hw(entry->irq);
msi_data = irq_get_chip_data(entry->irq);
irq_set_msi_desc(entry->irq, NULL);
- msi_bitmap_free_hwirqs(&msi_data->bitmap,
- virq_to_hw(entry->irq), 1);
irq_dispose_mapping(entry->irq);
+ msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
}
return;
@@ -219,7 +220,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
}
}
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
/*
* Loop over all the MSI devices until we find one that has an
* available interrupt.
@@ -405,6 +406,7 @@ static int fsl_of_msi_probe(struct platform_device *dev)
const struct fsl_msi_feature *features;
int len;
u32 offset;
+ struct pci_controller *phb;
match = of_match_device(fsl_of_msi_ids, &dev->dev);
if (!match)
@@ -541,14 +543,20 @@ static int fsl_of_msi_probe(struct platform_device *dev)
list_add_tail(&msi->list, &msi_head);
- /* The multiple setting ppc_md.setup_msi_irqs will not harm things */
- if (!ppc_md.setup_msi_irqs) {
- ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
- } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) {
- dev_err(&dev->dev, "Different MSI driver already installed!\n");
- err = -ENODEV;
- goto error_out;
+ /*
+ * Apply the MSI ops to all the controllers.
+ * It doesn't hurt to reassign the same ops,
+ * but bail out if we find another MSI driver.
+ */
+ list_for_each_entry(phb, &hose_list, list_node) {
+ if (!phb->controller_ops.setup_msi_irqs) {
+ phb->controller_ops.setup_msi_irqs = fsl_setup_msi_irqs;
+ phb->controller_ops.teardown_msi_irqs = fsl_teardown_msi_irqs;
+ } else if (phb->controller_ops.setup_msi_irqs != fsl_setup_msi_irqs) {
+ dev_err(&dev->dev, "Different MSI driver already installed!\n");
+ err = -ENODEV;
+ goto error_out;
+ }
}
return 0;
error_out:
diff --git a/kernel/arch/powerpc/sysdev/fsl_pci.c b/kernel/arch/powerpc/sysdev/fsl_pci.c
index 9a8fcf0d7..610f472f9 100644
--- a/kernel/arch/powerpc/sysdev/fsl_pci.c
+++ b/kernel/arch/powerpc/sysdev/fsl_pci.c
@@ -179,6 +179,19 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
return i;
}
+static bool is_kdump(void)
+{
+ struct device_node *node;
+
+ node = of_find_node_by_type(NULL, "memory");
+ if (!node) {
+ WARN_ON_ONCE(1);
+ return false;
+ }
+
+ return of_property_read_bool(node, "linux,usable-memory");
+}
+
/* atmu setup for fsl pci/pcie controller */
static void setup_pci_atmu(struct pci_controller *hose)
{
@@ -192,6 +205,16 @@ static void setup_pci_atmu(struct pci_controller *hose)
const char *name = hose->dn->full_name;
const u64 *reg;
int len;
+ bool setup_inbound;
+
+ /*
+ * If this is kdump, we don't want to trigger a bunch of PCI
+ * errors by closing the window on in-flight DMA.
+ *
+ * We still run most of the function's logic so that things like
+ * hose->dma_window_size still get set.
+ */
+ setup_inbound = !is_kdump();
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
@@ -204,8 +227,11 @@ static void setup_pci_atmu(struct pci_controller *hose)
/* Disable all windows (except powar0 since it's ignored) */
for(i = 1; i < 5; i++)
out_be32(&pci->pow[i].powar, 0);
- for (i = start_idx; i < end_idx; i++)
- out_be32(&pci->piw[i].piwar, 0);
+
+ if (setup_inbound) {
+ for (i = start_idx; i < end_idx; i++)
+ out_be32(&pci->piw[i].piwar, 0);
+ }
/* Setup outbound MEM window */
for(i = 0, j = 1; i < 3; i++) {
@@ -278,6 +304,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
/* Setup inbound mem window */
mem = memblock_end_of_DRAM();
+ pr_info("%s: end of DRAM %llx\n", __func__, mem);
/*
* The msi-address-64 property, if it exists, indicates the physical
@@ -320,12 +347,14 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
+ win_idx--;
hose->dma_window_base_cur = 0x00000000;
hose->dma_window_size = (resource_size_t)sz;
@@ -343,13 +372,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbear,
- pci64_dma_offset >> 44);
- out_be32(&pci->piw[win_idx].piwbar,
- pci64_dma_offset >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbear,
+ pci64_dma_offset >> 44);
+ out_be32(&pci->piw[win_idx].piwbar,
+ pci64_dma_offset >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
/*
* install our own dma_set_mask handler to fixup dma_ops
@@ -362,12 +393,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
} else {
u64 paddr = 0;
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, (piwar | (mem_log - 1)));
- win_idx--;
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwar,
+ (piwar | (mem_log - 1)));
+ }
+ win_idx--;
paddr += 1ull << mem_log;
sz -= 1ull << mem_log;
@@ -375,11 +409,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log = ilog2(sz);
piwar |= (mem_log - 1);
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
+ if (setup_inbound) {
+ out_be32(&pci->piw[win_idx].pitar,
+ paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwbar,
+ paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
+ win_idx--;
paddr += 1ull << mem_log;
}
@@ -999,10 +1037,10 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
ret = get_user(regs->nip, &inst);
pagefault_enable();
} else {
- ret = probe_kernel_address(regs->nip, inst);
+ ret = probe_kernel_address((void *)regs->nip, inst);
}
- if (mcheck_handle_load(regs, inst)) {
+ if (!ret && mcheck_handle_load(regs, inst)) {
regs->nip += 4;
return 1;
}
@@ -1113,7 +1151,7 @@ static int fsl_pci_pme_probe(struct pci_controller *hose)
IRQF_SHARED,
"[PCI] PME", hose);
if (res < 0) {
- dev_err(&dev->dev, "Unable to requiest irq %d for PME\n", pme_irq);
+ dev_err(&dev->dev, "Unable to request irq %d for PME\n", pme_irq);
irq_dispose_mapping(pme_irq);
return -ENODEV;
diff --git a/kernel/arch/powerpc/sysdev/ge/ge_pic.c b/kernel/arch/powerpc/sysdev/ge/ge_pic.c
index 2bcb78bb3..d57b77573 100644
--- a/kernel/arch/powerpc/sysdev/ge/ge_pic.c
+++ b/kernel/arch/powerpc/sysdev/ge/ge_pic.c
@@ -91,7 +91,7 @@ static int gef_pic_cascade_irq;
* should be masked out.
*/
-void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
+static void gef_pic_cascade(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq;
diff --git a/kernel/arch/powerpc/sysdev/ge/ge_pic.h b/kernel/arch/powerpc/sysdev/ge/ge_pic.h
index 908dbd982..5bf7e4b81 100644
--- a/kernel/arch/powerpc/sysdev/ge/ge_pic.h
+++ b/kernel/arch/powerpc/sysdev/ge/ge_pic.h
@@ -1,8 +1,6 @@
#ifndef __GEF_PIC_H__
#define __GEF_PIC_H__
-
-void gef_pic_cascade(unsigned int, struct irq_desc *);
unsigned int gef_pic_get_irq(void);
void gef_pic_init(struct device_node *);
diff --git a/kernel/arch/powerpc/sysdev/i8259.c b/kernel/arch/powerpc/sysdev/i8259.c
index 45598da0b..6f99ed396 100644
--- a/kernel/arch/powerpc/sysdev/i8259.c
+++ b/kernel/arch/powerpc/sysdev/i8259.c
@@ -162,9 +162,11 @@ static struct resource pic_edgectrl_iores = {
.flags = IORESOURCE_BUSY,
};
-static int i8259_host_match(struct irq_domain *h, struct device_node *node)
+static int i8259_host_match(struct irq_domain *h, struct device_node *node,
+ enum irq_domain_bus_token bus_token)
{
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int i8259_host_map(struct irq_domain *h, unsigned int virq,
@@ -204,7 +206,7 @@ static int i8259_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops i8259_host_ops = {
+static const struct irq_domain_ops i8259_host_ops = {
.match = i8259_host_match,
.map = i8259_host_map,
.xlate = i8259_host_xlate,
diff --git a/kernel/arch/powerpc/sysdev/ipic.c b/kernel/arch/powerpc/sysdev/ipic.c
index b28733727..f76ee39cb 100644
--- a/kernel/arch/powerpc/sysdev/ipic.c
+++ b/kernel/arch/powerpc/sysdev/ipic.c
@@ -624,10 +624,10 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
irqd_set_trigger_type(d, flow_type);
if (flow_type & IRQ_TYPE_LEVEL_LOW) {
- __irq_set_handler_locked(d->irq, handle_level_irq);
+ irq_set_handler_locked(d, handle_level_irq);
d->chip = &ipic_level_irq_chip;
} else {
- __irq_set_handler_locked(d->irq, handle_edge_irq);
+ irq_set_handler_locked(d, handle_edge_irq);
d->chip = &ipic_edge_irq_chip;
}
@@ -671,10 +671,12 @@ static struct irq_chip ipic_edge_irq_chip = {
.irq_set_type = ipic_set_irq_type,
};
-static int ipic_host_match(struct irq_domain *h, struct device_node *node)
+static int ipic_host_match(struct irq_domain *h, struct device_node *node,
+ enum irq_domain_bus_token bus_token)
{
/* Exact match, unless ipic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int ipic_host_map(struct irq_domain *h, unsigned int virq,
@@ -691,7 +693,7 @@ static int ipic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops ipic_host_ops = {
+static const struct irq_domain_ops ipic_host_ops = {
.match = ipic_host_match,
.map = ipic_host_map,
.xlate = irq_domain_xlate_onetwocell,
diff --git a/kernel/arch/powerpc/sysdev/mpc5xxx_clocks.c b/kernel/arch/powerpc/sysdev/mpc5xxx_clocks.c
index f4f0301b9..573292663 100644
--- a/kernel/arch/powerpc/sysdev/mpc5xxx_clocks.c
+++ b/kernel/arch/powerpc/sysdev/mpc5xxx_clocks.c
@@ -13,7 +13,6 @@
unsigned long mpc5xxx_get_bus_frequency(struct device_node *node)
{
- struct device_node *np;
const unsigned int *p_bus_freq = NULL;
of_node_get(node);
@@ -22,9 +21,7 @@ unsigned long mpc5xxx_get_bus_frequency(struct device_node *node)
if (p_bus_freq)
break;
- np = of_get_parent(node);
- of_node_put(node);
- node = np;
+ node = of_get_next_parent(node);
}
of_node_put(node);
diff --git a/kernel/arch/powerpc/sysdev/mpc8xx_pic.c b/kernel/arch/powerpc/sysdev/mpc8xx_pic.c
index c4828c0be..b7cf7abff 100644
--- a/kernel/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/kernel/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -55,13 +55,13 @@ static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
unsigned int siel = in_be32(&siu_reg->sc_siel);
siel |= mpc8xx_irqd_to_bit(d);
out_be32(&siu_reg->sc_siel, siel);
- __irq_set_handler_locked(d->irq, handle_edge_irq);
+ irq_set_handler_locked(d, handle_edge_irq);
}
return 0;
}
static struct irq_chip mpc8xx_pic = {
- .name = "MPC8XX SIU",
+ .name = "8XX SIU",
.irq_unmask = mpc8xx_unmask_irq,
.irq_mask = mpc8xx_mask_irq,
.irq_ack = mpc8xx_ack,
@@ -120,7 +120,7 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
}
-static struct irq_domain_ops mpc8xx_pic_host_ops = {
+static const struct irq_domain_ops mpc8xx_pic_host_ops = {
.map = mpc8xx_pic_host_map,
.xlate = mpc8xx_pic_host_xlate,
};
diff --git a/kernel/arch/powerpc/sysdev/mpic.c b/kernel/arch/powerpc/sysdev/mpic.c
index b2b8447a2..2a0452e36 100644
--- a/kernel/arch/powerpc/sysdev/mpic.c
+++ b/kernel/arch/powerpc/sysdev/mpic.c
@@ -924,22 +924,6 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
return IRQ_SET_MASK_OK_NOCOPY;
}
-static int mpic_irq_set_wake(struct irq_data *d, unsigned int on)
-{
- struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
- struct mpic *mpic = mpic_from_irq_data(d);
-
- if (!(mpic->flags & MPIC_FSL))
- return -ENXIO;
-
- if (on)
- desc->action->flags |= IRQF_NO_SUSPEND;
- else
- desc->action->flags &= ~IRQF_NO_SUSPEND;
-
- return 0;
-}
-
void mpic_set_vector(unsigned int virq, unsigned int vector)
{
struct mpic *mpic = mpic_from_irq(virq);
@@ -977,7 +961,6 @@ static struct irq_chip mpic_irq_chip = {
.irq_unmask = mpic_unmask_irq,
.irq_eoi = mpic_end_irq,
.irq_set_type = mpic_set_irq_type,
- .irq_set_wake = mpic_irq_set_wake,
};
#ifdef CONFIG_SMP
@@ -992,7 +975,6 @@ static struct irq_chip mpic_tm_chip = {
.irq_mask = mpic_mask_tm,
.irq_unmask = mpic_unmask_tm,
.irq_eoi = mpic_end_irq,
- .irq_set_wake = mpic_irq_set_wake,
};
#ifdef CONFIG_MPIC_U3_HT_IRQS
@@ -1007,10 +989,12 @@ static struct irq_chip mpic_irq_ht_chip = {
#endif /* CONFIG_MPIC_U3_HT_IRQS */
-static int mpic_host_match(struct irq_domain *h, struct device_node *node)
+static int mpic_host_match(struct irq_domain *h, struct device_node *node,
+ enum irq_domain_bus_token bus_token)
{
/* Exact match, unless mpic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int mpic_host_map(struct irq_domain *h, unsigned int virq,
@@ -1180,7 +1164,7 @@ static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
}
/* IRQ handler for a secondary MPIC cascaded from another IRQ controller */
-static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
+static void mpic_cascade(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
struct mpic *mpic = irq_desc_get_handler_data(desc);
@@ -1195,7 +1179,7 @@ static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
chip->irq_eoi(&desc->irq_data);
}
-static struct irq_domain_ops mpic_host_ops = {
+static const struct irq_domain_ops mpic_host_ops = {
.match = mpic_host_match,
.map = mpic_host_map,
.xlate = mpic_host_xlate,
@@ -1282,8 +1266,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
flags |= MPIC_NO_RESET;
if (of_get_property(node, "single-cpu-affinity", NULL))
flags |= MPIC_SINGLE_DEST_CPU;
- if (of_device_is_compatible(node, "fsl,mpic"))
+ if (of_device_is_compatible(node, "fsl,mpic")) {
flags |= MPIC_FSL | MPIC_LARGE_VECTORS;
+ mpic_irq_chip.flags |= IRQCHIP_SKIP_SET_WAKE;
+ mpic_tm_chip.flags |= IRQCHIP_SKIP_SET_WAKE;
+ }
mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
if (mpic == NULL)
diff --git a/kernel/arch/powerpc/sysdev/mpic.h b/kernel/arch/powerpc/sysdev/mpic.h
index 24bf07a63..32971a418 100644
--- a/kernel/arch/powerpc/sysdev/mpic.h
+++ b/kernel/arch/powerpc/sysdev/mpic.h
@@ -15,7 +15,6 @@
extern void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq);
extern int mpic_msi_init_allocator(struct mpic *mpic);
extern int mpic_u3msi_init(struct mpic *mpic);
-extern int mpic_pasemi_msi_init(struct mpic *mpic);
#else
static inline void mpic_msi_reserve_hwirq(struct mpic *mpic,
irq_hw_number_t hwirq)
@@ -27,11 +26,12 @@ static inline int mpic_u3msi_init(struct mpic *mpic)
{
return -1;
}
+#endif
-static inline int mpic_pasemi_msi_init(struct mpic *mpic)
-{
- return -1;
-}
+#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PPC_PASEMI)
+int mpic_pasemi_msi_init(struct mpic *mpic);
+#else
+static inline int mpic_pasemi_msi_init(struct mpic *mpic) { return -1; }
#endif
extern int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type);
diff --git a/kernel/arch/powerpc/sysdev/mpic_msi.c b/kernel/arch/powerpc/sysdev/mpic_msi.c
index 7dc39f35a..1d48a5385 100644
--- a/kernel/arch/powerpc/sysdev/mpic_msi.c
+++ b/kernel/arch/powerpc/sysdev/mpic_msi.c
@@ -84,7 +84,7 @@ int mpic_msi_init_allocator(struct mpic *mpic)
int rc;
rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->num_sources,
- mpic->irqhost->of_node);
+ irq_domain_get_of_node(mpic->irqhost));
if (rc)
return rc;
diff --git a/kernel/arch/powerpc/sysdev/mpic_pasemi_msi.c b/kernel/arch/powerpc/sysdev/mpic_pasemi_msi.c
deleted file mode 100644
index a3f660eed..000000000
--- a/kernel/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2007, Olof Johansson, PA Semi
- *
- * Based on arch/powerpc/sysdev/mpic_u3msi.c:
- *
- * Copyright 2006, Segher Boessenkool, IBM Corporation.
- * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2 of the
- * License.
- *
- */
-
-#undef DEBUG
-
-#include <linux/irq.h>
-#include <linux/msi.h>
-#include <asm/mpic.h>
-#include <asm/prom.h>
-#include <asm/hw_irq.h>
-#include <asm/ppc-pci.h>
-#include <asm/msi_bitmap.h>
-
-#include "mpic.h"
-
-/* Allocate 16 interrupts per device, to give an alignment of 16,
- * since that's the size of the grouping w.r.t. affinity. If someone
- * needs more than 32 MSI's down the road we'll have to rethink this,
- * but it should be OK for now.
- */
-#define ALLOC_CHUNK 16
-
-#define PASEMI_MSI_ADDR 0xfc080000
-
-/* A bit ugly, can we get this from the pci_dev somehow? */
-static struct mpic *msi_mpic;
-
-
-static void mpic_pasemi_msi_mask_irq(struct irq_data *data)
-{
- pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
- pci_msi_mask_irq(data);
- mpic_mask_irq(data);
-}
-
-static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
-{
- pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
- mpic_unmask_irq(data);
- pci_msi_unmask_irq(data);
-}
-
-static struct irq_chip mpic_pasemi_msi_chip = {
- .irq_shutdown = mpic_pasemi_msi_mask_irq,
- .irq_mask = mpic_pasemi_msi_mask_irq,
- .irq_unmask = mpic_pasemi_msi_unmask_irq,
- .irq_eoi = mpic_end_irq,
- .irq_set_type = mpic_set_irq_type,
- .irq_set_affinity = mpic_set_affinity,
- .name = "PASEMI-MSI",
-};
-
-static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
-{
- struct msi_desc *entry;
-
- pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);
-
- list_for_each_entry(entry, &pdev->msi_list, list) {
- if (entry->irq == NO_IRQ)
- continue;
-
- irq_set_msi_desc(entry->irq, NULL);
- msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
- virq_to_hw(entry->irq), ALLOC_CHUNK);
- irq_dispose_mapping(entry->irq);
- }
-
- return;
-}
-
-static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
-{
- unsigned int virq;
- struct msi_desc *entry;
- struct msi_msg msg;
- int hwirq;
-
- if (type == PCI_CAP_ID_MSIX)
- pr_debug("pasemi_msi: MSI-X untested, trying anyway\n");
- pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
- pdev, nvec, type);
-
- msg.address_hi = 0;
- msg.address_lo = PASEMI_MSI_ADDR;
-
- list_for_each_entry(entry, &pdev->msi_list, list) {
- /* Allocate 16 interrupts for now, since that's the grouping for
- * affinity. This can be changed later if it turns out 32 is too
- * few MSIs for someone, but restrictions will apply to how the
- * sources can be changed independently.
- */
- hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap,
- ALLOC_CHUNK);
- if (hwirq < 0) {
- pr_debug("pasemi_msi: failed allocating hwirq\n");
- return hwirq;
- }
-
- virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
- if (virq == NO_IRQ) {
- pr_debug("pasemi_msi: failed mapping hwirq 0x%x\n",
- hwirq);
- msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq,
- ALLOC_CHUNK);
- return -ENOSPC;
- }
-
- /* Vector on MSI is really an offset, the hardware adds
- * it to the value written at the magic address. So set
- * it to 0 to remain sane.
- */
- mpic_set_vector(virq, 0);
-
- irq_set_msi_desc(virq, entry);
- irq_set_chip(virq, &mpic_pasemi_msi_chip);
- irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
-
- pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%x) " \
- "addr 0x%x\n", virq, hwirq, msg.address_lo);
-
- /* Likewise, the device writes [0...511] into the target
- * register to generate MSI [512...1023]
- */
- msg.data = hwirq-0x200;
- pci_write_msi_msg(virq, &msg);
- }
-
- return 0;
-}
-
-int mpic_pasemi_msi_init(struct mpic *mpic)
-{
- int rc;
-
- if (!mpic->irqhost->of_node ||
- !of_device_is_compatible(mpic->irqhost->of_node,
- "pasemi,pwrficient-openpic"))
- return -ENODEV;
-
- rc = mpic_msi_init_allocator(mpic);
- if (rc) {
- pr_debug("pasemi_msi: Error allocating bitmap!\n");
- return rc;
- }
-
- pr_debug("pasemi_msi: Registering PA Semi MPIC MSI callbacks\n");
-
- msi_mpic = mpic;
- WARN_ON(ppc_md.setup_msi_irqs);
- ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs;
-
- return 0;
-}
diff --git a/kernel/arch/powerpc/sysdev/mpic_u3msi.c b/kernel/arch/powerpc/sysdev/mpic_u3msi.c
index b2cef1809..2cbc7e29b 100644
--- a/kernel/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/kernel/arch/powerpc/sysdev/mpic_u3msi.c
@@ -107,15 +107,16 @@ static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;
+ irq_hw_number_t hwirq;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
+ hwirq = virq_to_hw(entry->irq);
irq_set_msi_desc(entry->irq, NULL);
- msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
- virq_to_hw(entry->irq), 1);
irq_dispose_mapping(entry->irq);
+ msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
}
return;
@@ -140,7 +141,7 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return -ENXIO;
}
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
if (hwirq < 0) {
pr_debug("u3msi: failed allocating hwirq\n");
@@ -181,6 +182,7 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
int mpic_u3msi_init(struct mpic *mpic)
{
int rc;
+ struct pci_controller *phb;
rc = mpic_msi_init_allocator(mpic);
if (rc) {
@@ -193,9 +195,11 @@ int mpic_u3msi_init(struct mpic *mpic)
BUG_ON(msi_mpic);
msi_mpic = mpic;
- WARN_ON(ppc_md.setup_msi_irqs);
- ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs;
+ list_for_each_entry(phb, &hose_list, list_node) {
+ WARN_ON(phb->controller_ops.setup_msi_irqs);
+ phb->controller_ops.setup_msi_irqs = u3msi_setup_msi_irqs;
+ phb->controller_ops.teardown_msi_irqs = u3msi_teardown_msi_irqs;
+ }
return 0;
}
diff --git a/kernel/arch/powerpc/sysdev/msi_bitmap.c b/kernel/arch/powerpc/sysdev/msi_bitmap.c
index 73b64c735..ed5234ed8 100644
--- a/kernel/arch/powerpc/sysdev/msi_bitmap.c
+++ b/kernel/arch/powerpc/sysdev/msi_bitmap.c
@@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/bitmap.h>
+#include <linux/bootmem.h>
#include <asm/msi_bitmap.h>
#include <asm/setup.h>
@@ -111,7 +112,7 @@ int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp)
return 0;
}
-int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
+int __init_refok msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
struct device_node *of_node)
{
int size;
@@ -122,7 +123,15 @@ int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
size = BITS_TO_LONGS(irq_count) * sizeof(long);
pr_debug("msi_bitmap: allocator bitmap size is 0x%x bytes\n", size);
- bmp->bitmap = zalloc_maybe_bootmem(size, GFP_KERNEL);
+ bmp->bitmap_from_slab = slab_is_available();
+ if (bmp->bitmap_from_slab)
+ bmp->bitmap = kzalloc(size, GFP_KERNEL);
+ else {
+ bmp->bitmap = memblock_virt_alloc(size, 0);
+ /* the bitmap won't be freed from memblock allocator */
+ kmemleak_not_leak(bmp->bitmap);
+ }
+
if (!bmp->bitmap) {
pr_debug("msi_bitmap: ENOMEM allocating allocator bitmap!\n");
return -ENOMEM;
@@ -138,7 +147,8 @@ int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
void msi_bitmap_free(struct msi_bitmap *bmp)
{
- /* we can't free the bitmap we don't know if it's bootmem etc. */
+ if (bmp->bitmap_from_slab)
+ kfree(bmp->bitmap);
of_node_put(bmp->of_node);
bmp->bitmap = NULL;
}
@@ -203,8 +213,6 @@ static void __init test_basics(void)
/* Clients may WARN_ON bitmap == NULL for "not-allocated" */
WARN_ON(bmp.bitmap != NULL);
-
- kfree(bmp.bitmap);
}
static void __init test_of_node(void)
diff --git a/kernel/arch/powerpc/sysdev/mv64x60_pic.c b/kernel/arch/powerpc/sysdev/mv64x60_pic.c
index 8848e99a8..0f842dd16 100644
--- a/kernel/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/kernel/arch/powerpc/sysdev/mv64x60_pic.c
@@ -223,7 +223,7 @@ static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops mv64x60_host_ops = {
+static const struct irq_domain_ops mv64x60_host_ops = {
.map = mv64x60_host_map,
};
diff --git a/kernel/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/kernel/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
index f366d2d4c..52a93dcae 100644
--- a/kernel/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
+++ b/kernel/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
@@ -18,6 +18,7 @@
#include <linux/pci.h>
#include <linux/semaphore.h>
#include <asm/msi_bitmap.h>
+#include <asm/ppc-pci.h>
struct ppc4xx_hsta_msi {
struct device *dev;
@@ -50,7 +51,7 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return -EINVAL;
}
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1);
if (irq < 0) {
pr_debug("%s: Failed to allocate msi interrupt\n",
@@ -108,7 +109,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev)
struct msi_desc *entry;
int irq;
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;
@@ -128,9 +129,10 @@ static int hsta_msi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct resource *mem;
int irq, ret, irq_count;
+ struct pci_controller *phb;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (IS_ERR(mem)) {
+ if (!mem) {
dev_err(dev, "Unable to get mmio space\n");
return -EINVAL;
}
@@ -155,7 +157,7 @@ static int hsta_msi_probe(struct platform_device *pdev)
goto out;
ppc4xx_hsta_msi.irq_map = kmalloc(sizeof(int) * irq_count, GFP_KERNEL);
- if (IS_ERR(ppc4xx_hsta_msi.irq_map)) {
+ if (!ppc4xx_hsta_msi.irq_map) {
ret = -ENOMEM;
goto out1;
}
@@ -171,8 +173,10 @@ static int hsta_msi_probe(struct platform_device *pdev)
}
}
- ppc_md.setup_msi_irqs = hsta_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = hsta_teardown_msi_irqs;
+ list_for_each_entry(phb, &hose_list, list_node) {
+ phb->controller_ops.setup_msi_irqs = hsta_setup_msi_irqs;
+ phb->controller_ops.teardown_msi_irqs = hsta_teardown_msi_irqs;
+ }
return 0;
out2:
diff --git a/kernel/arch/powerpc/sysdev/ppc4xx_msi.c b/kernel/arch/powerpc/sysdev/ppc4xx_msi.c
index 6e2e6aa37..8fb806135 100644
--- a/kernel/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/kernel/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -93,7 +93,7 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (!msi_data->msi_virqs)
return -ENOMEM;
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
if (int_no >= 0)
break;
@@ -124,16 +124,17 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
struct ppc4xx_msi *msi_data = &ppc4xx_msi;
+ irq_hw_number_t hwirq;
dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;
+ hwirq = virq_to_hw(entry->irq);
irq_set_msi_desc(entry->irq, NULL);
- msi_bitmap_free_hwirqs(&msi_data->bitmap,
- virq_to_hw(entry->irq), 1);
irq_dispose_mapping(entry->irq);
+ msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
}
}
@@ -218,6 +219,7 @@ static int ppc4xx_msi_probe(struct platform_device *dev)
struct ppc4xx_msi *msi;
struct resource res;
int err = 0;
+ struct pci_controller *phb;
dev_dbg(&dev->dev, "PCIE-MSI: Setting up MSI support...\n");
@@ -250,8 +252,10 @@ static int ppc4xx_msi_probe(struct platform_device *dev)
}
ppc4xx_msi = *msi;
- ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs;
+ list_for_each_entry(phb, &hose_list, list_node) {
+ phb->controller_ops.setup_msi_irqs = ppc4xx_setup_msi_irqs;
+ phb->controller_ops.teardown_msi_irqs = ppc4xx_teardown_msi_irqs;
+ }
return err;
error_out:
diff --git a/kernel/arch/powerpc/sysdev/qe_lib/qe_ic.c b/kernel/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 543765e1e..ef36f16f9 100644
--- a/kernel/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/kernel/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -244,10 +244,12 @@ static struct irq_chip qe_ic_irq_chip = {
.irq_mask_ack = qe_ic_mask_irq,
};
-static int qe_ic_host_match(struct irq_domain *h, struct device_node *node)
+static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
+ enum irq_domain_bus_token bus_token)
{
/* Exact match, unless qe_ic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
@@ -271,7 +273,7 @@ static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops qe_ic_host_ops = {
+static const struct irq_domain_ops qe_ic_host_ops = {
.match = qe_ic_host_match,
.map = qe_ic_host_map,
.xlate = irq_domain_xlate_onetwocell,
@@ -310,8 +312,8 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
}
void __init qe_ic_init(struct device_node *node, unsigned int flags,
- void (*low_handler)(unsigned int irq, struct irq_desc *desc),
- void (*high_handler)(unsigned int irq, struct irq_desc *desc))
+ void (*low_handler)(struct irq_desc *desc),
+ void (*high_handler)(struct irq_desc *desc))
{
struct qe_ic *qe_ic;
struct resource res;
diff --git a/kernel/arch/powerpc/sysdev/tsi108_pci.c b/kernel/arch/powerpc/sysdev/tsi108_pci.c
index 188012c58..379de955a 100644
--- a/kernel/arch/powerpc/sysdev/tsi108_pci.c
+++ b/kernel/arch/powerpc/sysdev/tsi108_pci.c
@@ -397,7 +397,7 @@ static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops pci_irq_domain_ops = {
+static const struct irq_domain_ops pci_irq_domain_ops = {
.map = pci_irq_host_map,
.xlate = pci_irq_host_xlate,
};
@@ -428,7 +428,7 @@ void __init tsi108_pci_int_init(struct device_node *node)
init_pci_source();
}
-void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
+void tsi108_irq_cascade(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = get_pci_source();
diff --git a/kernel/arch/powerpc/sysdev/uic.c b/kernel/arch/powerpc/sysdev/uic.c
index 7c37157d4..6893d8f23 100644
--- a/kernel/arch/powerpc/sysdev/uic.c
+++ b/kernel/arch/powerpc/sysdev/uic.c
@@ -189,16 +189,16 @@ static int uic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops uic_host_ops = {
+static const struct irq_domain_ops uic_host_ops = {
.map = uic_host_map,
.xlate = irq_domain_xlate_twocell,
};
-void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
+static void uic_irq_cascade(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
struct irq_data *idata = irq_desc_get_irq_data(desc);
- struct uic *uic = irq_get_handler_data(virq);
+ struct uic *uic = irq_desc_get_handler_data(desc);
u32 msr;
int src;
int subvirq;
diff --git a/kernel/arch/powerpc/sysdev/xics/icp-native.c b/kernel/arch/powerpc/sysdev/xics/icp-native.c
index 2fc4cf1b7..eae32654b 100644
--- a/kernel/arch/powerpc/sysdev/xics/icp-native.c
+++ b/kernel/arch/powerpc/sysdev/xics/icp-native.c
@@ -147,12 +147,16 @@ static void icp_native_cause_ipi(int cpu, unsigned long data)
{
kvmppc_set_host_ipi(cpu, 1);
#ifdef CONFIG_PPC_DOORBELL
- if (cpu_has_feature(CPU_FTR_DBELL) &&
- (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id()))))
- doorbell_cause_ipi(cpu, data);
- else
+ if (cpu_has_feature(CPU_FTR_DBELL)) {
+ if (cpumask_test_cpu(cpu, cpu_sibling_mask(get_cpu()))) {
+ doorbell_cause_ipi(cpu, data);
+ put_cpu();
+ return;
+ }
+ put_cpu();
+ }
#endif
- icp_native_set_qirr(cpu, IPI_PRIORITY);
+ icp_native_set_qirr(cpu, IPI_PRIORITY);
}
/*
diff --git a/kernel/arch/powerpc/sysdev/xics/ics-opal.c b/kernel/arch/powerpc/sysdev/xics/ics-opal.c
index 68c7e5cc9..27c936c08 100644
--- a/kernel/arch/powerpc/sysdev/xics/ics-opal.c
+++ b/kernel/arch/powerpc/sysdev/xics/ics-opal.c
@@ -54,7 +54,7 @@ static void ics_opal_unmask_irq(struct irq_data *d)
if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
return;
- server = xics_get_irq_server(d->irq, d->affinity, 0);
+ server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
server = ics_opal_mangle_server(server);
rc = opal_set_xive(hw_irq, server, DEFAULT_PRIORITY);
@@ -72,7 +72,7 @@ static unsigned int ics_opal_startup(struct irq_data *d)
* card, using the MSI mask bits. Firmware doesn't appear to unmask
* at that level, so we do it here by hand.
*/
- if (d->msi_desc)
+ if (irq_data_get_msi_desc(d))
pci_msi_unmask_irq(d);
#endif
diff --git a/kernel/arch/powerpc/sysdev/xics/ics-rtas.c b/kernel/arch/powerpc/sysdev/xics/ics-rtas.c
index 0af97deb8..3854dd415 100644
--- a/kernel/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/kernel/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -47,7 +47,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
return;
- server = xics_get_irq_server(d->irq, d->affinity, 0);
+ server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
DEFAULT_PRIORITY);
@@ -75,7 +75,7 @@ static unsigned int ics_rtas_startup(struct irq_data *d)
* card, using the MSI mask bits. Firmware doesn't appear to unmask
* at that level, so we do it here by hand.
*/
- if (d->msi_desc)
+ if (irq_data_get_msi_desc(d))
pci_msi_unmask_irq(d);
#endif
/* unmask it */
diff --git a/kernel/arch/powerpc/sysdev/xics/xics-common.c b/kernel/arch/powerpc/sysdev/xics/xics-common.c
index 878a54036..47e43b7b0 100644
--- a/kernel/arch/powerpc/sysdev/xics/xics-common.c
+++ b/kernel/arch/powerpc/sysdev/xics/xics-common.c
@@ -227,7 +227,7 @@ void xics_migrate_irqs_away(void)
/* Locate interrupt server */
server = -1;
- ics = irq_get_chip_data(virq);
+ ics = irq_desc_get_chip_data(desc);
if (ics)
server = ics->get_server(ics, irq);
if (server < 0) {
@@ -298,7 +298,8 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
}
#endif /* CONFIG_SMP */
-static int xics_host_match(struct irq_domain *h, struct device_node *node)
+static int xics_host_match(struct irq_domain *h, struct device_node *node,
+ enum irq_domain_bus_token bus_token)
{
struct ics *ics;
@@ -360,7 +361,7 @@ static int xics_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops xics_host_ops = {
+static const struct irq_domain_ops xics_host_ops = {
.match = xics_host_match,
.map = xics_host_map,
.xlate = xics_host_xlate,
diff --git a/kernel/arch/powerpc/sysdev/xilinx_intc.c b/kernel/arch/powerpc/sysdev/xilinx_intc.c
index 56f0524e4..0f52d7955 100644
--- a/kernel/arch/powerpc/sysdev/xilinx_intc.c
+++ b/kernel/arch/powerpc/sysdev/xilinx_intc.c
@@ -179,7 +179,7 @@ static int xilinx_intc_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops xilinx_intc_ops = {
+static const struct irq_domain_ops xilinx_intc_ops = {
.map = xilinx_intc_map,
.xlate = xilinx_intc_xlate,
};
@@ -222,7 +222,7 @@ int xilinx_intc_get_irq(void)
/*
* Support code for cascading to 8259 interrupt controllers
*/
-static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
+static void xilinx_i8259_cascade(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();