diff mbox

[v3,12/15] pci: Add pci_fixup_suspend_late quirk pass.

Message ID 1401117492-2870-13-git-send-email-andreas.noever@gmail.com (mailing list archive)
State New, archived
Delegated to: Bjorn Helgaas
Headers show

Commit Message

Andreas Noever May 26, 2014, 3:18 p.m. UTC
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@gmail.com>
---
 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(-)

Comments

Bjorn Helgaas May 28, 2014, 10:36 p.m. UTC | #1
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@gmail.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

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@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andreas Noever May 30, 2014, 2:33 p.m. UTC | #2
On Thu, May 29, 2014 at 12:36 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> 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@gmail.com>
>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>

Thanks for reading through the series. I will make those changes for
the next version.

> I assume you'll merge this along with the rest of the series, not through
> my PCI tree.
Agreed, since I am the only user of this pass. Can you tell me whose
tree normally carries new drivers?

Thanks,
Andreas
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Greg KH May 30, 2014, 4:09 p.m. UTC | #3
On Fri, May 30, 2014 at 04:33:20PM +0200, Andreas Noever wrote:
> On Thu, May 29, 2014 at 12:36 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> > 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@gmail.com>
> >
> > Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> 
> Thanks for reading through the series. I will make those changes for
> the next version.
> 
> > I assume you'll merge this along with the rest of the series, not through
> > my PCI tree.
> Agreed, since I am the only user of this pass. Can you tell me whose
> tree normally carries new drivers?

That's mine.  But if Matthew wants to take this in his trees, I'll have
no objection.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

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);