From: Kitae Kim Date: Mon, 17 Dec 2012 17:02:50 +0000 (+0900) Subject: maru_codec : Fixed a bug when audio some codecs are decoded simultaneously. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5110cb4831a716d1dad666270a563787435794f0;p=sdk%2Femulator%2Femulator-kernel.git maru_codec : Fixed a bug when audio some codecs are decoded simultaneously. Source cleanup and codec driver can get and set offset of device memory for audio type. Signed-off-by: Kitae Kim --- diff --git a/drivers/maru/maru_codec.c b/drivers/maru/maru_codec.c index 2fa7b1b5e46b..ec691faa1793 100644 --- a/drivers/maru/maru_codec.c +++ b/drivers/maru/maru_codec.c @@ -59,29 +59,32 @@ MODULE_LICENSE("GPL2"); #define CODEC_IRQ 0x7f -/* Clean up source. : _param, svcodec_param_offset, paramindex */ struct codec_param { uint32_t api_index; uint32_t ctx_index; + uint32_t mem_index; uint32_t mmap_offset; uint32_t ret; }; enum codec_io_cmd { - CODEC_API_INDEX = 0, - CODEC_QUERY_STATE, - CODEC_CONTEXT_INDEX, - CODEC_MMAP_OFFSET, - CODEC_FILE_INDEX, - CODEC_CLOSED, + CODEC_CMD_API_INDEX = 0, + CODEC_CMD_CONTEXT_INDEX, + CODEC_CMD_FILE_INDEX, + CODEC_CMD_DEVICE_MEM_OFFSET, + CODEC_CMD_GET_THREAD_STATE, + CODEC_CMD_GET_VERSION, + CODEC_CMD_GET_DEVICE_MEM, + CODEC_CMD_SET_DEVICE_MEM, + CODEC_CMD_GET_MMAP_OFFSET, + CODEC_CMD_SET_MMAP_OFFSET, + CODEC_CMD_RESET_CODEC_INFO, }; enum codec_api_index { EMUL_AV_REGISTER_ALL = 1, - EMUL_AVCODEC_ALLOC_CONTEXT, EMUL_AVCODEC_OPEN, EMUL_AVCODEC_CLOSE, - EMUL_AV_FREE, EMUL_AVCODEC_FLUSH_BUFFERS, EMUL_AVCODEC_DECODE_VIDEO, EMUL_AVCODEC_ENCODE_VIDEO, @@ -91,8 +94,7 @@ enum codec_api_index { EMUL_AV_PARSER_INIT, EMUL_AV_PARSER_PARSE, EMUL_AV_PARSER_CLOSE, - EMUL_GET_CODEC_VER = 50, - EMUL_LOCK_MEM_REGION, + EMUL_LOCK_MEM_REGION = 50, EMUL_UNLOCK_MEM_REGION, }; @@ -109,10 +111,10 @@ struct svcodec_device { resource_size_t mem_size; /* irq handler */ - wait_queue_head_t codec_wq; + wait_queue_head_t codec_job_wq; spinlock_t lock; - int sleep_flag; + int codec_job_done; int availableMem; }; @@ -123,24 +125,34 @@ static long svcodec_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + long value; + mutex_lock(&codec_mutex); if (cmd == EMUL_LOCK_MEM_REGION) { - if (svcodec->availableMem == 0) + if (svcodec->availableMem == 0) { svcodec->availableMem = 1; - else + } else { svcodec->availableMem = -1; - + } + value = svcodec->availableMem; } else if (cmd == EMUL_UNLOCK_MEM_REGION) { - svcodec->availableMem = 0; + value = svcodec->availableMem = 0; + } else if (cmd == CODEC_CMD_GET_VERSION) { + value = readl(svcodec->ioaddr + cmd); + } else if (cmd == CODEC_CMD_GET_MMAP_OFFSET) { + value = readl(svcodec->ioaddr + cmd); + CODEC_LOG(KERN_DEBUG, + "ioctl: get mmap offset: %d.\n", value); } else { - CODEC_LOG(KERN_ERR, "there is no command.\n"); + CODEC_LOG(KERN_INFO, + "ioctl: no command available.\n"); + value = 0; } - if (copy_to_user((void *)arg, - &svcodec->availableMem, - sizeof(int))) - CODEC_LOG(KERN_ERR, "failed to copy data to user\n"); + if (copy_to_user((void *)arg, &value, sizeof(int))) { + CODEC_LOG(KERN_ERR, "ioctl: failed to copy data to user\n"); + } mutex_unlock(&codec_mutex); @@ -164,29 +176,36 @@ static ssize_t svcodec_write(struct file *file, const char __user *buf, if (!svcodec) { CODEC_LOG(KERN_ERR, "failed to get codec device info\n"); + mutex_unlock(&codec_mutex); return -EINVAL; } - if (copy_from_user(¶mInfo, buf, sizeof(struct codec_param))) + if (copy_from_user(¶mInfo, buf, sizeof(struct codec_param))) { CODEC_LOG(KERN_ERR, "failed to get codec parameter info from user\n"); + mutex_unlock(&codec_mutex); + return -EIO; + } - if (paramInfo.api_index == EMUL_AVCODEC_ALLOC_CONTEXT) - writel((uint32_t)file, svcodec->ioaddr + CODEC_FILE_INDEX); + if (paramInfo.api_index == EMUL_AVCODEC_OPEN) { + writel((uint32_t)file, svcodec->ioaddr + CODEC_CMD_FILE_INDEX); + writel((uint32_t)paramInfo.mem_index, + svcodec->ioaddr + CODEC_CMD_SET_MMAP_OFFSET); + } writel((uint32_t)paramInfo.ctx_index, - svcodec->ioaddr + CODEC_CONTEXT_INDEX); + svcodec->ioaddr + CODEC_CMD_CONTEXT_INDEX); writel((uint32_t)paramInfo.mmap_offset, - svcodec->ioaddr + CODEC_MMAP_OFFSET); + svcodec->ioaddr + CODEC_CMD_DEVICE_MEM_OFFSET); writel((uint32_t)paramInfo.api_index, - svcodec->ioaddr + CODEC_API_INDEX); + svcodec->ioaddr + CODEC_CMD_API_INDEX); /* wait decoding or encoding job */ if (paramInfo.api_index >= EMUL_AVCODEC_DECODE_VIDEO && paramInfo.api_index <= EMUL_AVCODEC_ENCODE_AUDIO) { - wait_event_interruptible(svcodec->codec_wq, - svcodec->sleep_flag != 0); - svcodec->sleep_flag = 0; + wait_event_interruptible(svcodec->codec_job_wq, + svcodec->codec_job_done != 0); + svcodec->codec_job_done = 0; } mutex_unlock(&codec_mutex); @@ -214,7 +233,7 @@ static int svcodec_mmap(struct file *file, struct vm_area_struct *vm) size, vm->vm_page_prot); if (ret < 0) { CODEC_LOG(KERN_ERR, "failed to remap page range\n"); - return -EAGAIN; + return ret; } vm->vm_flags |= VM_IO; @@ -226,21 +245,18 @@ static int svcodec_mmap(struct file *file, struct vm_area_struct *vm) static irqreturn_t svcodec_irq_handler (int irq, void *dev_id) { struct svcodec_device *dev = (struct svcodec_device *)dev_id; + unsigned long flags = 0; int val = 0; - unsigned long flags; - -/* spin_lock_irqsave(&dev->lock, flags); */ - val = readl(dev->ioaddr + CODEC_QUERY_STATE); + val = readl(dev->ioaddr + CODEC_CMD_GET_THREAD_STATE); if (!(val & CODEC_IRQ)) { -/* spin_unlock_irqrestore(&dev->lock, flags); */ return IRQ_NONE; } spin_lock_irqsave(&dev->lock, flags); - dev->sleep_flag = 1; - wake_up_interruptible(&dev->codec_wq); + dev->codec_job_done = 1; + wake_up_interruptible(&dev->codec_job_wq); spin_unlock_irqrestore(&dev->lock, flags); @@ -252,7 +268,7 @@ static int svcodec_open(struct inode *inode, struct file *file) mutex_lock(&codec_mutex); CODEC_LOG(KERN_DEBUG, "open! struct file:%p\n", file); - svcodec->sleep_flag = 0; + svcodec->codec_job_done = 0; /* register interrupt handler */ if (request_irq(svcodec->dev->irq, svcodec_irq_handler, @@ -279,8 +295,11 @@ static int svcodec_release(struct inode *inode, struct file *file) svcodec->availableMem = 0; /* notify closing codec device of qemu. */ - if (file) - writel((uint32_t)file, svcodec->ioaddr + CODEC_CLOSED); + if (file) { + CODEC_LOG(KERN_DEBUG, "reset codec info.\n"); + writel((uint32_t)file, + svcodec->ioaddr + CODEC_CMD_RESET_CODEC_INFO); + } module_put(THIS_MODULE); mutex_unlock(&codec_mutex); @@ -312,93 +331,77 @@ static int __devinit svcodec_probe(struct pci_dev *pci_dev, int ret; svcodec = kmalloc(sizeof(struct svcodec_device), GFP_KERNEL); + if (!svcodec) { + CODEC_LOG(KERN_ERR, "Failed to allocate memory for codec.\n"); + return -EIO; + } memset(svcodec, 0x00, sizeof(struct svcodec_device)); + svcodec->dev = pci_dev; - init_waitqueue_head(&svcodec->codec_wq); + init_waitqueue_head(&svcodec->codec_job_wq); spin_lock_init(&svcodec->lock); - svcodec->dev = pci_dev; - - if (pci_enable_device(pci_dev)) { + if ((ret = pci_enable_device(pci_dev))) { CODEC_LOG(KERN_ERR, "pci_enable_device failed\n"); - goto err_rel; + return ret; } pci_set_master(pci_dev); svcodec->mem_start = pci_resource_start(pci_dev, 0); svcodec->mem_size = pci_resource_len(pci_dev, 0); - if (!svcodec->mem_start) { CODEC_LOG(KERN_ERR, "pci_resource_start failed\n"); - goto err_out; + pci_disable_device(pci_dev); + return -ENODEV; } if (!request_mem_region(svcodec->mem_start, svcodec->mem_size, DEVICE_NAME)) { CODEC_LOG(KERN_ERR, "request_mem_region failed\n"); - goto err_out; + pci_disable_device(pci_dev); + return -EINVAL; } svcodec->io_start = pci_resource_start(pci_dev, 1); svcodec->io_size = pci_resource_len(pci_dev, 1); - if (!svcodec->io_start) { CODEC_LOG(KERN_ERR, "pci_resource_start failed\n"); - goto err_mem_region; + release_mem_region(svcodec->mem_start, svcodec->mem_size); + pci_disable_device(pci_dev); + return -ENODEV; } if (!request_mem_region(svcodec->io_start, svcodec->io_size, DEVICE_NAME)) { CODEC_LOG(KERN_ERR, "request_io_region failed\n"); - goto err_mem_region; - } - -#if 0 - svcodec->memaddr = ioremap(svcodec->mem_start, svcodec->mem_size); - if (!svcodec->memaddr) { - CODEC_LOG(KERN_ERR, "[%s] : ioremap failed\n", __func__); - goto err_io_region; + release_mem_region(svcodec->mem_start, svcodec->mem_size); + pci_disable_device(pci_dev); + return -EINVAL; } -#endif svcodec->ioaddr = ioremap_nocache(svcodec->io_start, svcodec->io_size); if (!svcodec->ioaddr) { CODEC_LOG(KERN_ERR, "ioremap failed\n"); - goto err_io_region; + release_mem_region(svcodec->io_start, svcodec->io_size); + release_mem_region(svcodec->mem_start, svcodec->mem_size); + pci_disable_device(pci_dev); + return -EINVAL; } -#if 0 - /* register chrdev */ - if (register_chrdev(CODEC_MAJOR, DEVICE_NAME, &svcodec_fops)) { - CODEC_LOG(KERN_ERR, "register_chrdev failed\n"); - goto err_io_unmap; - } -#endif ret = misc_register(&codec_dev); if (ret) { CODEC_LOG(KERN_ERR, "cannot register codec as misc\n"); - goto err_io_unmap; + iounmap(svcodec->ioaddr); + release_mem_region(svcodec->io_start, svcodec->io_size); + release_mem_region(svcodec->mem_start, svcodec->mem_size); + pci_disable_device(pci_dev); + return ret; } return 0; - -err_io_unmap: - iounmap(svcodec->ioaddr); -#if 0 -err_mem_unmap: - iounmap(svcodec->memaddr); -#endif -err_io_region: - release_mem_region(svcodec->io_start, svcodec->io_size); -err_mem_region: - release_mem_region(svcodec->mem_start, svcodec->mem_size); -err_out: - pci_disable_device(pci_dev); -err_rel: - return -EIO; } static void __devinit svcodec_remove(struct pci_dev *pci_dev) @@ -409,13 +412,6 @@ static void __devinit svcodec_remove(struct pci_dev *pci_dev) svcodec->ioaddr = 0; } -#if 0 - if (svcodec->memaddr) { - iounmap(svcodec->memaddr); - svcodec->memaddr = 0; - } -#endif - if (svcodec->io_start) { release_mem_region(svcodec->io_start, svcodec->io_size); diff --git a/package/changelog b/package/changelog index 3f9dabd4e2bd..c3a9bb891197 100644 --- a/package/changelog +++ b/package/changelog @@ -1,3 +1,7 @@ +* 1.4.10 +- Fixed a bug when audio some codecs are decoded simultaneously. +- Source cleanup and codec driver can get and set offset of device memory for audio type. +== Kitae Kim 2012-12-18 * 1.4.5 - Modified touchscreen range == GiWoong Kim 2012-11-27 diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest index af66509b7e2e..6af4be6b2bb0 100644 --- a/package/pkginfo.manifest +++ b/package/pkginfo.manifest @@ -1,4 +1,4 @@ -Version: 1.4.9 +Version: 1.4.10 Maintainer: Yeong-Kyoon, Lee Source: emulator-kernel