diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/aty/radeon_pm.c | 24 | ||||
-rw-r--r-- | drivers/video/au1100fb.c | 31 | ||||
-rw-r--r-- | drivers/video/au1200fb.c | 25 | ||||
-rw-r--r-- | drivers/video/pmag-ba-fb.c | 17 | ||||
-rw-r--r-- | drivers/video/pmagb-b-fb.c | 17 | ||||
-rw-r--r-- | drivers/video/ps3fb.c | 2 | ||||
-rw-r--r-- | drivers/video/pvr2fb.c | 16 | ||||
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 68 | ||||
-rw-r--r-- | drivers/video/tmiofb.c | 2 | ||||
-rw-r--r-- | drivers/video/uvesafb.c | 5 |
10 files changed, 146 insertions, 61 deletions
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 81603f85e17..c6d7cc76516 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c @@ -2507,6 +2507,25 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) #endif /* CONFIG_PPC_OF */ +static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t state) +{ + u16 pwr_cmd; + + for (;;) { + pci_read_config_word(rinfo->pdev, + rinfo->pm_reg+PCI_PM_CTRL, + &pwr_cmd); + if (pwr_cmd & 2) + break; + pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2; + pci_write_config_word(rinfo->pdev, + rinfo->pm_reg+PCI_PM_CTRL, + pwr_cmd); + msleep(500); + } + rinfo->pdev->current_state = state; +} + static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) { u32 tmp; @@ -2558,6 +2577,11 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) /* Switch PCI power management to D2. */ pci_disable_device(rinfo->pdev); pci_save_state(rinfo->pdev); + /* The chip seems to need us to whack the PM register + * repeatedly until it sticks. We do that -prior- to + * calling pci_set_power_state() + */ + radeonfb_whack_power_state(rinfo, PCI_D2); pci_set_power_state(rinfo->pdev, PCI_D2); } else { printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 62bd4441b5e..378f27745a1 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops = /* AU1100 LCD controller device driver */ -static int __init au1100fb_drv_probe(struct device *dev) +static int __init au1100fb_drv_probe(struct platform_device *dev) { struct au1100fb_device *fbdev = NULL; struct resource *regs_res; @@ -475,7 +475,7 @@ static int __init au1100fb_drv_probe(struct device *dev) fbdev->panel = &known_lcd_panels[drv_info.panel_idx]; - dev_set_drvdata(dev, (void*)fbdev); + platform_set_drvdata(dev, (void *)fbdev); /* Allocate region for our registers and map them */ if (!(regs_res = platform_get_resource(to_platform_device(dev), @@ -583,19 +583,19 @@ failed: fb_dealloc_cmap(&fbdev->info.cmap); } kfree(fbdev); - dev_set_drvdata(dev, NULL); + platform_set_drvdata(dev, NULL); return 0; } -int au1100fb_drv_remove(struct device *dev) +int au1100fb_drv_remove(struct platform_device *dev) { struct au1100fb_device *fbdev = NULL; if (!dev) return -ENODEV; - fbdev = (struct au1100fb_device*) dev_get_drvdata(dev); + fbdev = (struct au1100fb_device *) platform_get_drvdata(dev); #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); @@ -620,9 +620,9 @@ int au1100fb_drv_remove(struct device *dev) static u32 sys_clksrc; static struct au1100fb_regs fbregs; -int au1100fb_drv_suspend(struct device *dev, pm_message_t state) +int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) { - struct au1100fb_device *fbdev = dev_get_drvdata(dev); + struct au1100fb_device *fbdev = platform_get_drvdata(dev); if (!fbdev) return 0; @@ -641,9 +641,9 @@ int au1100fb_drv_suspend(struct device *dev, pm_message_t state) return 0; } -int au1100fb_drv_resume(struct device *dev) +int au1100fb_drv_resume(struct platform_device *dev) { - struct au1100fb_device *fbdev = dev_get_drvdata(dev); + struct au1100fb_device *fbdev = platform_get_drvdata(dev); if (!fbdev) return 0; @@ -663,10 +663,11 @@ int au1100fb_drv_resume(struct device *dev) #define au1100fb_drv_resume NULL #endif -static struct device_driver au1100fb_driver = { - .name = "au1100-lcd", - .bus = &platform_bus_type, - +static struct platform_driver au1100fb_driver = { + .driver = { + .name = "au1100-lcd", + .owner = THIS_MODULE, + }, .probe = au1100fb_drv_probe, .remove = au1100fb_drv_remove, .suspend = au1100fb_drv_suspend, @@ -753,12 +754,12 @@ int __init au1100fb_init(void) return ret; } - return driver_register(&au1100fb_driver); + return platform_driver_register(&au1100fb_driver); } void __exit au1100fb_cleanup(void) { - driver_unregister(&au1100fb_driver); + platform_driver_unregister(&au1100fb_driver); kfree(drv_info.opt_mode); } diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 03e57ef8837..0d96f1d2d4c 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -1622,7 +1622,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) /* AU1200 LCD controller device driver */ -static int au1200fb_drv_probe(struct device *dev) +static int au1200fb_drv_probe(struct platform_device *dev) { struct au1200fb_device *fbdev; unsigned long page; @@ -1645,7 +1645,7 @@ static int au1200fb_drv_probe(struct device *dev) /* Allocate the framebuffer to the maximum screen size */ fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - fbdev->fb_mem = dma_alloc_noncoherent(dev, + fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { @@ -1715,7 +1715,7 @@ failed: return ret; } -static int au1200fb_drv_remove(struct device *dev) +static int au1200fb_drv_remove(struct platform_device *dev) { struct au1200fb_device *fbdev; int plane; @@ -1733,7 +1733,8 @@ static int au1200fb_drv_remove(struct device *dev) /* Clean up all probe data */ unregister_framebuffer(&fbdev->fb_info); if (fbdev->fb_mem) - dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), + dma_free_noncoherent(&dev->dev, + PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, fbdev->fb_phys); if (fbdev->fb_info.cmap.len != 0) fb_dealloc_cmap(&fbdev->fb_info.cmap); @@ -1747,22 +1748,24 @@ static int au1200fb_drv_remove(struct device *dev) } #ifdef CONFIG_PM -static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level) +static int au1200fb_drv_suspend(struct platform_device *dev, u32 state) { /* TODO */ return 0; } -static int au1200fb_drv_resume(struct device *dev, u32 level) +static int au1200fb_drv_resume(struct platform_device *dev) { /* TODO */ return 0; } #endif /* CONFIG_PM */ -static struct device_driver au1200fb_driver = { - .name = "au1200-lcd", - .bus = &platform_bus_type, +static struct platform_driver au1200fb_driver = { + .driver = { + .name = "au1200-lcd", + .owner = THIS_MODULE, + }, .probe = au1200fb_drv_probe, .remove = au1200fb_drv_remove, #ifdef CONFIG_PM @@ -1906,12 +1909,12 @@ static int __init au1200fb_init(void) printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n"); #endif - return driver_register(&au1200fb_driver); + return platform_driver_register(&au1200fb_driver); } static void __exit au1200fb_cleanup(void) { - driver_unregister(&au1200fb_driver); + platform_driver_unregister(&au1200fb_driver); } module_init(au1200fb_init); diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index 3a3f80f6521..0573ec685a5 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c @@ -151,7 +151,7 @@ static int __init pmagbafb_probe(struct device *dev) info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); if (!info) { - printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id); + printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); return -ENOMEM; } @@ -160,7 +160,7 @@ static int __init pmagbafb_probe(struct device *dev) if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { printk(KERN_ERR "%s: Cannot allocate color map\n", - dev->bus_id); + dev_name(dev)); err = -ENOMEM; goto err_alloc; } @@ -173,8 +173,9 @@ static int __init pmagbafb_probe(struct device *dev) /* Request the I/O MEM resource. */ start = tdev->resource.start; len = tdev->resource.end - start + 1; - if (!request_mem_region(start, len, dev->bus_id)) { - printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id); + if (!request_mem_region(start, len, dev_name(dev))) { + printk(KERN_ERR "%s: Cannot reserve FB region\n", + dev_name(dev)); err = -EBUSY; goto err_cmap; } @@ -183,7 +184,7 @@ static int __init pmagbafb_probe(struct device *dev) info->fix.mmio_start = start; par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); if (!par->mmio) { - printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id); + printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev)); err = -ENOMEM; goto err_resource; } @@ -194,7 +195,7 @@ static int __init pmagbafb_probe(struct device *dev) info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); if (!info->screen_base) { - printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id); + printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev)); err = -ENOMEM; goto err_mmio_map; } @@ -205,14 +206,14 @@ static int __init pmagbafb_probe(struct device *dev) err = register_framebuffer(info); if (err < 0) { printk(KERN_ERR "%s: Cannot register framebuffer\n", - dev->bus_id); + dev_name(dev)); goto err_smem_map; } get_device(dev); pr_info("fb%d: %s frame buffer device at %s\n", - info->node, info->fix.id, dev->bus_id); + info->node, info->fix.id, dev_name(dev)); return 0; diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 9b80597241b..98748723af9 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c @@ -258,7 +258,7 @@ static int __init pmagbbfb_probe(struct device *dev) info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev); if (!info) { - printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id); + printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); return -ENOMEM; } @@ -267,7 +267,7 @@ static int __init pmagbbfb_probe(struct device *dev) if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { printk(KERN_ERR "%s: Cannot allocate color map\n", - dev->bus_id); + dev_name(dev)); err = -ENOMEM; goto err_alloc; } @@ -280,8 +280,9 @@ static int __init pmagbbfb_probe(struct device *dev) /* Request the I/O MEM resource. */ start = tdev->resource.start; len = tdev->resource.end - start + 1; - if (!request_mem_region(start, len, dev->bus_id)) { - printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id); + if (!request_mem_region(start, len, dev_name(dev))) { + printk(KERN_ERR "%s: Cannot reserve FB region\n", + dev_name(dev)); err = -EBUSY; goto err_cmap; } @@ -290,7 +291,7 @@ static int __init pmagbbfb_probe(struct device *dev) info->fix.mmio_start = start; par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); if (!par->mmio) { - printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id); + printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev)); err = -ENOMEM; goto err_resource; } @@ -301,7 +302,7 @@ static int __init pmagbbfb_probe(struct device *dev) info->fix.smem_start = start + PMAGB_B_FBMEM; par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); if (!par->smem) { - printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id); + printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev)); err = -ENOMEM; goto err_mmio_map; } @@ -316,7 +317,7 @@ static int __init pmagbbfb_probe(struct device *dev) err = register_framebuffer(info); if (err < 0) { printk(KERN_ERR "%s: Cannot register framebuffer\n", - dev->bus_id); + dev_name(dev)); goto err_smem_map; } @@ -328,7 +329,7 @@ static int __init pmagbbfb_probe(struct device *dev) par->osc1 / 1000, par->osc1 % 1000); pr_info("fb%d: %s frame buffer device at %s\n", - info->node, info->fix.id, dev->bus_id); + info->node, info->fix.id, dev_name(dev)); pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n", info->node, freq0, par->osc1 ? freq1 : "disabled", par->osc1 != 0); diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 87f826e4c95..e00c1dff55d 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -1213,7 +1213,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) dev->core.driver_data = info; dev_info(info->device, "%s %s, using %u KiB of video memory\n", - dev_driver_string(info->dev), info->dev->bus_id, + dev_driver_string(info->dev), dev_name(info->dev), info->fix.smem_len >> 10); task = kthread_run(ps3fbd, info, DEVICE_NAME); diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 0a0fd48a856..53f8f1100e8 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -61,7 +61,7 @@ #include <mach-dreamcast/mach/sysasic.h> #endif -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA #include <linux/pagemap.h> #include <mach/dma.h> #include <asm/dma.h> @@ -188,7 +188,7 @@ static unsigned int is_blanked = 0; /* Is the screen blanked? */ static unsigned long pvr2fb_map; #endif -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA static unsigned int shdma = PVR2_CASCADE_CHAN; static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; #endif @@ -207,7 +207,7 @@ static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id); static int pvr2_init_cable(void); static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, int size); -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, size_t count, loff_t *ppos); #endif @@ -218,7 +218,7 @@ static struct fb_ops pvr2fb_ops = { .fb_blank = pvr2fb_blank, .fb_check_var = pvr2fb_check_var, .fb_set_par = pvr2fb_set_par, -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA .fb_write = pvr2fb_write, #endif .fb_fillrect = cfb_fillrect, @@ -671,7 +671,7 @@ static int pvr2_init_cable(void) return cable_type; } -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, size_t count, loff_t *ppos) { @@ -743,7 +743,7 @@ out_unmap: return ret; } -#endif /* CONFIG_SH_DMA */ +#endif /* CONFIG_PVR2_DMA */ /** * pvr2fb_common_init @@ -893,7 +893,7 @@ static int __init pvr2fb_dc_init(void) return -EBUSY; } -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA if (request_dma(pvr2dma, "pvr2") != 0) { free_irq(HW_EVENT_VSYNC, 0); return -EBUSY; @@ -915,7 +915,7 @@ static void __exit pvr2fb_dc_exit(void) } free_irq(HW_EVENT_VSYNC, 0); -#ifdef CONFIG_SH_DMA +#ifdef CONFIG_PVR2_DMA free_dma(pvr2dma); #endif } diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 2c5d069e5f0..92ea0ab44ce 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -33,6 +33,8 @@ struct sh_mobile_lcdc_chan { struct fb_info info; dma_addr_t dma_handle; struct fb_deferred_io defio; + unsigned long frame_end; + wait_queue_head_t frame_end_wait; }; struct sh_mobile_lcdc_priv { @@ -226,7 +228,10 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) { struct sh_mobile_lcdc_priv *priv = data; + struct sh_mobile_lcdc_chan *ch; unsigned long tmp; + int is_sub; + int k; /* acknowledge interrupt */ tmp = lcdc_read(priv, _LDINTR); @@ -234,8 +239,24 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */ lcdc_write(priv, _LDINTR, tmp); - /* disable clocks */ - sh_mobile_lcdc_clk_off(priv); + /* figure out if this interrupt is for main or sub lcd */ + is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0; + + /* wake up channel and disable clocks*/ + for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { + ch = &priv->ch[k]; + + if (!ch->enabled) + continue; + + if (is_sub == lcdc_chan_is_sublcd(ch)) { + ch->frame_end = 1; + wake_up(&ch->frame_end_wait); + + sh_mobile_lcdc_clk_off(priv); + } + } + return IRQ_HANDLED; } @@ -448,18 +469,27 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) struct sh_mobile_lcdc_board_cfg *board_cfg; int k; - /* tell the board code to disable the panel */ + /* clean up deferred io and ask board code to disable panel */ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { ch = &priv->ch[k]; - board_cfg = &ch->cfg.board_cfg; - if (board_cfg->display_off) - board_cfg->display_off(board_cfg->board_data); - /* cleanup deferred io if enabled */ + /* deferred io mode: + * flush frame, and wait for frame end interrupt + * clean up deferred io and enable clock + */ if (ch->info.fbdefio) { + ch->frame_end = 0; + schedule_delayed_work(&ch->info.deferred_work, 0); + wait_event(ch->frame_end_wait, ch->frame_end); fb_deferred_io_cleanup(&ch->info); ch->info.fbdefio = NULL; + sh_mobile_lcdc_clk_on(priv); } + + board_cfg = &ch->cfg.board_cfg; + if (board_cfg->display_off) + board_cfg->display_off(board_cfg->board_data); + } /* stop the lcdc */ @@ -652,6 +682,26 @@ static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) return 0; } +static int sh_mobile_lcdc_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + sh_mobile_lcdc_stop(platform_get_drvdata(pdev)); + return 0; +} + +static int sh_mobile_lcdc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); +} + +static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { + .suspend = sh_mobile_lcdc_suspend, + .resume = sh_mobile_lcdc_resume, +}; + static int sh_mobile_lcdc_remove(struct platform_device *pdev); static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) @@ -687,7 +737,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) } error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, - pdev->dev.bus_id, priv); + dev_name(&pdev->dev), priv); if (error) { dev_err(&pdev->dev, "unable to request irq\n"); goto err1; @@ -707,6 +757,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "unsupported interface type\n"); goto err1; } + init_waitqueue_head(&priv->ch[i].frame_end_wait); switch (pdata->ch[i].chan) { case LCDC_CHAN_MAINLCD: @@ -860,6 +911,7 @@ static struct platform_driver sh_mobile_lcdc_driver = { .driver = { .name = "sh_mobile_lcdc_fb", .owner = THIS_MODULE, + .pm = &sh_mobile_lcdc_dev_pm_ops, }, .probe = sh_mobile_lcdc_probe, .remove = sh_mobile_lcdc_remove, diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c index 7baf2dd12d5..a1eb0862255 100644 --- a/drivers/video/tmiofb.c +++ b/drivers/video/tmiofb.c @@ -751,7 +751,7 @@ static int __devinit tmiofb_probe(struct platform_device *dev) } retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED, - dev->dev.bus_id, info); + dev_name(&dev->dev), info); if (retval) goto err_request_irq; diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 6c2d37fdd3b..74ae7589900 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -204,8 +204,11 @@ static int uvesafb_exec(struct uvesafb_ktask *task) } else { v86d_started = 1; err = cn_netlink_send(m, 0, gfp_any()); + if (err == -ENOBUFS) + err = 0; } - } + } else if (err == -ENOBUFS) + err = 0; if (!err && !(task->t.flags & TF_EXIT)) err = !wait_for_completion_timeout(task->done, |