Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions arch/powerpc/include/asm/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,6 @@ struct machdep_calls {
/* To setup PHBs when using automatic OF platform driver for PCI */
int (*pci_setup_phb)(struct pci_controller *host);

#ifdef CONFIG_PCI_MSI
int (*setup_msi_irqs)(struct pci_dev *dev,
int nvec, int type);
void (*teardown_msi_irqs)(struct pci_dev *dev);
#endif

void (*restart)(char *cmd);
void (*halt)(void);
void (*panic)(char *str);
Expand Down
8 changes: 8 additions & 0 deletions arch/powerpc/include/asm/pci-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ struct pci_controller_ops {
/* Called during PCI resource reassignment */
resource_size_t (*window_alignment)(struct pci_bus *, unsigned long type);
void (*reset_secondary_bus)(struct pci_dev *dev);

#ifdef CONFIG_PCI_MSI
int (*setup_msi_irqs)(struct pci_dev *dev,
int nvec, int type);
void (*teardown_msi_irqs)(struct pci_dev *dev);
#endif

int (*dma_set_mask)(struct pci_dev *dev, u64 dma_mask);
};

/*
Expand Down
8 changes: 8 additions & 0 deletions arch/powerpc/kernel/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,14 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
{
if (ppc_md.dma_set_mask)
return ppc_md.dma_set_mask(dev, dma_mask);

if (dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_controller *phb = pci_bus_to_host(pdev->bus);
if (phb->controller_ops.dma_set_mask)
return phb->controller_ops.dma_set_mask(pdev, dma_mask);
}

return __dma_set_mask(dev, dma_mask);
}
EXPORT_SYMBOL(dma_set_mask);
Expand Down
11 changes: 8 additions & 3 deletions arch/powerpc/kernel/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@

int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
struct pci_controller *phb = pci_bus_to_host(dev->bus);

if (!phb->controller_ops.setup_msi_irqs ||
!phb->controller_ops.teardown_msi_irqs) {
pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
return -ENOSYS;
}
Expand All @@ -24,10 +27,12 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

return ppc_md.setup_msi_irqs(dev, nvec, type);
return phb->controller_ops.setup_msi_irqs(dev, nvec, type);
}

void arch_teardown_msi_irqs(struct pci_dev *dev)
{
ppc_md.teardown_msi_irqs(dev);
struct pci_controller *phb = pci_bus_to_host(dev->bus);

phb->controller_ops.teardown_msi_irqs(dev);
}
5 changes: 3 additions & 2 deletions arch/powerpc/platforms/cell/axon_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <asm/machdep.h>
#include <asm/prom.h>

#include "cell.h"

/*
* MSIC registers, specified as offsets from dcr_base
Expand Down Expand Up @@ -406,8 +407,8 @@ static int axon_msi_probe(struct platform_device *device)

dev_set_drvdata(&device->dev, msic);

ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
cell_pci_controller_ops.setup_msi_irqs = axon_msi_setup_msi_irqs;
cell_pci_controller_ops.teardown_msi_irqs = axon_msi_teardown_msi_irqs;

axon_msi_debug_setup(dn, msic);

Expand Down
9 changes: 6 additions & 3 deletions arch/powerpc/platforms/pasemi/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
int mpic_pasemi_msi_init(struct mpic *mpic)
{
int rc;
struct pci_controller *phb;

if (!mpic->irqhost->of_node ||
!of_device_is_compatible(mpic->irqhost->of_node,
Expand All @@ -157,9 +158,11 @@ int mpic_pasemi_msi_init(struct mpic *mpic)
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;
list_for_each_entry(phb, &hose_list, list_node) {
WARN_ON(phb->controller_ops.setup_msi_irqs);
phb->controller_ops.setup_msi_irqs = pasemi_msi_setup_msi_irqs;
phb->controller_ops.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs;
}

return 0;
}
23 changes: 16 additions & 7 deletions arch/powerpc/platforms/powernv/pci-ioda.c
Original file line number Diff line number Diff line change
Expand Up @@ -1601,9 +1601,10 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev
set_iommu_table_base_and_group(&pdev->dev, pe->tce32_table);
}

static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
struct pci_dev *pdev, u64 dma_mask)
static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
struct pci_dn *pdn = pci_get_pdn(pdev);
struct pnv_ioda_pe *pe;
uint64_t top;
Expand Down Expand Up @@ -2648,6 +2649,18 @@ static void pnv_pci_ioda_shutdown(struct pnv_phb *phb)
OPAL_ASSERT_RESET);
}

static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
.dma_dev_setup = pnv_pci_dma_dev_setup,
#ifdef CONFIG_PCI_MSI
.setup_msi_irqs = pnv_setup_msi_irqs,
.teardown_msi_irqs = pnv_teardown_msi_irqs,
#endif
.enable_device_hook = pnv_pci_enable_device_hook,
.window_alignment = pnv_pci_window_alignment,
.reset_secondary_bus = pnv_pci_reset_secondary_bus,
.dma_set_mask = pnv_pci_ioda_dma_set_mask,
};

static void __init pnv_pci_init_ioda_phb(struct device_node *np,
u64 hub_id, int ioda_type)
{
Expand Down Expand Up @@ -2791,7 +2804,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,

/* Setup TCEs */
phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
phb->dma_set_mask = pnv_pci_ioda_dma_set_mask;
phb->dma_get_required_mask = pnv_pci_ioda_dma_get_required_mask;

/* Setup shutdown function for kexec */
Expand All @@ -2808,10 +2820,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
* the child P2P bridges) can form individual PE.
*/
ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
pnv_pci_controller_ops.enable_device_hook = pnv_pci_enable_device_hook;
pnv_pci_controller_ops.window_alignment = pnv_pci_window_alignment;
pnv_pci_controller_ops.reset_secondary_bus = pnv_pci_reset_secondary_bus;
hose->controller_ops = pnv_pci_controller_ops;
hose->controller_ops = pnv_pci_ioda_controller_ops;

