diff options
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.c | 227 |
1 files changed, 119 insertions, 108 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 aa2313f3bc..9fb8f657cc 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -12,6 +12,7 @@ #include <linux/cdev.h> #include <linux/fs.h> #include <linux/device.h> +#include <linux/device/bus.h> #include <linux/mm.h> #include <linux/highmem.h> #include <linux/pagemap.h> @@ -33,6 +34,7 @@ #include "vchiq_core.h" #include "vchiq_ioctl.h" #include "vchiq_arm.h" +#include "vchiq_bus.h" #include "vchiq_debugfs.h" #include "vchiq_connected.h" #include "vchiq_pagelist.h" @@ -58,15 +60,16 @@ #define KEEPALIVE_VER 1 #define KEEPALIVE_VER_MIN KEEPALIVE_VER -/* Run time control of log level, based on KERN_XXX level. */ -int vchiq_arm_log_level = VCHIQ_LOG_DEFAULT; -int vchiq_susp_log_level = VCHIQ_LOG_ERROR; - DEFINE_SPINLOCK(msg_queue_spinlock); struct vchiq_state g_state; -static struct platform_device *bcm2835_camera; -static struct platform_device *bcm2835_audio; +/* + * The devices implemented in the VCHIQ firmware are not discoverable, + * so we need to maintain a list of them in order to register them with + * the interface. + */ +static struct vchiq_device *bcm2835_audio; +static struct vchiq_device *bcm2835_camera; struct vchiq_drvdata { const unsigned int cache_line_size; @@ -252,7 +255,8 @@ create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr, GFP_KERNEL); - vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist); + vchiq_log_trace(instance->state->dev, VCHIQ_ARM, + "%s - %pK", __func__, pagelist); if (!pagelist) return NULL; @@ -307,9 +311,9 @@ create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, type == PAGELIST_READ, pages); if (actual_pages != num_pages) { - vchiq_log_info(vchiq_arm_log_level, - "%s - only %d/%d pages locked", - __func__, actual_pages, num_pages); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "%s - only %d/%d pages locked", + __func__, actual_pages, num_pages); /* This is probably due to the process being killed */ if (actual_pages > 0) @@ -403,8 +407,8 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel struct page **pages = pagelistinfo->pages; unsigned int num_pages = pagelistinfo->num_pages; - vchiq_log_trace(vchiq_arm_log_level, "%s - %pK, %d", - __func__, pagelistinfo->pagelist, actual); + vchiq_log_trace(instance->state->dev, VCHIQ_ARM, + "%s - %pK, %d", __func__, pagelistinfo->pagelist, actual); /* * NOTE: dma_unmap_sg must be called before the @@ -499,7 +503,7 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0); - vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); + vchiq_slot_zero = vchiq_init_slots(dev, slot_mem, slot_mem_size); if (!vchiq_slot_zero) return -ENOMEM; @@ -552,8 +556,8 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state return -ENXIO; } - vchiq_log_info(vchiq_arm_log_level, "vchiq_init - done (slots %pK, phys %pad)", - vchiq_slot_zero, &slot_phys); + vchiq_log_debug(&pdev->dev, VCHIQ_ARM, "vchiq_init - done (slots %pK, phys %pad)", + vchiq_slot_zero, &slot_phys); vchiq_call_connected_callbacks(); @@ -683,17 +687,18 @@ int vchiq_initialise(struct vchiq_instance **instance_out) usleep_range(500, 600); } if (i == VCHIQ_INIT_RETRIES) { - vchiq_log_error(vchiq_core_log_level, "%s: videocore not initialized\n", __func__); + vchiq_log_error(state->dev, VCHIQ_CORE, "%s: videocore not initialized\n", + __func__); ret = -ENOTCONN; goto failed; } else if (i > 0) { - vchiq_log_warning(vchiq_core_log_level, + vchiq_log_warning(state->dev, VCHIQ_CORE, "%s: videocore initialized after %d retries\n", __func__, i); } instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "%s: error allocating vchiq instance\n", __func__); ret = -ENOMEM; goto failed; @@ -709,7 +714,8 @@ int vchiq_initialise(struct vchiq_instance **instance_out) ret = 0; failed: - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, ret); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, ret); return ret; } @@ -722,8 +728,9 @@ void free_bulk_waiter(struct vchiq_instance *instance) 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); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "bulk_waiter - cleaned up %pK for pid %d", + waiter, waiter->pid); kfree(waiter); } } @@ -741,7 +748,8 @@ int vchiq_shutdown(struct vchiq_instance *instance) mutex_unlock(&state->mutex); - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); free_bulk_waiter(instance); kfree(instance); @@ -761,7 +769,8 @@ int vchiq_connect(struct vchiq_instance *instance) struct vchiq_state *state = instance->state; if (mutex_lock_killable(&state->mutex)) { - vchiq_log_trace(vchiq_core_log_level, "%s: call to mutex_lock failed", __func__); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s: call to mutex_lock failed", __func__); status = -EAGAIN; goto failed; } @@ -773,7 +782,8 @@ int vchiq_connect(struct vchiq_instance *instance) mutex_unlock(&state->mutex); failed: - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); return status; } @@ -804,7 +814,8 @@ vchiq_add_service(struct vchiq_instance *instance, status = -EINVAL; } - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); return status; } @@ -835,7 +846,8 @@ vchiq_open_service(struct vchiq_instance *instance, } failed: - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); return status; } @@ -959,7 +971,8 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl } else { waiter = kzalloc(sizeof(*waiter), GFP_KERNEL); if (!waiter) { - vchiq_log_error(vchiq_core_log_level, "%s - out of memory", __func__); + vchiq_log_error(service->state->dev, VCHIQ_CORE, + "%s - out of memory", __func__); return -ENOMEM; } } @@ -982,8 +995,9 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl mutex_lock(&instance->bulk_waiter_list_mutex); list_add(&waiter->list, &instance->bulk_waiter_list); mutex_unlock(&instance->bulk_waiter_list_mutex); - vchiq_log_info(vchiq_arm_log_level, "saved bulk_waiter %pK for pid %d", waiter, - current->pid); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "saved bulk_waiter %pK for pid %d", waiter, + current->pid); } return status; @@ -1003,13 +1017,16 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) { /* Out of space - wait for the client */ DEBUG_TRACE(SERVICE_CALLBACK_LINE); - vchiq_log_trace(vchiq_arm_log_level, "%s - completion queue full", __func__); + vchiq_log_trace(instance->state->dev, VCHIQ_CORE, + "%s - completion queue full", __func__); DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); if (wait_for_completion_interruptible(&instance->remove_event)) { - vchiq_log_info(vchiq_arm_log_level, "service_callback interrupted"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "service_callback interrupted"); return -EAGAIN; } else if (instance->closing) { - vchiq_log_info(vchiq_arm_log_level, "service_callback closing"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "service_callback closing"); return 0; } DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -1089,7 +1106,7 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, vchiq_service_get(service); rcu_read_unlock(); - vchiq_log_trace(vchiq_arm_log_level, + vchiq_log_trace(service->state->dev, VCHIQ_ARM, "%s - service %lx(%d,%p), reason %d, header %lx, instance %lx, bulk_userdata %lx", __func__, (unsigned long)user_service, service->localport, user_service->userdata, reason, (unsigned long)header, @@ -1102,7 +1119,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, spin_unlock(&msg_queue_spinlock); DEBUG_TRACE(SERVICE_CALLBACK_LINE); DEBUG_COUNT(MSG_QUEUE_FULL_COUNT); - vchiq_log_trace(vchiq_arm_log_level, "%s - msg queue full", __func__); + vchiq_log_trace(service->state->dev, VCHIQ_ARM, + "%s - msg queue full", __func__); /* * If there is no MESSAGE_AVAILABLE in the completion * queue, add one @@ -1111,8 +1129,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, instance->completion_remove) < 0) { int status; - vchiq_log_info(vchiq_arm_log_level, - "Inserting extra MESSAGE_AVAILABLE"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "Inserting extra MESSAGE_AVAILABLE"); DEBUG_TRACE(SERVICE_CALLBACK_LINE); status = add_completion(instance, reason, NULL, user_service, bulk_userdata); @@ -1125,12 +1143,14 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, DEBUG_TRACE(SERVICE_CALLBACK_LINE); if (wait_for_completion_interruptible(&user_service->remove_event)) { - vchiq_log_info(vchiq_arm_log_level, "%s interrupted", __func__); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "%s interrupted", __func__); DEBUG_TRACE(SERVICE_CALLBACK_LINE); vchiq_service_put(service); return -EAGAIN; } else if (instance->closing) { - vchiq_log_info(vchiq_arm_log_level, "%s closing", __func__); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "%s closing", __func__); DEBUG_TRACE(SERVICE_CALLBACK_LINE); vchiq_service_put(service); return -EINVAL; @@ -1326,7 +1346,8 @@ vchiq_keepalive_vchiq_callback(struct vchiq_instance *instance, struct vchiq_header *header, unsigned int service_user, void *bulk_user) { - vchiq_log_error(vchiq_susp_log_level, "%s callback reason %d", __func__, reason); + vchiq_log_error(instance->state->dev, VCHIQ_SUSPEND, + "%s callback reason %d", __func__, reason); return 0; } @@ -1350,22 +1371,22 @@ vchiq_keepalive_thread_func(void *v) ret = vchiq_initialise(&instance); if (ret) { - vchiq_log_error(vchiq_susp_log_level, "%s vchiq_initialise failed %d", __func__, - ret); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s vchiq_initialise failed %d", __func__, ret); goto exit; } status = vchiq_connect(instance); if (status) { - vchiq_log_error(vchiq_susp_log_level, "%s vchiq_connect failed %d", __func__, - status); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s vchiq_connect failed %d", __func__, status); goto shutdown; } status = vchiq_add_service(instance, ¶ms, &ka_handle); if (status) { - vchiq_log_error(vchiq_susp_log_level, "%s vchiq_open_service failed %d", __func__, - status); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s vchiq_open_service failed %d", __func__, status); goto shutdown; } @@ -1373,7 +1394,8 @@ vchiq_keepalive_thread_func(void *v) long rc = 0, uc = 0; if (wait_for_completion_interruptible(&arm_state->ka_evt)) { - vchiq_log_error(vchiq_susp_log_level, "%s interrupted", __func__); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s interrupted", __func__); flush_signals(current); continue; } @@ -1393,14 +1415,14 @@ vchiq_keepalive_thread_func(void *v) atomic_inc(&arm_state->ka_use_ack_count); status = vchiq_use_service(instance, ka_handle); if (status) { - vchiq_log_error(vchiq_susp_log_level, + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "%s vchiq_use_service error %d", __func__, status); } } while (rc--) { status = vchiq_release_service(instance, ka_handle); if (status) { - vchiq_log_error(vchiq_susp_log_level, + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "%s vchiq_release_service error %d", __func__, status); } @@ -1419,7 +1441,7 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, { struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); int ret = 0; - char entity[16]; + char entity[64]; int *entity_uc; int local_uc; @@ -1429,15 +1451,15 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, } if (use_type == USE_TYPE_VCHIQ) { - sprintf(entity, "VCHIQ: "); + snprintf(entity, sizeof(entity), "VCHIQ: "); entity_uc = &arm_state->peer_use_count; } else if (service) { - sprintf(entity, "%c%c%c%c:%03d", - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->client_id); + snprintf(entity, sizeof(entity), "%p4cc:%03d", + &service->base.fourcc, + service->client_id); entity_uc = &service->service_use_count; } else { - vchiq_log_error(vchiq_susp_log_level, "%s null service ptr", __func__); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "%s null service ptr", __func__); ret = -EINVAL; goto out; } @@ -1446,8 +1468,8 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, local_uc = ++arm_state->videocore_use_count; ++(*entity_uc); - vchiq_log_trace(vchiq_susp_log_level, "%s %s count %d, state count %d", __func__, entity, - *entity_uc, local_uc); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s %s count %d, state count %d", + __func__, entity, *entity_uc, local_uc); write_unlock_bh(&arm_state->susp_res_lock); @@ -1466,7 +1488,7 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, } out: - vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s exit %d", __func__, ret); return ret; } @@ -1475,7 +1497,7 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) { struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); int ret = 0; - char entity[16]; + char entity[64]; int *entity_uc; if (!arm_state) { @@ -1484,12 +1506,12 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) } if (service) { - sprintf(entity, "%c%c%c%c:%03d", - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->client_id); + snprintf(entity, sizeof(entity), "%p4cc:%03d", + &service->base.fourcc, + service->client_id); entity_uc = &service->service_use_count; } else { - sprintf(entity, "PEER: "); + snprintf(entity, sizeof(entity), "PEER: "); entity_uc = &arm_state->peer_use_count; } @@ -1504,14 +1526,14 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) --arm_state->videocore_use_count; --(*entity_uc); - vchiq_log_trace(vchiq_susp_log_level, "%s %s count %d, state count %d", __func__, entity, - *entity_uc, arm_state->videocore_use_count); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s %s count %d, state count %d", + __func__, entity, *entity_uc, arm_state->videocore_use_count); unlock: write_unlock_bh(&arm_state->susp_res_lock); out: - vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s exit %d", __func__, ret); return ret; } @@ -1685,17 +1707,19 @@ vchiq_dump_service_use_state(struct vchiq_state *state) read_unlock_bh(&arm_state->susp_res_lock); if (only_nonzero) - vchiq_log_warning(vchiq_susp_log_level, "Too many active services (%d). Only dumping up to first %d services with non-zero use-count", + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, + "Too many active services (%d). Only dumping up to first %d services with non-zero use-count", active_services, found); for (i = 0; i < found; i++) { - vchiq_log_warning(vchiq_susp_log_level, "----- %c%c%c%c:%d service count %d %s", - VCHIQ_FOURCC_AS_4CHARS(service_data[i].fourcc), + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, + "%p4cc:%d service count %d %s", + &service_data[i].fourcc, service_data[i].clientid, service_data[i].use_count, service_data[i].use_count ? nz : ""); } - vchiq_log_warning(vchiq_susp_log_level, "----- VCHIQ use count %d", peer_count); - vchiq_log_warning(vchiq_susp_log_level, "--- Overall vchiq instance use count %d", + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, "VCHIQ use count %d", peer_count); + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, "Overall vchiq instance use count %d", vc_use_count); kfree(service_data); @@ -1718,9 +1742,9 @@ vchiq_check_service(struct vchiq_service *service) read_unlock_bh(&arm_state->susp_res_lock); if (ret) { - vchiq_log_error(vchiq_susp_log_level, - "%s ERROR - %c%c%c%c:%d service count %d, state count %d", __func__, - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id, + vchiq_log_error(service->state->dev, VCHIQ_SUSPEND, + "%s ERROR - %p4cc:%d service count %d, state count %d", __func__, + &service->base.fourcc, service->client_id, service->service_use_count, arm_state->videocore_use_count); vchiq_dump_service_use_state(service->state); } @@ -1735,8 +1759,8 @@ void vchiq_platform_conn_state_changed(struct vchiq_state *state, struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); char threadname[16]; - vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id, - get_conn_state_name(oldstate), get_conn_state_name(newstate)); + vchiq_log_debug(state->dev, VCHIQ_SUSPEND, "%d: %s->%s", state->id, + get_conn_state_name(oldstate), get_conn_state_name(newstate)); if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED) return; @@ -1754,7 +1778,7 @@ void vchiq_platform_conn_state_changed(struct vchiq_state *state, (void *)state, threadname); if (IS_ERR(arm_state->ka_thread)) { - vchiq_log_error(vchiq_susp_log_level, + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "vchiq: FATAL: couldn't create thread %s", threadname); } else { @@ -1769,28 +1793,6 @@ 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; @@ -1823,9 +1825,9 @@ static int vchiq_probe(struct platform_device *pdev) vchiq_debugfs_init(); - vchiq_log_info(vchiq_arm_log_level, - "vchiq: platform initialised - version %d (min %d)", - VCHIQ_VERSION, VCHIQ_VERSION_MIN); + vchiq_log_debug(&pdev->dev, VCHIQ_ARM, + "vchiq: platform initialised - version %d (min %d)", + VCHIQ_VERSION, VCHIQ_VERSION_MIN); /* * Simply exit on error since the function handles cleanup in @@ -1833,26 +1835,26 @@ static int vchiq_probe(struct platform_device *pdev) */ err = vchiq_register_chrdev(&pdev->dev); if (err) { - vchiq_log_warning(vchiq_arm_log_level, + vchiq_log_warning(&pdev->dev, VCHIQ_ARM, "Failed to initialize vchiq cdev"); goto error_exit; } - bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); - bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); + bcm2835_audio = vchiq_device_register(&pdev->dev, "bcm2835-audio"); + bcm2835_camera = vchiq_device_register(&pdev->dev, "bcm2835-camera"); return 0; failed_platform_init: - vchiq_log_warning(vchiq_arm_log_level, "could not initialize vchiq platform"); + vchiq_log_warning(&pdev->dev, VCHIQ_ARM, "could not initialize vchiq platform"); error_exit: return err; } static void vchiq_remove(struct platform_device *pdev) { - platform_device_unregister(bcm2835_audio); - platform_device_unregister(bcm2835_camera); + vchiq_device_unregister(bcm2835_audio); + vchiq_device_unregister(bcm2835_camera); vchiq_debugfs_deinit(); vchiq_deregister_chrdev(); } @@ -1870,9 +1872,17 @@ static int __init vchiq_driver_init(void) { int ret; + ret = bus_register(&vchiq_bus_type); + if (ret) { + pr_err("Failed to register %s\n", vchiq_bus_type.name); + return ret; + } + ret = platform_driver_register(&vchiq_driver); - if (ret) + if (ret) { pr_err("Failed to register vchiq driver\n"); + bus_unregister(&vchiq_bus_type); + } return ret; } @@ -1880,6 +1890,7 @@ module_init(vchiq_driver_init); static void __exit vchiq_driver_exit(void) { + bus_unregister(&vchiq_bus_type); platform_driver_unregister(&vchiq_driver); } module_exit(vchiq_driver_exit); |