#include #include #if defined(MODVERSIONS) #include #endif #include #include #include #include #include #include LIST_HEAD(pd_head); /* This is a device-to-powerdomain mapper table for fast searching */ struct pm_pdtype *pd_hashtbl[MAX_PMDEVS]; void init_pd_hashtbl(void) { int i; for(i=0; iname)) { dev->devid = get_free_devid(); if (dev->devid < 0) { printk(KERN_WARNING "Too many devices\n"); return -EINVAL; } dev->pd = pd; pd_hashtbl[dev->devid] = pd; list_add_tail(&dev->entry, &pd->devhead); return dev->devid; } } /* We only get here when we can't find this device's power domain */ printk(KERN_WARNING "can't find this device's pd\n"); return -EINVAL; } int pd_unregister_dev(struct pm_devtype *dev) { pd_hashtbl[dev->devid] = NULL; // free devid dev->devid = 0; list_del_init(&dev->entry); return 0; } int pd_on(struct pm_pdtype *pd) { struct list_head *temp; struct pm_devtype *pdev; int ret = 0; /* supply power */ if (pd->on) { ret = pd->on(pd); // redirect to machine dependent code /* resume all devices in this power domain */ list_for_each(temp, &pd->devhead) { pdev = list_entry(temp, struct pm_devtype, entry); /* do initialization if needed */ if (pdev->after_pdon) pdev->after_pdon(); } } /* we assume pd is always on if no pd->on is defined */ return ret; } int pd_off(struct pm_pdtype *pd) { struct list_head *temp; struct pm_devtype *pdev; if (pd->off) { /* suspend all devices in this power domain */ list_for_each(temp, &pd->devhead) { pdev = list_entry(temp, struct pm_devtype, entry); /* saving device context */ if (pdev->before_pdoff) pdev->before_pdoff(); } return pd->off(pd); } /* cannot turn off since no pd->off is defined */ return -EINVAL; } int pd_sync(struct pm_pdtype *pd) { pd_md_sync(); printk(KERN_INFO "pdfw synchronized\n"); return 0; } int __init pd_init(void) { /* initialize machine dependent data structure */ init_pd_hashtbl(); pd_md_init(); pd_md_sync(); printk(KERN_INFO "Power Domain Framework initialized\n"); return 0; } void __exit pd_exit(void) { pd_md_cleanup(); return; } #ifdef MODULE module_init(pd_init); module_exit(pd_exit); #else __initcall(pd_init); #endif EXPORT_SYMBOL(pd_register_dev); EXPORT_SYMBOL(pd_unregister_dev); EXPORT_SYMBOL(pd_on); EXPORT_SYMBOL(pd_off); EXPORT_SYMBOL(pd_sync); EXPORT_SYMBOL(pd_head); EXPORT_SYMBOL(pd_hashtbl); MODULE_AUTHOR("Ikhwan Lee"); MODULE_LICENSE("Dual BSD/GPL");