#ifdef CONFIG_PCI_IOV
ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
Expand Down
10 changes: 9 additions & 1 deletion arch/powerpc/platforms/powernv/pci-p5ioc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
set_iommu_table_base_and_group(&pdev->dev, &phb->p5ioc2.iommu_table);
}

static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = {
.dma_dev_setup = pnv_pci_dma_dev_setup,
#ifdef CONFIG_PCI_MSI
.setup_msi_irqs = pnv_setup_msi_irqs,
.teardown_msi_irqs = pnv_teardown_msi_irqs,
#endif
};

static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
void *tce_mem, u64 tce_size)
{
Expand Down Expand Up @@ -133,7 +141,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
phb->hose->first_busno = 0;
phb->hose->last_busno = 0xff;
phb->hose->private_data = phb;
phb->hose->controller_ops = pnv_pci_controller_ops;
phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops;
phb->hub_id = hub_id;
phb->opal_id = phb_id;
phb->type = PNV_PHB_P5IOC2;
Expand Down
26 changes: 3 additions & 23 deletions arch/powerpc/platforms/powernv/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
//#define cfg_dbg(fmt...) printk(fmt)

#ifdef CONFIG_PCI_MSI
static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
Expand Down Expand Up @@ -94,7 +94,7 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return 0;
}

static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
void pnv_teardown_msi_irqs(struct pci_dev *pdev)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
Expand Down Expand Up @@ -662,7 +662,7 @@ void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
tbl->it_type = TCE_PCI;
}

static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
Expand All @@ -689,16 +689,6 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
phb->dma_dev_setup(phb, pdev);
}

int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;

if (phb && phb->dma_set_mask)
return phb->dma_set_mask(phb, pdev, dma_mask);
return __dma_set_mask(&pdev->dev, dma_mask);
}

u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
Expand Down Expand Up @@ -768,16 +758,6 @@ void __init pnv_pci_init(void)
ppc_md.tce_free_rm = pnv_tce_free_rm;
ppc_md.tce_get = pnv_tce_get;
set_pci_dma_ops(&dma_iommu_ops);

