-
-
Save anonymous/23f97f6c8bd919c21d944b8b191faf19 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms | |
index a8f17ab..1cf87e3 100644 | |
--- a/arch/arm64/Kconfig.platforms | |
+++ b/arch/arm64/Kconfig.platforms | |
@@ -35,6 +35,9 @@ config ARCH_BCM2710 | |
select BCM2835_WDT | |
select RASPBERRYPI_POWER | |
select BRCM_CHAR_DRIVERS | |
+ select BCM_VC_CMA | |
+ select BCM_VCIO | |
+ select BCM_VC_SM | |
select HW_RANDOM | |
select THERMAL | |
select CPU_FREQ | |
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c | |
index 3b6d8cc..051b130 100644 | |
--- a/arch/arm64/kernel/arm64ksyms.c | |
+++ b/arch/arm64/kernel/arm64ksyms.c | |
@@ -65,6 +65,15 @@ EXPORT_SYMBOL(test_and_clear_bit); | |
EXPORT_SYMBOL(change_bit); | |
EXPORT_SYMBOL(test_and_change_bit); | |
+extern void __dma_map_area(const void *, size_t, int); | |
+extern void __dma_unmap_area(const void *, size_t, int); | |
+extern void __dma_flush_range(const void *, const void *); | |
+extern void __inval_cache_range(const void *, const void *); | |
+EXPORT_SYMBOL(__dma_flush_range); | |
+EXPORT_SYMBOL(__dma_map_area); | |
+EXPORT_SYMBOL(__dma_unmap_area); | |
+EXPORT_SYMBOL(__inval_cache_range); | |
+ | |
#ifdef CONFIG_FUNCTION_TRACER | |
EXPORT_SYMBOL(_mcount); | |
#endif | |
diff --git a/drivers/char/broadcom/vc_cma/vc_cma.c b/drivers/char/broadcom/vc_cma/vc_cma.c | |
index 85f6e9d..7636e12 100644 | |
--- a/drivers/char/broadcom/vc_cma/vc_cma.c | |
+++ b/drivers/char/broadcom/vc_cma/vc_cma.c | |
@@ -79,6 +79,11 @@ | |
#define loud_error(...) \ | |
LOG_ERR("===== " __VA_ARGS__) | |
+#ifdef CONFIG_ARM64 | |
+#define dmac_flush_range __dma_flush_range | |
+static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) {} | |
+#endif | |
+ | |
enum { | |
VC_CMA_MSG_QUIT, | |
VC_CMA_MSG_OPEN, | |
@@ -344,7 +349,7 @@ static int vc_cma_proc_open(struct inode *inode, struct file *file) | |
* | |
***************************************************************************/ | |
-static int vc_cma_proc_write(struct file *file, | |
+static ssize_t vc_cma_proc_write(struct file *file, | |
const char __user *buffer, | |
size_t size, loff_t *ppos) | |
{ | |
@@ -645,17 +650,17 @@ static int cma_worker_proc(void *param) | |
VCHIQ_HEADER_T *msg; | |
static struct cma_msg msg_copy; | |
struct cma_msg *cma_msg = &msg_copy; | |
- int type, msg_size; | |
+ uintptr_t type, msg_size; | |
msg = vchiu_queue_pop(&cma_msg_queue); | |
- if ((unsigned int)msg >= VC_CMA_MSG_MAX) { | |
+ if ((uintptr_t)msg >= VC_CMA_MSG_MAX) { | |
msg_size = msg->size; | |
memcpy(&msg_copy, msg->data, msg_size); | |
type = cma_msg->type; | |
vchiq_release_message(cma_service, msg); | |
} else { | |
msg_size = 0; | |
- type = (int)msg; | |
+ type = (uintptr_t)msg; | |
if (type == VC_CMA_MSG_QUIT) | |
break; | |
else if (type == VC_CMA_MSG_UPDATE_RESERVE) { | |
@@ -677,9 +682,9 @@ static int cma_worker_proc(void *param) | |
if (num_chunks > VC_CMA_MAX_PARAMS_PER_MSG) { | |
LOG_ERR | |
("CMA_MSG_ALLOC - chunk count (%d) " | |
- "exceeds VC_CMA_MAX_PARAMS_PER_MSG (%d)", | |
+ "exceeds VC_CMA_MAX_PARAMS_PER_MSG (%lu)", | |
num_chunks, | |
- VC_CMA_MAX_PARAMS_PER_MSG); | |
+ (unsigned long)VC_CMA_MAX_PARAMS_PER_MSG); | |
num_chunks = VC_CMA_MAX_PARAMS_PER_MSG; | |
} | |
@@ -727,9 +732,8 @@ static int cma_worker_proc(void *param) | |
LOG_ERR | |
("CMA_MSG_FREE - failed to " | |
"release chunk %d (phys %pa, " | |
- "page %x)", chunk_num, | |
- &_pa, | |
- (unsigned int)page); | |
+ "page %p)", chunk_num, | |
+ &_pa, page); | |
} | |
vc_cma_chunks_used--; | |
} | |
@@ -771,7 +775,7 @@ static int cma_worker_proc(void *param) | |
break; | |
default: | |
- LOG_ERR("unexpected msg type %d", type); | |
+ LOG_ERR("unexpected msg type %lu", type); | |
break; | |
} | |
} | |
diff --git a/drivers/char/broadcom/vc_sm/vc_vchi_sm.c b/drivers/char/broadcom/vc_sm/vc_vchi_sm.c | |
index 7c6ba1a..ae2b9e4 100644 | |
--- a/drivers/char/broadcom/vc_sm/vc_vchi_sm.c | |
+++ b/drivers/char/broadcom/vc_sm/vc_vchi_sm.c | |
@@ -318,7 +318,7 @@ VC_VCHI_SM_HANDLE_T vc_vchi_sm_init(VCHI_INSTANCE_T vchi_instance, | |
set_user_nice(instance->io_thread, -10); | |
wake_up_process(instance->io_thread); | |
- pr_debug("%s: success - instance 0x%x", __func__, (unsigned)instance); | |
+ pr_debug("%s: success - instance %p", __func__, instance); | |
return instance; | |
err_close_services: | |
diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c | |
index 1db6716..2263b38 100644 | |
--- a/drivers/char/broadcom/vc_sm/vmcs_sm.c | |
+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c | |
@@ -42,6 +42,11 @@ | |
#include <linux/broadcom/vmcs_sm_ioctl.h> | |
#include "vc_sm_knl.h" | |
+#ifdef CONFIG_ARM64 | |
+extern void __dma_flush_range(const void *, const void *); | |
+#define dmac_flush_range __dma_flush_range | |
+#endif | |
+ | |
/* ---- Private Constants and Types --------------------------------------- */ | |
#define DEVICE_NAME "vcsm" | |
@@ -210,6 +215,18 @@ static const char *const sm_cache_map_vector[] = { | |
/* ---- Private Functions ------------------------------------------------ */ | |
+/* FIXME: It seems that L2 cache handling (CONFIG_OUTER_CACHE) is disabled for | |
+ * both bcm2709_defconfig and bcmrpi_defconfig, thus outer_* are nops. arm64 | |
+ * doesn't support outer caches but we can still provide outer functions as | |
+ * nops, no behaviour change is expected between the arm and the arm64 variants | |
+ */ | |
+#ifdef CONFIG_ARM64 | |
+static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) | |
+{ } | |
+static inline void outer_clean_range(phys_addr_t start, phys_addr_t end) | |
+{ } | |
+#endif | |
+ | |
static inline unsigned vcaddr_to_pfn(unsigned long vc_addr) | |
{ | |
unsigned long pfn = vc_addr & 0x3FFFFFFF; | |
@@ -500,8 +517,8 @@ static int vc_sm_global_state_show(struct seq_file *s, void *v) | |
if (sm_state == NULL) | |
return 0; | |
- seq_printf(s, "\nVC-ServiceHandle 0x%x\n", | |
- (unsigned int)sm_state->sm_handle); | |
+ seq_printf(s, "\nVC-ServiceHandle 0x%p\n", | |
+ sm_state->sm_handle); | |
/* Log all applicable mapping(s). | |
*/ | |
@@ -512,8 +529,8 @@ static int vc_sm_global_state_show(struct seq_file *s, void *v) | |
list_for_each_entry(map, &sm_state->map_list, map_list) { | |
map_count++; | |
- seq_printf(s, "\nMapping 0x%x\n", | |
- (unsigned int)map); | |
+ seq_printf(s, "\nMapping 0x%p\n", | |
+ map); | |
seq_printf(s, " TGID %u\n", | |
map->res_pid); | |
seq_printf(s, " VC-HDL 0x%x\n", | |
@@ -1170,7 +1187,7 @@ static int vcsm_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |
/* We don't use vmf->pgoff since that has the fake offset */ | |
page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start); | |
- pfn = (uint32_t)resource->res_base_mem & 0x3FFFFFFF; | |
+ pfn = (uintptr_t)resource->res_base_mem & 0x3FFFFFFF; | |
pfn += mm_vc_mem_phys_addr; | |
pfn += page_offset; | |
pfn >>= PAGE_SHIFT; | |
@@ -1732,7 +1749,7 @@ static int vc_sm_ioctl_lock(struct SM_PRIV_DATA_T *private, | |
/* Lock assumed taken already, address to be mapped is known. | |
*/ | |
else | |
- resource->res_base_mem = (void *)vc_addr; | |
+ resource->res_base_mem = (void *)(uintptr_t)vc_addr; | |
resource->res_stats[LOCK]++; | |
resource->lock_count++; | |
@@ -1793,7 +1810,7 @@ static int vc_sm_ioctl_lock(struct SM_PRIV_DATA_T *private, | |
ret = -ENOMEM; | |
goto error; | |
} else { | |
- phys_addr = (uint32_t)resource->res_base_mem & | |
+ phys_addr = (uintptr_t)resource->res_base_mem & | |
0x3FFFFFFF; | |
phys_addr += mm_vc_mem_phys_addr; | |
if (resource->res_cached | |
@@ -1882,7 +1899,7 @@ static int vc_sm_ioctl_unlock(struct SM_PRIV_DATA_T *private, | |
resource->res_stats[FLUSH]++; | |
phys_addr = | |
- (dma_addr_t)((uint32_t)resource->res_base_mem & | |
+ (dma_addr_t)((uintptr_t)resource->res_base_mem & | |
0x3FFFFFFF); | |
phys_addr += (dma_addr_t)mm_vc_mem_phys_addr; | |
@@ -1937,7 +1954,7 @@ static int vc_sm_ioctl_unlock(struct SM_PRIV_DATA_T *private, | |
VMCS_SM_CACHE_HOST)) { | |
long unsigned int | |
phys_addr; | |
- phys_addr = (uint32_t) | |
+ phys_addr = (uintptr_t) | |
resource->res_base_mem & 0x3FFFFFFF; | |
phys_addr += | |
mm_vc_mem_phys_addr; | |
@@ -2568,7 +2585,7 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
vmcs_sm_acquire_resource(file_data, ioparam.handle); | |
if (resource != NULL) { | |
ioparam.addr = | |
- (unsigned int)resource->res_base_mem; | |
+ (uintptr_t)resource->res_base_mem; | |
vmcs_sm_release_resource(resource, 0); | |
} else { | |
ioparam.addr = 0; | |
@@ -2645,7 +2662,7 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
resource->res_stats[FLUSH]++; | |
phys_addr = | |
- (dma_addr_t)((uint32_t) | |
+ (dma_addr_t)((uintptr_t) | |
resource->res_base_mem & | |
0x3FFFFFFF); | |
phys_addr += (dma_addr_t)mm_vc_mem_phys_addr; | |
@@ -2701,7 +2718,7 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
resource->res_stats[INVALID]++; | |
phys_addr = | |
- (dma_addr_t)((uint32_t) | |
+ (dma_addr_t)((uintptr_t) | |
resource->res_base_mem & | |
0x3FFFFFFF); | |
phys_addr += (dma_addr_t)mm_vc_mem_phys_addr; | |
diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig | |
index dc07f99..db8e1be 100644 | |
--- a/drivers/misc/vc04_services/Kconfig | |
+++ b/drivers/misc/vc04_services/Kconfig | |
@@ -1,7 +1,7 @@ | |
config BCM2708_VCHIQ | |
tristate "Videocore VCHIQ" | |
depends on RASPBERRYPI_FIRMWARE | |
- default n | |
+ default y | |
help | |
Kernel to VideoCore communication interface for the | |
BCM2708 family of products. | |
diff --git a/drivers/misc/vc04_services/Makefile b/drivers/misc/vc04_services/Makefile | |
index 8d038fe..0efb528 100644 | |
--- a/drivers/misc/vc04_services/Makefile | |
+++ b/drivers/misc/vc04_services/Makefile | |
@@ -10,5 +10,9 @@ vchiq-objs := \ | |
interface/vchiq_arm/vchiq_util.o \ | |
interface/vchiq_arm/vchiq_connected.o \ | |
+ifeq ($(CONFIG_COMPAT),y) | |
+ vchiq-objs += interface/vchiq_arm/vchiq_io32.o | |
+endif | |
+ | |
ccflags-y += -DVCOS_VERIFY_BKPTS=1 -Idrivers/misc/vc04_services -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | |
index c29040f..98308a3 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | |
@@ -45,11 +45,20 @@ | |
#include <asm/pgtable.h> | |
#include <soc/bcm2835/raspberrypi-firmware.h> | |
+#ifdef CONFIG_ARM64 | |
+#define dmac_map_area __dma_map_area | |
+#define dmac_unmap_area __dma_unmap_area | |
+#define dmac_flush_range __dma_flush_range | |
+#else | |
#define dmac_map_area __glue(_CACHE,_dma_map_area) | |
#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area) | |
+#endif | |
extern void dmac_map_area(const void *, size_t, int); | |
extern void dmac_unmap_area(const void *, size_t, int); | |
+#ifdef CONFIG_ARM64 | |
+extern void __dma_flush_range(const void *, const void *); | |
+#endif | |
#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) | |
@@ -104,7 +113,11 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) | |
int slot_mem_size, frag_mem_size; | |
int err, irq, i; | |
+#ifdef CONFIG_ARM64 | |
+ g_virt_to_bus_offset = phys_to_dma(dev, 0); | |
+#else | |
g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); | |
+#endif | |
(void)of_property_read_u32(dev->of_node, "cache-line-size", | |
&g_cache_line_size); | |
@@ -169,7 +182,7 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) | |
err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, | |
&channelbase, sizeof(channelbase)); | |
if (err || channelbase) { | |
- dev_err(dev, "failed to set channelbase\n"); | |
+ dev_err(dev, "failed to set channelbase, err: %d, channelbase: %u", err, channelbase); | |
return err ? : -ENXIO; | |
} | |
@@ -213,7 +226,7 @@ remote_event_signal(REMOTE_EVENT_T *event) | |
event->fired = 1; | |
- dsb(); /* data barrier operation */ | |
+ mb(); /* data barrier operation */ | |
if (event->armed) | |
writel(0, g_regs + BELL2); /* trigger vc interrupt */ | |
@@ -222,7 +235,7 @@ remote_event_signal(REMOTE_EVENT_T *event) | |
int | |
vchiq_copy_from_user(void *dst, const void *src, int size) | |
{ | |
- if ((uint32_t)src < TASK_SIZE) { | |
+ if ((uintptr_t)src < TASK_SIZE) { | |
return copy_from_user(dst, src, size); | |
} else { | |
memcpy(dst, src, size); | |
@@ -369,13 +382,13 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, | |
{ | |
PAGELIST_T *pagelist; | |
struct page **pages; | |
- unsigned long *addrs; | |
+ u32 *addrs; | |
unsigned int num_pages, offset, i; | |
char *addr, *base_addr, *next_addr; | |
int run, addridx, actual_pages; | |
- unsigned long *need_release; | |
+ u32 *need_release; | |
- offset = (unsigned int)buf & (PAGE_SIZE - 1); | |
+ offset = (uintptr_t)buf & (PAGE_SIZE - 1); | |
num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE; | |
*ppagelist = NULL; | |
@@ -384,18 +397,18 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, | |
** list | |
*/ | |
pagelist = kmalloc(sizeof(PAGELIST_T) + | |
- (num_pages * sizeof(unsigned long)) + | |
- sizeof(unsigned long) + | |
+ (num_pages * sizeof(u32)) + | |
+ sizeof(u32) + | |
(num_pages * sizeof(pages[0])), | |
GFP_KERNEL); | |
vchiq_log_trace(vchiq_arm_log_level, | |
- "create_pagelist - %x", (unsigned int)pagelist); | |
+ "create_pagelist - %p", pagelist); | |
if (!pagelist) | |
return -ENOMEM; | |
addrs = pagelist->addrs; | |
- need_release = (unsigned long *)(addrs + num_pages); | |
+ need_release = (u32 *)(addrs + num_pages); | |
pages = (struct page **)(addrs + num_pages + 1); | |
if (is_vmalloc_addr(buf)) { | |
@@ -466,7 +479,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, | |
next_addr += PAGE_SIZE; | |
run++; | |
} else { | |
- addrs[addridx] = (unsigned long)base_addr + run; | |
+ addrs[addridx] = (u32)(uintptr_t)base_addr + run; | |
addridx++; | |
base_addr = addr; | |
next_addr = addr + PAGE_SIZE; | |
@@ -474,7 +487,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, | |
} | |
} | |
- addrs[addridx] = (unsigned long)base_addr + run; | |
+ addrs[addridx] = (u32)(uintptr_t)base_addr + run; | |
addridx++; | |
/* Partial cache lines (fragments) require special measures */ | |
@@ -510,18 +523,18 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, | |
static void | |
free_pagelist(PAGELIST_T *pagelist, int actual) | |
{ | |
- unsigned long *need_release; | |
+ u32 *need_release; | |
struct page **pages; | |
unsigned int num_pages, i; | |
vchiq_log_trace(vchiq_arm_log_level, | |
- "free_pagelist - %x, %d", (unsigned int)pagelist, actual); | |
+ "free_pagelist - %p, %d", pagelist, actual); | |
num_pages = | |
(pagelist->length + pagelist->offset + PAGE_SIZE - 1) / | |
PAGE_SIZE; | |
- need_release = (unsigned long *)(pagelist->addrs + num_pages); | |
+ need_release = (u32 *)(pagelist->addrs + num_pages); | |
pages = (struct page **)(pagelist->addrs + num_pages + 1); | |
/* Deal with any partial cache lines (fragments) */ | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | |
index 98e0087..2a8ae3e 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | |
@@ -416,7 +416,7 @@ static void close_delivered(USER_SERVICE_T *user_service) | |
* vchiq_ioctl | |
* | |
***************************************************************************/ | |
-static long | |
+long | |
vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
{ | |
VCHIQ_INSTANCE_T instance = file->private_data; | |
@@ -1578,6 +1578,9 @@ static const struct file_operations | |
vchiq_fops = { | |
.owner = THIS_MODULE, | |
.unlocked_ioctl = vchiq_ioctl, | |
+#ifdef CONFIG_COMPAT | |
+ .compat_ioctl = vchiq_compat_ioctl, | |
+#endif | |
.open = vchiq_open, | |
.release = vchiq_release, | |
.read = vchiq_read | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h | |
index d2797db..0942a6b 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h | |
@@ -54,6 +54,7 @@ | |
#define VCHIQ_MAX_SERVICES 4096 | |
#define VCHIQ_MAX_SLOTS 128 | |
#define VCHIQ_MAX_SLOTS_PER_SIDE 64 | |
+#define VCHIQ_MAX_REMOTE_EVENTS 64 | |
#define VCHIQ_NUM_CURRENT_BULKS 32 | |
#define VCHIQ_NUM_SERVICE_BULKS 4 | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c | |
index 71a3bed..4f864f6 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c | |
@@ -95,6 +95,9 @@ DEFINE_SPINLOCK(quota_spinlock); | |
VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES]; | |
static unsigned int handle_seq; | |
+static struct semaphore *remote_event_semaphores[VCHIQ_MAX_REMOTE_EVENTS]; | |
+static DEFINE_MUTEX(remote_event_sema_lock); | |
+ | |
static const char *const srvstate_names[] = { | |
"FREE", | |
"HIDDEN", | |
@@ -405,18 +408,64 @@ vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate) | |
vchiq_platform_conn_state_changed(state, oldstate, newstate); | |
} | |
+static inline struct semaphore *evhandle_to_sema(REMOTE_EVENT_T *event) | |
+{ | |
+#if defined(CONFIG_ARM) | |
+ return (struct semaphore *)(void *)(uintptr_t)event->ev_handle; | |
+#elif defined(CONFIG_ARM64) | |
+ return remote_event_semaphores[event->ev_handle]; | |
+#else | |
+#error unexpected arch | |
+#endif | |
+} | |
+ | |
static inline void | |
-remote_event_create(REMOTE_EVENT_T *event) | |
+remote_event_create(REMOTE_EVENT_T *event, struct semaphore *sem) | |
{ | |
event->armed = 0; | |
/* Don't clear the 'fired' flag because it may already have been set | |
** by the other side. */ | |
- sema_init(event->event, 0); | |
+ sema_init(sem, 0); | |
+#if defined(CONFIG_ARM) | |
+ /* The "ev_handle" field is large enough to store the semaphore | |
+ ** pointer (pointer size = uint32_t) */ | |
+event->ev_handle = (u32)(uintptr_t)sem; | |
+#elif defined(CONFIG_ARM64) | |
+ /* The "ev_handle" field is not large enough to store the semaphore | |
+ ** pointer (pointer size = uint64_t). We can't also increase the | |
+ ** size of this field because this will break the GPU side, | |
+ ** instead use "ev_handle" as an index */ | |
+ size_t i; | |
+ mutex_lock(&remote_event_sema_lock); | |
+ for (i = 0; i < VCHIQ_MAX_REMOTE_EVENTS; i++) { | |
+ /* Use NULL as list terminator */ | |
+ if (remote_event_semaphores[i] == NULL) { | |
+ remote_event_semaphores[i] = sem; | |
+ event->ev_handle = i; | |
+ mutex_unlock(&remote_event_sema_lock); | |
+ return; | |
+ } | |
+ } | |
+ | |
+ mutex_unlock(&remote_event_sema_lock); | |
+ event->ev_handle = 0; | |
+ pr_err("Remote events overflow"); | |
+#else | |
+#error unexpected arch | |
+#endif | |
} | |
static inline void | |
remote_event_destroy(REMOTE_EVENT_T *event) | |
{ | |
+#ifdef CONFIG_ARM64 | |
+ mutex_lock(&remote_event_sema_lock); | |
+ if (remote_event_semaphores[event->ev_handle] == NULL) { | |
+ pr_warn("Trying to destroy an uninitialized remote event: %p, sema index: %u", event, event->ev_handle); | |
+ } | |
+ remote_event_semaphores[event->ev_handle] = NULL; | |
+ mutex_unlock(&remote_event_sema_lock); | |
+#endif | |
(void)event; | |
} | |
@@ -425,9 +474,9 @@ remote_event_wait(REMOTE_EVENT_T *event) | |
{ | |
if (!event->fired) { | |
event->armed = 1; | |
- dsb(); | |
+ mb(); | |
if (!event->fired) { | |
- if (down_interruptible(event->event) != 0) { | |
+ if (down_interruptible(evhandle_to_sema(event)) != 0) { | |
event->armed = 0; | |
return 0; | |
} | |
@@ -444,7 +493,7 @@ static inline void | |
remote_event_signal_local(REMOTE_EVENT_T *event) | |
{ | |
event->armed = 0; | |
- up(event->event); | |
+ up(evhandle_to_sema(event)); | |
} | |
static inline void | |
@@ -2408,6 +2457,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, | |
} | |
memset(state, 0, sizeof(VCHIQ_STATE_T)); | |
+ memset(remote_event_semaphores, 0, sizeof(remote_event_semaphores)); | |
state->id = id++; | |
state->is_master = is_master; | |
@@ -2462,19 +2512,14 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, | |
state->data_use_count = 0; | |
state->data_quota = state->slot_queue_available - 1; | |
- local->trigger.event = &state->trigger_event; | |
- remote_event_create(&local->trigger); | |
+ remote_event_create(&local->trigger, &state->trigger_event); | |
local->tx_pos = 0; | |
- local->recycle.event = &state->recycle_event; | |
- remote_event_create(&local->recycle); | |
+ remote_event_create(&local->recycle, &state->recycle_event); | |
local->slot_queue_recycle = state->slot_queue_available; | |
- local->sync_trigger.event = &state->sync_trigger_event; | |
- remote_event_create(&local->sync_trigger); | |
- | |
- local->sync_release.event = &state->sync_release_event; | |
- remote_event_create(&local->sync_release); | |
+ remote_event_create(&local->sync_trigger, &state->sync_trigger_event); | |
+ remote_event_create(&local->sync_release, &state->sync_release_event); | |
/* At start-of-day, the slot is empty and available */ | |
((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h | |
index 9be484c..b226d87 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h | |
@@ -43,7 +43,7 @@ | |
#include "vchiq.h" | |
/* Run time control of log level, based on KERN_XXX level. */ | |
-#define VCHIQ_LOG_DEFAULT 4 | |
+#define VCHIQ_LOG_DEFAULT 7 | |
#define VCHIQ_LOG_ERROR 3 | |
#define VCHIQ_LOG_WARNING 4 | |
#define VCHIQ_LOG_INFO 6 | |
@@ -184,11 +184,11 @@ enum { | |
#define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug; | |
#define DEBUG_TRACE(d) \ | |
- do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(); } while (0) | |
+ do { debug_ptr[DEBUG_ ## d] = __LINE__; mb(); } while (0) | |
#define DEBUG_VALUE(d, v) \ | |
- do { debug_ptr[DEBUG_ ## d] = (v); dsb(); } while (0) | |
+ do { debug_ptr[DEBUG_ ## d] = (v); mb(); } while (0) | |
#define DEBUG_COUNT(d) \ | |
- do { debug_ptr[DEBUG_ ## d]++; dsb(); } while (0) | |
+ do { debug_ptr[DEBUG_ ## d]++; mb(); } while (0) | |
#else /* VCHIQ_ENABLE_DEBUG */ | |
@@ -264,7 +264,7 @@ typedef struct vchiq_bulk_queue_struct { | |
typedef struct remote_event_struct { | |
int armed; | |
int fired; | |
- struct semaphore *event; | |
+ u32 ev_handle; | |
} REMOTE_EVENT_T; | |
typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T; | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_io32.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_io32.c | |
index e69de29..e2dec61 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_io32.c | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_io32.c | |
@@ -0,0 +1,354 @@ | |
+#include <linux/compat.h> | |
+#include <linux/fs.h> | |
+#include <asm/uaccess.h> | |
+ | |
+#include "vchiq_ioctl.h" | |
+ | |
+#define VCHIQ_IOC_CREATE_SERVICE32 \ | |
+ _IOWR(VCHIQ_IOC_MAGIC, 2, VCHIQ_CREATE_SERVICE_T32) | |
+#define VCHIQ_IOC_QUEUE_MESSAGE32 \ | |
+ _IOW(VCHIQ_IOC_MAGIC, 4, VCHIQ_QUEUE_MESSAGE_T32) | |
+#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT32 \ | |
+ _IOWR(VCHIQ_IOC_MAGIC, 5, VCHIQ_QUEUE_BULK_TRANSFER_T32) | |
+#define VCHIQ_IOC_QUEUE_BULK_RECEIVE32 \ | |
+ _IOWR(VCHIQ_IOC_MAGIC, 6, VCHIQ_QUEUE_BULK_TRANSFER_T32) | |
+#define VCHIQ_IOC_AWAIT_COMPLETION32 \ | |
+ _IOWR(VCHIQ_IOC_MAGIC, 7, VCHIQ_AWAIT_COMPLETION_T32) | |
+#define VCHIQ_IOC_DEQUEUE_MESSAGE32 \ | |
+ _IOWR(VCHIQ_IOC_MAGIC, 8, VCHIQ_DEQUEUE_MESSAGE_T32) | |
+#define VCHIQ_IOC_DUMP_PHYS_MEM32 \ | |
+ _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T32) | |
+#define VCHIQ_IOC_GET_CONFIG32 \ | |
+ _IOWR(VCHIQ_IOC_MAGIC, 10, VCHIQ_GET_CONFIG_T32) | |
+ | |
+typedef struct { | |
+ s32 fourcc; | |
+ u32 callback; | |
+ u32 userdata; | |
+ short version; /* Increment for non-trivial changes */ | |
+ short version_min; /* Update for incompatible changes */ | |
+} VCHIQ_SERVICE_PARAMS_T32; | |
+ | |
+typedef struct { | |
+ VCHIQ_SERVICE_PARAMS_T32 params; | |
+ s32 is_open; | |
+ s32 is_vchi; | |
+ u32 handle; /* OUT */ | |
+} VCHIQ_CREATE_SERVICE_T32; | |
+ | |
+typedef struct { | |
+ u32 data; | |
+ u32 size; | |
+} VCHIQ_ELEMENT_T32; | |
+ | |
+typedef struct { | |
+ u32 handle; | |
+ u32 count; | |
+ u32 elements; | |
+} VCHIQ_QUEUE_MESSAGE_T32; | |
+ | |
+typedef struct { | |
+ u32 handle; | |
+ u32 data; | |
+ u32 size; | |
+ u32 userdata; | |
+ VCHIQ_BULK_MODE_T mode; | |
+} VCHIQ_QUEUE_BULK_TRANSFER_T32; | |
+ | |
+typedef struct { | |
+ VCHIQ_REASON_T reason; | |
+ u32 header; | |
+ u32 service_userdata; | |
+ u32 bulk_userdata; | |
+} VCHIQ_COMPLETION_DATA_T32; | |
+ | |
+typedef struct { | |
+ u32 count; | |
+ u32 buf; | |
+ u32 msgbufsize; | |
+ u32 msgbufcount; /* IN/OUT */ | |
+ u32 msgbufs; | |
+} VCHIQ_AWAIT_COMPLETION_T32; | |
+ | |
+typedef struct { | |
+ u32 handle; | |
+ s32 blocking; | |
+ u32 bufsize; | |
+ u32 buf; | |
+} VCHIQ_DEQUEUE_MESSAGE_T32; | |
+ | |
+typedef struct { | |
+ u32 config_size; | |
+ u32 pconfig; | |
+} VCHIQ_GET_CONFIG_T32; | |
+ | |
+typedef struct { | |
+ u32 virt_addr; | |
+ u32 num_bytes; | |
+} VCHIQ_DUMP_MEM_T32; | |
+ | |
+/**************************************************************************** | |
+* | |
+* vchiq_compat_ioctl | |
+* | |
+***************************************************************************/ | |
+long | |
+vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
+{ | |
+ long ret = 0; | |
+ | |
+ /* Convert arguments to 64bit types */ | |
+ switch (cmd) { | |
+ case VCHIQ_IOC_CREATE_SERVICE32: { | |
+ VCHIQ_CREATE_SERVICE_T32 args32; | |
+ VCHIQ_CREATE_SERVICE_T __user *args; | |
+ | |
+ args = compat_alloc_user_space(sizeof(*args)); | |
+ if (!args) | |
+ return -EFAULT; | |
+ | |
+ if (copy_from_user(&args32, (const void __user *)arg, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(args32.params.fourcc, &args->params.fourcc) != 0 || | |
+ put_user(args32.params.callback, (uintptr_t *)(&args->params.callback)) != 0 || | |
+ put_user(args32.params.userdata, (uintptr_t *)(&args->params.userdata)) != 0 || | |
+ put_user(args32.params.version, &args->params.version) != 0 || | |
+ put_user(args32.params.version_min, &args->params.version_min) != 0 || | |
+ put_user(args32.is_open, &args->is_open) != 0 || | |
+ put_user(args32.is_vchi, &args->is_vchi) != 0 || | |
+ put_user(args32.handle, &args->handle) != 0) | |
+ return -EFAULT; | |
+ | |
+ ret = vchiq_ioctl(file, VCHIQ_IOC_CREATE_SERVICE, (unsigned long)args); | |
+ if (ret < 0) | |
+ return ret; | |
+ | |
+ if (get_user(args32.handle, &args->handle) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (copy_to_user((void __user *)arg, &args32, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ } break; | |
+ | |
+ case VCHIQ_IOC_QUEUE_MESSAGE32: { | |
+ VCHIQ_ELEMENT_T32 element32; | |
+ VCHIQ_QUEUE_MESSAGE_T32 message32; | |
+ VCHIQ_ELEMENT_T __user *element; | |
+ VCHIQ_QUEUE_MESSAGE_T __user *message; | |
+ size_t count; | |
+ | |
+ if (copy_from_user(&message32, (const void __user *)arg, | |
+ sizeof(message32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ message = compat_alloc_user_space(sizeof(*message) + sizeof(*element) * message32.count); | |
+ if (!message) | |
+ return -EFAULT; | |
+ | |
+ element = (VCHIQ_ELEMENT_T __user *)(((u8 *)message) + sizeof(*message)); | |
+ | |
+ /* Copy the message */ | |
+ if (put_user(message32.handle, &message->handle) != 0 || | |
+ put_user(message32.count, &message->count) != 0 || | |
+ put_user(element, &message->elements) != 0) | |
+ return -EFAULT; | |
+ | |
+ for (count = 0; count < message32.count; count++) { | |
+ /* Copy the current element into kernel space and fill the element array */ | |
+ if (copy_from_user(&element32, (const void __user *) | |
+ &((VCHIQ_ELEMENT_T32 *)(uintptr_t)message32.elements)[count], sizeof(element32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(element32.data, (uintptr_t *)(&element[count].data)) != 0 || | |
+ put_user(element32.size, &element[count].size) != 0) | |
+ return -EFAULT; | |
+ } | |
+ | |
+ ret = vchiq_ioctl(file, VCHIQ_IOC_QUEUE_MESSAGE, (unsigned long)message); | |
+ if (ret < 0) | |
+ return ret; | |
+ } break; | |
+ | |
+ case VCHIQ_IOC_QUEUE_BULK_TRANSMIT32: | |
+ case VCHIQ_IOC_QUEUE_BULK_RECEIVE32: { | |
+ VCHIQ_QUEUE_BULK_TRANSFER_T32 args32; | |
+ VCHIQ_QUEUE_BULK_TRANSFER_T __user *args; | |
+ | |
+ args = compat_alloc_user_space(sizeof(*args)); | |
+ if (!args) | |
+ return -EFAULT; | |
+ | |
+ if (copy_from_user(&args32, (const void __user *)arg, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(args32.handle, &args->handle) != 0 || | |
+ put_user(args32.data, (uintptr_t *)(&args->data)) != 0 || | |
+ put_user(args32.size, &args->size) != 0 || | |
+ put_user(args32.userdata, (uintptr_t *)(&args->userdata)) != 0 || | |
+ put_user(args32.mode, &args->mode) != 0) | |
+ return -EFAULT; | |
+ | |
+ ret = vchiq_ioctl(file, cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32 ? | |
+ VCHIQ_IOC_QUEUE_BULK_TRANSMIT : VCHIQ_IOC_QUEUE_BULK_RECEIVE, (unsigned long)args); | |
+ if (ret < 0) | |
+ return ret; | |
+ | |
+ if (get_user(args32.mode, &args->mode) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (copy_to_user((void __user *)arg, &args32, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ } break; | |
+ | |
+ case VCHIQ_IOC_AWAIT_COMPLETION32: { | |
+ VCHIQ_AWAIT_COMPLETION_T32 await32; | |
+ VCHIQ_COMPLETION_DATA_T data; | |
+ VCHIQ_COMPLETION_DATA_T32 __user *buf32; | |
+ VCHIQ_AWAIT_COMPLETION_T __user *await; | |
+ void __user **msgbufs; | |
+ VCHIQ_COMPLETION_DATA_T __user *buf; | |
+ u32 *msgbufs32; | |
+ size_t i; | |
+ | |
+ if (copy_from_user(&await32, (const void __user *)arg, | |
+ sizeof(await32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ await = compat_alloc_user_space(sizeof(*await) + sizeof(*msgbufs) * await32.msgbufcount + | |
+ sizeof(*buf) * await32.count); | |
+ if (!await) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(await32.count, &await->count) != 0 || | |
+ put_user(await32.msgbufsize, &await->msgbufsize) != 0 || | |
+ put_user(await32.msgbufcount, &await->msgbufcount) != 0) | |
+ return -EFAULT; | |
+ | |
+ /* await32.msgbufs is an array of await32.msgbufcount 32 bits pointers. | |
+ ** Allocate a new array of 64 bits pointers and copy them to the new array. | |
+ ** NOTE: Each of these pointers is supposed to point to a memory buffer large | |
+ ** enough to store a VCHIQ_HEADER_T. Fortunately the size of this struct | |
+ ** is the same for 32 bits and 64 bits platforms, so the buffers don't need | |
+ ** to be reallocated */ | |
+ msgbufs = (void __user **)(((u8 *)await) + sizeof(*await)); | |
+ | |
+ msgbufs32 = (u32 *)(uintptr_t)await32.msgbufs; | |
+ for (i = 0; i < await32.msgbufcount; i++) { | |
+ msgbufs[i] = (void *)(uintptr_t)msgbufs32[i]; | |
+ } | |
+ | |
+ if (put_user(msgbufs, &await->msgbufs) != 0) | |
+ return -EFAULT; | |
+ | |
+ /* await32.buf is an array of await32.count VCHIQ_COMPLETION_DATA_T. The size | |
+ ** of this struct is not the same for 32 bits and 64 bits platforms so a new | |
+ ** array must be allocated. This is an out parameter so it does not need | |
+ ** to be copied */ | |
+ buf = (VCHIQ_COMPLETION_DATA_T __user *)(((u8 *)await) + sizeof(*await) + sizeof(*msgbufs) * await32.msgbufcount); | |
+ | |
+ if (put_user(buf, &await->buf) != 0) | |
+ return -EFAULT; | |
+ | |
+ ret = vchiq_ioctl(file, VCHIQ_IOC_AWAIT_COMPLETION, (unsigned long)await); | |
+ if (ret < 0) | |
+ return ret; | |
+ | |
+ buf32 = (VCHIQ_COMPLETION_DATA_T32 __user *)(uintptr_t)await32.buf; | |
+ | |
+ for (i = 0; i < await32.count; i++) { | |
+ if (copy_from_user(&data, &buf[i], sizeof(*buf)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(data.reason, &buf32[i].reason) != 0 || | |
+ put_user((u32)(uintptr_t)data.header, &buf32[i].header) != 0 || | |
+ put_user((u32)(uintptr_t)data.service_userdata, &buf32[i].service_userdata) != 0 || | |
+ put_user((u32)(uintptr_t)data.bulk_userdata, &buf32[i].bulk_userdata) != 0) | |
+ return -EFAULT; | |
+ } | |
+ | |
+ if (get_user(await32.msgbufcount, &await->msgbufcount) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (copy_to_user((void __user *)arg, &await32, | |
+ sizeof(await32)) != 0) | |
+ return -EFAULT; | |
+ } break; | |
+ | |
+ case VCHIQ_IOC_DEQUEUE_MESSAGE32: { | |
+ VCHIQ_DEQUEUE_MESSAGE_T32 args32; | |
+ VCHIQ_DEQUEUE_MESSAGE_T __user *args; | |
+ | |
+ args = compat_alloc_user_space(sizeof(*args)); | |
+ if (!args) | |
+ return -EFAULT; | |
+ | |
+ if (copy_from_user(&args32, (const void __user *)arg, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(args32.handle, &args->handle) != 0 || | |
+ put_user(args32.blocking, &args->blocking) != 0 || | |
+ put_user(args32.bufsize, &args->bufsize) != 0 || | |
+ put_user(args32.buf, (uintptr_t *)(&args->buf)) != 0) | |
+ return -EFAULT; | |
+ | |
+ ret = vchiq_ioctl(file, VCHIQ_IOC_DEQUEUE_MESSAGE, (unsigned long)args); | |
+ if (ret < 0) | |
+ return ret; | |
+ } break; | |
+ | |
+ case VCHIQ_IOC_GET_CONFIG32: { | |
+ VCHIQ_GET_CONFIG_T32 args32; | |
+ VCHIQ_GET_CONFIG_T __user *args; | |
+ | |
+ args = compat_alloc_user_space(sizeof(*args)); | |
+ if (!args) | |
+ return -EFAULT; | |
+ | |
+ if (copy_from_user(&args32, (const void __user *)arg, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(args32.config_size, &args->config_size) != 0 || | |
+ put_user(args32.pconfig, (uintptr_t *)(&args->pconfig)) != 0) | |
+ return -EFAULT; | |
+ | |
+ ret = vchiq_ioctl(file, VCHIQ_IOC_GET_CONFIG, (unsigned long)args); | |
+ if (ret < 0) | |
+ return ret; | |
+ } break; | |
+ | |
+ case VCHIQ_IOC_DUMP_PHYS_MEM32: { | |
+ VCHIQ_DUMP_MEM_T32 args32; | |
+ VCHIQ_DUMP_MEM_T __user *args; | |
+ | |
+ args = compat_alloc_user_space(sizeof(*args)); | |
+ if (!args) | |
+ return -EFAULT; | |
+ | |
+ if (copy_from_user(&args32, (const void __user *)arg, | |
+ sizeof(args32)) != 0) | |
+ return -EFAULT; | |
+ | |
+ if (put_user(args32.virt_addr, (uintptr_t *)(&args->virt_addr)) != 0 || | |
+ put_user(args32.num_bytes, &args->num_bytes)) | |
+ return -EFAULT; | |
+ | |
+ ret = vchiq_ioctl(file, VCHIQ_IOC_DUMP_PHYS_MEM, (unsigned long)args); | |
+ if (ret < 0) | |
+ return ret; | |
+ } break; | |
+ | |
+ default: { | |
+ ret = vchiq_ioctl(file, cmd, arg); | |
+ } break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h | |
index 6137ae9..72eac51 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h | |
@@ -37,6 +37,11 @@ | |
#include <linux/ioctl.h> | |
#include "vchiq_if.h" | |
+#ifdef CONFIG_COMPAT | |
+extern long vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | |
+extern long vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | |
+#endif | |
+ | |
#define VCHIQ_IOC_MAGIC 0xc4 | |
#define VCHIQ_INVALID_HANDLE (~0) | |
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_pagelist.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_pagelist.h | |
index 54a3ece..a11af0d 100644 | |
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_pagelist.h | |
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_pagelist.h | |
@@ -43,10 +43,10 @@ | |
#define PAGELIST_READ_WITH_FRAGMENTS 2 | |
typedef struct pagelist_struct { | |
- unsigned long length; | |
+ u32 length; | |
unsigned short type; | |
unsigned short offset; | |
- unsigned long addrs[1]; /* N.B. 12 LSBs hold the number of following | |
+ u32 addrs[1]; /* N.B. 12 LSBs hold the number of following | |
pages at consecutive addresses. */ | |
} PAGELIST_T; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment