On Mon, May 26, 2014 at 05:18:09PM +0200, Andreas Noever wrote: Please adjust the subject to match the drivers/pci convention, i.e., change pci: Add pci_fixup_suspend_late quirk pass. to PCI: Add pci_fixup_suspend_late quirk pass > Add pci_fixup_suspend_late as a new pci_fixup_pass. The pass is called > from suspend_noirq and poweroff_noirq. Using the same pass for suspend > and hibernate is consistent with resume_early which is called by > resume_noirq and restore_noirq. > > The new quirk pass is required for Thunderbolt support on Apple > hardware. > > Signed-off-by: Andreas Noever <andreas.noever@xxxxxxxxx> Acked-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> I assume you'll merge this along with the rest of the series, not through my PCI tree. Bjorn > --- > drivers/pci/pci-driver.c | 18 ++++++++++++++---- > drivers/pci/quirks.c | 7 +++++++ > include/asm-generic/vmlinux.lds.h | 3 +++ > include/linux/pci.h | 12 +++++++++++- > 4 files changed, 35 insertions(+), 5 deletions(-) > > diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c > index d911e0c..55dc1b8 100644 > --- a/drivers/pci/pci-driver.c > +++ b/drivers/pci/pci-driver.c > @@ -542,7 +542,7 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) > WARN_ONCE(pci_dev->current_state != prev, > "PCI PM: Device state not saved by %pF\n", > drv->suspend_late); > - return 0; > + goto Fixup; > } > } > > @@ -551,6 +551,9 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) > > pci_pm_set_unknown_state(pci_dev); > > +Fixup: > + pci_fixup_device(pci_fixup_suspend_late, pci_dev); > + > return 0; > } > > @@ -694,7 +697,7 @@ static int pci_pm_suspend_noirq(struct device *dev) > > if (!pm) { > pci_save_state(pci_dev); > - return 0; > + goto Fixup; > } > > if (pm->suspend_noirq) { > @@ -711,7 +714,7 @@ static int pci_pm_suspend_noirq(struct device *dev) > WARN_ONCE(pci_dev->current_state != prev, > "PCI PM: State of device not saved by %pF\n", > pm->suspend_noirq); > - return 0; > + goto Fixup; > } > } > > @@ -735,6 +738,9 @@ static int pci_pm_suspend_noirq(struct device *dev) > if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) > pci_write_config_word(pci_dev, PCI_COMMAND, 0); > > +Fixup: > + pci_fixup_device(pci_fixup_suspend_late, pci_dev); > + > return 0; > } > > @@ -959,8 +965,10 @@ static int pci_pm_poweroff_noirq(struct device *dev) > if (pci_has_legacy_pm_support(to_pci_dev(dev))) > return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); > > - if (!drv || !drv->pm) > + if (!drv || !drv->pm) { > + pci_fixup_device(pci_fixup_suspend_late, pci_dev); > return 0; > + } > > if (drv->pm->poweroff_noirq) { > int error; > @@ -981,6 +989,8 @@ static int pci_pm_poweroff_noirq(struct device *dev) > if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) > pci_write_config_word(pci_dev, PCI_COMMAND, 0); > > + pci_fixup_device(pci_fixup_suspend_late, pci_dev); > + > if (pcibios_pm_ops.poweroff_noirq) > return pcibios_pm_ops.poweroff_noirq(dev); > > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c > index e729206..af2eba1 100644 > --- a/drivers/pci/quirks.c > +++ b/drivers/pci/quirks.c > @@ -3024,6 +3024,8 @@ extern struct pci_fixup __start_pci_fixups_resume_early[]; > extern struct pci_fixup __end_pci_fixups_resume_early[]; > extern struct pci_fixup __start_pci_fixups_suspend[]; > extern struct pci_fixup __end_pci_fixups_suspend[]; > +extern struct pci_fixup __start_pci_fixups_suspend_late[]; > +extern struct pci_fixup __end_pci_fixups_suspend_late[]; > > static bool pci_apply_fixup_final_quirks; > > @@ -3069,6 +3071,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) > end = __end_pci_fixups_suspend; > break; > > + case pci_fixup_suspend_late: > + start = __start_pci_fixups_suspend_late; > + end = __end_pci_fixups_suspend_late; > + break; > + > default: > /* stupid compiler warning, you would think with an enum... */ > return; > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h > index 146e4ff..2dea636 100644 > --- a/include/asm-generic/vmlinux.lds.h > +++ b/include/asm-generic/vmlinux.lds.h > @@ -288,6 +288,9 @@ > VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \ > *(.pci_fixup_suspend) \ > VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \ > + VMLINUX_SYMBOL(__start_pci_fixups_suspend_late) = .; \ > + *(.pci_fixup_suspend_late) \ > + VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \ > } \ > \ > /* Built-in firmware blobs */ \ > diff --git a/include/linux/pci.h b/include/linux/pci.h > index aab57b4..4724806 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -1458,8 +1458,9 @@ enum pci_fixup_pass { > pci_fixup_final, /* Final phase of device fixups */ > pci_fixup_enable, /* pci_enable_device() time */ > pci_fixup_resume, /* pci_device_resume() */ > - pci_fixup_suspend, /* pci_device_suspend */ > + pci_fixup_suspend, /* pci_device_suspend() */ > pci_fixup_resume_early, /* pci_device_resume_early() */ > + pci_fixup_suspend_late, /* pci_device_suspend_late() */ > }; > > /* Anonymous variables would be nice... */ > @@ -1500,6 +1501,11 @@ enum pci_fixup_pass { > DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ > suspend##hook, vendor, device, class, \ > class_shift, hook) > +#define DECLARE_PCI_FIXUP_CLASS_SUSPEND_LATE(vendor, device, class, \ > + class_shift, hook) \ > + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend_late, \ > + suspend_late##hook, vendor, device, \ > + class, class_shift, hook) > > #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ > DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ > @@ -1525,6 +1531,10 @@ enum pci_fixup_pass { > DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ > suspend##hook, vendor, device, \ > PCI_ANY_ID, 0, hook) > +#define DECLARE_PCI_FIXUP_SUSPEND_LATE(vendor, device, hook) \ > + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend_late, \ > + suspend_late##hook, vendor, device, \ > + PCI_ANY_ID, 0, hook) > > #ifdef CONFIG_PCI_QUIRKS > void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); > -- > 1.9.3 > -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html