-#ifdef CONFIG_PM
-
-static LIST_HEAD(sleep_notifiers);
-
-int
-pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
-{
- struct list_head *list;
- struct pmu_sleep_notifier *notifier;
-
- for (list = sleep_notifiers.next; list != &sleep_notifiers;
- list = list->next) {
- notifier = list_entry(list, struct pmu_sleep_notifier, list);
- if (n->priority > notifier->priority)
- break;
- }
- __list_add(&n->list, list->prev, list);
- return 0;
-}
-EXPORT_SYMBOL(pmu_register_sleep_notifier);
-
-int
-pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
-{
- if (n->list.next == 0)
- return -ENOENT;
- list_del(&n->list);
- n->list.next = NULL;
- return 0;
-}
-EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
-#endif /* CONFIG_PM */
-
-#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
-
-/* Sleep is broadcast last-to-first */
-static int
-broadcast_sleep(int when, int fallback)
-{
- int ret = PBOOK_SLEEP_OK;
- struct list_head *list;
- struct pmu_sleep_notifier *notifier;
-
- for (list = sleep_notifiers.prev; list != &sleep_notifiers;
- list = list->prev) {
- notifier = list_entry(list, struct pmu_sleep_notifier, list);
- ret = notifier->notifier_call(notifier, when);
- if (ret != PBOOK_SLEEP_OK) {
- printk(KERN_DEBUG "sleep %d rejected by %p (%p)\n",
- when, notifier, notifier->notifier_call);
- for (; list != &sleep_notifiers; list = list->next) {
- notifier = list_entry(list, struct pmu_sleep_notifier, list);
- notifier->notifier_call(notifier, fallback);
- }
- return ret;
- }
- }
- return ret;
-}
-
-/* Wake is broadcast first-to-last */
-static int
-broadcast_wake(void)
-{
- int ret = PBOOK_SLEEP_OK;
- struct list_head *list;
- struct pmu_sleep_notifier *notifier;
-
- for (list = sleep_notifiers.next; list != &sleep_notifiers;
- list = list->next) {
- notifier = list_entry(list, struct pmu_sleep_notifier, list);
- notifier->notifier_call(notifier, PBOOK_WAKE);
- }
- return ret;
-}
-
-/*
- * This struct is used to store config register values for
- * PCI devices which may get powered off when we sleep.
- */
-static struct pci_save {
-#ifndef HACKED_PCI_SAVE
- u16 command;
- u16 cache_lat;
- u16 intr;
- u32 rom_address;
-#else
- u32 config[16];
-#endif
-} *pbook_pci_saves;
-static int pbook_npci_saves;
-
-static void
-pbook_alloc_pci_save(void)
-{
- int npci;
- struct pci_dev *pd = NULL;
-
- npci = 0;
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
- ++npci;
- }
- if (npci == 0)
- return;
- pbook_pci_saves = (struct pci_save *)
- kmalloc(npci * sizeof(struct pci_save), GFP_KERNEL);
- pbook_npci_saves = npci;
-}
-
-static void
-pbook_free_pci_save(void)
-{
- if (pbook_pci_saves == NULL)
- return;
- kfree(pbook_pci_saves);
- pbook_pci_saves = NULL;
- pbook_npci_saves = 0;
-}
-
-static void
-pbook_pci_save(void)
-{
- struct pci_save *ps = pbook_pci_saves;
- struct pci_dev *pd = NULL;
- int npci = pbook_npci_saves;
-
- if (ps == NULL)
- return;
-
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
- if (npci-- == 0)
- return;
-#ifndef HACKED_PCI_SAVE
- pci_read_config_word(pd, PCI_COMMAND, &ps->command);
- pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
- pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
- pci_read_config_dword(pd, PCI_ROM_ADDRESS, &ps->rom_address);
-#else
- int i;
- for (i=1;i<16;i++)
- pci_read_config_dword(pd, i<<4, &ps->config[i]);
-#endif
- ++ps;
- }
-}
-
-/* For this to work, we must take care of a few things: If gmac was enabled
- * during boot, it will be in the pci dev list. If it's disabled at this point
- * (and it will probably be), then you can't access it's config space.
- */
-static void
-pbook_pci_restore(void)
-{
- u16 cmd;
- struct pci_save *ps = pbook_pci_saves - 1;
- struct pci_dev *pd = NULL;
- int npci = pbook_npci_saves;
- int j;
-
- while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
-#ifdef HACKED_PCI_SAVE
- int i;
- if (npci-- == 0)
- return;
- ps++;
- for (i=2;i<16;i++)
- pci_write_config_dword(pd, i<<4, ps->config[i]);
- pci_write_config_dword(pd, 4, ps->config[1]);
-#else
- if (npci-- == 0)
- return;
- ps++;
- if (ps->command == 0)
- continue;
- pci_read_config_word(pd, PCI_COMMAND, &cmd);
- if ((ps->command & ~cmd) == 0)
- continue;
- switch (pd->hdr_type) {
- case PCI_HEADER_TYPE_NORMAL:
- for (j = 0; j < 6; ++j)
- pci_write_config_dword(pd,
- PCI_BASE_ADDRESS_0 + j*4,
- pd->resource[j].start);
- pci_write_config_dword(pd, PCI_ROM_ADDRESS,
- ps->rom_address);
- pci_write_config_word(pd, PCI_CACHE_LINE_SIZE,
- ps->cache_lat);
- pci_write_config_word(pd, PCI_INTERRUPT_LINE,
- ps->intr);
- pci_write_config_word(pd, PCI_COMMAND, ps->command);
- break;
- }
-#endif
- }
-}
-
-#ifdef DEBUG_SLEEP
-/* N.B. This doesn't work on the 3400 */
-void
-pmu_blink(int n)
-{
- struct adb_request req;
-
- memset(&req, 0, sizeof(req));
-
- for (; n > 0; --n) {
- req.nbytes = 4;
- req.done = NULL;
- req.data[0] = 0xee;
- req.data[1] = 4;
- req.data[2] = 0;
- req.data[3] = 1;
- req.reply[0] = ADB_RET_OK;
- req.reply_len = 1;
- req.reply_expected = 0;
- pmu_polled_request(&req);
- mdelay(50);
- req.nbytes = 4;
- req.done = NULL;
- req.data[0] = 0xee;
- req.data[1] = 4;
- req.data[2] = 0;
- req.data[3] = 0;
- req.reply[0] = ADB_RET_OK;
- req.reply_len = 1;
- req.reply_expected = 0;
- pmu_polled_request(&req);
- mdelay(50);
- }
- mdelay(50);
-}
-#endif
-