summaryrefslogtreecommitdiff
path: root/drivers/staging/android
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/android')
-rw-r--r--drivers/staging/android/Kconfig2
-rw-r--r--drivers/staging/android/alarm-dev.c2
-rw-r--r--drivers/staging/android/binder.c225
-rw-r--r--drivers/staging/android/ion/Kconfig2
-rw-r--r--drivers/staging/android/ion/ion.h1
-rw-r--r--drivers/staging/android/ion/ion_chunk_heap.c2
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c9
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c71
-rw-r--r--drivers/staging/android/logger.c7
-rw-r--r--drivers/staging/android/sync.c3
-rw-r--r--drivers/staging/android/timed_gpio.c15
-rw-r--r--drivers/staging/android/timed_output.c4
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);