On Tuesday, 9 of September 2008, Li, Shaohua wrote: > >> > + > >> > /** > >> > * acpi_bus_notify > >> > * --------------- > >> > @@ -506,6 +519,8 @@ static void acpi_bus_notify(acpi_handle > >> > int result = 0; > >> > struct acpi_device *device = NULL; > >> > > >> > + blocking_notifier_call_chain(&acpi_bus_notify_list, > >> > + type, (void *)handle); > >> > >> Hm, perhaps I'm too tired and I'm missing something obvious, but can you > >> tell me please why that has to be a notifier chain? It looks like you > >add only > >> one notifier to it, so seemingly it could be replaced by a direct call to > >a > >> function like acpi_gpe_pme_handler() (with modified list of arguments). > >When the notifier chain is used, it can work regardless of whether the > >CONFIG_ACPI_GPE_WAKEUP is set. > >If the CONFIG_ACPI_GPE_WAKEUP is set, what you said is also OK. > I actually had another usage for this (I sent a patchset for docking station, which uses it) > > >> > if (acpi_bus_get_device(handle, &device)) > >> > return; > >> > Index: linux/drivers/acpi/sleep/wakeup.c > >> > =================================================================== > >> > --- linux.orig/drivers/acpi/sleep/wakeup.c 2008-09-08 > >14:28:55.000000000 +0800 > >> > +++ linux/drivers/acpi/sleep/wakeup.c 2008-09-08 > >15:04:23.000000000 +0800 > >> > @@ -142,6 +142,70 @@ void acpi_disable_wakeup_device(u8 sleep > >> > spin_unlock(&acpi_device_lock); > >> > } > >> > > >> > +#ifdef CONFIG_ACPI_GPE_WAKEUP > >> > +static int acpi_gpe_pme_check(struct acpi_device *dev) > >> > +{ > >> > + struct device *ldev; > >> > + > >> > + ldev = acpi_get_physical_device(dev->handle); > >> > + if (!ldev) > >> > + return -ENODEV; > >> > + /* > >> > + * AML code might already clear the event, so ignore the return > >value. > >> > + * Actually we can't correctly detect which device invokes GPE if > >the > >> > + * event is cleared. > >> > + */ > >> > + if (ldev->bus->pm && ldev->bus->pm->base.wakeup_event) > >> > + ldev->bus->pm->base.wakeup_event(ldev); > >> > + > >> > + /* > >> > + * We always send the event. AML code usually identifies the exact > >> > + * device of the GPE, let's trust it > >> > + */ > >> > + device_receive_wakeup_event(ldev); > >> > + > >> > + put_device(ldev); > >> > + return 0; > >> > +} > >> > + > >> > +static int acpi_gpe_pme_handler(struct notifier_block *nb, > >> > + unsigned long type, void *data) > >> > +{ > >> > + int ret; > >> > + acpi_handle handle = data; > >> > + struct acpi_device *dev; > >> > + > >> > + if (type != ACPI_NOTIFY_DEVICE_WAKE) > >> > + return NOTIFY_DONE; > >> > + > >> > + if (acpi_bus_get_device(handle, &dev)) > >> > + return NOTIFY_DONE; > >> > + > >> > + ret = acpi_gpe_pme_check(dev); > >> > + > >> > + acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, > >> > + ACPI_NOT_ISR); > >> > + > >> > >> At which point are dev->wakeup.gpe_device and dev->wakeup.gpe_number > >> determined, for example, for PCI devices, and how? > >In the boot phase a PCI device will be bound with an ACPI device. In the > >system based on ACPI(GPE) when a PCI device generates a wakeup event, an > >ACPI interrupt will be triggered and the ACPI AML code will send the > >device wakeup event to the corresponding ACPI device. In such case we > >can get the gpe number for the PCI device. > This is correct. For example: > > Method (_L07, 0, NotSerialized) > { > Notify (\_SB.PCI0.SMBS, 0x02) > } > > Method (_L05, 0, NotSerialized) > { > Notify (\_SB.PCI0.MODM, 0x02) > } > > GPE 5,7 are wakeup GPEs Well, it is not clear to me, though, which one of them is associated with the PME# signal. Also, the question was what piece of code in the kernel was responsible for the identification of the wake-up GPEs and for setting dev->wakeup.gpe_device and dev->wakeup.gpe_number as appropriate. In particular, how do we figure out which wake-up GPE will be used for signalling PME# for devices that are not on-board? Thanks, Rafael _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm