i915: fix memory leak

git-svn-id: svn://kolibrios.org@3037 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2012-11-14 06:08:43 +00:00
parent a34e834d07
commit c61318c4d9
13 changed files with 90 additions and 158 deletions

View File

@ -431,12 +431,9 @@ static int intel_gtt_init(void)
u32 gtt_map_size;
int ret;
ENTER();
ret = intel_private.driver->setup();
if (ret != 0)
{
LEAVE();
return ret;
};
@ -494,8 +491,6 @@ static int intel_gtt_init(void)
intel_private.base.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK);
LEAVE();
return 0;
}

View File

@ -16,19 +16,18 @@ struct hmm bm_mm;
extern struct drm_device *main_device;
void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
{
dma_addr_t *pages = bitmap->obj->allocated_pages;;
dma_addr_t *pages = bitmap->obj->allocated_pages;
int i;
printf("destroy bitmap %d\n", bitmap->handle);
free_handle(&bm_mm, bitmap->handle);
bitmap->handle = 0;
bitmap->obj->base.read_domains = I915_GEM_DOMAIN_GTT;
bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
mutex_lock(&main_device->struct_mutex);
drm_gem_object_unreference(&bitmap->obj->base);
mutex_unlock(&main_device->struct_mutex);
@ -37,6 +36,8 @@ void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
for (i = 0; i < bitmap->page_count; i++)
FreePage(pages[i]);
DRM_DEBUG("%s freec %d pages\n", __FUNCTION__, bitmap->page_count);
free(pages);
};
UserFree(bitmap->uaddr);
@ -212,6 +213,8 @@ int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap)
bitmap->max_count = max_count;
};
DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__, page_count);
obj = i915_gem_alloc_object(dev, size);
if (obj == NULL)
goto err4;
@ -243,7 +246,7 @@ int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap)
pbitmap->pitch = pitch;
printf("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
DRM_DEBUG("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
__FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
return 0;
@ -282,7 +285,9 @@ int lock_surface(struct io_call_12 *pbitmap)
if(unlikely(bitmap==NULL))
return -1;
mutex_lock(&main_device->struct_mutex);
ret = i915_gem_object_set_to_cpu_domain(bitmap->obj, true);
mutex_unlock(&main_device->struct_mutex);
if(ret != 0 )
{
@ -338,7 +343,7 @@ int get_driver_caps(hwcaps_t *caps)
void __attribute__((regparm(1))) destroy_context(struct context *context)
{
printf("destroy context %x\n", context);
DRM_DEBUG("destroy context %x\n", context);
context_map[context->slot] = NULL;
@ -365,7 +370,7 @@ struct context *get_context(struct drm_device *dev)
return context;
context = CreateObject(GetPid(), sizeof(*context));
printf("context %x\n", context);
if( context != NULL)
{
drm_i915_private_t *dev_priv = dev->dev_private;

View File

@ -1297,8 +1297,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
int ret = 0, mmio_bar, mmio_size;
uint32_t aperture_size;
ENTER();
info = (struct intel_device_info *) flags;
#if 0
@ -1384,17 +1382,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
dev_priv->mm.gtt_base_addr = dev_priv->mm.gtt->gma_bus_addr;
dbgprintf("gtt_base_addr %x aperture_size %d\n",
DRM_INFO("gtt_base_addr %x aperture_size %d\n",
dev_priv->mm.gtt_base_addr, aperture_size );
// dev_priv->mm.gtt_mapping =
// io_mapping_create_wc(dev_priv->mm.gtt_base_addr,
// aperture_size);
// if (dev_priv->mm.gtt_mapping == NULL) {
// ret = -EIO;
// goto out_rmmap;
// }
// i915_mtrr_setup(dev_priv, dev_priv->mm.gtt_base_addr,
// aperture_size);
@ -1489,8 +1479,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (IS_GEN5(dev))
intel_gpu_ips_init(dev_priv);
LEAVE();
return 0;
out_gem_unload:

View File

@ -455,7 +455,7 @@ int i915_init(void)
return -ENODEV;
}
dbgprintf("device %x:%x\n", device.pci_dev.vendor,
DRM_INFO("device %x:%x\n", device.pci_dev.vendor,
device.pci_dev.device);
if (intel_info->gen != 3) {
@ -475,8 +475,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
struct drm_device *dev;
int ret;
ENTER();
dev = kzalloc(sizeof(*dev), 0);
if (!dev)
return -ENOMEM;
@ -515,8 +513,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto err_g4;
LEAVE();
return 0;
err_g4:
@ -529,8 +525,6 @@ err_g4:
//err_g1:
free(dev);
LEAVE();
return ret;
}

View File

@ -1409,6 +1409,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
for (i = 0; i < obj->pages.nents; i++)
FreePage(obj->pages.page[i]);
DRM_DEBUG_KMS("%s free %d pages\n", __FUNCTION__, obj->pages.nents);
obj->dirty = 0;
kfree(obj->pages.page);
}
@ -1465,7 +1466,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
obj->pages.page[i] = page;
};
DRM_DEBUG_KMS("%s alloc %d pages\n", __FUNCTION__, page_count);
obj->pages.nents = page_count;
@ -1835,8 +1836,6 @@ i915_gem_retire_work_handler(struct work_struct *work)
bool idle;
int i;
// ENTER();
dev_priv = container_of(work, drm_i915_private_t,
mm.retire_work.work);
dev = dev_priv->dev;
@ -1844,7 +1843,6 @@ i915_gem_retire_work_handler(struct work_struct *work)
/* Come back later if the device is busy... */
if (!mutex_trylock(&dev->struct_mutex)) {
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
// LEAVE();
return;
}
@ -1867,7 +1865,6 @@ i915_gem_retire_work_handler(struct work_struct *work)
intel_mark_idle(dev);
mutex_unlock(&dev->struct_mutex);
// LEAVE();
}
/**

View File

@ -2518,7 +2518,6 @@ static struct drm_device *irq_device;
void irq_handler_kms()
{
printf("%s\n",__FUNCTION__);
ironlake_irq_handler(irq_device);
}
@ -2527,8 +2526,6 @@ int drm_irq_install(struct drm_device *dev)
int irq_line;
int ret = 0;
ENTER();
mutex_lock(&dev->struct_mutex);
/* Driver must have been initialized */
@ -2574,10 +2571,7 @@ int drm_irq_install(struct drm_device *dev)
PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
dbgprintf("PCI_CMD: %04x\n", cmd);
DRM_INFO("i915: irq initialized.\n");
LEAVE();
DRM_DEBUG("i915: irq initialized.\n");
return ret;
}

View File

@ -1821,7 +1821,6 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
I915_WRITE(reg, val & ~PIPECONF_ENABLE);
intel_wait_for_pipe_off(dev_priv->dev, pipe);
}
/*
@ -2216,7 +2215,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
mutex_unlock(&dev->struct_mutex);
DRM_ERROR("failed to update base address\n");
LEAVE();
return ret;
}
@ -3357,7 +3355,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
mutex_unlock(&dev->struct_mutex);
}
static void ironlake_crtc_off(struct drm_crtc *crtc)
@ -7486,7 +7483,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
dbgprintf("CRTC %d mode %x FB %x enable %d\n",
DRM_DEBUG_KMS("CRTC %d mode %x FB %x enable %d\n",
intel_crtc->base.base.id, intel_crtc->base.mode,
intel_crtc->base.fb, intel_crtc->base.enabled);

View File

@ -240,8 +240,6 @@ int intel_fbdev_init(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
ENTER();
ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
if (!ifbdev)
return -ENOMEM;
@ -260,8 +258,7 @@ int intel_fbdev_init(struct drm_device *dev)
drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
drm_fb_helper_initial_config(&ifbdev->helper, 32);
LEAVE();
return 0;
return 0;
}

View File

@ -34,7 +34,6 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
struct gmbus_port {
const char *name;
int reg;

View File

@ -33,7 +33,6 @@
#include <linux/moduleparam.h>
#include "intel_drv.h"
#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */
void

View File

@ -1104,24 +1104,13 @@ static bool g4x_compute_wm0(struct drm_device *dev,
int *cursor_wm)
{
struct drm_crtc *crtc;
int htotal, hdisplay, clock, pixel_size;
int line_time_us, line_count;
int entries, tlb_miss;
// ENTER();
// dbgprintf("plane %d display %x cursor %x \n", plane, display, cursor);
// dbgprintf("plane_wm %x cursor_wm %x \n", plane_wm, cursor_wm);
crtc = intel_get_crtc_for_plane(dev, plane);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
// dbgprintf("CRTC %d\n, fb %x, enabled %d\n",
// crtc->base.id, crtc->fb, crtc->enabled );
if (crtc->fb == NULL || !crtc->enabled || !intel_crtc->active) {
*cursor_wm = cursor->guard_size;
*plane_wm = display->guard_size;
@ -1133,8 +1122,6 @@ static bool g4x_compute_wm0(struct drm_device *dev,
clock = crtc->mode.clock;
pixel_size = crtc->fb->bits_per_pixel / 8;
// dbgprintf("mark 1\n");
/* Use the small buffer method to calculate plane watermark */
entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8;
@ -1145,37 +1132,18 @@ static bool g4x_compute_wm0(struct drm_device *dev,
if (*plane_wm > (int)display->max_wm)
*plane_wm = display->max_wm;
// dbgprintf("clock %d line_time_us %d\n",clock, line_time_us );
/* Use the large buffer method to calculate cursor watermark */
line_time_us = ((htotal * 1000) / clock);
line_count = (cursor_latency_ns / line_time_us + 1000) / 1000;
entries = line_count * 64 * pixel_size;
// dbgprintf("mark 3\n");
// dbgprintf("fifo size %d line size %d\n",
// cursor->fifo_size, cursor->cacheline_size);
tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8;
if (tlb_miss > 0)
entries += tlb_miss;
// dbgprintf("mark 4\n");
entries = DIV_ROUND_UP(entries, cursor->cacheline_size);
// dbgprintf("entries %d \n",entries);
*cursor_wm = entries + cursor->guard_size;
if (*cursor_wm > (int)cursor->max_wm)
*cursor_wm = (int)cursor->max_wm;
// LEAVE();
return true;
}
@ -1940,7 +1908,6 @@ static void sandybridge_update_wm(struct drm_device *dev)
(fbc_wm << WM1_LP_FBC_SHIFT) |
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
}
static void
@ -2163,7 +2130,6 @@ void intel_update_watermarks(struct drm_device *dev)
if (dev_priv->display.update_wm)
dev_priv->display.update_wm(dev);
}
void intel_update_linetime_watermarks(struct drm_device *dev,

View File

@ -1178,8 +1178,6 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
uint32_t __iomem *virt;
int rem = ring->size - ring->tail;
ENTER();
if (ring->space < rem) {
int ret = intel_wait_ring_buffer(ring, rem);
if (ret)
@ -1194,8 +1192,7 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
ring->tail = 0;
ring->space = ring_space(ring);
LEAVE();
return 0;
return 0;
}
static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno)

View File

@ -142,7 +142,7 @@ bool set_mode(struct drm_device *dev, struct drm_connector *connector,
};
};
printf("%s failed\n", __FUNCTION__);
DRM_ERROR("%s failed\n", __FUNCTION__);
return -1;
@ -202,7 +202,7 @@ do_set:
sysSetScreen(fb->width, fb->height, fb->pitches[0]);
dbgprintf("new mode %d x %d pitch %d\n",
DRM_DEBUG_KMS("new mode %d x %d pitch %d\n",
fb->width, fb->height, fb->pitches[0]);
}
else
@ -249,7 +249,7 @@ static struct drm_connector* get_def_connector(struct drm_device *dev)
crtc = encoder->crtc;
dbgprintf("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x",
DRM_DEBUG_KMS("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x",
connector, connector->base.id,
connector->status, connector->encoder,
crtc);
@ -278,8 +278,6 @@ int init_display_kms(struct drm_device *dev)
u32_t ifl;
int err;
// ENTER();
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
{
if( connector->status != connector_status_connected)
@ -289,14 +287,14 @@ int init_display_kms(struct drm_device *dev)
encoder = connector_funcs->best_encoder(connector);
if( encoder == NULL)
{
dbgprintf("CONNECTOR %x ID: %d no active encoders\n",
DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
connector, connector->base.id);
continue;
}
connector->encoder = encoder;
crtc = encoder->crtc;
dbgprintf("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
connector, connector->base.id,
connector->status, connector->encoder,
crtc, crtc->base.id );
@ -306,7 +304,7 @@ int init_display_kms(struct drm_device *dev)
if(connector == NULL)
{
dbgprintf("No active connectors!\n");
DRM_ERROR("No active connectors!\n");
return -1;
};
@ -329,7 +327,7 @@ int init_display_kms(struct drm_device *dev)
if(crtc == NULL)
{
dbgprintf("No CRTC for encoder %d\n", encoder->base.id);
DRM_ERROR("No CRTC for encoder %d\n", encoder->base.id);
return -1;
};
@ -371,13 +369,6 @@ int init_display_kms(struct drm_device *dev)
main_device = dev;
err = init_bitmaps();
if( !err )
{
printf("Initialize bitmap manager\n");
};
// LEAVE();
return 0;
};
@ -387,8 +378,6 @@ int get_videomodes(videomode_t *mode, int *count)
{
int err = -1;
// ENTER();
// dbgprintf("mode %x count %d\n", mode, *count);
if( *count == 0 )
@ -420,7 +409,6 @@ int get_videomodes(videomode_t *mode, int *count)
*count = i;
err = 0;
};
// LEAVE();
return err;
};
@ -428,8 +416,6 @@ int set_user_mode(videomode_t *mode)
{
int err = -1;
// ENTER();
// dbgprintf("width %d height %d vrefresh %d\n",
// mode->width, mode->height, mode->freq);
@ -444,17 +430,19 @@ int set_user_mode(videomode_t *mode)
err = 0;
};
// LEAVE();
return err;
};
void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
{
/* FIXME synchronization */
list_del(&cursor->list);
// radeon_bo_unpin(cursor->robj);
// KernelFree(cursor->data);
i915_gem_object_unpin(cursor->cobj);
mutex_lock(&main_device->struct_mutex);
drm_gem_object_unreference(&cursor->cobj->base);
mutex_unlock(&main_device->struct_mutex);
__DestroyObject(cursor);
};
@ -464,12 +452,11 @@ int init_cursor(cursor_t *cursor)
struct drm_i915_gem_object *obj;
uint32_t *bits;
uint32_t *src;
void *mapped;
int i,j;
int ret;
// ENTER();
if (dev_priv->info->cursor_needs_physical)
{
bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
@ -492,7 +479,7 @@ int init_cursor(cursor_t *cursor)
/* You don't need to worry about fragmentation issues.
* GTT space is continuous. I guarantee it. */
bits = (u32*)MapIoMem(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset,
mapped = bits = (u32*)MapIoMem(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset,
CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
if (unlikely(bits == NULL))
@ -516,6 +503,8 @@ int init_cursor(cursor_t *cursor)
for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
*bits++ = 0;
FreeKernelSpace(mapped);
// release old cursor
KernelFree(cursor->data);
@ -523,7 +512,6 @@ int init_cursor(cursor_t *cursor)
cursor->data = bits;
cursor->header.destroy = destroy_cursor;
// LEAVE();
return 0;
}
@ -679,37 +667,19 @@ static u32_t get_display_map()
typedef int v4si __attribute__ ((vector_size (16)));
static void
i915_gem_execbuffer_retire_commands(struct drm_device *dev,
struct drm_file *file,
struct intel_ring_buffer *ring)
{
struct drm_i915_gem_request *request;
u32 invalidate;
u32 req;
/*
* Ensure that the commands in the batch buffer are
* finished before the interrupt fires.
*
* The sampler always gets flushed on i965 (sigh).
*/
invalidate = I915_GEM_DOMAIN_COMMAND;
if (INTEL_INFO(dev)->gen >= 4)
invalidate |= I915_GEM_DOMAIN_SAMPLER;
if (ring->flush(ring, invalidate, 0)) {
i915_gem_next_request_seqno(ring);
return;
}
/* Unconditionally force add_request to emit a full flush. */
ring->gpu_caches_dirty = true;
/* Add a breadcrumb for the completion of the batch buffer */
if (request == NULL || i915_add_request(ring, NULL, &req)) {
i915_gem_next_request_seqno(ring);
}
(void)i915_add_request(ring, file, NULL);
}
int blit_video(u32 hbitmap, int dst_x, int dst_y,
int src_x, int src_y, u32 w, u32 h)
{
@ -728,6 +698,7 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y,
u32_t offset;
u8 slot;
int n=0;
int ret;
if(unlikely(hbitmap==0))
return -1;
@ -746,7 +717,7 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y,
dst_clip.xmin = 0;
dst_clip.ymin = 0;
dst_clip.xmax = winrc.right-winrc.left-1;
dst_clip.ymax = winrc.bottom -winrc.top -1;
dst_clip.ymax = winrc.bottom -winrc.top-1;
src_clip.xmin = 0;
src_clip.ymin = 0;
@ -913,18 +884,56 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y,
context->cmd_buffer+= n*4;
// i915_gem_object_set_to_gtt_domain(bitmap->obj, false);
context->obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
mutex_lock(&main_device->struct_mutex);
i915_gem_object_set_to_gtt_domain(bitmap->obj, false);
if (HAS_BLT(main_device))
{
int ret;
u32 seqno;
int i;
ring = &dev_priv->ring[BCS];
// printf("dispatch... ");
ring->dispatch_execbuffer(ring, offset, n*4);
i915_gem_object_sync(bitmap->obj, ring);
intel_ring_invalidate_all_caches(ring);
seqno = i915_gem_next_request_seqno(ring);
// printf("seqno = %d\n", seqno);
for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
if (seqno < ring->sync_seqno[i]) {
/* The GPU can not handle its semaphore value wrapping,
* so every billion or so execbuffers, we need to stall
* the GPU in order to reset the counters.
*/
DRM_DEBUG("wrap seqno\n");
ret = i915_gpu_idle(main_device);
if (ret)
goto fail;
i915_gem_retire_requests(main_device);
BUG_ON(ring->sync_seqno[i]);
}
}
ret = ring->dispatch_execbuffer(ring, offset, n*4);
if (ret)
goto fail;
// printf("done\n");
i915_gem_execbuffer_retire_commands(main_device, ring);
bitmap->obj->base.read_domains = bitmap->obj->base.pending_read_domains;
bitmap->obj->base.write_domain = bitmap->obj->base.pending_write_domain;
bitmap->obj->fenced_gpu_access = bitmap->obj->pending_fenced_gpu_access;
i915_gem_object_move_to_active(bitmap->obj, ring, seqno);
i915_gem_execbuffer_retire_commands(main_device, NULL, ring);
// printf("retire\n");
}
else
@ -934,12 +943,12 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y,
ring->flush(ring, 0, I915_GEM_DOMAIN_RENDER);
};
bitmap->obj->base.read_domains = I915_GEM_DOMAIN_CPU;
bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
// bitmap->obj->base.read_domains = I915_GEM_DOMAIN_CPU;
// bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
return 0;
mutex_unlock(&main_device->struct_mutex);
fail:
return -1;
return ret;
};
@ -1317,7 +1326,6 @@ int __queue_work(struct workqueue_struct *wq,
struct work_struct *work)
{
unsigned long flags;
// ENTER();
// dbgprintf("wq: %x, work: %x\n",
// wq, work );
@ -1336,13 +1344,11 @@ int __queue_work(struct workqueue_struct *wq,
// dbgprintf("wq: %x head %x, next %x\n",
// wq, &wq->worklist, wq->worklist.next);
// LEAVE();
return 1;
};
void __stdcall delayed_work_timer_fn(unsigned long __data)
{
// ENTER();
struct delayed_work *dwork = (struct delayed_work *)__data;
struct workqueue_struct *wq = dwork->work.data;
@ -1350,7 +1356,6 @@ void __stdcall delayed_work_timer_fn(unsigned long __data)
// wq, &dwork->work );
__queue_work(wq, &dwork->work);
// LEAVE();
}
@ -1368,7 +1373,6 @@ int queue_delayed_work(struct workqueue_struct *wq,
struct delayed_work *dwork, unsigned long delay)
{
u32 flags;
// ENTER();
// dbgprintf("wq: %x, work: %x\n",
// wq, &dwork->work );