From 95ef39403f890360a3e48fe550d8e8e5d088ad74 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Mar 2013 10:37:52 -0300 Subject: [PATCH] [media] go7007: remember boot firmware Don't load it everytime you stop encoding. Instead remember it. Another reason for not loading it every time is that this could be called from within the release() file operation, which turns out to be deadly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/go7007/go7007-driver.c | 43 ++++++++++---------- drivers/staging/media/go7007/go7007-priv.h | 2 + 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index 09d0ef4984d3..db9a4b3a7113 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -95,34 +95,34 @@ static int go7007_load_encoder(struct go7007 *go) int fw_len, rv = 0; u16 intr_val, intr_data; - if (request_firmware(&fw_entry, fw_name, go->dev)) { - v4l2_err(go, "unable to load firmware from file " - "\"%s\"\n", fw_name); - return -1; - } - if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { - v4l2_err(go, "file \"%s\" does not appear to be " - "go7007 firmware\n", fw_name); + if (go->boot_fw == NULL) { + if (request_firmware(&fw_entry, fw_name, go->dev)) { + v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name); + return -1; + } + if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { + v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name); + release_firmware(fw_entry); + return -1; + } + fw_len = fw_entry->size - 16; + bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL); + if (bounce == NULL) { + v4l2_err(go, "unable to allocate %d bytes for firmware transfer\n", fw_len); + release_firmware(fw_entry); + return -1; + } release_firmware(fw_entry); - return -1; + go->boot_fw_len = fw_len; + go->boot_fw = bounce; } - fw_len = fw_entry->size - 16; - bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL); - if (bounce == NULL) { - v4l2_err(go, "unable to allocate %d bytes for " - "firmware transfer\n", fw_len); - release_firmware(fw_entry); - return -1; - } - release_firmware(fw_entry); if (go7007_interface_reset(go) < 0 || - go7007_send_firmware(go, bounce, fw_len) < 0 || - go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || + go7007_send_firmware(go, go->boot_fw, go->boot_fw_len) < 0 || + go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || (intr_val & ~0x1) != 0x5a5a) { v4l2_err(go, "error transferring firmware\n"); rv = -1; } - kfree(bounce); return rv; } @@ -675,6 +675,7 @@ void go7007_remove(struct go7007 *go) if (go->audio_enabled) go7007_snd_remove(go); + kfree(go->boot_fw); go7007_v4l2_remove(go); } EXPORT_SYMBOL(go7007_remove); diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index daae6ddc4689..d390120e4db4 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -178,6 +178,8 @@ struct go7007 { int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */ char name[64]; struct video_device *video_dev; + void *boot_fw; + unsigned boot_fw_len; struct v4l2_device v4l2_dev; int ref_count; enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;