* [RFC] fix asus_hides_smbus_lpc_ich6() for resume
@ 2008-03-14 3:49 Shaohua Li
2008-03-14 4:44 ` Greg KH
2008-03-17 3:40 ` Sergio Monteiro Basto
0 siblings, 2 replies; 21+ messages in thread
From: Shaohua Li @ 2008-03-14 3:49 UTC (permalink / raw)
To: linux acpi, linux-pci; +Cc: Len Brown, Rafael J. Wysocki, Greg KH
asus_hides_smbus_lpc_ich6() is called with interrupt disabled in resume
time, but ioremap_nocache() and iounmap() can't be called with interrupt
disabled. Below is my debug fix. If you have better fix, please speak.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e571c72..2abb85a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -289,6 +289,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
if (pci_dev->current_state == PCI_D0)
pci_dev->current_state = PCI_UNKNOWN;
}
+
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
+
return i;
}
@@ -334,6 +337,7 @@ static int pci_device_resume(struct device * dev)
error = drv->resume(pci_dev);
else
error = pci_default_resume(pci_dev);
+ pci_fixup_device(pci_fixup_resume_later, pci_dev);
return error;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e9a333d..32e9b61 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1100,23 +1100,53 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, as
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
-static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+/* It appears we just have one such device. If not, we have a warning */
+static void __iomem *asus_rcba_base;
+static void asus_hides_smbus_lpc_ich6_suspend(struct pci_dev *dev)
{
- u32 val, rcba;
- void __iomem *base;
+ u32 rcba;
if (likely(!asus_hides_smbus))
return;
+ WARN_ON(asus_rcba_base);
+
pci_read_config_dword(dev, 0xF0, &rcba);
- base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
- if (base == NULL) return;
- val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
- writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
- iounmap(base);
+ /* use bits 31:14, 16 kB aligned */
+ asus_rcba_base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000);
+ if (asus_rcba_base == NULL)
+ return;
+}
+
+static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
+{
+ u32 val;
+
+ if (likely(!asus_hides_smbus || !asus_rcba_base))
+ return;
+ /* read the Function Disable register, dword mode only */
+ val = readl(asus_rcba_base + 0x3418);
+ writel(val & 0xFFFFFFF7, asus_rcba_base + 0x3418); /* enable the SMBus device */
+}
+
+static void asus_hides_smbus_lpc_ich6_resume_later(struct pci_dev *dev)
+{
+ if (likely(!asus_hides_smbus || !asus_rcba_base))
+ return;
+ iounmap(asus_rcba_base);
+ asus_rcba_base = NULL;
dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
}
+
+static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+{
+ asus_hides_smbus_lpc_ich6_suspend(dev);
+ asus_hides_smbus_lpc_ich6_resume(dev);
+ asus_hides_smbus_lpc_ich6_resume_later(dev);
+}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_suspend);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume);
+DECLARE_PCI_FIXUP_RESUME_LATER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume_later);
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
@@ -1521,6 +1551,10 @@ extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
extern struct pci_fixup __start_pci_fixups_resume[];
extern struct pci_fixup __end_pci_fixups_resume[];
+extern struct pci_fixup __start_pci_fixups_resume_later[];
+extern struct pci_fixup __end_pci_fixups_resume_later[];
+extern struct pci_fixup __start_pci_fixups_suspend[];
+extern struct pci_fixup __end_pci_fixups_suspend[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
@@ -1553,6 +1587,16 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
end = __end_pci_fixups_resume;
break;
+ case pci_fixup_resume_later:
+ start = __start_pci_fixups_resume_later;
+ end = __end_pci_fixups_resume_later;
+ break;
+
+ case pci_fixup_suspend:
+ start = __start_pci_fixups_suspend;
+ end = __end_pci_fixups_suspend;
+ 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 f054778..06ac714 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -84,6 +84,12 @@
VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
*(.pci_fixup_resume) \
VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
+ VMLINUX_SYMBOL(__start_pci_fixups_resume_later) = .; \
+ *(.pci_fixup_resume_later) \
+ VMLINUX_SYMBOL(__end_pci_fixups_resume_later) = .; \
+ VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \
+ *(.pci_fixup_suspend) \
+ VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \
} \
\
/* RapidIO route ops */ \
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9010f54..821ad02 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
pci_fixup_final, /* Final phase of device fixups */
pci_fixup_enable, /* pci_enable_device() time */
pci_fixup_resume, /* pci_enable_device() time */
+ pci_fixup_suspend,
+ pci_fixup_resume_later,
};
/* Anonymous variables would be nice... */
@@ -1037,6 +1039,12 @@ enum pci_fixup_pass {
#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
resume##vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_RESUME_LATER(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_later, \
+ resume_later##vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
+ suspend##vendor##device##hook, vendor, device, hook)
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 3:49 [RFC] fix asus_hides_smbus_lpc_ich6() for resume Shaohua Li
@ 2008-03-14 4:44 ` Greg KH
2008-03-14 7:50 ` Shaohua Li
2008-03-14 12:26 ` Matthew Wilcox
2008-03-17 3:40 ` Sergio Monteiro Basto
1 sibling, 2 replies; 21+ messages in thread
From: Greg KH @ 2008-03-14 4:44 UTC (permalink / raw)
To: Shaohua Li; +Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki
On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 9010f54..821ad02 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> pci_fixup_final, /* Final phase of device fixups */
> pci_fixup_enable, /* pci_enable_device() time */
> pci_fixup_resume, /* pci_enable_device() time */
> + pci_fixup_suspend,
> + pci_fixup_resume_later,
Please document when these quirks are run.
And why "_later"? What's wrong with the normal resume time?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 4:44 ` Greg KH
@ 2008-03-14 7:50 ` Shaohua Li
2008-03-14 14:37 ` Rafael J. Wysocki
2008-03-14 12:26 ` Matthew Wilcox
1 sibling, 1 reply; 21+ messages in thread
From: Shaohua Li @ 2008-03-14 7:50 UTC (permalink / raw)
To: Greg KH; +Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki
On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index 9010f54..821ad02 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > pci_fixup_final, /* Final phase of device fixups */
> > pci_fixup_enable, /* pci_enable_device() time */
> > pci_fixup_resume, /* pci_enable_device() time */
> > + pci_fixup_suspend,
> > + pci_fixup_resume_later,
>
> Please document when these quirks are run.
will do if you think the method is correct.
> And why "_later"? What's wrong with the normal resume time?
pci_fixup_resume is called in pci_device_resume_earily(), which is
called with interrupt disable, so I added a new one which is called at
pci_device_resume(), this routine is called with interrupt enabled.
Thanks,
Shaohua
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 4:44 ` Greg KH
2008-03-14 7:50 ` Shaohua Li
@ 2008-03-14 12:26 ` Matthew Wilcox
2008-03-14 14:34 ` Rafael J. Wysocki
1 sibling, 1 reply; 21+ messages in thread
From: Matthew Wilcox @ 2008-03-14 12:26 UTC (permalink / raw)
To: Greg KH; +Cc: Shaohua Li, linux acpi, linux-pci, Len Brown, Rafael J. Wysocki
On Thu, Mar 13, 2008 at 09:44:08PM -0700, Greg KH wrote:
> And why "_later"? What's wrong with the normal resume time?
He said:
> asus_hides_smbus_lpc_ich6() is called with interrupt disabled in resume
> time, but ioremap_nocache() and iounmap() can't be called with interrupt
> disabled. Below is my debug fix. If you have better fix, please speak.
Maybe _resume is run too early and could be run later when interrupts
are enabled? But I haven't looked into that at all.
--
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 12:26 ` Matthew Wilcox
@ 2008-03-14 14:34 ` Rafael J. Wysocki
2008-03-14 14:43 ` Matthew Wilcox
0 siblings, 1 reply; 21+ messages in thread
From: Rafael J. Wysocki @ 2008-03-14 14:34 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: Greg KH, Shaohua Li, linux acpi, linux-pci, Len Brown
On Friday, 14 of March 2008, Matthew Wilcox wrote:
> On Thu, Mar 13, 2008 at 09:44:08PM -0700, Greg KH wrote:
> > And why "_later"? What's wrong with the normal resume time?
>
> He said:
> > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in resume
> > time, but ioremap_nocache() and iounmap() can't be called with interrupt
> > disabled. Below is my debug fix. If you have better fix, please speak.
>
> Maybe _resume is run too early and could be run later when interrupts
> are enabled?
That's what Shaohua is trying to achieve, AFAICS.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 7:50 ` Shaohua Li
@ 2008-03-14 14:37 ` Rafael J. Wysocki
2008-03-14 17:15 ` Jesse Barnes
0 siblings, 1 reply; 21+ messages in thread
From: Rafael J. Wysocki @ 2008-03-14 14:37 UTC (permalink / raw)
To: Shaohua Li; +Cc: Greg KH, linux acpi, linux-pci, Len Brown
On Friday, 14 of March 2008, Shaohua Li wrote:
>
> On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > index 9010f54..821ad02 100644
> > > --- a/include/linux/pci.h
> > > +++ b/include/linux/pci.h
> > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > pci_fixup_final, /* Final phase of device fixups */
> > > pci_fixup_enable, /* pci_enable_device() time */
> > > pci_fixup_resume, /* pci_enable_device() time */
> > > + pci_fixup_suspend,
> > > + pci_fixup_resume_later,
> >
> > Please document when these quirks are run.
> will do if you think the method is correct.
>
> > And why "_later"? What's wrong with the normal resume time?
> pci_fixup_resume is called in pci_device_resume_earily(), which is
> called with interrupt disable, so I added a new one which is called at
> pci_device_resume(), this routine is called with interrupt enabled.
Is the pci_fixup_resume thing used at all? If it is, how can I check who uses
it?
Thanks,
Rafael
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 14:34 ` Rafael J. Wysocki
@ 2008-03-14 14:43 ` Matthew Wilcox
2008-03-14 15:44 ` Rafael J. Wysocki
0 siblings, 1 reply; 21+ messages in thread
From: Matthew Wilcox @ 2008-03-14 14:43 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Greg KH, Shaohua Li, linux acpi, linux-pci, Len Brown
On Fri, Mar 14, 2008 at 03:34:34PM +0100, Rafael J. Wysocki wrote:
> On Friday, 14 of March 2008, Matthew Wilcox wrote:
> > On Thu, Mar 13, 2008 at 09:44:08PM -0700, Greg KH wrote:
> > > And why "_later"? What's wrong with the normal resume time?
> >
> > He said:
> > > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in resume
> > > time, but ioremap_nocache() and iounmap() can't be called with interrupt
> > > disabled. Below is my debug fix. If you have better fix, please speak.
> >
> > Maybe _resume is run too early and could be run later when interrupts
> > are enabled?
>
> That's what Shaohua is trying to achieve, AFAICS.
Shaohua is adding an extra class of resume_later fixups and moving this
one to it. I'm saying that maybe resume fixups should all be run later.
But I haven't looked at the dependencies here. That may not be possible.
--
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 14:43 ` Matthew Wilcox
@ 2008-03-14 15:44 ` Rafael J. Wysocki
2008-03-14 17:14 ` Jesse Barnes
0 siblings, 1 reply; 21+ messages in thread
From: Rafael J. Wysocki @ 2008-03-14 15:44 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: Greg KH, Shaohua Li, linux acpi, linux-pci, Len Brown
On Friday, 14 of March 2008, Matthew Wilcox wrote:
> On Fri, Mar 14, 2008 at 03:34:34PM +0100, Rafael J. Wysocki wrote:
> > On Friday, 14 of March 2008, Matthew Wilcox wrote:
> > > On Thu, Mar 13, 2008 at 09:44:08PM -0700, Greg KH wrote:
> > > > And why "_later"? What's wrong with the normal resume time?
> > >
> > > He said:
> > > > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in resume
> > > > time, but ioremap_nocache() and iounmap() can't be called with interrupt
> > > > disabled. Below is my debug fix. If you have better fix, please speak.
> > >
> > > Maybe _resume is run too early and could be run later when interrupts
> > > are enabled?
> >
> > That's what Shaohua is trying to achieve, AFAICS.
>
> Shaohua is adding an extra class of resume_later fixups and moving this
> one to it. I'm saying that maybe resume fixups should all be run later.
Yes, I thought about that too.
> But I haven't looked at the dependencies here. That may not be possible.
Well, I'm not sure how to find out (reliably) who uses it.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 15:44 ` Rafael J. Wysocki
@ 2008-03-14 17:14 ` Jesse Barnes
0 siblings, 0 replies; 21+ messages in thread
From: Jesse Barnes @ 2008-03-14 17:14 UTC (permalink / raw)
To: linux-pci
Cc: Rafael J. Wysocki, Matthew Wilcox, Greg KH, Shaohua Li,
linux acpi, Len Brown
On Friday, March 14, 2008 8:44 am Rafael J. Wysocki wrote:
> On Friday, 14 of March 2008, Matthew Wilcox wrote:
> > On Fri, Mar 14, 2008 at 03:34:34PM +0100, Rafael J. Wysocki wrote:
> > > On Friday, 14 of March 2008, Matthew Wilcox wrote:
> > > > On Thu, Mar 13, 2008 at 09:44:08PM -0700, Greg KH wrote:
> > > > > And why "_later"? What's wrong with the normal resume time?
> > > >
> > > > He said:
> > > > > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in
> > > > > resume time, but ioremap_nocache() and iounmap() can't be called
> > > > > with interrupt disabled. Below is my debug fix. If you have better
> > > > > fix, please speak.
> > > >
> > > > Maybe _resume is run too early and could be run later when interrupts
> > > > are enabled?
> > >
> > > That's what Shaohua is trying to achieve, AFAICS.
> >
> > Shaohua is adding an extra class of resume_later fixups and moving this
> > one to it. I'm saying that maybe resume fixups should all be run later.
>
> Yes, I thought about that too.
>
> > But I haven't looked at the dependencies here. That may not be possible.
>
> Well, I'm not sure how to find out (reliably) who uses it.
Seems a little risky, there are quite a few resume fixups (looks like at least
18 unique routines) but it might be ok as long as someone was willing to
audit them all for irq enable safety...
Jesse
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 14:37 ` Rafael J. Wysocki
@ 2008-03-14 17:15 ` Jesse Barnes
2008-03-14 21:03 ` Rafael J. Wysocki
0 siblings, 1 reply; 21+ messages in thread
From: Jesse Barnes @ 2008-03-14 17:15 UTC (permalink / raw)
To: linux-pci; +Cc: Rafael J. Wysocki, Shaohua Li, Greg KH, linux acpi, Len Brown
On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> On Friday, 14 of March 2008, Shaohua Li wrote:
> > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > index 9010f54..821ad02 100644
> > > > --- a/include/linux/pci.h
> > > > +++ b/include/linux/pci.h
> > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > pci_fixup_final, /* Final phase of device fixups */
> > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > + pci_fixup_suspend,
> > > > + pci_fixup_resume_later,
> > >
> > > Please document when these quirks are run.
> >
> > will do if you think the method is correct.
> >
> > > And why "_later"? What's wrong with the normal resume time?
> >
> > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > called with interrupt disable, so I added a new one which is called at
> > pci_device_resume(), this routine is called with interrupt enabled.
>
> Is the pci_fixup_resume thing used at all? If it is, how can I check who
> uses it?
Oh good catch, it looks like it's unused at this point (at least there's no
DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
completeness.
Jesse
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 17:15 ` Jesse Barnes
@ 2008-03-14 21:03 ` Rafael J. Wysocki
2008-03-17 1:15 ` Shaohua Li
0 siblings, 1 reply; 21+ messages in thread
From: Rafael J. Wysocki @ 2008-03-14 21:03 UTC (permalink / raw)
To: Jesse Barnes; +Cc: linux-pci, Shaohua Li, Greg KH, linux acpi, Len Brown
On Friday, 14 of March 2008, Jesse Barnes wrote:
> On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> > On Friday, 14 of March 2008, Shaohua Li wrote:
> > > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > index 9010f54..821ad02 100644
> > > > > --- a/include/linux/pci.h
> > > > > +++ b/include/linux/pci.h
> > > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > > pci_fixup_final, /* Final phase of device fixups */
> > > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > > + pci_fixup_suspend,
> > > > > + pci_fixup_resume_later,
> > > >
> > > > Please document when these quirks are run.
> > >
> > > will do if you think the method is correct.
> > >
> > > > And why "_later"? What's wrong with the normal resume time?
> > >
> > > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > > called with interrupt disable, so I added a new one which is called at
> > > pci_device_resume(), this routine is called with interrupt enabled.
> >
> > Is the pci_fixup_resume thing used at all? If it is, how can I check who
> > uses it?
>
> Oh good catch, it looks like it's unused at this point (at least there's no
> DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
> completeness.
It seems to be used only in quirks.c .
I'd prefer to rename the existing one to pci_fixup_resume_noirq and define a
new one called pci_fixup_resume to be used by pci_device_resume().
Also, it would be worth checking if all of the existing resume quirks need to
be run with interrupts disabled.
Thanks,
Rafael
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 21:03 ` Rafael J. Wysocki
@ 2008-03-17 1:15 ` Shaohua Li
2008-03-17 16:26 ` Rafael J. Wysocki
0 siblings, 1 reply; 21+ messages in thread
From: Shaohua Li @ 2008-03-17 1:15 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Jesse Barnes, linux-pci, Greg KH, linux acpi, Len Brown
On Fri, 2008-03-14 at 22:03 +0100, Rafael J. Wysocki wrote:
> On Friday, 14 of March 2008, Jesse Barnes wrote:
> > On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> > > On Friday, 14 of March 2008, Shaohua Li wrote:
> > > > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > > index 9010f54..821ad02 100644
> > > > > > --- a/include/linux/pci.h
> > > > > > +++ b/include/linux/pci.h
> > > > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > > > pci_fixup_final, /* Final phase of device fixups */
> > > > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > > > + pci_fixup_suspend,
> > > > > > + pci_fixup_resume_later,
> > > > >
> > > > > Please document when these quirks are run.
> > > >
> > > > will do if you think the method is correct.
> > > >
> > > > > And why "_later"? What's wrong with the normal resume time?
> > > >
> > > > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > > > called with interrupt disable, so I added a new one which is called at
> > > > pci_device_resume(), this routine is called with interrupt enabled.
> > >
> > > Is the pci_fixup_resume thing used at all? If it is, how can I check who
> > > uses it?
> >
> > Oh good catch, it looks like it's unused at this point (at least there's no
> > DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
> > completeness.
>
> It seems to be used only in quirks.c .
>
> I'd prefer to rename the existing one to pci_fixup_resume_noirq and define a
> new one called pci_fixup_resume to be used by pci_device_resume().
>
> Also, it would be worth checking if all of the existing resume quirks need to
> be run with interrupts disabled.
As far as I checked, only this one need interrupt enabled. Introducing
pci_fixup_resume_noirq and move the quirk to .resume is feasible in the
case, but it's not quite good to me. The quirk is to make smbus
controller not hide and then smbus can be resumed, the order is
important. If the quirk is called in .resume, that means smbus
controller can't have a .resume_early. The quirk is a FIXUP_HEADER, it
really should be called early, eg in .resume_early.
Thanks,
Shaohua
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-14 3:49 [RFC] fix asus_hides_smbus_lpc_ich6() for resume Shaohua Li
2008-03-14 4:44 ` Greg KH
@ 2008-03-17 3:40 ` Sergio Monteiro Basto
2008-03-17 21:39 ` Sergio Monteiro Basto
1 sibling, 1 reply; 21+ messages in thread
From: Sergio Monteiro Basto @ 2008-03-17 3:40 UTC (permalink / raw)
To: Shaohua Li; +Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki, Greg KH
[-- Attachment #1: Type: text/plain, Size: 658 bytes --]
On Fri, 2008-03-14 at 11:49 +0800, Shaohua Li wrote:
> asus_hides_smbus_lpc_ich6() is called with interrupt disabled in
> resume
> time, but ioremap_nocache() and iounmap() can't be called with
> interrupt
> disabled. Below is my debug fix. If you have better fix, please
> speak.
yap , I have a better fix for my laptop
I have a Compaq nx , and this quirk is applied ,
I simply remove the quirk like I had write
http://lkml.org/lkml/2007/3/9/516
Especially if we don't an ASUS, which may need the quirk.
I have been working almost an year without the quirk on my laptop and
things seems that work better
--
Sérgio M. B.
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2192 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-17 1:15 ` Shaohua Li
@ 2008-03-17 16:26 ` Rafael J. Wysocki
2008-03-18 3:11 ` Shaohua Li
0 siblings, 1 reply; 21+ messages in thread
From: Rafael J. Wysocki @ 2008-03-17 16:26 UTC (permalink / raw)
To: Shaohua Li; +Cc: Jesse Barnes, linux-pci, Greg KH, linux acpi, Len Brown
On Monday, 17 of March 2008, Shaohua Li wrote:
>
> On Fri, 2008-03-14 at 22:03 +0100, Rafael J. Wysocki wrote:
> > On Friday, 14 of March 2008, Jesse Barnes wrote:
> > > On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> > > > On Friday, 14 of March 2008, Shaohua Li wrote:
> > > > > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > > > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > > > index 9010f54..821ad02 100644
> > > > > > > --- a/include/linux/pci.h
> > > > > > > +++ b/include/linux/pci.h
> > > > > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > > > > pci_fixup_final, /* Final phase of device fixups */
> > > > > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > > > > + pci_fixup_suspend,
> > > > > > > + pci_fixup_resume_later,
> > > > > >
> > > > > > Please document when these quirks are run.
> > > > >
> > > > > will do if you think the method is correct.
> > > > >
> > > > > > And why "_later"? What's wrong with the normal resume time?
> > > > >
> > > > > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > > > > called with interrupt disable, so I added a new one which is called at
> > > > > pci_device_resume(), this routine is called with interrupt enabled.
> > > >
> > > > Is the pci_fixup_resume thing used at all? If it is, how can I check who
> > > > uses it?
> > >
> > > Oh good catch, it looks like it's unused at this point (at least there's no
> > > DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
> > > completeness.
> >
> > It seems to be used only in quirks.c .
> >
> > I'd prefer to rename the existing one to pci_fixup_resume_noirq and define a
> > new one called pci_fixup_resume to be used by pci_device_resume().
> >
> > Also, it would be worth checking if all of the existing resume quirks need to
> > be run with interrupts disabled.
> As far as I checked, only this one need interrupt enabled.
Still, do all of the others _require_ interrupts to be disabled?
> Introducing
> pci_fixup_resume_noirq and move the quirk to .resume is feasible in the
> case, but it's not quite good to me. The quirk is to make smbus
> controller not hide and then smbus can be resumed, the order is
> important. If the quirk is called in .resume, that means smbus
> controller can't have a .resume_early. The quirk is a FIXUP_HEADER, it
> really should be called early, eg in .resume_early.
I meant "move all of the other quirks that need to run with interrupts
disabled to pci_fixup_resume_noirq, leave those that may run with interrups
enabled within pci_fixup_resume and add yours to pci_fixup_resume".
Thanks,
Rafael
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-17 3:40 ` Sergio Monteiro Basto
@ 2008-03-17 21:39 ` Sergio Monteiro Basto
2008-03-18 3:14 ` Shaohua Li
0 siblings, 1 reply; 21+ messages in thread
From: Sergio Monteiro Basto @ 2008-03-17 21:39 UTC (permalink / raw)
To: Shaohua Li; +Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki, Greg KH
[-- Attachment #1: Type: text/plain, Size: 1366 bytes --]
On Mon, 2008-03-17 at 03:40 +0000, Sergio Monteiro Basto wrote:
> On Fri, 2008-03-14 at 11:49 +0800, Shaohua Li wrote:
> > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in
> > resume
> > time, but ioremap_nocache() and iounmap() can't be called with
> > interrupt
> > disabled. Below is my debug fix. If you have better fix, please
> > speak.
>
> yap , I have a better fix for my laptop
> I have a Compaq nx , and this quirk is applied ,
>
> I simply remove the quirk like I had write
> http://lkml.org/lkml/2007/3/9/516
>
> Especially if we don't an ASUS, which may need the quirk.
>
> I have been working almost an year without the quirk on my laptop and
> things seems that work better
Btw I am running 2.6.24.3-12 fedora kernel , I recompile from the
src.rpm and apply with 2 patches one:
http://bugzilla.kernel.org/show_bug.cgi?id=9642
this one seems that I don't need anymore on 2.6.25-rc
and remove this quirk.
And enable ACPI_DEBUG.
And I am very happy with it , hibernation, suspend works very well and
don't loose ACPI events after resume, backlight also works always fine,
ACPI events always on, resume from ram don't have to go to console to
have screen .
I just use git Intel drive.
Which make me think, will not updates kernels for a very long time :)
Regards,
--
Sérgio M. B.
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2192 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-17 16:26 ` Rafael J. Wysocki
@ 2008-03-18 3:11 ` Shaohua Li
2008-04-16 17:30 ` Rafael J. Wysocki
0 siblings, 1 reply; 21+ messages in thread
From: Shaohua Li @ 2008-03-18 3:11 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Jesse Barnes, linux-pci, Greg KH, linux acpi, Len Brown
On Mon, 2008-03-17 at 17:26 +0100, Rafael J. Wysocki wrote:
> On Monday, 17 of March 2008, Shaohua Li wrote:
> >
> > On Fri, 2008-03-14 at 22:03 +0100, Rafael J. Wysocki wrote:
> > > On Friday, 14 of March 2008, Jesse Barnes wrote:
> > > > On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> > > > > On Friday, 14 of March 2008, Shaohua Li wrote:
> > > > > > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > > > > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > > > > index 9010f54..821ad02 100644
> > > > > > > > --- a/include/linux/pci.h
> > > > > > > > +++ b/include/linux/pci.h
> > > > > > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > > > > > pci_fixup_final, /* Final phase of device fixups */
> > > > > > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > > > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > > > > > + pci_fixup_suspend,
> > > > > > > > + pci_fixup_resume_later,
> > > > > > >
> > > > > > > Please document when these quirks are run.
> > > > > >
> > > > > > will do if you think the method is correct.
> > > > > >
> > > > > > > And why "_later"? What's wrong with the normal resume time?
> > > > > >
> > > > > > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > > > > > called with interrupt disable, so I added a new one which is called at
> > > > > > pci_device_resume(), this routine is called with interrupt enabled.
> > > > >
> > > > > Is the pci_fixup_resume thing used at all? If it is, how can I check who
> > > > > uses it?
> > > >
> > > > Oh good catch, it looks like it's unused at this point (at least there's no
> > > > DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
> > > > completeness.
> > >
> > > It seems to be used only in quirks.c .
> > >
> > > I'd prefer to rename the existing one to pci_fixup_resume_noirq and define a
> > > new one called pci_fixup_resume to be used by pci_device_resume().
> > >
> > > Also, it would be worth checking if all of the existing resume quirks need to
> > > be run with interrupts disabled.
> > As far as I checked, only this one need interrupt enabled.
>
> Still, do all of the others _require_ interrupts to be disabled?
No, they don't need interrupt disabled, but be called in .resume_early,
which will disable interrupt.
> > Introducing
> > pci_fixup_resume_noirq and move the quirk to .resume is feasible in the
> > case, but it's not quite good to me. The quirk is to make smbus
> > controller not hide and then smbus can be resumed, the order is
> > important. If the quirk is called in .resume, that means smbus
> > controller can't have a .resume_early. The quirk is a FIXUP_HEADER, it
> > really should be called early, eg in .resume_early.
>
> I meant "move all of the other quirks that need to run with interrupts
> disabled to pci_fixup_resume_noirq, leave those that may run with interrups
> enabled within pci_fixup_resume and add yours to pci_fixup_resume".
Just change the name? then I'd prefer use pci_fixup_resume and
pci_fixup_resume_early.
Some quirks should be called with interrupt disabled, we can't directly
call them in .resume_early. Also the patch introduces
pci_fixup_resume_early and pci_fixup_suspend, which matches current
device core callbacks (.suspend/.resume_early).
TBD: Somebody knows why we need quirk resume should double check if a
quirk should be called in resume or resume_early. I changed some per my
understanding, but can't make sure I fixed all.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e571c72..59307d6 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -289,6 +289,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
if (pci_dev->current_state == PCI_D0)
pci_dev->current_state = PCI_UNKNOWN;
}
+
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
+
return i;
}
@@ -334,6 +337,7 @@ static int pci_device_resume(struct device * dev)
error = drv->resume(pci_dev);
else
error = pci_default_resume(pci_dev);
+ pci_fixup_device(pci_fixup_resume, pci_dev);
return error;
}
@@ -343,7 +347,7 @@ static int pci_device_resume_early(struct device * dev)
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- pci_fixup_device(pci_fixup_resume, pci_dev);
+ pci_fixup_device(pci_fixup_resume_early, pci_dev);
if (drv && drv->resume_early)
error = drv->resume_early(pci_dev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e9a333d..21e9cdb 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -556,7 +556,7 @@ static void quirk_via_ioapic(struct pci_dev *dev)
pci_write_config_byte (dev, 0x58, tmp);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
/*
* VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
@@ -576,7 +576,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
/*
* The AMD io apic can hang the box when an apic irq is masked.
@@ -622,7 +622,7 @@ static void quirk_amd_8131_ioapic(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
#endif /* CONFIG_X86_IO_APIC */
/*
@@ -774,7 +774,7 @@ static void quirk_cardbus_legacy(struct pci_dev *dev)
pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
-DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
/*
* Following the PCI ordering rules is optional on the AMD762. I'm not
@@ -797,7 +797,7 @@ static void quirk_amd_ordering(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
/*
* DreamWorks provided workaround for Dunord I-3000 problem
@@ -865,7 +865,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
{
@@ -885,9 +885,9 @@ static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
/*
* Serverworks CSB5 IDE does not fully support native mode
@@ -1092,31 +1092,61 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
-static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+/* It appears we just have one such device. If not, we have a warning */
+static void __iomem *asus_rcba_base;
+static void asus_hides_smbus_lpc_ich6_suspend(struct pci_dev *dev)
{
- u32 val, rcba;
- void __iomem *base;
+ u32 rcba;
if (likely(!asus_hides_smbus))
return;
+ WARN_ON(asus_rcba_base);
+
pci_read_config_dword(dev, 0xF0, &rcba);
- base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
- if (base == NULL) return;
- val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
- writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
- iounmap(base);
+ /* use bits 31:14, 16 kB aligned */
+ asus_rcba_base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000);
+ if (asus_rcba_base == NULL)
+ return;
+}
+
+static void asus_hides_smbus_lpc_ich6_resume_early(struct pci_dev *dev)
+{
+ u32 val;
+
+ if (likely(!asus_hides_smbus || !asus_rcba_base))
+ return;
+ /* read the Function Disable register, dword mode only */
+ val = readl(asus_rcba_base + 0x3418);
+ writel(val & 0xFFFFFFF7, asus_rcba_base + 0x3418); /* enable the SMBus device */
+}
+
+static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
+{
+ if (likely(!asus_hides_smbus || !asus_rcba_base))
+ return;
+ iounmap(asus_rcba_base);
+ asus_rcba_base = NULL;
dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
}
+
+static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+{
+ asus_hides_smbus_lpc_ich6_suspend(dev);
+ asus_hides_smbus_lpc_ich6_resume_early(dev);
+ asus_hides_smbus_lpc_ich6_resume(dev);
+}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_suspend);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume_early);
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
@@ -1134,10 +1164,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
/*
* ... This is further complicated by the fact that some SiS96x south
@@ -1171,7 +1201,7 @@ static void quirk_sis_503(struct pci_dev *dev)
quirk_sis_96x_smbus(dev);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
/*
@@ -1204,7 +1234,7 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
@@ -1269,12 +1299,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, qui
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
#endif
@@ -1521,6 +1551,10 @@ extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
extern struct pci_fixup __start_pci_fixups_resume[];
extern struct pci_fixup __end_pci_fixups_resume[];
+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[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
@@ -1553,6 +1587,16 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
end = __end_pci_fixups_resume;
break;
+ case pci_fixup_resume_early:
+ start = __start_pci_fixups_resume_early;
+ end = __end_pci_fixups_resume_early;
+ break;
+
+ case pci_fixup_suspend:
+ start = __start_pci_fixups_suspend;
+ end = __end_pci_fixups_suspend;
+ break;
+
default:
/* stupid compiler warning, you would think with an enum... */
return;
@@ -1629,7 +1673,7 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index f054778..cf108a3 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -84,6 +84,12 @@
VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
*(.pci_fixup_resume) \
VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
+ VMLINUX_SYMBOL(__start_pci_fixups_resume_early) = .; \
+ *(.pci_fixup_resume_early) \
+ VMLINUX_SYMBOL(__end_pci_fixups_resume_early) = .; \
+ VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \
+ *(.pci_fixup_suspend) \
+ VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \
} \
\
/* RapidIO route ops */ \
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b7e4b63..ec68b45 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1015,7 +1015,9 @@ enum pci_fixup_pass {
pci_fixup_header, /* After reading configuration header */
pci_fixup_final, /* Final phase of device fixups */
pci_fixup_enable, /* pci_enable_device() time */
- pci_fixup_resume, /* pci_enable_device() time */
+ pci_fixup_resume, /* pci_device_resume() */
+ pci_fixup_suspend, /* pci_device_suspend */
+ pci_fixup_resume_early, /* pci_device_resume_early() */
};
/* Anonymous variables would be nice... */
@@ -1037,6 +1039,12 @@ enum pci_fixup_pass {
#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
resume##vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
+ resume_early##vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
+ suspend##vendor##device##hook, vendor, device, hook)
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-17 21:39 ` Sergio Monteiro Basto
@ 2008-03-18 3:14 ` Shaohua Li
2008-03-18 23:47 ` Sergio Monteiro Basto
2008-04-06 2:05 ` Sergio Monteiro Basto
0 siblings, 2 replies; 21+ messages in thread
From: Shaohua Li @ 2008-03-18 3:14 UTC (permalink / raw)
To: Sergio Monteiro Basto
Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki, Greg KH
On Mon, 2008-03-17 at 21:39 +0000, Sergio Monteiro Basto wrote:
> On Mon, 2008-03-17 at 03:40 +0000, Sergio Monteiro Basto wrote:
> > On Fri, 2008-03-14 at 11:49 +0800, Shaohua Li wrote:
> > > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in
> > > resume
> > > time, but ioremap_nocache() and iounmap() can't be called with
> > > interrupt
> > > disabled. Below is my debug fix. If you have better fix, please
> > > speak.
> >
> > yap , I have a better fix for my laptop
> > I have a Compaq nx , and this quirk is applied ,
> >
> > I simply remove the quirk like I had write
> > http://lkml.org/lkml/2007/3/9/516
> >
> > Especially if we don't an ASUS, which may need the quirk.
> >
> > I have been working almost an year without the quirk on my laptop and
> > things seems that work better
>
> Btw I am running 2.6.24.3-12 fedora kernel , I recompile from the
> src.rpm and apply with 2 patches one:
> http://bugzilla.kernel.org/show_bug.cgi?id=9642
> this one seems that I don't need anymore on 2.6.25-rc
> and remove this quirk.
> And enable ACPI_DEBUG.
>
> And I am very happy with it , hibernation, suspend works very well and
> don't loose ACPI events after resume, backlight also works always fine,
> ACPI events always on, resume from ram don't have to go to console to
> have screen .
> I just use git Intel drive.
>
> Which make me think, will not updates kernels for a very long time :)
> Regards,
Sure, you can remove the quirk without any problem if you don't want to
use the smbus device.
Thanks,
Shaohua
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-18 3:14 ` Shaohua Li
@ 2008-03-18 23:47 ` Sergio Monteiro Basto
2008-04-06 2:05 ` Sergio Monteiro Basto
1 sibling, 0 replies; 21+ messages in thread
From: Sergio Monteiro Basto @ 2008-03-18 23:47 UTC (permalink / raw)
To: Shaohua Li; +Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki, Greg KH
[-- Attachment #1: Type: text/plain, Size: 2011 bytes --]
On Tue, 2008-03-18 at 11:14 +0800, Shaohua Li wrote:
> On Mon, 2008-03-17 at 21:39 +0000, Sergio Monteiro Basto wrote:
> > On Mon, 2008-03-17 at 03:40 +0000, Sergio Monteiro Basto wrote:
> > > On Fri, 2008-03-14 at 11:49 +0800, Shaohua Li wrote:
> > > > asus_hides_smbus_lpc_ich6() is called with interrupt disabled in
> > > > resume
> > > > time, but ioremap_nocache() and iounmap() can't be called with
> > > > interrupt
> > > > disabled. Below is my debug fix. If you have better fix, please
> > > > speak.
> > >
> > > yap , I have a better fix for my laptop
> > > I have a Compaq nx , and this quirk is applied ,
> > >
> > > I simply remove the quirk like I had write
> > > http://lkml.org/lkml/2007/3/9/516
> > >
> > > Especially if we don't an ASUS, which may need the quirk.
> > >
> > > I have been working almost an year without the quirk on my laptop and
> > > things seems that work better
> >
> > Btw I am running 2.6.24.3-12 fedora kernel , I recompile from the
> > src.rpm and apply with 2 patches one:
> > http://bugzilla.kernel.org/show_bug.cgi?id=9642
> > this one seems that I don't need anymore on 2.6.25-rc
> > and remove this quirk.
> > And enable ACPI_DEBUG.
> >
> > And I am very happy with it , hibernation, suspend works very well and
> > don't loose ACPI events after resume, backlight also works always fine,
> > ACPI events always on, resume from ram don't have to go to console to
> > have screen .
> > I just use git Intel drive.
> >
> > Which make me think, will not updates kernels for a very long time :)
> > Regards,
> Sure, you can remove the quirk without any problem if you don't want to
> use the smbus device.
smbus came with lm_sensors ? isn't it ?
I will see, If I can have smbus working or not but just in next month, I
am very busy right now.
But at least name of quirk is wrong, says that if for an ASUS, which I
though that not should be applied on HP Compaqs .
Thanks,
--
Sérgio M.B.
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2192 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-18 3:14 ` Shaohua Li
2008-03-18 23:47 ` Sergio Monteiro Basto
@ 2008-04-06 2:05 ` Sergio Monteiro Basto
1 sibling, 0 replies; 21+ messages in thread
From: Sergio Monteiro Basto @ 2008-04-06 2:05 UTC (permalink / raw)
To: Shaohua Li; +Cc: linux acpi, linux-pci, Len Brown, Rafael J. Wysocki, Greg KH
[-- Attachment #1: Type: text/plain, Size: 251 bytes --]
On Tue, 2008-03-18 at 11:14 +0800, Shaohua Li wrote:
> Sure, you can remove the quirk without any problem if you don't want
> to
> use the smbus device.
yah I confirm that I need quirk for get smbus detected.
Thanks,
--
Sérgio M. B.
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2192 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-03-18 3:11 ` Shaohua Li
@ 2008-04-16 17:30 ` Rafael J. Wysocki
2008-04-17 2:16 ` Shaohua Li
0 siblings, 1 reply; 21+ messages in thread
From: Rafael J. Wysocki @ 2008-04-16 17:30 UTC (permalink / raw)
To: Shaohua Li; +Cc: Jesse Barnes, linux-pci, Greg KH, linux acpi, Len Brown
On Tuesday, 18 of March 2008, Shaohua Li wrote:
>
> On Mon, 2008-03-17 at 17:26 +0100, Rafael J. Wysocki wrote:
> > On Monday, 17 of March 2008, Shaohua Li wrote:
> > >
> > > On Fri, 2008-03-14 at 22:03 +0100, Rafael J. Wysocki wrote:
> > > > On Friday, 14 of March 2008, Jesse Barnes wrote:
> > > > > On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> > > > > > On Friday, 14 of March 2008, Shaohua Li wrote:
> > > > > > > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > > > > > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > > > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > > > > > index 9010f54..821ad02 100644
> > > > > > > > > --- a/include/linux/pci.h
> > > > > > > > > +++ b/include/linux/pci.h
> > > > > > > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > > > > > > pci_fixup_final, /* Final phase of device fixups */
> > > > > > > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > > > > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > > > > > > + pci_fixup_suspend,
> > > > > > > > > + pci_fixup_resume_later,
> > > > > > > >
> > > > > > > > Please document when these quirks are run.
> > > > > > >
> > > > > > > will do if you think the method is correct.
> > > > > > >
> > > > > > > > And why "_later"? What's wrong with the normal resume time?
> > > > > > >
> > > > > > > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > > > > > > called with interrupt disable, so I added a new one which is called at
> > > > > > > pci_device_resume(), this routine is called with interrupt enabled.
> > > > > >
> > > > > > Is the pci_fixup_resume thing used at all? If it is, how can I check who
> > > > > > uses it?
> > > > >
> > > > > Oh good catch, it looks like it's unused at this point (at least there's no
> > > > > DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
> > > > > completeness.
> > > >
> > > > It seems to be used only in quirks.c .
> > > >
> > > > I'd prefer to rename the existing one to pci_fixup_resume_noirq and define a
> > > > new one called pci_fixup_resume to be used by pci_device_resume().
> > > >
> > > > Also, it would be worth checking if all of the existing resume quirks need to
> > > > be run with interrupts disabled.
> > > As far as I checked, only this one need interrupt enabled.
> >
> > Still, do all of the others _require_ interrupts to be disabled?
> No, they don't need interrupt disabled, but be called in .resume_early,
> which will disable interrupt.
>
> > > Introducing
> > > pci_fixup_resume_noirq and move the quirk to .resume is feasible in the
> > > case, but it's not quite good to me. The quirk is to make smbus
> > > controller not hide and then smbus can be resumed, the order is
> > > important. If the quirk is called in .resume, that means smbus
> > > controller can't have a .resume_early. The quirk is a FIXUP_HEADER, it
> > > really should be called early, eg in .resume_early.
> >
> > I meant "move all of the other quirks that need to run with interrupts
> > disabled to pci_fixup_resume_noirq, leave those that may run with interrups
> > enabled within pci_fixup_resume and add yours to pci_fixup_resume".
> Just change the name? then I'd prefer use pci_fixup_resume and
> pci_fixup_resume_early.
>
> Some quirks should be called with interrupt disabled, we can't directly
> call them in .resume_early. Also the patch introduces
> pci_fixup_resume_early and pci_fixup_suspend, which matches current
> device core callbacks (.suspend/.resume_early).
>
> TBD: Somebody knows why we need quirk resume should double check if a
> quirk should be called in resume or resume_early. I changed some per my
> understanding, but can't make sure I fixed all.
What is the current status of this patch. Would you like it to be merged as is
or are you going to modify it?
Rafael
> Signed-off-by: Shaohua Li <shaohua.li@intel.com>
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index e571c72..59307d6 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -289,6 +289,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
> if (pci_dev->current_state == PCI_D0)
> pci_dev->current_state = PCI_UNKNOWN;
> }
> +
> + pci_fixup_device(pci_fixup_suspend, pci_dev);
> +
> return i;
> }
>
> @@ -334,6 +337,7 @@ static int pci_device_resume(struct device * dev)
> error = drv->resume(pci_dev);
> else
> error = pci_default_resume(pci_dev);
> + pci_fixup_device(pci_fixup_resume, pci_dev);
> return error;
> }
>
> @@ -343,7 +347,7 @@ static int pci_device_resume_early(struct device * dev)
> struct pci_dev * pci_dev = to_pci_dev(dev);
> struct pci_driver * drv = pci_dev->driver;
>
> - pci_fixup_device(pci_fixup_resume, pci_dev);
> + pci_fixup_device(pci_fixup_resume_early, pci_dev);
>
> if (drv && drv->resume_early)
> error = drv->resume_early(pci_dev);
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index e9a333d..21e9cdb 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -556,7 +556,7 @@ static void quirk_via_ioapic(struct pci_dev *dev)
> pci_write_config_byte (dev, 0x58, tmp);
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
>
> /*
> * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
> @@ -576,7 +576,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
> }
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
>
> /*
> * The AMD io apic can hang the box when an apic irq is masked.
> @@ -622,7 +622,7 @@ static void quirk_amd_8131_ioapic(struct pci_dev *dev)
> }
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
> #endif /* CONFIG_X86_IO_APIC */
>
> /*
> @@ -774,7 +774,7 @@ static void quirk_cardbus_legacy(struct pci_dev *dev)
> pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
> -DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
>
> /*
> * Following the PCI ordering rules is optional on the AMD762. I'm not
> @@ -797,7 +797,7 @@ static void quirk_amd_ordering(struct pci_dev *dev)
> }
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
>
> /*
> * DreamWorks provided workaround for Dunord I-3000 problem
> @@ -865,7 +865,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
> }
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
>
> static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
> {
> @@ -885,9 +885,9 @@ static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
> }
> }
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
>
> /*
> * Serverworks CSB5 IDE does not fully support native mode
> @@ -1092,31 +1092,61 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
>
> -static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
> +/* It appears we just have one such device. If not, we have a warning */
> +static void __iomem *asus_rcba_base;
> +static void asus_hides_smbus_lpc_ich6_suspend(struct pci_dev *dev)
> {
> - u32 val, rcba;
> - void __iomem *base;
> + u32 rcba;
>
> if (likely(!asus_hides_smbus))
> return;
> + WARN_ON(asus_rcba_base);
> +
> pci_read_config_dword(dev, 0xF0, &rcba);
> - base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
> - if (base == NULL) return;
> - val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
> - writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
> - iounmap(base);
> + /* use bits 31:14, 16 kB aligned */
> + asus_rcba_base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000);
> + if (asus_rcba_base == NULL)
> + return;
> +}
> +
> +static void asus_hides_smbus_lpc_ich6_resume_early(struct pci_dev *dev)
> +{
> + u32 val;
> +
> + if (likely(!asus_hides_smbus || !asus_rcba_base))
> + return;
> + /* read the Function Disable register, dword mode only */
> + val = readl(asus_rcba_base + 0x3418);
> + writel(val & 0xFFFFFFF7, asus_rcba_base + 0x3418); /* enable the SMBus device */
> +}
> +
> +static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
> +{
> + if (likely(!asus_hides_smbus || !asus_rcba_base))
> + return;
> + iounmap(asus_rcba_base);
> + asus_rcba_base = NULL;
> dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
> }
> +
> +static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
> +{
> + asus_hides_smbus_lpc_ich6_suspend(dev);
> + asus_hides_smbus_lpc_ich6_resume_early(dev);
> + asus_hides_smbus_lpc_ich6_resume(dev);
> +}
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
> +DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_suspend);
> +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume_early);
>
> /*
> * SiS 96x south bridge: BIOS typically hides SMBus device...
> @@ -1134,10 +1164,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
>
> /*
> * ... This is further complicated by the fact that some SiS96x south
> @@ -1171,7 +1201,7 @@ static void quirk_sis_503(struct pci_dev *dev)
> quirk_sis_96x_smbus(dev);
> }
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
>
>
> /*
> @@ -1204,7 +1234,7 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
> }
> }
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
>
> #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
>
> @@ -1269,12 +1299,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, qui
> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
>
> #endif
>
> @@ -1521,6 +1551,10 @@ extern struct pci_fixup __start_pci_fixups_enable[];
> extern struct pci_fixup __end_pci_fixups_enable[];
> extern struct pci_fixup __start_pci_fixups_resume[];
> extern struct pci_fixup __end_pci_fixups_resume[];
> +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[];
>
>
> void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
> @@ -1553,6 +1587,16 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
> end = __end_pci_fixups_resume;
> break;
>
> + case pci_fixup_resume_early:
> + start = __start_pci_fixups_resume_early;
> + end = __end_pci_fixups_resume_early;
> + break;
> +
> + case pci_fixup_suspend:
> + start = __start_pci_fixups_suspend;
> + end = __end_pci_fixups_suspend;
> + break;
> +
> default:
> /* stupid compiler warning, you would think with an enum... */
> return;
> @@ -1629,7 +1673,7 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
> }
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
> quirk_nvidia_ck804_pcie_aer_ext_cap);
> -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
> +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
> quirk_nvidia_ck804_pcie_aer_ext_cap);
>
> static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index f054778..cf108a3 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -84,6 +84,12 @@
> VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
> *(.pci_fixup_resume) \
> VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
> + VMLINUX_SYMBOL(__start_pci_fixups_resume_early) = .; \
> + *(.pci_fixup_resume_early) \
> + VMLINUX_SYMBOL(__end_pci_fixups_resume_early) = .; \
> + VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \
> + *(.pci_fixup_suspend) \
> + VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \
> } \
> \
> /* RapidIO route ops */ \
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index b7e4b63..ec68b45 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1015,7 +1015,9 @@ enum pci_fixup_pass {
> pci_fixup_header, /* After reading configuration header */
> pci_fixup_final, /* Final phase of device fixups */
> pci_fixup_enable, /* pci_enable_device() time */
> - pci_fixup_resume, /* pci_enable_device() time */
> + pci_fixup_resume, /* pci_device_resume() */
> + pci_fixup_suspend, /* pci_device_suspend */
> + pci_fixup_resume_early, /* pci_device_resume_early() */
> };
>
> /* Anonymous variables would be nice... */
> @@ -1037,6 +1039,12 @@ enum pci_fixup_pass {
> #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
> DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
> resume##vendor##device##hook, vendor, device, hook)
> +#define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \
> + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
> + resume_early##vendor##device##hook, vendor, device, hook)
> +#define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \
> + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
> + suspend##vendor##device##hook, vendor, device, hook)
>
>
> void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
--
"Premature optimization is the root of all evil." - Donald Knuth
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC] fix asus_hides_smbus_lpc_ich6() for resume
2008-04-16 17:30 ` Rafael J. Wysocki
@ 2008-04-17 2:16 ` Shaohua Li
0 siblings, 0 replies; 21+ messages in thread
From: Shaohua Li @ 2008-04-17 2:16 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Jesse Barnes, linux-pci, Greg KH, linux acpi, Len Brown
On Wed, 2008-04-16 at 19:30 +0200, Rafael J. Wysocki wrote:
> On Tuesday, 18 of March 2008, Shaohua Li wrote:
> >
> > On Mon, 2008-03-17 at 17:26 +0100, Rafael J. Wysocki wrote:
> > > On Monday, 17 of March 2008, Shaohua Li wrote:
> > > >
> > > > On Fri, 2008-03-14 at 22:03 +0100, Rafael J. Wysocki wrote:
> > > > > On Friday, 14 of March 2008, Jesse Barnes wrote:
> > > > > > On Friday, March 14, 2008 7:37 am Rafael J. Wysocki wrote:
> > > > > > > On Friday, 14 of March 2008, Shaohua Li wrote:
> > > > > > > > On Thu, 2008-03-13 at 21:44 -0700, Greg KH wrote:
> > > > > > > > > On Fri, Mar 14, 2008 at 11:49:09AM +0800, Shaohua Li wrote:
> > > > > > > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > > > > > > index 9010f54..821ad02 100644
> > > > > > > > > > --- a/include/linux/pci.h
> > > > > > > > > > +++ b/include/linux/pci.h
> > > > > > > > > > @@ -1016,6 +1016,8 @@ enum pci_fixup_pass {
> > > > > > > > > > pci_fixup_final, /* Final phase of device fixups */
> > > > > > > > > > pci_fixup_enable, /* pci_enable_device() time */
> > > > > > > > > > pci_fixup_resume, /* pci_enable_device() time */
> > > > > > > > > > + pci_fixup_suspend,
> > > > > > > > > > + pci_fixup_resume_later,
> > > > > > > > >
> > > > > > > > > Please document when these quirks are run.
> > > > > > > >
> > > > > > > > will do if you think the method is correct.
> > > > > > > >
> > > > > > > > > And why "_later"? What's wrong with the normal resume time?
> > > > > > > >
> > > > > > > > pci_fixup_resume is called in pci_device_resume_earily(), which is
> > > > > > > > called with interrupt disable, so I added a new one which is called at
> > > > > > > > pci_device_resume(), this routine is called with interrupt enabled.
> > > > > > >
> > > > > > > Is the pci_fixup_resume thing used at all? If it is, how can I check who
> > > > > > > uses it?
> > > > > >
> > > > > > Oh good catch, it looks like it's unused at this point (at least there's no
> > > > > > DECLARE_PCI_FIXUP_SUSPEND macro in pci.h), it was probably just put there for
> > > > > > completeness.
> > > > >
> > > > > It seems to be used only in quirks.c .
> > > > >
> > > > > I'd prefer to rename the existing one to pci_fixup_resume_noirq and define a
> > > > > new one called pci_fixup_resume to be used by pci_device_resume().
> > > > >
> > > > > Also, it would be worth checking if all of the existing resume quirks need to
> > > > > be run with interrupts disabled.
> > > > As far as I checked, only this one need interrupt enabled.
> > >
> > > Still, do all of the others _require_ interrupts to be disabled?
> > No, they don't need interrupt disabled, but be called in .resume_early,
> > which will disable interrupt.
> >
> > > > Introducing
> > > > pci_fixup_resume_noirq and move the quirk to .resume is feasible in the
> > > > case, but it's not quite good to me. The quirk is to make smbus
> > > > controller not hide and then smbus can be resumed, the order is
> > > > important. If the quirk is called in .resume, that means smbus
> > > > controller can't have a .resume_early. The quirk is a FIXUP_HEADER, it
> > > > really should be called early, eg in .resume_early.
> > >
> > > I meant "move all of the other quirks that need to run with interrupts
> > > disabled to pci_fixup_resume_noirq, leave those that may run with interrups
> > > enabled within pci_fixup_resume and add yours to pci_fixup_resume".
> > Just change the name? then I'd prefer use pci_fixup_resume and
> > pci_fixup_resume_early.
> >
> > Some quirks should be called with interrupt disabled, we can't directly
> > call them in .resume_early. Also the patch introduces
> > pci_fixup_resume_early and pci_fixup_suspend, which matches current
> > device core callbacks (.suspend/.resume_early).
> >
> > TBD: Somebody knows why we need quirk resume should double check if a
> > quirk should be called in resume or resume_early. I changed some per my
> > understanding, but can't make sure I fixed all.
>
> What is the current status of this patch. Would you like it to be merged as is
> or are you going to modify it?
If no objection, I'd like it to be merged.
Thanks,
Shaohua
> > Signed-off-by: Shaohua Li <shaohua.li@intel.com>
> > diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> > index e571c72..59307d6 100644
> > --- a/drivers/pci/pci-driver.c
> > +++ b/drivers/pci/pci-driver.c
> > @@ -289,6 +289,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
> > if (pci_dev->current_state == PCI_D0)
> > pci_dev->current_state = PCI_UNKNOWN;
> > }
> > +
> > + pci_fixup_device(pci_fixup_suspend, pci_dev);
> > +
> > return i;
> > }
> >
> > @@ -334,6 +337,7 @@ static int pci_device_resume(struct device * dev)
> > error = drv->resume(pci_dev);
> > else
> > error = pci_default_resume(pci_dev);
> > + pci_fixup_device(pci_fixup_resume, pci_dev);
> > return error;
> > }
> >
> > @@ -343,7 +347,7 @@ static int pci_device_resume_early(struct device * dev)
> > struct pci_dev * pci_dev = to_pci_dev(dev);
> > struct pci_driver * drv = pci_dev->driver;
> >
> > - pci_fixup_device(pci_fixup_resume, pci_dev);
> > + pci_fixup_device(pci_fixup_resume_early, pci_dev);
> >
> > if (drv && drv->resume_early)
> > error = drv->resume_early(pci_dev);
> > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> > index e9a333d..21e9cdb 100644
> > --- a/drivers/pci/quirks.c
> > +++ b/drivers/pci/quirks.c
> > @@ -556,7 +556,7 @@ static void quirk_via_ioapic(struct pci_dev *dev)
> > pci_write_config_byte (dev, 0x58, tmp);
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic);
> >
> > /*
> > * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
> > @@ -576,7 +576,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
> > }
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
> >
> > /*
> > * The AMD io apic can hang the box when an apic irq is masked.
> > @@ -622,7 +622,7 @@ static void quirk_amd_8131_ioapic(struct pci_dev *dev)
> > }
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
> > #endif /* CONFIG_X86_IO_APIC */
> >
> > /*
> > @@ -774,7 +774,7 @@ static void quirk_cardbus_legacy(struct pci_dev *dev)
> > pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
> >
> > /*
> > * Following the PCI ordering rules is optional on the AMD762. I'm not
> > @@ -797,7 +797,7 @@ static void quirk_amd_ordering(struct pci_dev *dev)
> > }
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
> >
> > /*
> > * DreamWorks provided workaround for Dunord I-3000 problem
> > @@ -865,7 +865,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
> > }
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
> >
> > static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
> > {
> > @@ -885,9 +885,9 @@ static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
> > }
> > }
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
> >
> > /*
> > * Serverworks CSB5 IDE does not fully support native mode
> > @@ -1092,31 +1092,61 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
> >
> > -static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
> > +/* It appears we just have one such device. If not, we have a warning */
> > +static void __iomem *asus_rcba_base;
> > +static void asus_hides_smbus_lpc_ich6_suspend(struct pci_dev *dev)
> > {
> > - u32 val, rcba;
> > - void __iomem *base;
> > + u32 rcba;
> >
> > if (likely(!asus_hides_smbus))
> > return;
> > + WARN_ON(asus_rcba_base);
> > +
> > pci_read_config_dword(dev, 0xF0, &rcba);
> > - base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
> > - if (base == NULL) return;
> > - val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
> > - writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
> > - iounmap(base);
> > + /* use bits 31:14, 16 kB aligned */
> > + asus_rcba_base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000);
> > + if (asus_rcba_base == NULL)
> > + return;
> > +}
> > +
> > +static void asus_hides_smbus_lpc_ich6_resume_early(struct pci_dev *dev)
> > +{
> > + u32 val;
> > +
> > + if (likely(!asus_hides_smbus || !asus_rcba_base))
> > + return;
> > + /* read the Function Disable register, dword mode only */
> > + val = readl(asus_rcba_base + 0x3418);
> > + writel(val & 0xFFFFFFF7, asus_rcba_base + 0x3418); /* enable the SMBus device */
> > +}
> > +
> > +static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
> > +{
> > + if (likely(!asus_hides_smbus || !asus_rcba_base))
> > + return;
> > + iounmap(asus_rcba_base);
> > + asus_rcba_base = NULL;
> > dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
> > }
> > +
> > +static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
> > +{
> > + asus_hides_smbus_lpc_ich6_suspend(dev);
> > + asus_hides_smbus_lpc_ich6_resume_early(dev);
> > + asus_hides_smbus_lpc_ich6_resume(dev);
> > +}
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
> > +DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_suspend);
> > +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume_early);
> >
> > /*
> > * SiS 96x south bridge: BIOS typically hides SMBus device...
> > @@ -1134,10 +1164,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
> >
> > /*
> > * ... This is further complicated by the fact that some SiS96x south
> > @@ -1171,7 +1201,7 @@ static void quirk_sis_503(struct pci_dev *dev)
> > quirk_sis_96x_smbus(dev);
> > }
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
> >
> >
> > /*
> > @@ -1204,7 +1234,7 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
> > }
> > }
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
> >
> > #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
> >
> > @@ -1269,12 +1299,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, qui
> > DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
> > DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
> > DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
> >
> > #endif
> >
> > @@ -1521,6 +1551,10 @@ extern struct pci_fixup __start_pci_fixups_enable[];
> > extern struct pci_fixup __end_pci_fixups_enable[];
> > extern struct pci_fixup __start_pci_fixups_resume[];
> > extern struct pci_fixup __end_pci_fixups_resume[];
> > +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[];
> >
> >
> > void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
> > @@ -1553,6 +1587,16 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
> > end = __end_pci_fixups_resume;
> > break;
> >
> > + case pci_fixup_resume_early:
> > + start = __start_pci_fixups_resume_early;
> > + end = __end_pci_fixups_resume_early;
> > + break;
> > +
> > + case pci_fixup_suspend:
> > + start = __start_pci_fixups_suspend;
> > + end = __end_pci_fixups_suspend;
> > + break;
> > +
> > default:
> > /* stupid compiler warning, you would think with an enum... */
> > return;
> > @@ -1629,7 +1673,7 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
> > }
> > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
> > quirk_nvidia_ck804_pcie_aer_ext_cap);
> > -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
> > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
> > quirk_nvidia_ck804_pcie_aer_ext_cap);
> >
> > static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
> > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> > index f054778..cf108a3 100644
> > --- a/include/asm-generic/vmlinux.lds.h
> > +++ b/include/asm-generic/vmlinux.lds.h
> > @@ -84,6 +84,12 @@
> > VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
> > *(.pci_fixup_resume) \
> > VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
> > + VMLINUX_SYMBOL(__start_pci_fixups_resume_early) = .; \
> > + *(.pci_fixup_resume_early) \
> > + VMLINUX_SYMBOL(__end_pci_fixups_resume_early) = .; \
> > + VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \
> > + *(.pci_fixup_suspend) \
> > + VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \
> > } \
> > \
> > /* RapidIO route ops */ \
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index b7e4b63..ec68b45 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -1015,7 +1015,9 @@ enum pci_fixup_pass {
> > pci_fixup_header, /* After reading configuration header */
> > pci_fixup_final, /* Final phase of device fixups */
> > pci_fixup_enable, /* pci_enable_device() time */
> > - pci_fixup_resume, /* pci_enable_device() time */
> > + pci_fixup_resume, /* pci_device_resume() */
> > + pci_fixup_suspend, /* pci_device_suspend */
> > + pci_fixup_resume_early, /* pci_device_resume_early() */
> > };
> >
> > /* Anonymous variables would be nice... */
> > @@ -1037,6 +1039,12 @@ enum pci_fixup_pass {
> > #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
> > DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
> > resume##vendor##device##hook, vendor, device, hook)
> > +#define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \
> > + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
> > + resume_early##vendor##device##hook, vendor, device, hook)
> > +#define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \
> > + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
> > + suspend##vendor##device##hook, vendor, device, hook)
> >
> >
> > void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
> >
>
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2008-04-17 2:13 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-14 3:49 [RFC] fix asus_hides_smbus_lpc_ich6() for resume Shaohua Li
2008-03-14 4:44 ` Greg KH
2008-03-14 7:50 ` Shaohua Li
2008-03-14 14:37 ` Rafael J. Wysocki
2008-03-14 17:15 ` Jesse Barnes
2008-03-14 21:03 ` Rafael J. Wysocki
2008-03-17 1:15 ` Shaohua Li
2008-03-17 16:26 ` Rafael J. Wysocki
2008-03-18 3:11 ` Shaohua Li
2008-04-16 17:30 ` Rafael J. Wysocki
2008-04-17 2:16 ` Shaohua Li
2008-03-14 12:26 ` Matthew Wilcox
2008-03-14 14:34 ` Rafael J. Wysocki
2008-03-14 14:43 ` Matthew Wilcox
2008-03-14 15:44 ` Rafael J. Wysocki
2008-03-14 17:14 ` Jesse Barnes
2008-03-17 3:40 ` Sergio Monteiro Basto
2008-03-17 21:39 ` Sergio Monteiro Basto
2008-03-18 3:14 ` Shaohua Li
2008-03-18 23:47 ` Sergio Monteiro Basto
2008-04-06 2:05 ` Sergio Monteiro Basto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox