aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c')
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c942
1 files changed, 440 insertions, 502 deletions
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 45de21c210c1..064d0db4c51e 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -44,18 +44,18 @@
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/bug.h>
-#include <linux/semaphore.h>
+#include <linux/completion.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/compat.h>
+#include <linux/dma-mapping.h>
#include <soc/bcm2835/raspberrypi-firmware.h>
#include "vchiq_core.h"
#include "vchiq_ioctl.h"
#include "vchiq_arm.h"
#include "vchiq_debugfs.h"
-#include "vchiq_killable.h"
#define DEVICE_NAME "vchiq"
@@ -63,8 +63,6 @@
#undef MODULE_PARAM_PREFIX
#define MODULE_PARAM_PREFIX DEVICE_NAME "."
-#define VCHIQ_MINOR 0
-
/* Some per-instance constants */
#define MAX_COMPLETIONS 128
#define MAX_SERVICES 64
@@ -111,8 +109,8 @@ static const char *const resume_state_names[] = {
static void suspend_timer_callback(struct timer_list *t);
-typedef struct user_service_struct {
- VCHIQ_SERVICE_T *service;
+struct user_service {
+ struct vchiq_service *service;
void *userdata;
VCHIQ_INSTANCE_T instance;
char is_vchi;
@@ -121,11 +119,11 @@ typedef struct user_service_struct {
int message_available_pos;
int msg_insert;
int msg_remove;
- struct semaphore insert_event;
- struct semaphore remove_event;
- struct semaphore close_event;
- VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE];
-} USER_SERVICE_T;
+ struct completion insert_event;
+ struct completion remove_event;
+ struct completion close_event;
+ struct vchiq_header *msg_queue[MSG_QUEUE_SIZE];
+};
struct bulk_waiter_node {
struct bulk_waiter bulk_waiter;
@@ -134,12 +132,12 @@ struct bulk_waiter_node {
};
struct vchiq_instance_struct {
- VCHIQ_STATE_T *state;
- VCHIQ_COMPLETION_DATA_T completions[MAX_COMPLETIONS];
+ struct vchiq_state *state;
+ struct vchiq_completion_data completions[MAX_COMPLETIONS];
int completion_insert;
int completion_remove;
- struct semaphore insert_event;
- struct semaphore remove_event;
+ struct completion insert_event;
+ struct completion remove_event;
struct mutex completion_mutex;
int connected;
@@ -152,23 +150,23 @@ struct vchiq_instance_struct {
struct list_head bulk_waiter_list;
struct mutex bulk_waiter_list_mutex;
- VCHIQ_DEBUGFS_NODE_T debugfs_node;
+ struct vchiq_debugfs_node debugfs_node;
};
-typedef struct dump_context_struct {
+struct dump_context {
char __user *buf;
size_t actual;
size_t space;
loff_t offset;
-} DUMP_CONTEXT_T;
+};
static struct cdev vchiq_cdev;
static dev_t vchiq_devid;
-static VCHIQ_STATE_T g_state;
+static struct vchiq_state g_state;
static struct class *vchiq_class;
-static struct device *vchiq_dev;
static DEFINE_SPINLOCK(msg_queue_spinlock);
static struct platform_device *bcm2835_camera;
+static struct platform_device *bcm2835_audio;
static struct vchiq_drvdata bcm2835_drvdata = {
.cache_line_size = 32,
@@ -210,7 +208,7 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instance_out)
{
VCHIQ_STATUS_T status = VCHIQ_ERROR;
- VCHIQ_STATE_T *state;
+ struct vchiq_state *state;
VCHIQ_INSTANCE_T instance = NULL;
int i;
@@ -263,7 +261,7 @@ EXPORT_SYMBOL(vchiq_initialise);
VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
{
VCHIQ_STATUS_T status;
- VCHIQ_STATE_T *state = instance->state;
+ struct vchiq_state *state = instance->state;
vchiq_log_trace(vchiq_core_log_level,
"%s(%p) called", __func__, instance);
@@ -280,16 +278,11 @@ VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
"%s(%p): returning %d", __func__, instance, status);
if (status == VCHIQ_SUCCESS) {
- struct list_head *pos, *next;
+ struct bulk_waiter_node *waiter, *next;
- list_for_each_safe(pos, next,
- &instance->bulk_waiter_list) {
- struct bulk_waiter_node *waiter;
-
- waiter = list_entry(pos,
- struct bulk_waiter_node,
- list);
- list_del(pos);
+ list_for_each_entry_safe(waiter, next,
+ &instance->bulk_waiter_list, list) {
+ list_del(&waiter->list);
vchiq_log_info(vchiq_arm_log_level,
"bulk_waiter - cleaned up %pK for pid %d",
waiter, waiter->pid);
@@ -310,7 +303,7 @@ static int vchiq_is_connected(VCHIQ_INSTANCE_T instance)
VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance)
{
VCHIQ_STATUS_T status;
- VCHIQ_STATE_T *state = instance->state;
+ struct vchiq_state *state = instance->state;
vchiq_log_trace(vchiq_core_log_level,
"%s(%p) called", __func__, instance);
@@ -338,12 +331,12 @@ EXPORT_SYMBOL(vchiq_connect);
VCHIQ_STATUS_T vchiq_add_service(
VCHIQ_INSTANCE_T instance,
- const VCHIQ_SERVICE_PARAMS_T *params,
+ const struct vchiq_service_params *params,
VCHIQ_SERVICE_HANDLE_T *phandle)
{
VCHIQ_STATUS_T status;
- VCHIQ_STATE_T *state = instance->state;
- VCHIQ_SERVICE_T *service = NULL;
+ struct vchiq_state *state = instance->state;
+ struct vchiq_service *service = NULL;
int srvstate;
vchiq_log_trace(vchiq_core_log_level,
@@ -377,12 +370,12 @@ EXPORT_SYMBOL(vchiq_add_service);
VCHIQ_STATUS_T vchiq_open_service(
VCHIQ_INSTANCE_T instance,
- const VCHIQ_SERVICE_PARAMS_T *params,
+ const struct vchiq_service_params *params,
VCHIQ_SERVICE_HANDLE_T *phandle)
{
VCHIQ_STATUS_T status = VCHIQ_ERROR;
- VCHIQ_STATE_T *state = instance->state;
- VCHIQ_SERVICE_T *service = NULL;
+ struct vchiq_state *state = instance->state;
+ struct vchiq_service *service = NULL;
vchiq_log_trace(vchiq_core_log_level,
"%s(%p) called", __func__, instance);
@@ -424,9 +417,9 @@ vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle, const void *data,
switch (mode) {
case VCHIQ_BULK_MODE_NOCALLBACK:
case VCHIQ_BULK_MODE_CALLBACK:
- status = vchiq_bulk_transfer(handle,
- VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
- mode, VCHIQ_BULK_TRANSMIT);
+ status = vchiq_bulk_transfer(handle, (void *)data, size,
+ userdata, mode,
+ VCHIQ_BULK_TRANSMIT);
break;
case VCHIQ_BULK_MODE_BLOCKING:
status = vchiq_blocking_bulk_transfer(handle,
@@ -449,9 +442,8 @@ vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data,
switch (mode) {
case VCHIQ_BULK_MODE_NOCALLBACK:
case VCHIQ_BULK_MODE_CALLBACK:
- status = vchiq_bulk_transfer(handle,
- VCHI_MEM_HANDLE_INVALID, data, size, userdata,
- mode, VCHIQ_BULK_RECEIVE);
+ status = vchiq_bulk_transfer(handle, data, size, userdata,
+ mode, VCHIQ_BULK_RECEIVE);
break;
case VCHIQ_BULK_MODE_BLOCKING:
status = vchiq_blocking_bulk_transfer(handle,
@@ -470,10 +462,9 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
unsigned int size, VCHIQ_BULK_DIR_T dir)
{
VCHIQ_INSTANCE_T instance;
- VCHIQ_SERVICE_T *service;
+ struct vchiq_service *service;
VCHIQ_STATUS_T status;
struct bulk_waiter_node *waiter = NULL;
- struct list_head *pos;
service = find_service_by_handle(handle);
if (!service)
@@ -484,20 +475,16 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
unlock_service(service);
mutex_lock(&instance->bulk_waiter_list_mutex);
- list_for_each(pos, &instance->bulk_waiter_list) {
- if (list_entry(pos, struct bulk_waiter_node,
- list)->pid == current->pid) {
- waiter = list_entry(pos,
- struct bulk_waiter_node,
- list);
- list_del(pos);
+ list_for_each_entry(waiter, &instance->bulk_waiter_list, list) {
+ if (waiter->pid == current->pid) {
+ list_del(&waiter->list);
break;
}
}
mutex_unlock(&instance->bulk_waiter_list_mutex);
if (waiter) {
- VCHIQ_BULK_T *bulk = waiter->bulk_waiter.bulk;
+ struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk;
if (bulk) {
/* This thread has an outstanding bulk transfer. */
@@ -523,12 +510,11 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
}
}
- status = vchiq_bulk_transfer(handle, VCHI_MEM_HANDLE_INVALID,
- data, size, &waiter->bulk_waiter, VCHIQ_BULK_MODE_BLOCKING,
- dir);
+ status = vchiq_bulk_transfer(handle, data, size, &waiter->bulk_waiter,
+ VCHIQ_BULK_MODE_BLOCKING, dir);
if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) ||
!waiter->bulk_waiter.bulk) {
- VCHIQ_BULK_T *bulk = waiter->bulk_waiter.bulk;
+ struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk;
if (bulk) {
/* Cancel the signal when the transfer
@@ -559,10 +545,10 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
static VCHIQ_STATUS_T
add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
- VCHIQ_HEADER_T *header, USER_SERVICE_T *user_service,
- void *bulk_userdata)
+ struct vchiq_header *header, struct user_service *user_service,
+ void *bulk_userdata)
{
- VCHIQ_COMPLETION_DATA_T *completion;
+ struct vchiq_completion_data *completion;
int insert;
DEBUG_INITIALISE(g_state.local)
@@ -574,7 +560,7 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
vchiq_log_trace(vchiq_arm_log_level,
"%s - completion queue full", __func__);
DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
- if (down_interruptible(&instance->remove_event) != 0) {
+ if (wait_for_completion_killable( &instance->remove_event)) {
vchiq_log_info(vchiq_arm_log_level,
"service_callback interrupted");
return VCHIQ_RETRY;
@@ -612,7 +598,7 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
insert++;
instance->completion_insert = insert;
- up(&instance->insert_event);
+ complete(&instance->insert_event);
return VCHIQ_SUCCESS;
}
@@ -624,16 +610,16 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
***************************************************************************/
static VCHIQ_STATUS_T
-service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
- VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
+service_callback(VCHIQ_REASON_T reason, struct vchiq_header *header,
+ VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
{
/* How do we ensure the callback goes to the right client?
- ** The service_user data points to a USER_SERVICE_T record containing
- ** the original callback and the user state structure, which contains a
- ** circular buffer for completion records.
+ ** The service_user data points to a user_service record
+ ** containing the original callback and the user state structure, which
+ ** contains a circular buffer for completion records.
*/
- USER_SERVICE_T *user_service;
- VCHIQ_SERVICE_T *service;
+ struct user_service *user_service;
+ struct vchiq_service *service;
VCHIQ_INSTANCE_T instance;
bool skip_completion = false;
@@ -643,7 +629,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
service = handle_to_service(handle);
BUG_ON(!service);
- user_service = (USER_SERVICE_T *)service->base.userdata;
+ user_service = (struct user_service *)service->base.userdata;
instance = user_service->instance;
if (!instance || instance->closing)
@@ -685,7 +671,8 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
}
DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- if (down_interruptible(&user_service->remove_event)
+ if (wait_for_completion_killable(
+ &user_service->remove_event)
!= 0) {
vchiq_log_info(vchiq_arm_log_level,
"%s interrupted", __func__);
@@ -717,7 +704,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
}
spin_unlock(&msg_queue_spinlock);
- up(&user_service->insert_event);
+ complete(&user_service->insert_event);
header = NULL;
}
@@ -746,7 +733,7 @@ user_service_free(void *userdata)
* close_delivered
*
***************************************************************************/
-static void close_delivered(USER_SERVICE_T *user_service)
+static void close_delivered(struct user_service *user_service)
{
vchiq_log_info(vchiq_arm_log_level,
"%s(handle=%x)",
@@ -757,81 +744,55 @@ static void close_delivered(USER_SERVICE_T *user_service)
unlock_service(user_service->service);
/* Wake the user-thread blocked in close_ or remove_service */
- up(&user_service->close_event);
+ complete(&user_service->close_event);
user_service->close_pending = 0;
}
}
struct vchiq_io_copy_callback_context {
- struct vchiq_element *current_element;
- size_t current_element_offset;
+ struct vchiq_element *element;
+ size_t element_offset;
unsigned long elements_to_go;
- size_t current_offset;
};
-static ssize_t
-vchiq_ioc_copy_element_data(
- void *context,
- void *dest,
- size_t offset,
- size_t maxsize)
+static ssize_t vchiq_ioc_copy_element_data(void *context, void *dest,
+ size_t offset, size_t maxsize)
{
- long res;
+ struct vchiq_io_copy_callback_context *cc = context;
+ size_t total_bytes_copied = 0;
size_t bytes_this_round;
- struct vchiq_io_copy_callback_context *copy_context =
- (struct vchiq_io_copy_callback_context *)context;
- if (offset != copy_context->current_offset)
- return 0;
-
- if (!copy_context->elements_to_go)
- return 0;
-
- /*
- * Complex logic here to handle the case of 0 size elements
- * in the middle of the array of elements.
- *
- * Need to skip over these 0 size elements.
- */
- while (1) {
- bytes_this_round = min(copy_context->current_element->size -
- copy_context->current_element_offset,
- maxsize);
+ while (total_bytes_copied < maxsize) {
+ if (!cc->elements_to_go)
+ return total_bytes_copied;
- if (bytes_this_round)
- break;
-
- copy_context->elements_to_go--;
- copy_context->current_element++;
- copy_context->current_element_offset = 0;
-
- if (!copy_context->elements_to_go)
- return 0;
- }
+ if (!cc->element->size) {
+ cc->elements_to_go--;
+ cc->element++;
+ cc->element_offset = 0;
+ continue;
+ }
- res = copy_from_user(dest,
- copy_context->current_element->data +
- copy_context->current_element_offset,
- bytes_this_round);
+ bytes_this_round = min(cc->element->size - cc->element_offset,
+ maxsize - total_bytes_copied);
- if (res != 0)
- return -EFAULT;
+ if (copy_from_user(dest + total_bytes_copied,
+ cc->element->data + cc->element_offset,
+ bytes_this_round))
+ return -EFAULT;
- copy_context->current_element_offset += bytes_this_round;
- copy_context->current_offset += bytes_this_round;
+ cc->element_offset += bytes_this_round;
+ total_bytes_copied += bytes_this_round;
- /*
- * Check if done with current element, and if so advance to the next.
- */
- if (copy_context->current_element_offset ==
- copy_context->current_element->size) {
- copy_context->elements_to_go--;
- copy_context->current_element++;
- copy_context->current_element_offset = 0;
+ if (cc->element_offset == cc->element->size) {
+ cc->elements_to_go--;
+ cc->element++;
+ cc->element_offset = 0;
+ }
}
- return bytes_this_round;
+ return maxsize;
}
/**************************************************************************
@@ -848,10 +809,9 @@ vchiq_ioc_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
unsigned long i;
size_t total_size = 0;
- context.current_element = elements;
- context.current_element_offset = 0;
+ context.element = elements;
+ context.element_offset = 0;
context.elements_to_go = count;
- context.current_offset = 0;
for (i = 0; i < count; i++) {
if (!elements[i].data && elements[i].size != 0)
@@ -874,7 +834,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
VCHIQ_INSTANCE_T instance = file->private_data;
VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
- VCHIQ_SERVICE_T *service = NULL;
+ struct vchiq_service *service = NULL;
long ret = 0;
int i, rc;
@@ -906,7 +866,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (status == VCHIQ_SUCCESS) {
/* Wake the completion thread and ask it to exit */
instance->closing = 1;
- up(&instance->insert_event);
+ complete(&instance->insert_event);
}
break;
@@ -936,8 +896,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
case VCHIQ_IOC_CREATE_SERVICE: {
- VCHIQ_CREATE_SERVICE_T args;
- USER_SERVICE_T *user_service = NULL;
+ struct vchiq_create_service args;
+ struct user_service *user_service = NULL;
void *userdata;
int srvstate;
@@ -948,7 +908,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
- user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL);
+ user_service = kmalloc(sizeof(*user_service), GFP_KERNEL);
if (!user_service) {
ret = -ENOMEM;
break;
@@ -987,9 +947,9 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
instance->completion_remove - 1;
user_service->msg_insert = 0;
user_service->msg_remove = 0;
- sema_init(&user_service->insert_event, 0);
- sema_init(&user_service->remove_event, 0);
- sema_init(&user_service->close_event, 0);
+ init_completion(&user_service->insert_event);
+ init_completion(&user_service->remove_event);
+ init_completion(&user_service->close_event);
if (args.is_open) {
status = vchiq_open_service_internal
@@ -1004,7 +964,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
if (copy_to_user((void __user *)
- &(((VCHIQ_CREATE_SERVICE_T __user *)
+ &(((struct vchiq_create_service __user *)
arg)->handle),
(const void *)&service->handle,
sizeof(service->handle)) != 0) {
@@ -1019,55 +979,38 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
} break;
- case VCHIQ_IOC_CLOSE_SERVICE: {
+ case VCHIQ_IOC_CLOSE_SERVICE:
+ case VCHIQ_IOC_REMOVE_SERVICE: {
VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+ struct user_service *user_service;
service = find_service_for_instance(instance, handle);
- if (service != NULL) {
- USER_SERVICE_T *user_service =
- (USER_SERVICE_T *)service->base.userdata;
- /* close_pending is false on first entry, and when the
- wait in vchiq_close_service has been interrupted. */
- if (!user_service->close_pending) {
- status = vchiq_close_service(service->handle);
- if (status != VCHIQ_SUCCESS)
- break;
- }
-
- /* close_pending is true once the underlying service
- has been closed until the client library calls the
- CLOSE_DELIVERED ioctl, signalling close_event. */
- if (user_service->close_pending &&
- down_interruptible(&user_service->close_event))
- status = VCHIQ_RETRY;
- } else
+ if (!service) {
ret = -EINVAL;
- } break;
+ break;
+ }
- case VCHIQ_IOC_REMOVE_SERVICE: {
- VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+ user_service = service->base.userdata;
- service = find_service_for_instance(instance, handle);
- if (service != NULL) {
- USER_SERVICE_T *user_service =
- (USER_SERVICE_T *)service->base.userdata;
- /* close_pending is false on first entry, and when the
- wait in vchiq_close_service has been interrupted. */
- if (!user_service->close_pending) {
- status = vchiq_remove_service(service->handle);
- if (status != VCHIQ_SUCCESS)
- break;
- }
+ /* close_pending is false on first entry, and when the
+ wait in vchiq_close_service has been interrupted. */
+ if (!user_service->close_pending) {
+ status = (cmd == VCHIQ_IOC_CLOSE_SERVICE) ?
+ vchiq_close_service(service->handle) :
+ vchiq_remove_service(service->handle);
+ if (status != VCHIQ_SUCCESS)
+ break;
+ }
- /* close_pending is true once the underlying service
- has been closed until the client library calls the
- CLOSE_DELIVERED ioctl, signalling close_event. */
- if (user_service->close_pending &&
- down_interruptible(&user_service->close_event))
- status = VCHIQ_RETRY;
- } else
- ret = -EINVAL;
- } break;
+ /* close_pending is true once the underlying service
+ has been closed until the client library calls the
+ CLOSE_DELIVERED ioctl, signalling close_event. */
+ if (user_service->close_pending &&
+ wait_for_completion_killable(
+ &user_service->close_event))
+ status = VCHIQ_RETRY;
+ break;
+ }
case VCHIQ_IOC_USE_SERVICE:
case VCHIQ_IOC_RELEASE_SERVICE: {
@@ -1097,7 +1040,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} break;
case VCHIQ_IOC_QUEUE_MESSAGE: {
- VCHIQ_QUEUE_MESSAGE_T args;
+ struct vchiq_queue_message args;
if (copy_from_user
(&args, (const void __user *)arg,
@@ -1126,7 +1069,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
case VCHIQ_IOC_QUEUE_BULK_RECEIVE: {
- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+ struct vchiq_queue_bulk_transfer args;
struct bulk_waiter_node *waiter = NULL;
VCHIQ_BULK_DIR_T dir =
@@ -1153,21 +1096,16 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = -ENOMEM;
break;
}
+
args.userdata = &waiter->bulk_waiter;
} else if (args.mode == VCHIQ_BULK_MODE_WAITING) {
- struct list_head *pos;
-
mutex_lock(&instance->bulk_waiter_list_mutex);
- list_for_each(pos, &instance->bulk_waiter_list) {
- if (list_entry(pos, struct bulk_waiter_node,
- list)->pid == current->pid) {
- waiter = list_entry(pos,
- struct bulk_waiter_node,
- list);
- list_del(pos);
+ list_for_each_entry(waiter, &instance->bulk_waiter_list,
+ list) {
+ if (waiter->pid == current->pid) {
+ list_del(&waiter->list);
break;
}
-
}
mutex_unlock(&instance->bulk_waiter_list_mutex);
if (!waiter) {
@@ -1182,14 +1120,13 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
current->pid);
args.userdata = &waiter->bulk_waiter;
}
- status = vchiq_bulk_transfer
- (args.handle,
- VCHI_MEM_HANDLE_INVALID,
- args.data, args.size,
- args.userdata, args.mode,
- dir);
+
+ status = vchiq_bulk_transfer(args.handle, args.data, args.size,
+ args.userdata, args.mode, dir);
+
if (!waiter)
break;
+
if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) ||
!waiter->bulk_waiter.bulk) {
if (waiter->bulk_waiter.bulk) {
@@ -1212,7 +1149,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
waiter, current->pid);
if (copy_to_user((void __user *)
- &(((VCHIQ_QUEUE_BULK_TRANSFER_T __user *)
+ &(((struct vchiq_queue_bulk_transfer __user *)
arg)->mode),
(const void *)&mode_waiting,
sizeof(mode_waiting)) != 0)
@@ -1221,7 +1158,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} break;
case VCHIQ_IOC_AWAIT_COMPLETION: {
- VCHIQ_AWAIT_COMPLETION_T args;
+ struct vchiq_await_completion args;
DEBUG_TRACE(AWAIT_COMPLETION_LINE);
if (!instance->connected) {
@@ -1245,7 +1182,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
DEBUG_TRACE(AWAIT_COMPLETION_LINE);
mutex_unlock(&instance->completion_mutex);
- rc = down_interruptible(&instance->insert_event);
+ rc = wait_for_completion_killable(
+ &instance->insert_event);
mutex_lock(&instance->completion_mutex);
if (rc != 0) {
DEBUG_TRACE(AWAIT_COMPLETION_LINE);
@@ -1262,10 +1200,10 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int remove = instance->completion_remove;
for (ret = 0; ret < args.count; ret++) {
- VCHIQ_COMPLETION_DATA_T *completion;
- VCHIQ_SERVICE_T *service;
- USER_SERVICE_T *user_service;
- VCHIQ_HEADER_T *header;
+ struct vchiq_completion_data *completion;
+ struct vchiq_service *service;
+ struct user_service *user_service;
+ struct vchiq_header *header;
if (remove == instance->completion_insert)
break;
@@ -1290,7 +1228,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int msglen;
msglen = header->size +
- sizeof(VCHIQ_HEADER_T);
+ sizeof(struct vchiq_header);
/* This must be a VCHIQ-style service */
if (args.msgbufsize < msglen) {
vchiq_log_error(
@@ -1343,10 +1281,11 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
unlock_service(service);
if (copy_to_user((void __user *)(
- (size_t)args.buf +
- ret * sizeof(VCHIQ_COMPLETION_DATA_T)),
+ (size_t)args.buf + ret *
+ sizeof(struct vchiq_completion_data)),
completion,
- sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) {
+ sizeof(struct vchiq_completion_data))
+ != 0) {
if (ret == 0)
ret = -EFAULT;
break;
@@ -1363,8 +1302,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (msgbufcount != args.msgbufcount) {
if (copy_to_user((void __user *)
- &((VCHIQ_AWAIT_COMPLETION_T *)arg)->
- msgbufcount,
+ &((struct vchiq_await_completion *)arg)
+ ->msgbufcount,
&msgbufcount,
sizeof(msgbufcount)) != 0) {
ret = -EFAULT;
@@ -1373,15 +1312,15 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
if (ret != 0)
- up(&instance->remove_event);
+ complete(&instance->remove_event);
mutex_unlock(&instance->completion_mutex);
DEBUG_TRACE(AWAIT_COMPLETION_LINE);
} break;
case VCHIQ_IOC_DEQUEUE_MESSAGE: {
- VCHIQ_DEQUEUE_MESSAGE_T args;
- USER_SERVICE_T *user_service;
- VCHIQ_HEADER_T *header;
+ struct vchiq_dequeue_message args;
+ struct user_service *user_service;
+ struct vchiq_header *header;
DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
if (copy_from_user
@@ -1395,7 +1334,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = -EINVAL;
break;
}
- user_service = (USER_SERVICE_T *)service->base.userdata;
+ user_service = (struct user_service *)service->base.userdata;
if (user_service->is_vchi == 0) {
ret = -EINVAL;
break;
@@ -1413,8 +1352,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
do {
spin_unlock(&msg_queue_spinlock);
DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
- if (down_interruptible(
- &user_service->insert_event) != 0) {
+ if (wait_for_completion_killable(
+ &user_service->insert_event)) {
vchiq_log_info(vchiq_arm_log_level,
"DEQUEUE_MESSAGE interrupted");
ret = -EINTR;
@@ -1436,7 +1375,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
user_service->msg_remove++;
spin_unlock(&msg_queue_spinlock);
- up(&user_service->remove_event);
+ complete(&user_service->remove_event);
if (header == NULL)
ret = -ENOTCONN;
else if (header->size <= args.bufsize) {
@@ -1468,8 +1407,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} break;
case VCHIQ_IOC_GET_CONFIG: {
- VCHIQ_GET_CONFIG_T args;
- VCHIQ_CONFIG_T config;
+ struct vchiq_get_config args;
+ struct vchiq_config config;
if (copy_from_user(&args, (const void __user *)arg,
sizeof(args)) != 0) {
@@ -1480,18 +1419,16 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = -EINVAL;
break;
}
- status = vchiq_get_config(instance, args.config_size, &config);
- if (status == VCHIQ_SUCCESS) {
- if (copy_to_user((void __user *)args.pconfig,
- &config, args.config_size) != 0) {
- ret = -EFAULT;
- break;
- }
+
+ vchiq_get_config(&config);
+ if (copy_to_user(args.pconfig, &config, args.config_size)) {
+ ret = -EFAULT;
+ break;
}
} break;
case VCHIQ_IOC_SET_SERVICE_OPTION: {
- VCHIQ_SET_SERVICE_OPTION_T args;
+ struct vchiq_set_service_option args;
if (copy_from_user(
&args, (const void __user *)arg,
@@ -1524,8 +1461,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
service = find_closed_service_for_instance(instance, handle);
if (service != NULL) {
- USER_SERVICE_T *user_service =
- (USER_SERVICE_T *)service->base.userdata;
+ struct user_service *user_service =
+ (struct user_service *)service->base.userdata;
close_delivered(user_service);
} else
ret = -EINVAL;
@@ -1593,7 +1530,7 @@ vchiq_compat_ioctl_create_service(
unsigned int cmd,
unsigned long arg)
{
- VCHIQ_CREATE_SERVICE_T __user *args;
+ struct vchiq_create_service __user *args;
struct vchiq_create_service32 __user *ptrargs32 =
(struct vchiq_create_service32 __user *)arg;
struct vchiq_create_service32 args32;
@@ -1656,8 +1593,8 @@ vchiq_compat_ioctl_queue_message(struct file *file,
unsigned int cmd,
unsigned long arg)
{
- VCHIQ_QUEUE_MESSAGE_T *args;
- struct vchiq_element *elements;
+ struct vchiq_queue_message *args;
+ struct vchiq_element __user *elements;
struct vchiq_queue_message32 args32;
unsigned int count;
@@ -1723,7 +1660,7 @@ vchiq_compat_ioctl_queue_bulk(struct file *file,
unsigned int cmd,
unsigned long arg)
{
- VCHIQ_QUEUE_BULK_TRANSFER_T *args;
+ struct vchiq_queue_bulk_transfer __user *args;
struct vchiq_queue_bulk_transfer32 args32;
struct vchiq_queue_bulk_transfer32 *ptrargs32 =
(struct vchiq_queue_bulk_transfer32 *)arg;
@@ -1789,16 +1726,16 @@ vchiq_compat_ioctl_await_completion(struct file *file,
unsigned int cmd,
unsigned long arg)
{
- VCHIQ_AWAIT_COMPLETION_T *args;
- VCHIQ_COMPLETION_DATA_T *completion;
- VCHIQ_COMPLETION_DATA_T completiontemp;
+ struct vchiq_await_completion __user *args;
+ struct vchiq_completion_data __user *completion;
+ struct vchiq_completion_data completiontemp;
struct vchiq_await_completion32 args32;
struct vchiq_completion_data32 completion32;
- unsigned int *msgbufcount32;
+ unsigned int __user *msgbufcount32;
unsigned int msgbufcount_native;
compat_uptr_t msgbuf32;
- void *msgbuf;
- void **msgbufptr;
+ void __user *msgbuf;
+ void * __user *msgbufptr;
long ret;
args = compat_alloc_user_space(sizeof(*args) +
@@ -1807,11 +1744,11 @@ vchiq_compat_ioctl_await_completion(struct file *file,
if (!args)
return -EFAULT;
- completion = (VCHIQ_COMPLETION_DATA_T *)(args + 1);
- msgbufptr = (void __user **)(completion + 1);
+ completion = (struct vchiq_completion_data __user *)(args + 1);
+ msgbufptr = (void * __user *)(completion + 1);
if (copy_from_user(&args32,
- (struct vchiq_completion_data32 *)arg,
+ (struct vchiq_completion_data32 __user *)arg,
sizeof(args32)))
return -EFAULT;
@@ -1939,7 +1876,7 @@ vchiq_compat_ioctl_dequeue_message(struct file *file,
unsigned int cmd,
unsigned long arg)
{
- VCHIQ_DEQUEUE_MESSAGE_T *args;
+ struct vchiq_dequeue_message __user *args;
struct vchiq_dequeue_message32 args32;
args = compat_alloc_user_space(sizeof(*args));
@@ -1947,7 +1884,7 @@ vchiq_compat_ioctl_dequeue_message(struct file *file,
return -EFAULT;
if (copy_from_user(&args32,
- (struct vchiq_dequeue_message32 *)arg,
+ (struct vchiq_dequeue_message32 __user *)arg,
sizeof(args32)))
return -EFAULT;
@@ -1974,7 +1911,7 @@ vchiq_compat_ioctl_get_config(struct file *file,
unsigned int cmd,
unsigned long arg)
{
- VCHIQ_GET_CONFIG_T *args;
+ struct vchiq_get_config __user *args;
struct vchiq_get_config32 args32;
args = compat_alloc_user_space(sizeof(*args));
@@ -1982,7 +1919,7 @@ vchiq_compat_ioctl_get_config(struct file *file,
return -EFAULT;
if (copy_from_user(&args32,
- (struct vchiq_get_config32 *)arg,
+ (struct vchiq_get_config32 __user *)arg,
sizeof(args32)))
return -EFAULT;
@@ -2017,201 +1954,152 @@ vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#endif
-/****************************************************************************
-*
-* vchiq_open
-*
-***************************************************************************/
-
-static int
-vchiq_open(struct inode *inode, struct file *file)
+static int vchiq_open(struct inode *inode, struct file *file)
{
- int dev = iminor(inode) & 0x0f;
+ struct vchiq_state *state = vchiq_get_state();
+ VCHIQ_INSTANCE_T instance;
vchiq_log_info(vchiq_arm_log_level, "vchiq_open");
- switch (dev) {
- case VCHIQ_MINOR: {
- VCHIQ_STATE_T *state = vchiq_get_state();
- VCHIQ_INSTANCE_T instance;
- if (!state) {
- vchiq_log_error(vchiq_arm_log_level,
+ if (!state) {
+ vchiq_log_error(vchiq_arm_log_level,
"vchiq has no connection to VideoCore");
- return -ENOTCONN;
- }
-
- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
- if (!instance)
- return -ENOMEM;
+ return -ENOTCONN;
+ }
- instance->state = state;
- instance->pid = current->tgid;
+ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+ if (!instance)
+ return -ENOMEM;
- vchiq_debugfs_add_instance(instance);
+ instance->state = state;
+ instance->pid = current->tgid;
- sema_init(&instance->insert_event, 0);
- sema_init(&instance->remove_event, 0);
- mutex_init(&instance->completion_mutex);
- mutex_init(&instance->bulk_waiter_list_mutex);
- INIT_LIST_HEAD(&instance->bulk_waiter_list);
+ vchiq_debugfs_add_instance(instance);
- file->private_data = instance;
- } break;
+ init_completion(&instance->insert_event);
+ init_completion(&instance->remove_event);
+ mutex_init(&instance->completion_mutex);
+ mutex_init(&instance->bulk_waiter_list_mutex);
+ INIT_LIST_HEAD(&instance->bulk_waiter_list);
- default:
- vchiq_log_error(vchiq_arm_log_level,
- "Unknown minor device: %d", dev);
- return -ENXIO;
- }
+ file->private_data = instance;
return 0;
}
-/****************************************************************************
-*
-* vchiq_release
-*
-***************************************************************************/
-
-static int
-vchiq_release(struct inode *inode, struct file *file)
+static int vchiq_release(struct inode *inode, struct file *file)
{
- int dev = iminor(inode) & 0x0f;
+ VCHIQ_INSTANCE_T instance = file->private_data;
+ struct vchiq_state *state = vchiq_get_state();
+ struct vchiq_service *service;
int ret = 0;
+ int i;
- switch (dev) {
- case VCHIQ_MINOR: {
- VCHIQ_INSTANCE_T instance = file->private_data;
- VCHIQ_STATE_T *state = vchiq_get_state();
- VCHIQ_SERVICE_T *service;
- int i;
-
- vchiq_log_info(vchiq_arm_log_level,
- "%s: instance=%lx",
- __func__, (unsigned long)instance);
+ vchiq_log_info(vchiq_arm_log_level, "%s: instance=%lx", __func__,
+ (unsigned long)instance);
- if (!state) {
- ret = -EPERM;
- goto out;
- }
+ if (!state) {
+ ret = -EPERM;
+ goto out;
+ }
- /* Ensure videocore is awake to allow termination. */
- vchiq_use_internal(instance->state, NULL,
- USE_TYPE_VCHIQ);
+ /* Ensure videocore is awake to allow termination. */
+ vchiq_use_internal(instance->state, NULL, USE_TYPE_VCHIQ);
- mutex_lock(&instance->completion_mutex);
+ mutex_lock(&instance->completion_mutex);
- /* Wake the completion thread and ask it to exit */
- instance->closing = 1;
- up(&instance->insert_event);
+ /* Wake the completion thread and ask it to exit */
+ instance->closing = 1;
+ complete(&instance->insert_event);
- mutex_unlock(&instance->completion_mutex);
+ mutex_unlock(&instance->completion_mutex);
- /* Wake the slot handler if the completion queue is full. */
- up(&instance->remove_event);
+ /* Wake the slot handler if the completion queue is full. */
+ complete(&instance->remove_event);
- /* Mark all services for termination... */
- i = 0;
- while ((service = next_service_by_instance(state, instance,
- &i)) != NULL) {
- USER_SERVICE_T *user_service = service->base.userdata;
+ /* Mark all services for termination... */
+ i = 0;
+ while ((service = next_service_by_instance(state, instance, &i))) {
+ struct user_service *user_service = service->base.userdata;
- /* Wake the slot handler if the msg queue is full. */
- up(&user_service->remove_event);
+ /* Wake the slot handler if the msg queue is full. */
+ complete(&user_service->remove_event);
- vchiq_terminate_service_internal(service);
- unlock_service(service);
- }
+ vchiq_terminate_service_internal(service);
+ unlock_service(service);
+ }
- /* ...and wait for them to die */
- i = 0;
- while ((service = next_service_by_instance(state, instance, &i))
- != NULL) {
- USER_SERVICE_T *user_service = service->base.userdata;
+ /* ...and wait for them to die */
+ i = 0;
+ while ((service = next_service_by_instance(state, instance, &i))) {
+ struct user_service *user_service = service->base.userdata;
- down(&service->remove_event);
+ wait_for_completion(&service->remove_event);
- BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
+ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
- spin_lock(&msg_queue_spinlock);
-
- while (user_service->msg_remove !=
- user_service->msg_insert) {
- VCHIQ_HEADER_T *header;
- int m = user_service->msg_remove &
- (MSG_QUEUE_SIZE - 1);
+ spin_lock(&msg_queue_spinlock);
- header = user_service->msg_queue[m];
- user_service->msg_remove++;
- spin_unlock(&msg_queue_spinlock);
-
- if (header)
- vchiq_release_message(
- service->handle,
- header);
- spin_lock(&msg_queue_spinlock);
- }
+ while (user_service->msg_remove != user_service->msg_insert) {
+ struct vchiq_header *header;
+ int m = user_service->msg_remove & (MSG_QUEUE_SIZE - 1);
+ header = user_service->msg_queue[m];
+ user_service->msg_remove++;
spin_unlock(&msg_queue_spinlock);
- unlock_service(service);
+ if (header)
+ vchiq_release_message(service->handle, header);
+ spin_lock(&msg_queue_spinlock);
}
- /* Release any closed services */
- while (instance->completion_remove !=
- instance->completion_insert) {
- VCHIQ_COMPLETION_DATA_T *completion;
- VCHIQ_SERVICE_T *service;
-
- completion = &instance->completions[
- instance->completion_remove &
- (MAX_COMPLETIONS - 1)];
- service = completion->service_userdata;
- if (completion->reason == VCHIQ_SERVICE_CLOSED) {
- USER_SERVICE_T *user_service =
- service->base.userdata;
-
- /* Wake any blocked user-thread */
- if (instance->use_close_delivered)
- up(&user_service->close_event);
- unlock_service(service);
- }
- instance->completion_remove++;
- }
+ spin_unlock(&msg_queue_spinlock);
- /* Release the PEER service count. */
- vchiq_release_internal(instance->state, NULL);
+ unlock_service(service);
+ }
- {
- struct list_head *pos, *next;
+ /* Release any closed services */
+ while (instance->completion_remove !=
+ instance->completion_insert) {
+ struct vchiq_completion_data *completion;
+ struct vchiq_service *service;
- list_for_each_safe(pos, next,
- &instance->bulk_waiter_list) {
- struct bulk_waiter_node *waiter;
+ completion = &instance->completions[
+ instance->completion_remove & (MAX_COMPLETIONS - 1)];
+ service = completion->service_userdata;
+ if (completion->reason == VCHIQ_SERVICE_CLOSED) {
+ struct user_service *user_service =
+ service->base.userdata;
- waiter = list_entry(pos,
- struct bulk_waiter_node,
- list);
- list_del(pos);
- vchiq_log_info(vchiq_arm_log_level,
- "bulk_waiter - cleaned up %pK for pid %d",
- waiter, waiter->pid);
- kfree(waiter);
- }
+ /* Wake any blocked user-thread */
+ if (instance->use_close_delivered)
+ complete(&user_service->close_event);
+ unlock_service(service);
}
+ instance->completion_remove++;
+ }
- vchiq_debugfs_remove_instance(instance);
+ /* Release the PEER service count. */
+ vchiq_release_internal(instance->state, NULL);
- kfree(instance);
- file->private_data = NULL;
- } break;
+ {
+ struct bulk_waiter_node *waiter, *next;
- default:
- vchiq_log_error(vchiq_arm_log_level,
- "Unknown minor device: %d", dev);
- ret = -ENXIO;
+ list_for_each_entry_safe(waiter, next,
+ &instance->bulk_waiter_list, list) {
+ list_del(&waiter->list);
+ vchiq_log_info(vchiq_arm_log_level,
+ "bulk_waiter - cleaned up %pK for pid %d",
+ waiter, waiter->pid);
+ kfree(waiter);
+ }
}
+ vchiq_debugfs_remove_instance(instance);
+
+ kfree(instance);
+ file->private_data = NULL;
+
out:
return ret;
}
@@ -2225,7 +2113,7 @@ out:
void
vchiq_dump(void *dump_context, const char *str, int len)
{
- DUMP_CONTEXT_T *context = (DUMP_CONTEXT_T *)dump_context;
+ struct dump_context *context = (struct dump_context *)dump_context;
if (context->actual < context->space) {
int copy_bytes;
@@ -2270,7 +2158,7 @@ vchiq_dump(void *dump_context, const char *str, int len)
void
vchiq_dump_platform_instances(void *dump_context)
{
- VCHIQ_STATE_T *state = vchiq_get_state();
+ struct vchiq_state *state = vchiq_get_state();
char buf[80];
int len;
int i;
@@ -2279,7 +2167,7 @@ vchiq_dump_platform_instances(void *dump_context)
marking those that have been dumped. */
for (i = 0; i < state->unused_service; i++) {
- VCHIQ_SERVICE_T *service = state->services[i];
+ struct vchiq_service *service = state->services[i];
VCHIQ_INSTANCE_T instance;
if (service && (service->base.callback == service_callback)) {
@@ -2290,7 +2178,7 @@ vchiq_dump_platform_instances(void *dump_context)
}
for (i = 0; i < state->unused_service; i++) {
- VCHIQ_SERVICE_T *service = state->services[i];
+ struct vchiq_service *service = state->services[i];
VCHIQ_INSTANCE_T instance;
if (service && (service->base.callback == service_callback)) {
@@ -2320,9 +2208,11 @@ vchiq_dump_platform_instances(void *dump_context)
***************************************************************************/
void
-vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
+vchiq_dump_platform_service_state(void *dump_context,
+ struct vchiq_service *service)
{
- USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata;
+ struct user_service *user_service =
+ (struct user_service *)service->base.userdata;
char buf[80];
int len;
@@ -2353,7 +2243,7 @@ static ssize_t
vchiq_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- DUMP_CONTEXT_T context;
+ struct dump_context context;
context.buf = buf;
context.actual = 0;
@@ -2367,7 +2257,7 @@ vchiq_read(struct file *file, char __user *buf,
return context.actual;
}
-VCHIQ_STATE_T *
+struct vchiq_state *
vchiq_get_state(void)
{
@@ -2398,9 +2288,9 @@ vchiq_fops = {
*/
int
-vchiq_videocore_wanted(VCHIQ_STATE_T *state)
+vchiq_videocore_wanted(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
if (!arm_state)
/* autosuspend not supported - always return wanted */
@@ -2420,7 +2310,7 @@ vchiq_videocore_wanted(VCHIQ_STATE_T *state)
static VCHIQ_STATUS_T
vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason,
- VCHIQ_HEADER_T *header,
+ struct vchiq_header *header,
VCHIQ_SERVICE_HANDLE_T service_user,
void *bulk_user)
{
@@ -2432,14 +2322,14 @@ vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason,
static int
vchiq_keepalive_thread_func(void *v)
{
- VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_state *state = (struct vchiq_state *)v;
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T status;
VCHIQ_INSTANCE_T instance;
VCHIQ_SERVICE_HANDLE_T ka_handle;
- VCHIQ_SERVICE_PARAMS_T params = {
+ struct vchiq_service_params params = {
.fourcc = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'),
.callback = vchiq_keepalive_vchiq_callback,
.version = KEEPALIVE_VER,
@@ -2470,7 +2360,7 @@ vchiq_keepalive_thread_func(void *v)
while (1) {
long rc = 0, uc = 0;
- if (wait_for_completion_interruptible(&arm_state->ka_evt)
+ if (wait_for_completion_killable(&arm_state->ka_evt)
!= 0) {
vchiq_log_error(vchiq_susp_log_level,
"%s interrupted", __func__);
@@ -2511,7 +2401,8 @@ exit:
}
VCHIQ_STATUS_T
-vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state)
+vchiq_arm_init_state(struct vchiq_state *state,
+ struct vchiq_arm_state *arm_state)
{
if (arm_state) {
rwlock_init(&arm_state->susp_res_lock);
@@ -2607,8 +2498,8 @@ vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state)
*/
void
-set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
- enum vc_suspend_status new_state)
+set_suspend_state(struct vchiq_arm_state *arm_state,
+ enum vc_suspend_status new_state)
{
/* set the state in all cases */
arm_state->vc_suspend_state = new_state;
@@ -2644,8 +2535,8 @@ set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
}
void
-set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
- enum vc_resume_status new_state)
+set_resume_state(struct vchiq_arm_state *arm_state,
+ enum vc_resume_status new_state)
{
/* set the state in all cases */
arm_state->vc_resume_state = new_state;
@@ -2673,7 +2564,7 @@ set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
/* should be called with the write lock held */
inline void
-start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
+start_suspend_timer(struct vchiq_arm_state *arm_state)
{
del_timer(&arm_state->suspend_timer);
arm_state->suspend_timer.expires = jiffies +
@@ -2684,7 +2575,7 @@ start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
/* should be called with the write lock held */
static inline void
-stop_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
+stop_suspend_timer(struct vchiq_arm_state *arm_state)
{
if (arm_state->suspend_timer_running) {
del_timer(&arm_state->suspend_timer);
@@ -2693,9 +2584,9 @@ stop_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
}
static inline int
-need_resume(VCHIQ_STATE_T *state)
+need_resume(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
return (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) &&
(arm_state->vc_resume_state < VC_RESUME_REQUESTED) &&
@@ -2703,7 +2594,7 @@ need_resume(VCHIQ_STATE_T *state)
}
static int
-block_resume(VCHIQ_ARM_STATE_T *arm_state)
+block_resume(struct vchiq_arm_state *arm_state)
{
int status = VCHIQ_SUCCESS;
const unsigned long timeout_val =
@@ -2720,7 +2611,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
write_unlock_bh(&arm_state->susp_res_lock);
vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
"blocked clients", __func__);
- if (wait_for_completion_interruptible_timeout(
+ if (wait_for_completion_killable_timeout(
&arm_state->blocked_blocker, timeout_val)
<= 0) {
vchiq_log_error(vchiq_susp_log_level, "%s wait for "
@@ -2746,7 +2637,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
write_unlock_bh(&arm_state->susp_res_lock);
vchiq_log_info(vchiq_susp_log_level, "%s wait for resume",
__func__);
- if (wait_for_completion_interruptible_timeout(
+ if (wait_for_completion_killable_timeout(
&arm_state->vc_resume_complete, timeout_val)
<= 0) {
vchiq_log_error(vchiq_susp_log_level, "%s wait for "
@@ -2769,7 +2660,7 @@ out:
}
static inline void
-unblock_resume(VCHIQ_ARM_STATE_T *arm_state)
+unblock_resume(struct vchiq_arm_state *arm_state)
{
complete_all(&arm_state->resume_blocker);
arm_state->resume_blocked = 0;
@@ -2778,10 +2669,10 @@ unblock_resume(VCHIQ_ARM_STATE_T *arm_state)
/* Initiate suspend via slot handler. Should be called with the write lock
* held */
VCHIQ_STATUS_T
-vchiq_arm_vcsuspend(VCHIQ_STATE_T *state)
+vchiq_arm_vcsuspend(struct vchiq_state *state)
{
VCHIQ_STATUS_T status = VCHIQ_ERROR;
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
if (!arm_state)
goto out;
@@ -2827,9 +2718,9 @@ out:
}
void
-vchiq_platform_check_suspend(VCHIQ_STATE_T *state)
+vchiq_platform_check_suspend(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
int susp = 0;
if (!arm_state)
@@ -2854,9 +2745,9 @@ out:
}
static void
-output_timeout_error(VCHIQ_STATE_T *state)
+output_timeout_error(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
char err[50] = "";
int vc_use_count = arm_state->videocore_use_count;
int active_services = state->unused_service;
@@ -2867,7 +2758,7 @@ output_timeout_error(VCHIQ_STATE_T *state)
goto output_msg;
}
for (i = 0; i < active_services; i++) {
- VCHIQ_SERVICE_T *service_ptr = state->services[i];
+ struct vchiq_service *service_ptr = state->services[i];
if (service_ptr && service_ptr->service_use_count &&
(service_ptr->srvstate != VCHIQ_SRVSTATE_FREE)) {
@@ -2899,9 +2790,9 @@ output_msg:
** videocore failed to suspend in time or VCHIQ_ERROR if interrupted.
*/
VCHIQ_STATUS_T
-vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+vchiq_arm_force_suspend(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T status = VCHIQ_ERROR;
long rc = 0;
int repeat = -1;
@@ -2953,7 +2844,7 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
do {
write_unlock_bh(&arm_state->susp_res_lock);
- rc = wait_for_completion_interruptible_timeout(
+ rc = wait_for_completion_killable_timeout(
&arm_state->vc_suspend_complete,
msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS));
@@ -3010,9 +2901,9 @@ out:
}
void
-vchiq_check_suspend(VCHIQ_STATE_T *state)
+vchiq_check_suspend(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
if (!arm_state)
goto out;
@@ -3032,9 +2923,9 @@ out:
}
int
-vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
+vchiq_arm_allow_resume(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
int resume = 0;
int ret = -1;
@@ -3049,7 +2940,7 @@ vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
write_unlock_bh(&arm_state->susp_res_lock);
if (resume) {
- if (wait_for_completion_interruptible(
+ if (wait_for_completion_killable(
&arm_state->vc_resume_complete) < 0) {
vchiq_log_error(vchiq_susp_log_level,
"%s interrupted", __func__);
@@ -3076,9 +2967,9 @@ out:
/* This function should be called with the write lock held */
int
-vchiq_check_resume(VCHIQ_STATE_T *state)
+vchiq_check_resume(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
int resume = 0;
if (!arm_state)
@@ -3098,10 +2989,10 @@ out:
}
VCHIQ_STATUS_T
-vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
- enum USE_TYPE_E use_type)
+vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
+ enum USE_TYPE_E use_type)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
char entity[16];
int *entity_uc;
@@ -3231,9 +3122,9 @@ out:
}
VCHIQ_STATUS_T
-vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
+vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
char entity[16];
int *entity_uc;
@@ -3293,9 +3184,9 @@ out:
}
void
-vchiq_on_remote_use(VCHIQ_STATE_T *state)
+vchiq_on_remote_use(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
atomic_inc(&arm_state->ka_use_count);
@@ -3303,9 +3194,9 @@ vchiq_on_remote_use(VCHIQ_STATE_T *state)
}
void
-vchiq_on_remote_release(VCHIQ_STATE_T *state)
+vchiq_on_remote_release(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
atomic_inc(&arm_state->ka_release_count);
@@ -3313,18 +3204,18 @@ vchiq_on_remote_release(VCHIQ_STATE_T *state)
}
VCHIQ_STATUS_T
-vchiq_use_service_internal(VCHIQ_SERVICE_T *service)
+vchiq_use_service_internal(struct vchiq_service *service)
{
return vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
}
VCHIQ_STATUS_T
-vchiq_release_service_internal(VCHIQ_SERVICE_T *service)
+vchiq_release_service_internal(struct vchiq_service *service)
{
return vchiq_release_internal(service->state, service);
}
-VCHIQ_DEBUGFS_NODE_T *
+struct vchiq_debugfs_node *
vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance)
{
return &instance->debugfs_node;
@@ -3333,7 +3224,7 @@ vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance)
int
vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance)
{
- VCHIQ_SERVICE_T *service;
+ struct vchiq_service *service;
int use_count = 0, i;
i = 0;
@@ -3360,7 +3251,7 @@ vchiq_instance_get_trace(VCHIQ_INSTANCE_T instance)
void
vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace)
{
- VCHIQ_SERVICE_T *service;
+ struct vchiq_service *service;
int i;
i = 0;
@@ -3374,8 +3265,9 @@ vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace)
static void suspend_timer_callback(struct timer_list *t)
{
- VCHIQ_ARM_STATE_T *arm_state = from_timer(arm_state, t, suspend_timer);
- VCHIQ_STATE_T *state = arm_state->state;
+ struct vchiq_arm_state *arm_state =
+ from_timer(arm_state, t, suspend_timer);
+ struct vchiq_state *state = arm_state->state;
vchiq_log_info(vchiq_susp_log_level,
"%s - suspend timer expired - check suspend", __func__);
@@ -3386,7 +3278,7 @@ VCHIQ_STATUS_T
vchiq_use_service_no_resume(VCHIQ_SERVICE_HANDLE_T handle)
{
VCHIQ_STATUS_T ret = VCHIQ_ERROR;
- VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(handle);
if (service) {
ret = vchiq_use_internal(service->state, service,
@@ -3400,7 +3292,7 @@ VCHIQ_STATUS_T
vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle)
{
VCHIQ_STATUS_T ret = VCHIQ_ERROR;
- VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(handle);
if (service) {
ret = vchiq_use_internal(service->state, service,
@@ -3414,7 +3306,7 @@ VCHIQ_STATUS_T
vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle)
{
VCHIQ_STATUS_T ret = VCHIQ_ERROR;
- VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(handle);
if (service) {
ret = vchiq_release_internal(service->state, service);
@@ -3430,9 +3322,9 @@ struct service_data_struct {
};
void
-vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
+vchiq_dump_service_use_state(struct vchiq_state *state)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
struct service_data_struct *service_data;
int i, found = 0;
/* If there's more than 64 services, only dump ones with
@@ -3464,7 +3356,7 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
only_nonzero = 1;
for (i = 0; i < active_services; i++) {
- VCHIQ_SERVICE_T *service_ptr = state->services[i];
+ struct vchiq_service *service_ptr = state->services[i];
if (!service_ptr)
continue;
@@ -3516,9 +3408,9 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
}
VCHIQ_STATUS_T
-vchiq_check_service(VCHIQ_SERVICE_T *service)
+vchiq_check_service(struct vchiq_service *service)
{
- VCHIQ_ARM_STATE_T *arm_state;
+ struct vchiq_arm_state *arm_state;
VCHIQ_STATUS_T ret = VCHIQ_ERROR;
if (!service || !service->state)
@@ -3549,15 +3441,16 @@ out:
}
/* stub functions */
-void vchiq_on_remote_use_active(VCHIQ_STATE_T *state)
+void vchiq_on_remote_use_active(struct vchiq_state *state)
{
(void)state;
}
-void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
- VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate)
+void vchiq_platform_conn_state_changed(struct vchiq_state *state,
+ VCHIQ_CONNSTATE_T oldstate,
+ VCHIQ_CONNSTATE_T newstate)
{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id,
get_conn_state_name(oldstate), get_conn_state_name(newstate));
@@ -3593,11 +3486,34 @@ static const struct of_device_id vchiq_of_match[] = {
};
MODULE_DEVICE_TABLE(of, vchiq_of_match);
+static struct platform_device *
+vchiq_register_child(struct platform_device *pdev, const char *name)
+{
+ struct platform_device_info pdevinfo;
+ struct platform_device *child;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+
+ pdevinfo.parent = &pdev->dev;
+ pdevinfo.name = name;
+ pdevinfo.id = PLATFORM_DEVID_NONE;
+ pdevinfo.dma_mask = DMA_BIT_MASK(32);
+
+ child = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(child)) {
+ dev_warn(&pdev->dev, "%s not registered\n", name);
+ child = NULL;
+ }
+
+ return child;
+}
+
static int vchiq_probe(struct platform_device *pdev)
{
struct device_node *fw_node;
const struct of_device_id *of_id;
struct vchiq_drvdata *drvdata;
+ struct device *vchiq_dev;
int err;
of_id = of_match_node(vchiq_of_match, pdev->dev.of_node);
@@ -3623,34 +3539,22 @@ static int vchiq_probe(struct platform_device *pdev)
if (err != 0)
goto failed_platform_init;
- err = alloc_chrdev_region(&vchiq_devid, VCHIQ_MINOR, 1, DEVICE_NAME);
- if (err != 0) {
- vchiq_log_error(vchiq_arm_log_level,
- "Unable to allocate device number");
- goto failed_platform_init;
- }
cdev_init(&vchiq_cdev, &vchiq_fops);
vchiq_cdev.owner = THIS_MODULE;
err = cdev_add(&vchiq_cdev, vchiq_devid, 1);
if (err != 0) {
vchiq_log_error(vchiq_arm_log_level,
"Unable to register device");
- goto failed_cdev_add;
+ goto failed_platform_init;
}
- /* create sysfs entries */
- vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
- err = PTR_ERR(vchiq_class);
- if (IS_ERR(vchiq_class))
- goto failed_class_create;
-
- vchiq_dev = device_create(vchiq_class, NULL,
- vchiq_devid, NULL, "vchiq");
- err = PTR_ERR(vchiq_dev);
- if (IS_ERR(vchiq_dev))
+ vchiq_dev = device_create(vchiq_class, &pdev->dev, vchiq_devid, NULL,
+ "vchiq");
+ if (IS_ERR(vchiq_dev)) {
+ err = PTR_ERR(vchiq_dev);
goto failed_device_create;
+ }
- /* create debugfs entries */
vchiq_debugfs_init();
vchiq_log_info(vchiq_arm_log_level,
@@ -3658,18 +3562,13 @@ static int vchiq_probe(struct platform_device *pdev)
VCHIQ_VERSION, VCHIQ_VERSION_MIN,
MAJOR(vchiq_devid), MINOR(vchiq_devid));
- bcm2835_camera = platform_device_register_data(&pdev->dev,
- "bcm2835-camera", -1,
- NULL, 0);
+ bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera");
+ bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio");
return 0;
failed_device_create:
- class_destroy(vchiq_class);
-failed_class_create:
cdev_del(&vchiq_cdev);
-failed_cdev_add:
- unregister_chrdev_region(vchiq_devid, 1);
failed_platform_init:
vchiq_log_warning(vchiq_arm_log_level, "could not load vchiq");
return err;
@@ -3680,9 +3579,7 @@ static int vchiq_remove(struct platform_device *pdev)
platform_device_unregister(bcm2835_camera);
vchiq_debugfs_deinit();
device_destroy(vchiq_class, vchiq_devid);
- class_destroy(vchiq_class);
cdev_del(&vchiq_cdev);
- unregister_chrdev_region(vchiq_devid, 1);
return 0;
}
@@ -3695,7 +3592,48 @@ static struct platform_driver vchiq_driver = {
.probe = vchiq_probe,
.remove = vchiq_remove,
};
-module_platform_driver(vchiq_driver);
+
+static int __init vchiq_driver_init(void)
+{
+ int ret;
+
+ vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
+ if (IS_ERR(vchiq_class)) {
+ pr_err("Failed to create vchiq class\n");
+ return PTR_ERR(vchiq_class);
+ }
+
+ ret = alloc_chrdev_region(&vchiq_devid, 0, 1, DEVICE_NAME);
+ if (ret) {
+ pr_err("Failed to allocate vchiq's chrdev region\n");
+ goto class_destroy;
+ }
+
+ ret = platform_driver_register(&vchiq_driver);
+ if (ret) {
+ pr_err("Failed to register vchiq driver\n");
+ goto region_unregister;
+ }
+
+ return 0;
+
+region_unregister:
+ platform_driver_unregister(&vchiq_driver);
+
+class_destroy:
+ class_destroy(vchiq_class);
+
+ return ret;
+}
+module_init(vchiq_driver_init);
+
+static void __exit vchiq_driver_exit(void)
+{
+ platform_driver_unregister(&vchiq_driver);
+ unregister_chrdev_region(vchiq_devid, 1);
+ class_destroy(vchiq_class);
+}
+module_exit(vchiq_driver_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Videocore VCHIQ driver");