Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git
Freescale updates from Scott (27 commits): "Highlights include DMA32 zone support (SATA, USB, etc now works on 64-bit FSL kernels), MSI changes, 8xx optimizations and cleanup, t104x board support, and PrPMC PCI enumeration."
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/hw_irq.h>
|
||||
@@ -50,6 +52,7 @@ struct fsl_msi_feature {
|
||||
struct fsl_msi_cascade_data {
|
||||
struct fsl_msi *msi_data;
|
||||
int index;
|
||||
int virq;
|
||||
};
|
||||
|
||||
static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
|
||||
@@ -65,11 +68,24 @@ static void fsl_msi_end_irq(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static void fsl_msi_print_chip(struct irq_data *irqd, struct seq_file *p)
|
||||
{
|
||||
struct fsl_msi *msi_data = irqd->domain->host_data;
|
||||
irq_hw_number_t hwirq = irqd_to_hwirq(irqd);
|
||||
int cascade_virq, srs;
|
||||
|
||||
srs = (hwirq >> msi_data->srs_shift) & MSI_SRS_MASK;
|
||||
cascade_virq = msi_data->cascade_array[srs]->virq;
|
||||
|
||||
seq_printf(p, " fsl-msi-%d", cascade_virq);
|
||||
}
|
||||
|
||||
|
||||
static struct irq_chip fsl_msi_chip = {
|
||||
.irq_mask = mask_msi_irq,
|
||||
.irq_unmask = unmask_msi_irq,
|
||||
.irq_ack = fsl_msi_end_irq,
|
||||
.name = "FSL-MSI",
|
||||
.irq_print_chip = fsl_msi_print_chip,
|
||||
};
|
||||
|
||||
static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
|
||||
@@ -180,7 +196,8 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||
np = of_parse_phandle(hose->dn, "fsl,msi", 0);
|
||||
if (np) {
|
||||
if (of_device_is_compatible(np, "fsl,mpic-msi") ||
|
||||
of_device_is_compatible(np, "fsl,vmpic-msi"))
|
||||
of_device_is_compatible(np, "fsl,vmpic-msi") ||
|
||||
of_device_is_compatible(np, "fsl,vmpic-msi-v4.3"))
|
||||
phandle = np->phandle;
|
||||
else {
|
||||
dev_err(&pdev->dev,
|
||||
@@ -239,40 +256,24 @@ out_free:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
static irqreturn_t fsl_msi_cascade(int irq, void *data)
|
||||
{
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct irq_data *idata = irq_desc_get_irq_data(desc);
|
||||
unsigned int cascade_irq;
|
||||
struct fsl_msi *msi_data;
|
||||
int msir_index = -1;
|
||||
u32 msir_value = 0;
|
||||
u32 intr_index;
|
||||
u32 have_shift = 0;
|
||||
struct fsl_msi_cascade_data *cascade_data;
|
||||
struct fsl_msi_cascade_data *cascade_data = data;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
cascade_data = irq_get_handler_data(irq);
|
||||
msi_data = cascade_data->msi_data;
|
||||
|
||||
raw_spin_lock(&desc->lock);
|
||||
if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
|
||||
if (chip->irq_mask_ack)
|
||||
chip->irq_mask_ack(idata);
|
||||
else {
|
||||
chip->irq_mask(idata);
|
||||
chip->irq_ack(idata);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(irqd_irq_inprogress(idata)))
|
||||
goto unlock;
|
||||
|
||||
msir_index = cascade_data->index;
|
||||
|
||||
if (msir_index >= NR_MSI_REG_MAX)
|
||||
cascade_irq = NO_IRQ;
|
||||
|
||||
irqd_set_chained_irq_inprogress(idata);
|
||||
switch (msi_data->feature & FSL_PIC_IP_MASK) {
|
||||
case FSL_PIC_IP_MPIC:
|
||||
msir_value = fsl_msi_read(msi_data->msi_regs,
|
||||
@@ -301,40 +302,32 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
cascade_irq = irq_linear_revmap(msi_data->irqhost,
|
||||
msi_hwirq(msi_data, msir_index,
|
||||
intr_index + have_shift));
|
||||
if (cascade_irq != NO_IRQ)
|
||||
if (cascade_irq != NO_IRQ) {
|
||||
generic_handle_irq(cascade_irq);
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
have_shift += intr_index + 1;
|
||||
msir_value = msir_value >> (intr_index + 1);
|
||||
}
|
||||
irqd_clr_chained_irq_inprogress(idata);
|
||||
|
||||
switch (msi_data->feature & FSL_PIC_IP_MASK) {
|
||||
case FSL_PIC_IP_MPIC:
|
||||
case FSL_PIC_IP_VMPIC:
|
||||
chip->irq_eoi(idata);
|
||||
break;
|
||||
case FSL_PIC_IP_IPIC:
|
||||
if (!irqd_irq_disabled(idata) && chip->irq_unmask)
|
||||
chip->irq_unmask(idata);
|
||||
break;
|
||||
}
|
||||
unlock:
|
||||
raw_spin_unlock(&desc->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_of_msi_remove(struct platform_device *ofdev)
|
||||
{
|
||||
struct fsl_msi *msi = platform_get_drvdata(ofdev);
|
||||
int virq, i;
|
||||
struct fsl_msi_cascade_data *cascade_data;
|
||||
|
||||
if (msi->list.prev != NULL)
|
||||
list_del(&msi->list);
|
||||
for (i = 0; i < NR_MSI_REG_MAX; i++) {
|
||||
virq = msi->msi_virqs[i];
|
||||
if (virq != NO_IRQ) {
|
||||
cascade_data = irq_get_handler_data(virq);
|
||||
kfree(cascade_data);
|
||||
if (msi->cascade_array[i]) {
|
||||
virq = msi->cascade_array[i]->virq;
|
||||
|
||||
BUG_ON(virq == NO_IRQ);
|
||||
|
||||
free_irq(virq, msi->cascade_array[i]);
|
||||
kfree(msi->cascade_array[i]);
|
||||
irq_dispose_mapping(virq);
|
||||
}
|
||||
}
|
||||
@@ -353,7 +346,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev,
|
||||
int offset, int irq_index)
|
||||
{
|
||||
struct fsl_msi_cascade_data *cascade_data = NULL;
|
||||
int virt_msir, i;
|
||||
int virt_msir, i, ret;
|
||||
|
||||
virt_msir = irq_of_parse_and_map(dev->dev.of_node, irq_index);
|
||||
if (virt_msir == NO_IRQ) {
|
||||
@@ -368,11 +361,18 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev,
|
||||
return -ENOMEM;
|
||||
}
|
||||
irq_set_lockdep_class(virt_msir, &fsl_msi_irq_class);
|
||||
msi->msi_virqs[irq_index] = virt_msir;
|
||||
cascade_data->index = offset;
|
||||
cascade_data->msi_data = msi;
|
||||
irq_set_handler_data(virt_msir, cascade_data);
|
||||
irq_set_chained_handler(virt_msir, fsl_msi_cascade);
|
||||
cascade_data->virq = virt_msir;
|
||||
msi->cascade_array[irq_index] = cascade_data;
|
||||
|
||||
ret = request_irq(virt_msir, fsl_msi_cascade, 0,
|
||||
"fsl-msi-cascade", cascade_data);
|
||||
if (ret) {
|
||||
dev_err(&dev->dev, "failed to request_irq(%d), ret = %d\n",
|
||||
virt_msir, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Release the hwirqs corresponding to this MSI register */
|
||||
for (i = 0; i < IRQS_PER_MSI_REG; i++)
|
||||
@@ -466,7 +466,8 @@ static int fsl_of_msi_probe(struct platform_device *dev)
|
||||
|
||||
p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
|
||||
|
||||
if (of_device_is_compatible(dev->dev.of_node, "fsl,mpic-msi-v4.3")) {
|
||||
if (of_device_is_compatible(dev->dev.of_node, "fsl,mpic-msi-v4.3") ||
|
||||
of_device_is_compatible(dev->dev.of_node, "fsl,vmpic-msi-v4.3")) {
|
||||
msi->srs_shift = MSIIR1_SRS_SHIFT;
|
||||
msi->ibs_shift = MSIIR1_IBS_SHIFT;
|
||||
if (p)
|
||||
@@ -572,6 +573,10 @@ static const struct of_device_id fsl_of_msi_ids[] = {
|
||||
.compatible = "fsl,vmpic-msi",
|
||||
.data = &vmpic_msi_feature,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,vmpic-msi-v4.3",
|
||||
.data = &vmpic_msi_feature,
|
||||
},
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
@@ -27,6 +27,8 @@
|
||||
#define FSL_PIC_IP_IPIC 0x00000002
|
||||
#define FSL_PIC_IP_VMPIC 0x00000003
|
||||
|
||||
struct fsl_msi_cascade_data;
|
||||
|
||||
struct fsl_msi {
|
||||
struct irq_domain *irqhost;
|
||||
|
||||
@@ -37,7 +39,7 @@ struct fsl_msi {
|
||||
u32 srs_shift; /* Shift of the shared interrupt register select */
|
||||
void __iomem *msi_regs;
|
||||
u32 feature;
|
||||
int msi_virqs[NR_MSI_REG_MAX];
|
||||
struct fsl_msi_cascade_data *cascade_array[NR_MSI_REG_MAX];
|
||||
|
||||
struct msi_bitmap bitmap;
|
||||
|
||||
|
@@ -522,7 +522,8 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
|
||||
} else {
|
||||
/* For PCI read PROG to identify controller mode */
|
||||
early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
|
||||
if ((progif & 1) == 1)
|
||||
if ((progif & 1) &&
|
||||
!of_property_read_bool(dev, "fsl,pci-agent-force-enum"))
|
||||
goto no_bridge;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user