diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-12-12 22:39:59 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-12-12 22:39:59 +0100 |
commit | 79dbddaf8e9613a529d1b07f181f07894bf6fb8e (patch) | |
tree | 964ba851b4db3083a91cb4a7e921c6597011637f /arch | |
parent | Merge branch 'akpm' (patches from Andrew) (diff) | |
parent | Revert "powerpc/eeh: Don't unfreeze PHB PE after reset" (diff) | |
download | linux-79dbddaf8e9613a529d1b07f181f07894bf6fb8e.tar.xz linux-79dbddaf8e9613a529d1b07f181f07894bf6fb8e.zip |
Merge tag 'powerpc-4.4-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman:
- opal-irqchip: Fix double endian conversion from Alistair Popple
- cxl: Set endianess of kernel contexts from Frederic Barrat
- sbc8641: drop bogus PHY IRQ entries from DTS file from Paul Gortmaker
- Revert "powerpc/eeh: Don't unfreeze PHB PE after reset" from Andrew
Donnellan
* tag 'powerpc-4.4-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
Revert "powerpc/eeh: Don't unfreeze PHB PE after reset"
powerpc/sbc8641: drop bogus PHY IRQ entries from DTS file
cxl: Set endianess of kernel contexts
powerpc/opal-irqchip: Fix double endian conversion
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/boot/dts/sbc8641d.dts | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-irqchip.c | 58 |
3 files changed, 33 insertions, 47 deletions
diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts index 631ede72e226..68f0ed7626bd 100644 --- a/arch/powerpc/boot/dts/sbc8641d.dts +++ b/arch/powerpc/boot/dts/sbc8641d.dts @@ -227,23 +227,15 @@ reg = <0x520 0x20>; phy0: ethernet-phy@1f { - interrupt-parent = <&mpic>; - interrupts = <10 1>; reg = <0x1f>; }; phy1: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; reg = <0>; }; phy2: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; reg = <1>; }; phy3: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; reg = <2>; }; tbi0: tbi-phy@11 { diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 80dfe8965df9..8d14feb40f12 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -590,16 +590,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) eeh_ops->configure_bridge(pe); eeh_pe_restore_bars(pe); - /* - * If it's PHB PE, the frozen state on all available PEs should have - * been cleared by the PHB reset. Otherwise, we unfreeze the PE and its - * child PEs because they might be in frozen state. - */ - if (!(pe->type & EEH_PE_PHB)) { - rc = eeh_clear_pe_frozen_state(pe, false); - if (rc) - return rc; - } + /* Clear frozen state */ + rc = eeh_clear_pe_frozen_state(pe, false); + if (rc) + return rc; /* Give the system 5 seconds to finish running the user-space * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c index 6ccfb6c1c707..0a00e2aed393 100644 --- a/arch/powerpc/platforms/powernv/opal-irqchip.c +++ b/arch/powerpc/platforms/powernv/opal-irqchip.c @@ -43,11 +43,34 @@ static unsigned int opal_irq_count; static unsigned int *opal_irqs; static void opal_handle_irq_work(struct irq_work *work); -static __be64 last_outstanding_events; +static u64 last_outstanding_events; static struct irq_work opal_event_irq_work = { .func = opal_handle_irq_work, }; +void opal_handle_events(uint64_t events) +{ + int virq, hwirq = 0; + u64 mask = opal_event_irqchip.mask; + + if (!in_irq() && (events & mask)) { + last_outstanding_events = events; + irq_work_queue(&opal_event_irq_work); + return; + } + + while (events & mask) { + hwirq = fls64(events) - 1; + if (BIT_ULL(hwirq) & mask) { + virq = irq_find_mapping(opal_event_irqchip.domain, + hwirq); + if (virq) + generic_handle_irq(virq); + } + events &= ~BIT_ULL(hwirq); + } +} + static void opal_event_mask(struct irq_data *d) { clear_bit(d->hwirq, &opal_event_irqchip.mask); @@ -55,12 +78,12 @@ static void opal_event_mask(struct irq_data *d) static void opal_event_unmask(struct irq_data *d) { + __be64 events; + set_bit(d->hwirq, &opal_event_irqchip.mask); - opal_poll_events(&last_outstanding_events); - if (last_outstanding_events & opal_event_irqchip.mask) - /* Need to retrigger the interrupt */ - irq_work_queue(&opal_event_irq_work); + opal_poll_events(&events); + opal_handle_events(be64_to_cpu(events)); } static int opal_event_set_type(struct irq_data *d, unsigned int flow_type) @@ -96,29 +119,6 @@ static int opal_event_map(struct irq_domain *d, unsigned int irq, return 0; } -void opal_handle_events(uint64_t events) -{ - int virq, hwirq = 0; - u64 mask = opal_event_irqchip.mask; - - if (!in_irq() && (events & mask)) { - last_outstanding_events = events; - irq_work_queue(&opal_event_irq_work); - return; - } - - while (events & mask) { - hwirq = fls64(events) - 1; - if (BIT_ULL(hwirq) & mask) { - virq = irq_find_mapping(opal_event_irqchip.domain, - hwirq); - if (virq) - generic_handle_irq(virq); - } - events &= ~BIT_ULL(hwirq); - } -} - static irqreturn_t opal_interrupt(int irq, void *data) { __be64 events; @@ -131,7 +131,7 @@ static irqreturn_t opal_interrupt(int irq, void *data) static void opal_handle_irq_work(struct irq_work *work) { - opal_handle_events(be64_to_cpu(last_outstanding_events)); + opal_handle_events(last_outstanding_events); } static int opal_event_match(struct irq_domain *h, struct device_node *node, |