diff options
Diffstat (limited to 'drivers/staging/android')
| -rw-r--r-- | drivers/staging/android/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/staging/android/alarm-dev.c | 2 | ||||
| -rw-r--r-- | drivers/staging/android/binder.c | 225 | ||||
| -rw-r--r-- | drivers/staging/android/ion/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/staging/android/ion/ion.h | 1 | ||||
| -rw-r--r-- | drivers/staging/android/ion/ion_chunk_heap.c | 2 | ||||
| -rw-r--r-- | drivers/staging/android/ion/ion_cma_heap.c | 9 | ||||
| -rw-r--r-- | drivers/staging/android/ion/ion_system_heap.c | 71 | ||||
| -rw-r--r-- | drivers/staging/android/logger.c | 7 | ||||
| -rw-r--r-- | drivers/staging/android/sync.c | 3 | ||||
| -rw-r--r-- | drivers/staging/android/timed_gpio.c | 15 | ||||
| -rw-r--r-- | drivers/staging/android/timed_output.c | 4 |
12 files changed, 174 insertions, 169 deletions
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 51607e9aa049..7a0e28852965 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -76,7 +76,7 @@ config ANDROID_LOW_MEMORY_KILLER Registers processes to be killed when memory is low config ANDROID_INTF_ALARM_DEV - bool "Android alarm driver" + tristate "Android alarm driver" depends on RTC_CLASS default n ---help--- diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index f200e8a84325..ff4b3e8758a7 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -443,4 +443,4 @@ static void __exit alarm_dev_exit(void) module_init(alarm_dev_init); module_exit(alarm_dev_exit); - +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index a741da77828a..02b0379ae550 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -454,9 +454,8 @@ static size_t binder_buffer_size(struct binder_proc *proc, { if (list_is_last(&buffer->entry, &proc->buffers)) return proc->buffer + proc->buffer_size - (void *)buffer->data; - else - return (size_t)list_entry(buffer->entry.next, - struct binder_buffer, entry) - (size_t)buffer->data; + return (size_t)list_entry(buffer->entry.next, + struct binder_buffer, entry) - (size_t)buffer->data; } static void binder_insert_free_buffer(struct binder_proc *proc, @@ -1186,6 +1185,7 @@ static void binder_send_failed_reply(struct binder_transaction *t, uint32_t error_code) { struct binder_thread *target_thread; + struct binder_transaction *next; BUG_ON(t->flags & TF_ONE_WAY); while (1) { @@ -1213,24 +1213,23 @@ static void binder_send_failed_reply(struct binder_transaction *t, target_thread->return_error); } return; - } else { - struct binder_transaction *next = t->from_parent; + } + next = t->from_parent; - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "send failed reply for transaction %d, target dead\n", - t->debug_id); + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "send failed reply for transaction %d, target dead\n", + t->debug_id); - binder_pop_transaction(target_thread, t); - if (next == NULL) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "reply failed, no target thread at root\n"); - return; - } - t = next; + binder_pop_transaction(target_thread, t); + if (next == NULL) { binder_debug(BINDER_DEBUG_DEAD_BINDER, - "reply failed, no target thread -- retry %d\n", - t->debug_id); + "reply failed, no target thread at root\n"); + return; } + t = next; + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "reply failed, no target thread -- retry %d\n", + t->debug_id); } } @@ -2594,6 +2593,106 @@ static unsigned int binder_poll(struct file *filp, return 0; } +static int binder_ioctl_write_read(struct file *filp, + unsigned int cmd, unsigned long arg, + struct binder_thread *thread) +{ + int ret = 0; + struct binder_proc *proc = filp->private_data; + unsigned int size = _IOC_SIZE(cmd); + void __user *ubuf = (void __user *)arg; + struct binder_write_read bwr; + + if (size != sizeof(struct binder_write_read)) { + ret = -EINVAL; + goto out; + } + if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { + ret = -EFAULT; + goto out; + } + binder_debug(BINDER_DEBUG_READ_WRITE, + "%d:%d write %lld at %016llx, read %lld at %016llx\n", + proc->pid, thread->pid, + (u64)bwr.write_size, (u64)bwr.write_buffer, + (u64)bwr.read_size, (u64)bwr.read_buffer); + + if (bwr.write_size > 0) { + ret = binder_thread_write(proc, thread, + bwr.write_buffer, + bwr.write_size, + &bwr.write_consumed); + trace_binder_write_done(ret); + if (ret < 0) { + bwr.read_consumed = 0; + if (copy_to_user(ubuf, &bwr, sizeof(bwr))) + ret = -EFAULT; + goto out; + } + } + if (bwr.read_size > 0) { + ret = binder_thread_read(proc, thread, bwr.read_buffer, + bwr.read_size, + &bwr.read_consumed, + filp->f_flags & O_NONBLOCK); + trace_binder_read_done(ret); + if (!list_empty(&proc->todo)) + wake_up_interruptible(&proc->wait); + if (ret < 0) { + if (copy_to_user(ubuf, &bwr, sizeof(bwr))) + ret = -EFAULT; + goto out; + } + } + binder_debug(BINDER_DEBUG_READ_WRITE, + "%d:%d wrote %lld of %lld, read return %lld of %lld\n", + proc->pid, thread->pid, + (u64)bwr.write_consumed, (u64)bwr.write_size, + (u64)bwr.read_consumed, (u64)bwr.read_size); + if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { + ret = -EFAULT; + goto out; + } +out: + return ret; +} + +static int binder_ioctl_set_ctx_mgr(struct file *filp) +{ + int ret = 0; + struct binder_proc *proc = filp->private_data; + kuid_t curr_euid = current_euid(); + + if (binder_context_mgr_node != NULL) { + pr_err("BINDER_SET_CONTEXT_MGR already set\n"); + ret = -EBUSY; + goto out; + } + if (uid_valid(binder_context_mgr_uid)) { + if (!uid_eq(binder_context_mgr_uid, curr_euid)) { + pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", + from_kuid(&init_user_ns, curr_euid), + from_kuid(&init_user_ns, + binder_context_mgr_uid)); + ret = -EPERM; + goto out; + } + } else { + binder_context_mgr_uid = curr_euid; + } + binder_context_mgr_node = binder_new_node(proc, 0, 0); + if (binder_context_mgr_node == NULL) { + ret = -ENOMEM; + goto out; + } + binder_context_mgr_node->local_weak_refs++; + binder_context_mgr_node->local_strong_refs++; + binder_context_mgr_node->has_strong_ref = 1; + binder_context_mgr_node->has_weak_ref = 1; +out: + return ret; +} + static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int ret; @@ -2601,9 +2700,9 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct binder_thread *thread; unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; - kuid_t curr_euid = current_euid(); - /*pr_info("binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ + /*pr_info("binder_ioctl: %d:%d %x %lx\n", + proc->pid, current->pid, cmd, arg);*/ trace_binder_ioctl(cmd, arg); @@ -2619,61 +2718,11 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } switch (cmd) { - case BINDER_WRITE_READ: { - struct binder_write_read bwr; - - if (size != sizeof(struct binder_write_read)) { - ret = -EINVAL; - goto err; - } - if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "%d:%d write %lld at %016llx, read %lld at %016llx\n", - proc->pid, thread->pid, - (u64)bwr.write_size, (u64)bwr.write_buffer, - (u64)bwr.read_size, (u64)bwr.read_buffer); - - if (bwr.write_size > 0) { - ret = binder_thread_write(proc, thread, - bwr.write_buffer, - bwr.write_size, - &bwr.write_consumed); - trace_binder_write_done(ret); - if (ret < 0) { - bwr.read_consumed = 0; - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - if (bwr.read_size > 0) { - ret = binder_thread_read(proc, thread, bwr.read_buffer, - bwr.read_size, - &bwr.read_consumed, - filp->f_flags & O_NONBLOCK); - trace_binder_read_done(ret); - if (!list_empty(&proc->todo)) - wake_up_interruptible(&proc->wait); - if (ret < 0) { - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "%d:%d wrote %lld of %lld, read return %lld of %lld\n", - proc->pid, thread->pid, - (u64)bwr.write_consumed, (u64)bwr.write_size, - (u64)bwr.read_consumed, (u64)bwr.read_size); - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { - ret = -EFAULT; + case BINDER_WRITE_READ: + ret = binder_ioctl_write_read(filp, cmd, arg, thread); + if (ret) goto err; - } break; - } case BINDER_SET_MAX_THREADS: if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { ret = -EINVAL; @@ -2681,31 +2730,9 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case BINDER_SET_CONTEXT_MGR: - if (binder_context_mgr_node != NULL) { - pr_err("BINDER_SET_CONTEXT_MGR already set\n"); - ret = -EBUSY; + ret = binder_ioctl_set_ctx_mgr(filp); + if (ret) goto err; - } - if (uid_valid(binder_context_mgr_uid)) { - if (!uid_eq(binder_context_mgr_uid, curr_euid)) { - pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", - from_kuid(&init_user_ns, curr_euid), - from_kuid(&init_user_ns, binder_context_mgr_uid)); - ret = -EPERM; - goto err; - } - } else { - binder_context_mgr_uid = curr_euid; - } - binder_context_mgr_node = binder_new_node(proc, 0, 0); - if (binder_context_mgr_node == NULL) { - ret = -ENOMEM; - goto err; - } - binder_context_mgr_node->local_weak_refs++; - binder_context_mgr_node->local_strong_refs++; - binder_context_mgr_node->has_strong_ref = 1; - binder_context_mgr_node->has_weak_ref = 1; break; case BINDER_THREAD_EXIT: binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n", @@ -2769,9 +2796,15 @@ static void binder_vma_close(struct vm_area_struct *vma) binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); } +static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + return VM_FAULT_SIGBUS; +} + static struct vm_operations_struct binder_vm_ops = { .open = binder_vma_open, .close = binder_vma_close, + .fault = binder_vm_fault, }; static int binder_mmap(struct file *filp, struct vm_area_struct *vma) diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 0f8fec1f84e5..345234624492 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -1,6 +1,6 @@ menuconfig ION bool "Ion Memory Manager" - depends on HAVE_MEMBLOCK + depends on HAVE_MEMBLOCK && HAS_DMA && MMU select GENERIC_ALLOCATOR select DMA_SHARED_BUFFER ---help--- diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index dcd2a0cdb192..d305bb7e9a74 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -84,7 +84,6 @@ void ion_reserve(struct ion_platform_data *data); /** * ion_client_create() - allocate a client and returns it * @dev: the global ion device - * @heap_type_mask: mask of heaps this client can allocate from * @name: used for debugging */ struct ion_client *ion_client_create(struct ion_device *dev, diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 3f2c12ba4d14..9c3e49aa204b 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -106,7 +106,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) if (ion_buffer_cached(buffer)) dma_sync_sg_for_device(NULL, table->sgl, table->nents, - DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); for_each_sg(table->sgl, sg, table->nents, i) { gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index ce68ecfed31f..f8cabcbc39e5 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -76,10 +76,8 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, return -EINVAL; info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL); - if (!info) { - dev_err(dev, "Can't allocate buffer info\n"); + if (!info) return ION_CMA_ALLOCATE_FAILED; - } info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), GFP_HIGHUSER | __GFP_ZERO); @@ -90,10 +88,8 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, } info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!info->table) { - dev_err(dev, "Fail to allocate sg table\n"); + if (!info->table) goto free_mem; - } if (ion_cma_get_sgtable (dev, info->table, info->cpu_addr, info->handle, len)) @@ -155,7 +151,6 @@ static struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap, static void ion_cma_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - return; } static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer, diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index cb7ae08a5e24..6b77c5195b4d 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -49,13 +49,7 @@ static inline unsigned int order_to_size(int order) struct ion_system_heap { struct ion_heap heap; - struct ion_page_pool **pools; -}; - -struct page_info { - struct page *page; - unsigned int order; - struct list_head list; + struct ion_page_pool *pools[0]; }; static struct page *alloc_buffer_page(struct ion_system_heap *heap, @@ -84,9 +78,9 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap, } static void free_buffer_page(struct ion_system_heap *heap, - struct ion_buffer *buffer, struct page *page, - unsigned int order) + struct ion_buffer *buffer, struct page *page) { + unsigned int order = compound_order(page); bool cached = ion_buffer_cached(buffer); if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) { @@ -99,19 +93,14 @@ static void free_buffer_page(struct ion_system_heap *heap, } -static struct page_info *alloc_largest_available(struct ion_system_heap *heap, - struct ion_buffer *buffer, - unsigned long size, - unsigned int max_order) +static struct page *alloc_largest_available(struct ion_system_heap *heap, + struct ion_buffer *buffer, + unsigned long size, + unsigned int max_order) { struct page *page; - struct page_info *info; int i; - info = kmalloc(sizeof(struct page_info), GFP_KERNEL); - if (!info) - return NULL; - for (i = 0; i < num_orders; i++) { if (size < order_to_size(orders[i])) continue; @@ -122,11 +111,8 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap, if (!page) continue; - info->page = page; - info->order = orders[i]; - return info; + return page; } - kfree(info); return NULL; } @@ -142,7 +128,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, struct sg_table *table; struct scatterlist *sg; struct list_head pages; - struct page_info *info, *tmp_info; + struct page *page, *tmp_page; int i = 0; unsigned long size_remaining = PAGE_ALIGN(size); unsigned int max_order = orders[0]; @@ -155,13 +141,13 @@ static int ion_system_heap_allocate(struct ion_heap *heap, INIT_LIST_HEAD(&pages); while (size_remaining > 0) { - info = alloc_largest_available(sys_heap, buffer, size_remaining, + page = alloc_largest_available(sys_heap, buffer, size_remaining, max_order); - if (!info) + if (!page) goto free_pages; - list_add_tail(&info->list, &pages); - size_remaining -= PAGE_SIZE << info->order; - max_order = info->order; + list_add_tail(&page->lru, &pages); + size_remaining -= PAGE_SIZE << compound_order(page); + max_order = compound_order(page); i++; } table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); @@ -172,12 +158,10 @@ static int ion_system_heap_allocate(struct ion_heap *heap, goto free_table; sg = table->sgl; - list_for_each_entry_safe(info, tmp_info, &pages, list) { - struct page *page = info->page; - sg_set_page(sg, page, PAGE_SIZE << info->order, 0); + list_for_each_entry_safe(page, tmp_page, &pages, lru) { + sg_set_page(sg, page, PAGE_SIZE << compound_order(page), 0); sg = sg_next(sg); - list_del(&info->list); - kfree(info); + list_del(&page->lru); } buffer->priv_virt = table; @@ -186,10 +170,8 @@ static int ion_system_heap_allocate(struct ion_heap *heap, free_table: kfree(table); free_pages: - list_for_each_entry_safe(info, tmp_info, &pages, list) { - free_buffer_page(sys_heap, buffer, info->page, info->order); - kfree(info); - } + list_for_each_entry_safe(page, tmp_page, &pages, lru) + free_buffer_page(sys_heap, buffer, page); return -ENOMEM; } @@ -209,8 +191,7 @@ static void ion_system_heap_free(struct ion_buffer *buffer) ion_heap_buffer_zero(buffer); for_each_sg(table->sgl, sg, table->nents, i) - free_buffer_page(sys_heap, buffer, sg_page(sg), - get_order(sg->length)); + free_buffer_page(sys_heap, buffer, sg_page(sg)); sg_free_table(table); kfree(table); } @@ -283,16 +264,15 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) struct ion_system_heap *heap; int i; - heap = kzalloc(sizeof(struct ion_system_heap), GFP_KERNEL); + heap = kzalloc(sizeof(struct ion_system_heap) + + sizeof(struct ion_page_pool *) * num_orders, + GFP_KERNEL); if (!heap) return ERR_PTR(-ENOMEM); heap->heap.ops = &system_heap_ops; heap->heap.type = ION_HEAP_TYPE_SYSTEM; heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; - heap->pools = kzalloc(sizeof(struct ion_page_pool *) * num_orders, - GFP_KERNEL); - if (!heap->pools) - goto free_heap; + for (i = 0; i < num_orders; i++) { struct ion_page_pool *pool; gfp_t gfp_flags = low_order_gfp_flags; @@ -311,8 +291,6 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) destroy_pools: while (i--) ion_page_pool_destroy(heap->pools[i]); - kfree(heap->pools); -free_heap: kfree(heap); return ERR_PTR(-ENOMEM); } @@ -326,7 +304,6 @@ void ion_system_heap_destroy(struct ion_heap *heap) for (i = 0; i < num_orders; i++) ion_page_pool_destroy(sys_heap->pools[i]); - kfree(sys_heap->pools); kfree(sys_heap); } diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 2772e01b37f5..9b47e66599a3 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -110,8 +110,8 @@ static inline struct logger_log *file_get_log(struct file *file) struct logger_reader *reader = file->private_data; return reader->log; - } else - return file->private_data; + } + return file->private_data; } /* @@ -159,8 +159,7 @@ static size_t get_user_hdr_len(int ver) { if (ver < 2) return sizeof(struct user_logger_entry_compat); - else - return sizeof(struct logger_entry); + return sizeof(struct logger_entry); } static ssize_t copy_header_to_user(int ver, struct logger_entry *entry, diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index c9a0c2cdc81a..e7b2e0234196 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -555,8 +555,7 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait) return POLLIN; else if (status < 0) return POLLERR; - else - return 0; + return 0; } static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index 180c209a009e..8fa4758517c0 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -45,16 +45,17 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) static int gpio_get_time(struct timed_output_dev *dev) { - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); + struct timed_gpio_data *data; + struct timeval t; - if (hrtimer_active(&data->timer)) { - ktime_t r = hrtimer_get_remaining(&data->timer); - struct timeval t = ktime_to_timeval(r); + data = container_of(dev, struct timed_gpio_data, dev); - return t.tv_sec * 1000 + t.tv_usec / 1000; - } else + if (!hrtimer_active(&data->timer)) return 0; + + t = ktime_to_timeval(hrtimer_get_remaining(&data->timer)); + + return t.tv_sec * 1000 + t.tv_usec / 1000; } static void gpio_enable(struct timed_output_dev *dev, int value) diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c index c341ac11c5a3..b41429f379fe 100644 --- a/drivers/staging/android/timed_output.c +++ b/drivers/staging/android/timed_output.c @@ -41,8 +41,10 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, { struct timed_output_dev *tdev = dev_get_drvdata(dev); int value; + int rc; - if (sscanf(buf, "%d", &value) != 1) + rc = kstrtoint(buf, 0, &value); + if (rc != 0) return -EINVAL; tdev->enable(tdev, value); |
