diff options
author | Christoph Hellwig <hch@lst.de> | 2019-01-29 08:34:09 +0100 |
---|---|---|
committer | Darren Hart (VMware) <dvhart@infradead.org> | 2019-02-23 18:20:25 +0100 |
commit | fd47a36fba257b91d4a0bdc2f94fe323e8819c2f (patch) | |
tree | df4412966847ad549e180d5eabb1e46337b5e8f3 /drivers/platform | |
parent | platform/x86: ideapad-laptop: Fix no_hw_rfkill_list for Lenovo RESCUER R720-1... (diff) | |
download | linux-fd47a36fba257b91d4a0bdc2f94fe323e8819c2f.tar.xz linux-fd47a36fba257b91d4a0bdc2f94fe323e8819c2f.zip |
platform/x86: dell_rbu: stop abusing the DMA API
For some odd reason dell_rbu actually seems to want the physical and
not a bus address for the allocated buffer. Lets assume that actually
is correct given that it is BIOS-related and that is a good source
of insanity. In that case we should not use dma_alloc_coherent with
a NULL device to allocate memory, but use GFP_DMA32 to stay under
the 32-bit BIOS limit.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/dell_rbu.c | 52 |
1 files changed, 15 insertions, 37 deletions
diff --git a/drivers/platform/x86/dell_rbu.c b/drivers/platform/x86/dell_rbu.c index ccefa84f7305..8104ca0c44ca 100644 --- a/drivers/platform/x86/dell_rbu.c +++ b/drivers/platform/x86/dell_rbu.c @@ -59,7 +59,6 @@ static struct _rbu_data { unsigned long image_update_buffer_size; unsigned long bios_image_size; int image_update_ordernum; - int dma_alloc; spinlock_t lock; unsigned long packet_read_count; unsigned long num_packets; @@ -89,7 +88,6 @@ static struct packet_data packet_data_head; static struct platform_device *rbu_device; static int context; -static dma_addr_t dell_rbu_dmaaddr; static void init_packet_head(void) { @@ -380,12 +378,8 @@ static void img_update_free(void) */ memset(rbu_data.image_update_buffer, 0, rbu_data.image_update_buffer_size); - if (rbu_data.dma_alloc == 1) - dma_free_coherent(NULL, rbu_data.bios_image_size, - rbu_data.image_update_buffer, dell_rbu_dmaaddr); - else - free_pages((unsigned long) rbu_data.image_update_buffer, - rbu_data.image_update_ordernum); + free_pages((unsigned long) rbu_data.image_update_buffer, + rbu_data.image_update_ordernum); /* * Re-initialize the rbu_data variables after a free @@ -394,7 +388,6 @@ static void img_update_free(void) rbu_data.image_update_buffer = NULL; rbu_data.image_update_buffer_size = 0; rbu_data.bios_image_size = 0; - rbu_data.dma_alloc = 0; } /* @@ -410,10 +403,8 @@ static void img_update_free(void) static int img_update_realloc(unsigned long size) { unsigned char *image_update_buffer = NULL; - unsigned long rc; unsigned long img_buf_phys_addr; int ordernum; - int dma_alloc = 0; /* * check if the buffer of sufficient size has been @@ -444,36 +435,23 @@ static int img_update_realloc(unsigned long size) ordernum = get_order(size); image_update_buffer = - (unsigned char *) __get_free_pages(GFP_KERNEL, ordernum); - - img_buf_phys_addr = - (unsigned long) virt_to_phys(image_update_buffer); - - if (img_buf_phys_addr > BIOS_SCAN_LIMIT) { - free_pages((unsigned long) image_update_buffer, ordernum); - ordernum = -1; - image_update_buffer = dma_alloc_coherent(NULL, size, - &dell_rbu_dmaaddr, GFP_KERNEL); - dma_alloc = 1; - } - - spin_lock(&rbu_data.lock); - - if (image_update_buffer != NULL) { - rbu_data.image_update_buffer = image_update_buffer; - rbu_data.image_update_buffer_size = size; - rbu_data.bios_image_size = - rbu_data.image_update_buffer_size; - rbu_data.image_update_ordernum = ordernum; - rbu_data.dma_alloc = dma_alloc; - rc = 0; - } else { + (unsigned char *)__get_free_pages(GFP_DMA32, ordernum); + if (!image_update_buffer) { pr_debug("Not enough memory for image update:" "size = %ld\n", size); - rc = -ENOMEM; + return -ENOMEM; } - return rc; + img_buf_phys_addr = (unsigned long)virt_to_phys(image_update_buffer); + if (WARN_ON_ONCE(img_buf_phys_addr > BIOS_SCAN_LIMIT)) + return -EINVAL; /* can't happen per definition */ + + spin_lock(&rbu_data.lock); + rbu_data.image_update_buffer = image_update_buffer; + rbu_data.image_update_buffer_size = size; + rbu_data.bios_image_size = rbu_data.image_update_buffer_size; + rbu_data.image_update_ordernum = ordernum; + return 0; } static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) |