GFP_DMA32 is an illegal flag to pass when calling kmalloc(), please see GFP_SLAB_BUG_MASK definition. Allocating dma buffer using kmalloc() is not recommended. Use dma_alloc_noncoherent() instead. DMA API will assume the device has 32 bit addressing limitation when allocating buffer. [ 42.hyeyoo@xxxxxxxxx: Use dma_alloc_noncoherent() instead of __get_free_pages ] Signed-off-by: Baoquan He <bhe@xxxxxxxxxx> Signed-off-by: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> Cc: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx> Cc: Jiri Kosina <jikos@xxxxxxxxxx> Cc: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx> Cc: Sumit Semwal <sumit.semwal@xxxxxxxxxx> Cc: christian.koenig@xxxxxxx Cc: linux-input@xxxxxxxxxxxxxxx --- drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 23 +++++++-------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c index e24988586710..3be1e3329962 100644 --- a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c +++ b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c @@ -661,21 +661,15 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, */ payload_max_size &= ~(L1_CACHE_BYTES - 1); - dma_buf = kmalloc(payload_max_size, GFP_KERNEL | GFP_DMA32); + dma_buf = dma_alloc_noncoherent(devc, get_order(payload_max_size), + &dma_buf_phy, DMA_TO_DEVICE, + GFP_KERNEL); if (!dma_buf) { + dev_err(cl_data_to_dev(client_data), "DMA alloc failed\n"); client_data->flag_retry = true; return -ENOMEM; } - dma_buf_phy = dma_map_single(devc, dma_buf, payload_max_size, - DMA_TO_DEVICE); - if (dma_mapping_error(devc, dma_buf_phy)) { - dev_err(cl_data_to_dev(client_data), "DMA map failed\n"); - client_data->flag_retry = true; - rv = -ENOMEM; - goto end_err_dma_buf_release; - } - ldr_xfer_dma_frag.fragment.hdr.command = LOADER_CMD_XFER_FRAGMENT; ldr_xfer_dma_frag.fragment.xfer_mode = LOADER_XFER_MODE_DIRECT_DMA; ldr_xfer_dma_frag.ddr_phys_addr = (u64)dma_buf_phy; @@ -725,15 +719,14 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, fragment_offset += fragment_size; } - dma_unmap_single(devc, dma_buf_phy, payload_max_size, DMA_TO_DEVICE); - kfree(dma_buf); + dma_free_noncoherent(devc, get_order(payload_max_size), dma_buf, + dma_buf_phy, DMA_TO_DEVICE); return 0; end_err_resp_buf_release: /* Free ISH buffer if not done already, in error case */ - dma_unmap_single(devc, dma_buf_phy, payload_max_size, DMA_TO_DEVICE); -end_err_dma_buf_release: - kfree(dma_buf); + dma_free_noncoherent(devc, get_order(payload_max_size), dma_buf, + dma_buf_phy, DMA_TO_DEVICE); return rv; } -- 2.17.2