/* Configure MSIs */
#ifdef CONFIG_PCI_MSI
ppc_md.setup_msi_irqs = pnv_setup_msi_irqs;
ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
#endif
}

machine_subsys_initcall_sync(powernv, tce_iommu_bus_notifier_init);

struct pci_controller_ops pnv_pci_controller_ops = {
.dma_dev_setup = pnv_pci_dma_dev_setup,
};
6 changes: 4 additions & 2 deletions arch/powerpc/platforms/powernv/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ struct pnv_phb {
unsigned int hwirq, unsigned int virq,
unsigned int is_64, struct msi_msg *msg);
void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
int (*dma_set_mask)(struct pnv_phb *phb, struct pci_dev *pdev,
u64 dma_mask);
u64 (*dma_get_required_mask)(struct pnv_phb *phb,
struct pci_dev *pdev);
void (*fixup_phb)(struct pci_controller *hose);
Expand Down Expand Up @@ -218,4 +216,8 @@ extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);

extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);

#endif /* __POWERNV_PCI_H */
8 changes: 0 additions & 8 deletions arch/powerpc/platforms/powernv/powernv.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,17 @@ struct pci_dev;
#ifdef CONFIG_PCI
extern void pnv_pci_init(void);
extern void pnv_pci_shutdown(void);
extern int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask);
extern u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev);
#else
static inline void pnv_pci_init(void) { }
static inline void pnv_pci_shutdown(void) { }

static inline int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
{
return -ENODEV;
}

static inline u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev)
{
return 0;
}
#endif

extern struct pci_controller_ops pnv_pci_controller_ops;

extern u32 pnv_get_supported_cpuidle_states(void);

extern void pnv_lpc_init(void);
Expand Down
8 changes: 0 additions & 8 deletions arch/powerpc/platforms/powernv/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,6 @@ static void pnv_progress(char *s, unsigned short hex)
{
}

static int pnv_dma_set_mask(struct device *dev, u64 dma_mask)
{
if (dev_is_pci(dev))
return pnv_pci_dma_set_mask(to_pci_dev(dev), dma_mask);
return __dma_set_mask(dev, dma_mask);
}

static u64 pnv_dma_get_required_mask(struct device *dev)
{
if (dev_is_pci(dev))
Expand Down Expand Up @@ -492,7 +485,6 @@ define_machine(powernv) {
.machine_shutdown = pnv_shutdown,
.power_save = power7_idle,
.calibrate_decr = generic_calibrate_decr,
.dma_set_mask = pnv_dma_set_mask,
.dma_get_required_mask = pnv_dma_get_required_mask,
#ifdef CONFIG_KEXEC
.kexec_cpu_down = pnv_kexec_cpu_down,
Expand Down
8 changes: 5 additions & 3 deletions arch/powerpc/platforms/pseries/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <asm/ppc-pci.h>
#include <asm/machdep.h>

#include "pseries.h"

static int query_token, change_token;

#define RTAS_QUERY_FN 0
Expand Down Expand Up @@ -516,9 +518,9 @@ static int rtas_msi_init(void)

pr_debug("rtas_msi: Registering RTAS MSI callbacks.\n");

WARN_ON(ppc_md.setup_msi_irqs);
ppc_md.setup_msi_irqs = rtas_setup_msi_irqs;
ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs;
WARN_ON(pseries_pci_controller_ops.setup_msi_irqs);
pseries_pci_controller_ops.setup_msi_irqs = rtas_setup_msi_irqs;
pseries_pci_controller_ops.teardown_msi_irqs = rtas_teardown_msi_irqs;

WARN_ON(ppc_md.pci_irq_fixup);
ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup;
Expand Down
23 changes: 15 additions & 8 deletions arch/powerpc/sysdev/fsl_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,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)
Expand Down Expand Up @@ -541,14 +542,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:
Expand Down
9 changes: 6 additions & 3 deletions arch/powerpc/sysdev/mpic_u3msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,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) {
Expand All @@ -193,9 +194,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;
}
Loading