summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@linaro.org>2011-05-05 11:28:37 +0200
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:14:58 +0200
commit6b1380af9947bbca3dc1cee7a263f19418a988e6 (patch)
tree0f6efd561182eec75725be756b56c55165c1b99f /drivers
parent2fb71937579f2fd1b5333cbea8d07cb1f8c7d773 (diff)
HWMEM: Update API
Perform queued hwmem API changes. One commit to ease dependency handling. Depends-On: I13f249cf5f51f9f138171e8d6f59e1d5d2f72de1, I31030bcfda7cf76d15402c2137576da4f3fb2761, I2dc7e6aa5686492550b5164e50c06ed750ac9e16, Ia12bbb9f378c331cfb9b1376dedb3b7b65f56429, Ibc3404df4876971d8b69272c63120e2fe3bb2787 ST-Ericsson ID: AP 327001 ST-Ericsson FOSS-OUT ID: STETL-FOSS-OUT-10068 Change-Id: I9a45ad54a0cc8a5cdb1e3b9038ad50aeacb3f9c3 Signed-off-by: Johan Mossberg <johan.xx.mossberg@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/17518 Reviewed-by: Robert FEKETE <robert.fekete@stericsson.com> Conflicts: drivers/misc/dispdev/dispdev.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/hwmem/cache_handler.c109
-rw-r--r--drivers/misc/hwmem/hwmem-ioctl.c155
-rw-r--r--drivers/misc/hwmem/hwmem-main.c42
-rw-r--r--drivers/video/b2r2/b2r2_blt_main.c21
-rw-r--r--drivers/video/mcde/mcde_fb.c9
5 files changed, 208 insertions, 128 deletions
diff --git a/drivers/misc/hwmem/cache_handler.c b/drivers/misc/hwmem/cache_handler.c
index b313da36aa4..e0ab4ee6cf8 100644
--- a/drivers/misc/hwmem/cache_handler.c
+++ b/drivers/misc/hwmem/cache_handler.c
@@ -65,9 +65,6 @@ static u32 offset_2_paddr(struct cach_buf *buf, u32 offset);
static u32 align_up(u32 value, u32 alignment);
static u32 align_down(u32 value, u32 alignment);
-static bool is_wb(enum hwmem_alloc_flags cache_settings);
-static bool is_inner_only(enum hwmem_alloc_flags cache_settings);
-
/*
* Exported functions
*/
@@ -89,7 +86,7 @@ void cach_set_buf_addrs(struct cach_buf *buf, void* vaddr, u32 paddr)
buf->vstart = vaddr;
buf->pstart = paddr;
- if (buf->cache_settings & HWMEM_ALLOC_CACHED) {
+ if (buf->cache_settings & HWMEM_ALLOC_HINT_CACHED) {
/*
* Keep whatever is in the cache. This way we avoid an
* unnecessary synch if CPU is the first user.
@@ -124,9 +121,9 @@ void cach_set_domain(struct cach_buf *buf, enum hwmem_access access,
struct hwmem_region *__region;
struct hwmem_region full_region;
- if (region != NULL)
+ if (region != NULL) {
__region = region;
- else {
+ } else {
full_region.offset = 0;
full_region.count = 1;
full_region.start = 0;
@@ -156,27 +153,39 @@ void cach_set_domain(struct cach_buf *buf, enum hwmem_access access,
enum hwmem_alloc_flags __attribute__((weak)) cachi_get_cache_settings(
enum hwmem_alloc_flags requested_cache_settings)
{
- enum hwmem_alloc_flags cache_settings =
- requested_cache_settings & ~HWMEM_ALLOC_CACHE_HINT_MASK;
-
- if ((cache_settings & HWMEM_ALLOC_CACHED) == HWMEM_ALLOC_CACHED) {
- /*
- * If the alloc is cached we'll use the default setting. We
- * don't know what this setting is so we have to assume the
- * worst case, ie write back inner and outer.
- */
- cache_settings |= HWMEM_ALLOC_CACHE_HINT_WB;
- }
-
- return cache_settings;
+ static const u32 CACHE_ON_FLAGS_MASK = HWMEM_ALLOC_HINT_CACHED |
+ HWMEM_ALLOC_HINT_CACHE_WB | HWMEM_ALLOC_HINT_CACHE_WT |
+ HWMEM_ALLOC_HINT_CACHE_NAOW | HWMEM_ALLOC_HINT_CACHE_AOW |
+ HWMEM_ALLOC_HINT_INNER_AND_OUTER_CACHE |
+ HWMEM_ALLOC_HINT_INNER_CACHE_ONLY;
+ /* We don't know the cache setting so we assume worst case. */
+ static const u32 CACHE_SETTING = HWMEM_ALLOC_HINT_WRITE_COMBINE |
+ HWMEM_ALLOC_HINT_CACHED | HWMEM_ALLOC_HINT_CACHE_WB |
+ HWMEM_ALLOC_HINT_CACHE_AOW |
+ HWMEM_ALLOC_HINT_INNER_AND_OUTER_CACHE;
+
+ if (requested_cache_settings & CACHE_ON_FLAGS_MASK)
+ return CACHE_SETTING;
+ else if (requested_cache_settings & HWMEM_ALLOC_HINT_WRITE_COMBINE ||
+ (requested_cache_settings & HWMEM_ALLOC_HINT_UNCACHED &&
+ !(requested_cache_settings &
+ HWMEM_ALLOC_HINT_NO_WRITE_COMBINE)))
+ return HWMEM_ALLOC_HINT_WRITE_COMBINE;
+ else if (requested_cache_settings &
+ (HWMEM_ALLOC_HINT_NO_WRITE_COMBINE |
+ HWMEM_ALLOC_HINT_UNCACHED))
+ return 0;
+ else
+ /* Nothing specified, use cached */
+ return CACHE_SETTING;
}
void __attribute__((weak)) cachi_set_pgprot_cache_options(
enum hwmem_alloc_flags cache_settings, pgprot_t *pgprot)
{
- if ((cache_settings & HWMEM_ALLOC_CACHED) == HWMEM_ALLOC_CACHED)
+ if (cache_settings & HWMEM_ALLOC_HINT_CACHED)
*pgprot = *pgprot; /* To silence compiler and checkpatch */
- else if (cache_settings & HWMEM_ALLOC_BUFFERED)
+ else if (cache_settings & HWMEM_ALLOC_HINT_WRITE_COMBINE)
*pgprot = pgprot_writecombine(*pgprot);
else
*pgprot = pgprot_noncached(*pgprot);
@@ -197,23 +206,32 @@ static void sync_buf_pre_cpu(struct cach_buf *buf, enum hwmem_access access,
if (!write && !read)
return;
- if ((buf->cache_settings & HWMEM_ALLOC_CACHED) == HWMEM_ALLOC_CACHED) {
+ if (buf->cache_settings & HWMEM_ALLOC_HINT_CACHED) {
struct cach_range region_range;
region_2_range(region, buf->size, &region_range);
- if (read || (write && is_wb(buf->cache_settings)))
+ if (read || (write && buf->cache_settings &
+ HWMEM_ALLOC_HINT_CACHE_WB))
/* Perform defered invalidates */
invalidate_cpu_cache(buf, &region_range);
- if (read)
- expand_range(&buf->range_in_cpu_cache, &region_range);
- if (write && is_wb(buf->cache_settings)) {
+ if (read || (write && buf->cache_settings &
+ HWMEM_ALLOC_HINT_CACHE_AOW))
expand_range(&buf->range_in_cpu_cache, &region_range);
+ if (write && buf->cache_settings & HWMEM_ALLOC_HINT_CACHE_WB) {
+ struct cach_range dirty_range_addition;
+
+ if (buf->cache_settings & HWMEM_ALLOC_HINT_CACHE_AOW)
+ dirty_range_addition = region_range;
+ else
+ intersect_range(&buf->range_in_cpu_cache,
+ &region_range, &dirty_range_addition);
+
expand_range(&buf->range_dirty_in_cpu_cache,
- &region_range);
+ &dirty_range_addition);
}
}
- if (buf->cache_settings & HWMEM_ALLOC_BUFFERED) {
+ if (buf->cache_settings & HWMEM_ALLOC_HINT_WRITE_COMBINE) {
if (write)
buf->in_cpu_write_buf = true;
}
@@ -243,8 +261,9 @@ static void sync_buf_post_cpu(struct cach_buf *buf,
&intersection);
clean_cpu_cache(buf, &region_range);
- } else
+ } else {
flush_cpu_cache(buf, &region_range);
+ }
}
if (read)
clean_cpu_cache(buf, &region_range);
@@ -277,13 +296,14 @@ static void invalidate_cpu_cache(struct cach_buf *buf, struct cach_range *range)
offset_2_vaddr(buf, intersection.start),
offset_2_paddr(buf, intersection.start),
range_length(&intersection),
- is_inner_only(buf->cache_settings),
+ buf->cache_settings &
+ HWMEM_ALLOC_HINT_INNER_CACHE_ONLY,
&flushed_everything);
if (flushed_everything) {
null_range(&buf->range_invalid_in_cpu_cache);
null_range(&buf->range_dirty_in_cpu_cache);
- } else
+ } else {
/*
* No need to shrink range_in_cpu_cache as invalidate
* is only used when we can't keep track of what's in
@@ -291,6 +311,7 @@ static void invalidate_cpu_cache(struct cach_buf *buf, struct cach_range *range)
*/
shrink_range(&buf->range_invalid_in_cpu_cache,
&intersection);
+ }
}
}
@@ -309,7 +330,8 @@ static void clean_cpu_cache(struct cach_buf *buf, struct cach_range *range)
offset_2_vaddr(buf, intersection.start),
offset_2_paddr(buf, intersection.start),
range_length(&intersection),
- is_inner_only(buf->cache_settings),
+ buf->cache_settings &
+ HWMEM_ALLOC_HINT_INNER_CACHE_ONLY,
&cleaned_everything);
if (cleaned_everything)
@@ -334,7 +356,8 @@ static void flush_cpu_cache(struct cach_buf *buf, struct cach_range *range)
offset_2_vaddr(buf, intersection.start),
offset_2_paddr(buf, intersection.start),
range_length(&intersection),
- is_inner_only(buf->cache_settings),
+ buf->cache_settings &
+ HWMEM_ALLOC_HINT_INNER_CACHE_ONLY,
&flushed_everything);
if (flushed_everything) {
@@ -485,23 +508,3 @@ static u32 align_down(u32 value, u32 alignment)
return value - remainder;
}
-
-static bool is_wb(enum hwmem_alloc_flags cache_settings)
-{
- u32 cache_hints = cache_settings & HWMEM_ALLOC_CACHE_HINT_MASK;
- if (cache_hints == HWMEM_ALLOC_CACHE_HINT_WB ||
- cache_hints == HWMEM_ALLOC_CACHE_HINT_WB_INNER)
- return true;
- else
- return false;
-}
-
-static bool is_inner_only(enum hwmem_alloc_flags cache_settings)
-{
- u32 cache_hints = cache_settings & HWMEM_ALLOC_CACHE_HINT_MASK;
- if (cache_hints == HWMEM_ALLOC_CACHE_HINT_WT_INNER ||
- cache_hints == HWMEM_ALLOC_CACHE_HINT_WB_INNER)
- return true;
- else
- return false;
-}
diff --git a/drivers/misc/hwmem/hwmem-ioctl.c b/drivers/misc/hwmem/hwmem-ioctl.c
index 8759c395147..e9e50de78bd 100644
--- a/drivers/misc/hwmem/hwmem-ioctl.c
+++ b/drivers/misc/hwmem/hwmem-ioctl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) ST-Ericsson AB 2010
+ * Copyright (C) ST-Ericsson SA 2010
*
* Hardware memory driver, hwmem
*
@@ -21,12 +21,6 @@
#include <linux/device.h>
#include <linux/sched.h>
-/*
- * TODO:
- * Count pin unpin at this level to ensure applications can't interfer
- * with each other.
- */
-
static int hwmem_open(struct inode *inode, struct file *file);
static int hwmem_ioctl_mmap(struct file *file, struct vm_area_struct *vma);
static int hwmem_release_fop(struct inode *inode, struct file *file);
@@ -56,7 +50,7 @@ struct hwmem_file {
struct hwmem_alloc *fd_alloc; /* Ref counted */
};
-static int create_id(struct hwmem_file *hwfile, struct hwmem_alloc *alloc)
+static s32 create_id(struct hwmem_file *hwfile, struct hwmem_alloc *alloc)
{
int id, ret;
@@ -72,42 +66,42 @@ static int create_id(struct hwmem_file *hwfile, struct hwmem_alloc *alloc)
}
/*
- * IDR always returns the lowest free id so the only way we can fail
- * here is if hwfile has 2^19 - 1 (524287) allocations.
+ * IDR always returns the lowest free id so there is no wrapping issue
+ * because of this.
*/
- if (id >= 1 << (31 - PAGE_SHIFT)) {
+ if (id >= (s32)1 << (31 - PAGE_SHIFT)) {
dev_err(hwmem_device.this_device, "Out of IDs!\n");
idr_remove(&hwfile->idr, id);
return -ENOMSG;
}
- return id << PAGE_SHIFT;
+ return (s32)id << PAGE_SHIFT;
}
-static void remove_id(struct hwmem_file *hwfile, int id)
+static void remove_id(struct hwmem_file *hwfile, s32 id)
{
idr_remove(&hwfile->idr, id >> PAGE_SHIFT);
}
-static struct hwmem_alloc *resolve_id(struct hwmem_file *hwfile, int id)
+static struct hwmem_alloc *resolve_id(struct hwmem_file *hwfile, s32 id)
{
struct hwmem_alloc *alloc;
alloc = id ? idr_find(&hwfile->idr, id >> PAGE_SHIFT) :
- hwfile->fd_alloc;
+ hwfile->fd_alloc;
if (alloc == NULL)
alloc = ERR_PTR(-EINVAL);
return alloc;
}
-static int alloc(struct hwmem_file *hwfile, struct hwmem_alloc_request *req)
+static s32 alloc(struct hwmem_file *hwfile, struct hwmem_alloc_request *req)
{
- int ret = 0;
+ s32 ret = 0;
struct hwmem_alloc *alloc;
alloc = hwmem_alloc(req->size, req->flags, req->default_access,
- req->mem_type);
+ req->mem_type);
if (IS_ERR(alloc))
return PTR_ERR(alloc);
@@ -123,10 +117,10 @@ static int alloc_fd(struct hwmem_file *hwfile, struct hwmem_alloc_request *req)
struct hwmem_alloc *alloc;
if (hwfile->fd_alloc)
- return -EBUSY;
+ return -EINVAL;
alloc = hwmem_alloc(req->size, req->flags, req->default_access,
- req->mem_type);
+ req->mem_type);
if (IS_ERR(alloc))
return PTR_ERR(alloc);
@@ -139,6 +133,9 @@ static int release(struct hwmem_file *hwfile, s32 id)
{
struct hwmem_alloc *alloc;
+ if (id == 0)
+ return -EINVAL;
+
alloc = resolve_id(hwfile, id);
if (IS_ERR(alloc))
return PTR_ERR(alloc);
@@ -149,7 +146,20 @@ static int release(struct hwmem_file *hwfile, s32 id)
return 0;
}
-static int hwmem_ioctl_set_domain(struct hwmem_file *hwfile,
+static int set_cpu_domain(struct hwmem_file *hwfile,
+ struct hwmem_set_domain_request *req)
+{
+ struct hwmem_alloc *alloc;
+
+ alloc = resolve_id(hwfile, req->id);
+ if (IS_ERR(alloc))
+ return PTR_ERR(alloc);
+
+ return hwmem_set_domain(alloc, req->access, HWMEM_DOMAIN_CPU,
+ (struct hwmem_region *)&req->region);
+}
+
+static int set_sync_domain(struct hwmem_file *hwfile,
struct hwmem_set_domain_request *req)
{
struct hwmem_alloc *alloc;
@@ -158,18 +168,33 @@ static int hwmem_ioctl_set_domain(struct hwmem_file *hwfile,
if (IS_ERR(alloc))
return PTR_ERR(alloc);
- return hwmem_set_domain(alloc, req->access, req->domain, &req->region);
+ return hwmem_set_domain(alloc, req->access, HWMEM_DOMAIN_SYNC,
+ (struct hwmem_region *)&req->region);
}
static int pin(struct hwmem_file *hwfile, struct hwmem_pin_request *req)
{
+ int ret;
struct hwmem_alloc *alloc;
+ enum hwmem_mem_type mem_type;
+ struct hwmem_mem_chunk mem_chunk;
+ size_t mem_chunk_length = 1;
alloc = resolve_id(hwfile, req->id);
if (IS_ERR(alloc))
return PTR_ERR(alloc);
- return hwmem_pin(alloc, &req->phys_addr, req->scattered_addrs);
+ hwmem_get_info(alloc, NULL, &mem_type, NULL);
+ if (mem_type != HWMEM_MEM_CONTIGUOUS_SYS)
+ return -EINVAL;
+
+ ret = hwmem_pin(alloc, &mem_chunk, &mem_chunk_length);
+ if (ret < 0)
+ return ret;
+
+ req->phys_addr = mem_chunk.paddr;
+
+ return 0;
}
static int unpin(struct hwmem_file *hwfile, s32 id)
@@ -211,13 +236,10 @@ static int get_info(struct hwmem_file *hwfile,
return 0;
}
-static int export(struct hwmem_file *hwfile, s32 id)
+static s32 export(struct hwmem_file *hwfile, s32 id)
{
- int ret;
+ s32 ret;
struct hwmem_alloc *alloc;
-
- uint32_t size;
- enum hwmem_mem_type mem_type;
enum hwmem_access access;
alloc = resolve_id(hwfile, id);
@@ -234,26 +256,20 @@ static int export(struct hwmem_file *hwfile, s32 id)
* security as the process already has access to the buffer (otherwise
* it would not be able to get here).
*/
- hwmem_get_info(alloc, &size, &mem_type, &access);
+ hwmem_get_info(alloc, NULL, NULL, &access);
ret = hwmem_set_access(alloc, (access | HWMEM_ACCESS_IMPORT),
- task_tgid_nr(current));
+ task_tgid_nr(current));
if (ret < 0)
- goto error;
+ return ret;
return hwmem_get_name(alloc);
-
-error:
- return ret;
}
-static int import(struct hwmem_file *hwfile, s32 name)
+static s32 import(struct hwmem_file *hwfile, s32 name)
{
- int ret = 0;
+ s32 ret = 0;
struct hwmem_alloc *alloc;
-
- uint32_t size;
- enum hwmem_mem_type mem_type;
enum hwmem_access access;
alloc = hwmem_resolve_by_name(name);
@@ -261,8 +277,7 @@ static int import(struct hwmem_file *hwfile, s32 name)
return PTR_ERR(alloc);
/* Check access permissions for process */
- hwmem_get_info(alloc, &size, &mem_type, &access);
-
+ hwmem_get_info(alloc, NULL, NULL, &access);
if (!(access & HWMEM_ACCESS_IMPORT)) {
ret = -EPERM;
goto error;
@@ -270,26 +285,44 @@ static int import(struct hwmem_file *hwfile, s32 name)
ret = create_id(hwfile, alloc);
if (ret < 0)
- hwmem_release(alloc);
+ goto error;
+
+ return ret;
error:
+ hwmem_release(alloc);
+
return ret;
}
static int import_fd(struct hwmem_file *hwfile, s32 name)
{
+ int ret;
struct hwmem_alloc *alloc;
+ enum hwmem_access access;
if (hwfile->fd_alloc)
- return -EBUSY;
+ return -EINVAL;
alloc = hwmem_resolve_by_name(name);
if (IS_ERR(alloc))
return PTR_ERR(alloc);
+ /* Check access permissions for process */
+ hwmem_get_info(alloc, NULL, NULL, &access);
+ if (!(access & HWMEM_ACCESS_IMPORT)) {
+ ret = -EPERM;
+ goto error;
+ }
+
hwfile->fd_alloc = alloc;
return 0;
+
+error:
+ hwmem_release(alloc);
+
+ return ret;
}
static int hwmem_open(struct inode *inode, struct file *file)
@@ -315,7 +348,7 @@ static int hwmem_ioctl_mmap(struct file *file, struct vm_area_struct *vma)
mutex_lock(&hwfile->lock);
- alloc = resolve_id(hwfile, vma->vm_pgoff << PAGE_SHIFT);
+ alloc = resolve_id(hwfile, (s32)vma->vm_pgoff << PAGE_SHIFT);
if (IS_ERR(alloc)) {
ret = PTR_ERR(alloc);
goto out;
@@ -385,23 +418,29 @@ static long hwmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case HWMEM_RELEASE_IOC:
ret = release(hwfile, (s32)arg);
break;
- case HWMEM_SET_DOMAIN_IOC:
+ case HWMEM_SET_CPU_DOMAIN_IOC:
{
struct hwmem_set_domain_request req;
if (copy_from_user(&req, (void __user *)arg,
sizeof(struct hwmem_set_domain_request)))
ret = -EFAULT;
else
- ret = hwmem_ioctl_set_domain(hwfile, &req);
+ ret = set_cpu_domain(hwfile, &req);
+ }
+ break;
+ case HWMEM_SET_SYNC_DOMAIN_IOC:
+ {
+ struct hwmem_set_domain_request req;
+ if (copy_from_user(&req, (void __user *)arg,
+ sizeof(struct hwmem_set_domain_request)))
+ ret = -EFAULT;
+ else
+ ret = set_sync_domain(hwfile, &req);
}
break;
case HWMEM_PIN_IOC:
{
struct hwmem_pin_request req;
- /*
- * TODO: Validate and copy scattered_addrs. Not a
- * problem right now as it's never used.
- */
if (copy_from_user(&req, (void __user *)arg,
sizeof(struct hwmem_pin_request)))
ret = -EFAULT;
@@ -468,6 +507,22 @@ static unsigned long hwmem_get_unmapped_area(struct file *file,
int __init hwmem_ioctl_init(void)
{
+ if (PAGE_SHIFT < 1 || PAGE_SHIFT > 30 || sizeof(size_t) != 4 ||
+ sizeof(int) > 4 || sizeof(enum hwmem_alloc_flags) != 4 ||
+ sizeof(enum hwmem_access) != 4 ||
+ sizeof(enum hwmem_mem_type) != 4) {
+ dev_err(hwmem_device.this_device, "PAGE_SHIFT < 1 || PAGE_SHIFT"
+ " > 30 || sizeof(size_t) != 4 || sizeof(int) > 4 ||"
+ " sizeof(enum hwmem_alloc_flags) != 4 || sizeof(enum"
+ " hwmem_access) != 4 || sizeof(enum hwmem_mem_type)"
+ " != 4\n");
+ return -ENOMSG;
+ }
+ if (PAGE_SHIFT > 15)
+ dev_warn(hwmem_device.this_device, "Due to the page size only"
+ " %u id:s per file instance are available\n",
+ ((u32)1 << (31 - PAGE_SHIFT)) - 1);
+
return misc_register(&hwmem_device);
}
diff --git a/drivers/misc/hwmem/hwmem-main.c b/drivers/misc/hwmem/hwmem-main.c
index 0010e45ff52..fbfd8502a1d 100644
--- a/drivers/misc/hwmem/hwmem-main.c
+++ b/drivers/misc/hwmem/hwmem-main.c
@@ -1,10 +1,10 @@
/*
- * Copyright (C) ST-Ericsson AB 2010
+ * Copyright (C) ST-Ericsson SA 2010
*
* Hardware memory driver, hwmem
*
- * Author: Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com>
- * for ST-Ericsson.
+ * Author: Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com>,
+ * Johan Mossberg <johan.xx.mossberg@stericsson.com> for ST-Ericsson.
*
* License terms: GNU General Public License (GPL), version 2.
*/
@@ -46,7 +46,7 @@ struct hwmem_alloc {
u32 paddr;
void *kaddr;
u32 size;
- u32 name;
+ s32 name;
/* Access control */
enum hwmem_access default_access;
@@ -446,12 +446,19 @@ int hwmem_set_domain(struct hwmem_alloc *alloc, enum hwmem_access access,
}
EXPORT_SYMBOL(hwmem_set_domain);
-int hwmem_pin(struct hwmem_alloc *alloc, uint32_t *phys_addr,
- uint32_t *scattered_phys_addrs)
+int hwmem_pin(struct hwmem_alloc *alloc, struct hwmem_mem_chunk *mem_chunks,
+ u32 *mem_chunks_length)
{
+ if (*mem_chunks_length < 1) {
+ *mem_chunks_length = 1;
+ return -ENOSPC;
+ }
+
mutex_lock(&lock);
- *phys_addr = alloc->paddr;
+ mem_chunks[0].paddr = alloc->paddr;
+ mem_chunks[0].size = alloc->size;
+ *mem_chunks_length = 1;
mutex_unlock(&lock);
@@ -492,7 +499,7 @@ int hwmem_mmap(struct hwmem_alloc *alloc, struct vm_area_struct *vma)
goto illegal_access;
}
- if (vma_size > (unsigned long)alloc->size) {
+ if (vma_size > alloc->size) {
ret = -EINVAL;
goto illegal_size;
}
@@ -590,14 +597,17 @@ error_get_pid:
}
EXPORT_SYMBOL(hwmem_set_access);
-void hwmem_get_info(struct hwmem_alloc *alloc, uint32_t *size,
+void hwmem_get_info(struct hwmem_alloc *alloc, u32 *size,
enum hwmem_mem_type *mem_type, enum hwmem_access *access)
{
mutex_lock(&lock);
- *size = alloc->size;
- *mem_type = HWMEM_MEM_CONTIGUOUS_SYS;
- *access = get_access(alloc);
+ if (size != NULL)
+ *size = alloc->size;
+ if (mem_type != NULL)
+ *mem_type = HWMEM_MEM_CONTIGUOUS_SYS;
+ if (access != NULL)
+ *access = get_access(alloc);
mutex_unlock(&lock);
}
@@ -766,6 +776,14 @@ static int __devinit hwmem_probe(struct platform_device *pdev)
int ret = 0;
struct hwmem_platform_data *platform_data = pdev->dev.platform_data;
+ if (sizeof(int) != 4 || sizeof(phys_addr_t) < 4 ||
+ sizeof(void *) < 4 || sizeof(size_t) != 4) {
+ dev_err(&pdev->dev, "sizeof(int) != 4 || sizeof(phys_addr_t)"
+ " < 4 || sizeof(void *) < 4 || sizeof(size_t) !="
+ " 4\n");
+ return -ENOMSG;
+ }
+
if (hwdev || platform_data->size == 0 ||
platform_data->start != PAGE_ALIGN(platform_data->start) ||
platform_data->size != PAGE_ALIGN(platform_data->size)) {
diff --git a/drivers/video/b2r2/b2r2_blt_main.c b/drivers/video/b2r2/b2r2_blt_main.c
index 1f5be3d0d95..a2b21f4a2c1 100644
--- a/drivers/video/b2r2/b2r2_blt_main.c
+++ b/drivers/video/b2r2/b2r2_blt_main.c
@@ -2241,11 +2241,11 @@ static void set_up_hwmem_region(struct b2r2_blt_img *img,
int img_fmt_bpp = b2r2_get_fmt_bpp(img->fmt);
u32 img_pitch = b2r2_get_img_pitch(img);
- region->offset = (uint32_t)(img->buf.offset + (rect->y *
+ region->offset = (u32)(img->buf.offset + (rect->y *
img_pitch));
- region->count = (uint32_t)rect->height;
- region->start = (uint32_t)((rect->x * img_fmt_bpp) / 8);
- region->end = (uint32_t)b2r2_div_round_up(
+ region->count = (u32)rect->height;
+ region->start = (u32)((rect->x * img_fmt_bpp) / 8);
+ region->end = (u32)b2r2_div_round_up(
(rect->x + rect->width) * img_fmt_bpp, 8);
region->size = img_pitch;
} else {
@@ -2255,11 +2255,11 @@ static void set_up_hwmem_region(struct b2r2_blt_img *img,
* synching. Pixel interleaved YCbCr formats should be quite
* easy, just align start and stop points on 2.
*/
- region->offset = (uint32_t)img->buf.offset;
+ region->offset = (u32)img->buf.offset;
region->count = 1;
region->start = 0;
- region->end = (uint32_t)img_size;
- region->size = (uint32_t)img_size;
+ region->end = (u32)img_size;
+ region->size = (u32)img_size;
}
}
@@ -2272,6 +2272,8 @@ static int resolve_hwmem(struct b2r2_blt_img *img,
enum hwmem_mem_type mem_type;
enum hwmem_access access;
enum hwmem_access required_access;
+ struct hwmem_mem_chunk mem_chunk;
+ size_t mem_chunk_length = 1;
struct hwmem_region region;
resolved_buf->hwmem_alloc =
@@ -2308,13 +2310,14 @@ static int resolve_hwmem(struct b2r2_blt_img *img,
goto size_check_failed;
}
- return_value = hwmem_pin(resolved_buf->hwmem_alloc,
- &resolved_buf->file_physical_start, NULL);
+ return_value = hwmem_pin(resolved_buf->hwmem_alloc, &mem_chunk,
+ &mem_chunk_length);
if (return_value < 0) {
b2r2_log_info("%s: hwmem_pin failed, "
"error code: %i\n", __func__, return_value);
goto pin_failed;
}
+ resolved_buf->file_physical_start = mem_chunk.paddr;
set_up_hwmem_region(img, rect_2b_used, &region);
return_value = hwmem_set_domain(resolved_buf->hwmem_alloc,
diff --git a/drivers/video/mcde/mcde_fb.c b/drivers/video/mcde/mcde_fb.c
index ae21f46b0a1..2390bd742df 100644
--- a/drivers/video/mcde/mcde_fb.c
+++ b/drivers/video/mcde/mcde_fb.c
@@ -209,9 +209,10 @@ static int init_var_fmt(struct fb_var_screeninfo *var,
static int reallocate_fb_mem(struct fb_info *fbi, u32 size)
{
struct mcde_fb *mfb = to_mcde_fb(fbi);
- dma_addr_t paddr;
void *vaddr;
struct hwmem_alloc *alloc;
+ struct hwmem_mem_chunk mem_chunk;
+ size_t num_mem_chunks = 1;
int name;
size = PAGE_ALIGN(size);
@@ -228,7 +229,7 @@ static int reallocate_fb_mem(struct fb_info *fbi, u32 size)
MCDE_FB_VYRES_MAX;
#endif
- alloc = hwmem_alloc(size, HWMEM_ALLOC_BUFFERED,
+ alloc = hwmem_alloc(size, HWMEM_ALLOC_HINT_WRITE_COMBINE,
(HWMEM_ACCESS_READ | HWMEM_ACCESS_WRITE |
HWMEM_ACCESS_IMPORT),
HWMEM_MEM_CONTIGUOUS_SYS);
@@ -247,7 +248,7 @@ static int reallocate_fb_mem(struct fb_info *fbi, u32 size)
hwmem_release(mfb->alloc);
}
- (void)hwmem_pin(alloc, &paddr, NULL);
+ (void)hwmem_pin(alloc, &mem_chunk, &num_mem_chunks);
vaddr = hwmem_kmap(alloc);
if (vaddr == NULL) {
@@ -260,7 +261,7 @@ static int reallocate_fb_mem(struct fb_info *fbi, u32 size)
mfb->alloc_name = name;
fbi->screen_base = vaddr;
- fbi->fix.smem_start = paddr;
+ fbi->fix.smem_start = mem_chunk.paddr;
#ifdef CONFIG_MCDE_FB_AVOID_REALLOC
size = old_size;