diff options
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/sep/sep_dev.h | 2 | ||||
-rw-r--r-- | drivers/staging/sep/sep_driver.c | 128 | ||||
-rw-r--r-- | drivers/staging/sep/sep_driver_api.h | 26 |
3 files changed, 47 insertions, 109 deletions
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h index fd33945db6c8..f0dc715cbcb6 100644 --- a/drivers/staging/sep/sep_dev.h +++ b/drivers/staging/sep/sep_dev.h @@ -54,7 +54,7 @@ struct sep_device { unsigned long resident_size; void *resident_addr; - unsigned long rar_region_addr; + void *rar_region_addr; /* start address of the access to the SEP registers from driver */ void __iomem *reg_addr; diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 6185cbd93da3..4d3b1630ef5b 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -170,39 +170,25 @@ static DEFINE_MUTEX(sep_mutex); /* wait queue head (event) of the driver */ static DECLARE_WAIT_QUEUE_HEAD(sep_event); -/* - This functions copies the cache and resident from their source location into - destination memory, which is external to Linux VM and is given as - bus address -*/ -static int sep_copy_cache_resident_to_area(struct sep_device *sep, - unsigned long src_cache_addr, - unsigned long cache_size_in_bytes, - unsigned long src_resident_addr, - unsigned long resident_size_in_bytes, - unsigned long *dst_new_cache_addr_ptr, - unsigned long *dst_new_resident_addr_ptr) +/** + * sep_load_firmware - copy firmware cache/resident + * @sep: device we are loading + * + * This functions copies the cache and resident from their source + * location into destination shared memory. + */ + +static int sep_load_firmware(struct sep_device *sep) { - void *resident_addr; - void *cache_addr; const struct firmware *fw; - char *cache_name = "cache.image.bin"; char *res_name = "resident.image.bin"; - - /* error */ int error; - /*-------------------------------- - CODE - -------------------------------------*/ - error = 0; - edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); - sep->rar_region_addr = (unsigned long) sep->rar_addr; - + sep->rar_region_addr = sep->rar_addr; sep->cache_bus = sep->rar_bus; sep->cache_addr = sep->rar_addr; @@ -210,18 +196,12 @@ static int sep_copy_cache_resident_to_area(struct sep_device *sep, error = request_firmware(&fw, cache_name, &sep->pdev->dev); if (error) { edbg("SEP Driver:cant request cache fw\n"); - goto end_function; + return error; } + edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data); - edbg("SEP Driver:cache data loc is %p\n", (void *) fw->data); - edbg("SEP Driver:cache data size is %08Zx\n", fw->size); - - memcpy(sep->cache_addr, (void *) fw->data, fw->size); - + memcpy(sep->cache_addr, (void *)fw->data, fw->size); sep->cache_size = fw->size; - - cache_addr = sep->cache_addr; - release_firmware(fw); sep->resident_bus = sep->cache_bus + sep->cache_size; @@ -231,36 +211,18 @@ static int sep_copy_cache_resident_to_area(struct sep_device *sep, error = request_firmware(&fw, res_name, &sep->pdev->dev); if (error) { edbg("SEP Driver:cant request res fw\n"); - goto end_function; + return error; } + edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data); - edbg("SEP Driver:res data loc is %p\n", (void *) fw->data); - edbg("SEP Driver:res data size is %08Zx\n", fw->size); - - memcpy((void *) sep->resident_addr, (void *) fw->data, fw->size); - + memcpy(sep->resident_addr, (void *) fw->data, fw->size); sep->resident_size = fw->size; - release_firmware(fw); - resident_addr = sep->resident_addr; - - edbg("SEP Driver:resident_addr (bus)is %08llx\n", (unsigned long long)sep->resident_bus); - edbg("SEP Driver:cache_addr (bus) is %08llx\n", (unsigned long long)sep->cache_bus); - - edbg("SEP Driver:resident_addr (virtual)is %p\n", resident_addr); - edbg("SEP Driver:cache_addr (virtual) is %08llx\n", (unsigned long long)cache_addr); - - edbg("SEP Driver:resident_size is %08lx\n", sep->resident_size); - edbg("SEP Driver:cache_size is %08llx\n", (unsigned long long)sep->cache_size); - - - - /* bus addresses */ - *dst_new_cache_addr_ptr = sep->cache_bus; - *dst_new_resident_addr_ptr = sep->resident_bus; -end_function: - return error; + edbg("sep: resident v %p b %08llx cache v %p b %08llx\n", + sep->resident_addr, (unsigned long long)sep->resident_bus, + sep->cache_addr, (unsigned long long)sep->cache_bus); + return 0; } /** @@ -2125,46 +2087,39 @@ end_function: static int sep_realloc_cache_resident_handler(struct sep_device *sep, unsigned long arg) { - int error; - unsigned long bus_cache_address; - unsigned long bus_resident_address; struct sep_driver_realloc_cache_resident_t command_args; - - /* copy the data */ - error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_realloc_cache_resident_t)); - if (error) - goto end_function; + int error; /* copy cache and resident to the their intended locations */ - error = sep_copy_cache_resident_to_area(sep, command_args.cache_addr, command_args.cache_size_in_bytes, command_args.resident_addr, command_args.resident_size_in_bytes, &bus_cache_address, &bus_resident_address); + error = sep_load_firmware(sep); if (error) - goto end_function; + return error; command_args.new_base_addr = sep->shared_area_bus; /* find the new base address according to the lowest address between cache, resident and shared area */ - if (bus_resident_address < command_args.new_base_addr) - command_args.new_base_addr = bus_resident_address; - if (bus_cache_address < command_args.new_base_addr) - command_args.new_base_addr = bus_cache_address; + if (sep->resident_bus < command_args.new_base_addr) + command_args.new_base_addr = sep->resident_bus; + if (sep->cache_bus < command_args.new_base_addr) + command_args.new_base_addr = sep->cache_bus; /* set the return parameters */ - command_args.new_cache_addr = bus_cache_address; - command_args.new_resident_addr = bus_resident_address; + command_args.new_cache_addr = sep->cache_bus; + command_args.new_resident_addr = sep->resident_bus; /* set the new shared area */ command_args.new_shared_area_addr = sep->shared_area_bus; - edbg("SEP Driver:command_args.new_shared_area is %08lx\n", command_args.new_shared_area_addr); - edbg("SEP Driver:command_args.new_base_addr is %08lx\n", command_args.new_base_addr); - edbg("SEP Driver:command_args.new_resident_addr is %08lx\n", command_args.new_resident_addr); - edbg("SEP Driver:command_args.new_cache_addr is %08lx\n", command_args.new_cache_addr); + edbg("SEP Driver:command_args.new_shared_area is %08llx\n", command_args.new_shared_area_addr); + edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr); + edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr); + edbg("SEP Driver:command_args.new_cache_addr is %08llx\n", command_args.new_cache_addr); /* return to user */ - error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)); -end_function: - return error; + if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t))) + return -EFAULT; + return 0; } /* @@ -2573,14 +2528,14 @@ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id /* set up system base address and shared memory location */ - sep->rar_addr = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, GFP_KERNEL); + sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev, + 2 * SEP_RAR_IO_MEM_REGION_SIZE, + &sep->rar_bus, GFP_KERNEL); if (!sep->rar_addr) { - edbg("SEP Driver:cant kmalloc rar\n"); + edbg("SEP Driver:can't allocate rar\n"); goto end_function_uniomap; } - /* FIXME */ - sep->rar_bus = __pa(sep->rar_addr); edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); @@ -2608,7 +2563,8 @@ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); end_function_free_res: - kfree(sep->rar_addr); + dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE, + sep->rar_addr, sep->rar_bus); #endif /* SEP_DRIVER_POLLING_MODE */ end_function_uniomap: iounmap(sep->io_addr); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index 08b4c2418506..383543d97f9c 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -116,32 +116,14 @@ struct sep_driver_init_t { realloc cache resident command */ struct sep_driver_realloc_cache_resident_t { - /* base address */ - unsigned long base_addr; - - /* current cache address */ - unsigned long cache_addr; - - /* cache size in bytes */ - unsigned long cache_size_in_bytes; - - /* current resident address */ - unsigned long resident_addr; - - /* resident size in bytes */ - unsigned long resident_size_in_bytes; - /* new cache address */ - unsigned long new_cache_addr; - + u64 new_cache_addr; /* new resident address */ - unsigned long new_resident_addr; - + u64 new_resident_addr; /* new resident address */ - unsigned long new_shared_area_addr; - + u64 new_shared_area_addr; /* new base address */ - unsigned long new_base_addr; + u64 new_base_addr; }; struct sep_driver_alloc_t { |