mirror of
https://github.com/torvalds/linux
synced 2024-10-17 16:58:15 +00:00
[media] s2255drv: dynamic memory allocation efficiency fix
Driver was allocating a kernel buffer each time it was sending a command. It is better to allocate this buffer once at startup. Signed-off-by: Dean Anderson <linux-dev@sensoray.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
8bf405a0da
commit
47d8c881c3
|
@ -260,6 +260,7 @@ struct s2255_dev {
|
|||
atomic_t num_channels;
|
||||
int frames;
|
||||
struct mutex lock; /* channels[].vdev.lock */
|
||||
struct mutex cmdlock; /* protects cmdbuf */
|
||||
struct usb_device *udev;
|
||||
struct usb_interface *interface;
|
||||
u8 read_endpoint;
|
||||
|
@ -273,6 +274,8 @@ struct s2255_dev {
|
|||
/* dsp firmware version (f2255usb.bin) */
|
||||
int dsp_fw_ver;
|
||||
u16 pid; /* product id */
|
||||
#define S2255_CMDBUF_SIZE 512
|
||||
__le32 *cmdbuf;
|
||||
};
|
||||
|
||||
static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
|
||||
|
@ -1121,11 +1124,12 @@ static int s2255_set_mode(struct s2255_vc *vc,
|
|||
struct s2255_mode *mode)
|
||||
{
|
||||
int res;
|
||||
__le32 *buffer;
|
||||
unsigned long chn_rev;
|
||||
struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
|
||||
int i;
|
||||
__le32 *buffer = dev->cmdbuf;
|
||||
|
||||
mutex_lock(&dev->cmdlock);
|
||||
chn_rev = G_chnmap[vc->idx];
|
||||
dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
|
||||
/* if JPEG, set the quality */
|
||||
|
@ -1139,11 +1143,6 @@ static int s2255_set_mode(struct s2255_vc *vc,
|
|||
vc->mode = *mode;
|
||||
vc->req_image_size = get_transfer_size(mode);
|
||||
dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
|
||||
buffer = kzalloc(512, GFP_KERNEL);
|
||||
if (buffer == NULL) {
|
||||
dev_err(&dev->udev->dev, "out of mem\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* set the mode */
|
||||
buffer[0] = IN_DATA_TOKEN;
|
||||
buffer[1] = (__le32) cpu_to_le32(chn_rev);
|
||||
|
@ -1154,7 +1153,6 @@ static int s2255_set_mode(struct s2255_vc *vc,
|
|||
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
|
||||
if (debug)
|
||||
s2255_print_cfg(dev, mode);
|
||||
kfree(buffer);
|
||||
/* wait at least 3 frames before continuing */
|
||||
if (mode->restart) {
|
||||
wait_event_timeout(vc->wait_setmode,
|
||||
|
@ -1168,22 +1166,20 @@ static int s2255_set_mode(struct s2255_vc *vc,
|
|||
/* clear the restart flag */
|
||||
vc->mode.restart = 0;
|
||||
dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
|
||||
mutex_unlock(&dev->cmdlock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
|
||||
{
|
||||
int res;
|
||||
__le32 *buffer;
|
||||
u32 chn_rev;
|
||||
struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
|
||||
__le32 *buffer = dev->cmdbuf;
|
||||
|
||||
mutex_lock(&dev->cmdlock);
|
||||
chn_rev = G_chnmap[vc->idx];
|
||||
dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
|
||||
buffer = kzalloc(512, GFP_KERNEL);
|
||||
if (buffer == NULL) {
|
||||
dev_err(&dev->udev->dev, "out of mem\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* form the get vid status command */
|
||||
buffer[0] = IN_DATA_TOKEN;
|
||||
buffer[1] = (__le32) cpu_to_le32(chn_rev);
|
||||
|
@ -1191,7 +1187,6 @@ static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
|
|||
*pstatus = 0;
|
||||
vc->vidstatus_ready = 0;
|
||||
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
|
||||
kfree(buffer);
|
||||
wait_event_timeout(vc->wait_vidstatus,
|
||||
(vc->vidstatus_ready != 0),
|
||||
msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
|
||||
|
@ -1201,6 +1196,7 @@ static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
|
|||
}
|
||||
*pstatus = vc->vidstatus;
|
||||
dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
|
||||
mutex_unlock(&dev->cmdlock);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1724,6 +1720,7 @@ static void s2255_destroy(struct s2255_dev *dev)
|
|||
mutex_destroy(&dev->lock);
|
||||
usb_put_dev(dev->udev);
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
kfree(dev->cmdbuf);
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
|
@ -2350,18 +2347,14 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
|
|||
/* starts acquisition process */
|
||||
static int s2255_start_acquire(struct s2255_vc *vc)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
int res;
|
||||
unsigned long chn_rev;
|
||||
int j;
|
||||
struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
|
||||
chn_rev = G_chnmap[vc->idx];
|
||||
buffer = kzalloc(512, GFP_KERNEL);
|
||||
if (buffer == NULL) {
|
||||
dev_err(&dev->udev->dev, "out of mem\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
__le32 *buffer = dev->cmdbuf;
|
||||
|
||||
mutex_lock(&dev->cmdlock);
|
||||
chn_rev = G_chnmap[vc->idx];
|
||||
vc->last_frame = -1;
|
||||
vc->bad_payload = 0;
|
||||
vc->cur_frame = 0;
|
||||
|
@ -2371,24 +2364,26 @@ static int s2255_start_acquire(struct s2255_vc *vc)
|
|||
}
|
||||
|
||||
/* send the start command */
|
||||
*(__le32 *) buffer = IN_DATA_TOKEN;
|
||||
*((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
|
||||
*((__le32 *) buffer + 2) = CMD_START;
|
||||
buffer[0] = IN_DATA_TOKEN;
|
||||
buffer[1] = (__le32) cpu_to_le32(chn_rev);
|
||||
buffer[2] = CMD_START;
|
||||
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
|
||||
if (res != 0)
|
||||
dev_err(&dev->udev->dev, "CMD_START error\n");
|
||||
|
||||
dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
|
||||
kfree(buffer);
|
||||
mutex_unlock(&dev->cmdlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s2255_stop_acquire(struct s2255_vc *vc)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
int res;
|
||||
unsigned long chn_rev;
|
||||
struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
|
||||
__le32 *buffer = dev->cmdbuf;
|
||||
|
||||
mutex_lock(&dev->cmdlock);
|
||||
chn_rev = G_chnmap[vc->idx];
|
||||
buffer = kzalloc(512, GFP_KERNEL);
|
||||
if (buffer == NULL) {
|
||||
|
@ -2396,15 +2391,17 @@ static int s2255_stop_acquire(struct s2255_vc *vc)
|
|||
return -ENOMEM;
|
||||
}
|
||||
/* send the stop command */
|
||||
*(__le32 *) buffer = IN_DATA_TOKEN;
|
||||
*((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
|
||||
*((__le32 *) buffer + 2) = CMD_STOP;
|
||||
buffer[0] = IN_DATA_TOKEN;
|
||||
buffer[1] = (__le32) cpu_to_le32(chn_rev);
|
||||
buffer[2] = CMD_STOP;
|
||||
|
||||
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
|
||||
if (res != 0)
|
||||
dev_err(&dev->udev->dev, "CMD_STOP error\n");
|
||||
kfree(buffer);
|
||||
|
||||
vc->b_acquire = 0;
|
||||
dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
|
||||
mutex_unlock(&dev->cmdlock);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2451,18 +2448,27 @@ static int s2255_probe(struct usb_interface *interface,
|
|||
int retval = -ENOMEM;
|
||||
__le32 *pdata;
|
||||
int fw_size;
|
||||
|
||||
/* allocate memory for our device state and initialize it to zero */
|
||||
dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
|
||||
if (dev == NULL) {
|
||||
s2255_dev_err(&interface->dev, "out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
|
||||
if (dev->cmdbuf == NULL) {
|
||||
s2255_dev_err(&interface->dev, "out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
atomic_set(&dev->num_channels, 0);
|
||||
dev->pid = le16_to_cpu(id->idProduct);
|
||||
dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
|
||||
if (!dev->fw_data)
|
||||
goto errorFWDATA1;
|
||||
mutex_init(&dev->lock);
|
||||
mutex_init(&dev->cmdlock);
|
||||
/* grab usb_device and save it */
|
||||
dev->udev = usb_get_dev(interface_to_usbdev(interface));
|
||||
if (dev->udev == NULL) {
|
||||
|
@ -2568,6 +2574,7 @@ static int s2255_probe(struct usb_interface *interface,
|
|||
kfree(dev->fw_data);
|
||||
mutex_destroy(&dev->lock);
|
||||
errorFWDATA1:
|
||||
kfree(dev->cmdbuf);
|
||||
kfree(dev);
|
||||
pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
|
||||
return retval;
|
||||
|
|
Loading…
Reference in a new issue