Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 375553
b: refs/heads/master
c: 73ed148
h: refs/heads/master
i:
  375551: ce0d482
v: v3
  • Loading branch information
Benjamin Herrenschmidt committed May 10, 2013
1 parent 70f4b30 commit 8870ed7
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1de1455f33709a8afd8d41d26d09739a1148105b
refs/heads/master: 73ed148aea9dc0508be7e30e7a447f55c1b2f378
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/include/asm/opal.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,8 @@ extern void opal_nvram_init(void);

extern int opal_machine_check(struct pt_regs *regs);

extern void opal_shutdown(void);

#endif /* __ASSEMBLY__ */

#endif /* __OPAL_H */
17 changes: 17 additions & 0 deletions trunk/arch/powerpc/platforms/powernv/opal.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <asm/opal.h>
#include <asm/firmware.h>

Expand All @@ -28,6 +29,8 @@ struct opal {
static struct device_node *opal_node;
static DEFINE_SPINLOCK(opal_write_lock);
extern u64 opal_mc_secondary_handler[];
static unsigned int *opal_irqs;
static unsigned int opal_irq_count;

int __init early_init_dt_scan_opal(unsigned long node,
const char *uname, int depth, void *data)
Expand Down Expand Up @@ -323,6 +326,8 @@ static int __init opal_init(void)
irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
pr_debug("opal: Found %d interrupts reserved for OPAL\n",
irqs ? (irqlen / 4) : 0);
opal_irq_count = irqlen / 4;
opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
unsigned int hwirq = be32_to_cpup(irqs);
unsigned int irq = irq_create_mapping(NULL, hwirq);
Expand All @@ -334,7 +339,19 @@ static int __init opal_init(void)
if (rc)
pr_warning("opal: Error %d requesting irq %d"
" (0x%x)\n", rc, irq, hwirq);
opal_irqs[i] = irq;
}
return 0;
}
subsys_initcall(opal_init);

void opal_shutdown(void)
{
unsigned int i;

for (i = 0; i < opal_irq_count; i++) {
if (opal_irqs[i])
free_irq(opal_irqs[i], 0);
opal_irqs[i] = 0;
}
}
9 changes: 9 additions & 0 deletions trunk/arch/powerpc/platforms/powernv/pci-ioda.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,12 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus,
return phb->ioda.pe_rmap[(bus->number << 8) | devfn];
}

static void pnv_pci_ioda_shutdown(struct pnv_phb *phb)
{
opal_pci_reset(phb->opal_id, OPAL_PCI_IODA_TABLE_RESET,
OPAL_ASSERT_RESET);
}

void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type)
{
struct pci_controller *hose;
Expand Down Expand Up @@ -1178,6 +1184,9 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type)
/* Setup TCEs */
phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;

/* Setup shutdown function for kexec */
phb->shutdown = pnv_pci_ioda_shutdown;

/* Setup MSI support */
pnv_pci_init_ioda_msis(phb);

Expand Down
12 changes: 12 additions & 0 deletions trunk/arch/powerpc/platforms/powernv/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,18 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
pnv_pci_dma_fallback_setup(hose, pdev);
}

void pnv_pci_shutdown(void)
{
struct pci_controller *hose;

list_for_each_entry(hose, &hose_list, list_node) {
struct pnv_phb *phb = hose->private_data;

if (phb && phb->shutdown)
phb->shutdown(phb);
}
}

/* Fixup wrong class code in p7ioc and p8 root complex */
static void pnv_p7ioc_rc_quirk(struct pci_dev *dev)
{
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/platforms/powernv/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct pnv_phb {
void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
void (*fixup_phb)(struct pci_controller *hose);
u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
void (*shutdown)(struct pnv_phb *phb);

union {
struct {
Expand Down Expand Up @@ -158,4 +159,5 @@ extern void pnv_pci_init_ioda_hub(struct device_node *np);
extern void pnv_pci_init_ioda2_phb(struct device_node *np);
extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
u64 *startp, u64 *endp);

#endif /* __POWERNV_PCI_H */
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/platforms/powernv/powernv.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ static inline void pnv_smp_init(void) { }

#ifdef CONFIG_PCI
extern void pnv_pci_init(void);
extern void pnv_pci_shutdown(void);
#else
static inline void pnv_pci_init(void) { }
static inline void pnv_pci_shutdown(void) { }
#endif

#endif /* _POWERNV_H */
12 changes: 12 additions & 0 deletions trunk/arch/powerpc/platforms/powernv/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ static void pnv_progress(char *s, unsigned short hex)
{
}

static void pnv_shutdown(void)
{
/* Let the PCI code clear up IODA tables */
pnv_pci_shutdown();

/* And unregister all OPAL interrupts so they don't fire
* up while we kexec
*/
opal_shutdown();
}

#ifdef CONFIG_KEXEC
static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
{
Expand Down Expand Up @@ -187,6 +198,7 @@ define_machine(powernv) {
.init_IRQ = pnv_init_IRQ,
.show_cpuinfo = pnv_show_cpuinfo,
.progress = pnv_progress,
.machine_shutdown = pnv_shutdown,
.power_save = power7_idle,
.calibrate_decr = generic_calibrate_decr,
#ifdef CONFIG_KEXEC
Expand Down

0 comments on commit 8870ed7

Please sign in to comment.