summaryrefslogtreecommitdiff
path: root/drivers/hid/intel-ish-hid/ishtp-fw-loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/intel-ish-hid/ishtp-fw-loader.c')
-rw-r--r--drivers/hid/intel-ish-hid/ishtp-fw-loader.c159
1 files changed, 51 insertions, 108 deletions
diff --git a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c
index 6cf59fd26ad7..f4a671d6386c 100644
--- a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c
+++ b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c
@@ -31,13 +31,13 @@
/**
* enum ish_loader_commands - ISH loader host commands.
- * LOADER_CMD_XFER_QUERY Query the Shim firmware loader for
+ * @LOADER_CMD_XFER_QUERY: Query the Shim firmware loader for
* capabilities
- * LOADER_CMD_XFER_FRAGMENT Transfer one firmware image fragment at a
+ * @LOADER_CMD_XFER_FRAGMENT: Transfer one firmware image fragment at a
* time. The command may be executed
* multiple times until the entire firmware
* image is downloaded to SRAM.
- * LOADER_CMD_START Start executing the main firmware.
+ * @LOADER_CMD_START: Start executing the main firmware.
*/
enum ish_loader_commands {
LOADER_CMD_XFER_QUERY = 0,
@@ -76,9 +76,12 @@ enum ish_loader_commands {
#define LOADER_XFER_MODE_ISHTP BIT(1)
/* ISH Transport Loader client unique GUID */
-static const guid_t loader_ishtp_guid =
- GUID_INIT(0xc804d06a, 0x55bd, 0x4ea7,
- 0xad, 0xed, 0x1e, 0x31, 0x22, 0x8c, 0x76, 0xdc);
+static const struct ishtp_device_id loader_ishtp_id_table[] = {
+ { .guid = GUID_INIT(0xc804d06a, 0x55bd, 0x4ea7,
+ 0xad, 0xed, 0x1e, 0x31, 0x22, 0x8c, 0x76, 0xdc) },
+ { }
+};
+MODULE_DEVICE_TABLE(ishtp, loader_ishtp_id_table);
#define FILENAME_SIZE 256
@@ -95,6 +98,7 @@ static int dma_buf_size_limit = 4 * PAGE_SIZE;
/**
* struct loader_msg_hdr - Header for ISH Loader commands.
* @command: LOADER_CMD* commands. Bit 7 is the response.
+ * @reserved: Reserved space
* @status: Command response status. Non 0, is error
* condition.
*
@@ -173,16 +177,16 @@ struct loader_start {
* struct response_info - Encapsulate firmware response related
* information for passing between function
* loader_cl_send() and process_recv() callback.
- * @data Copy the data received from firmware here.
- * @max_size Max size allocated for the @data buffer. If the
+ * @data: Copy the data received from firmware here.
+ * @max_size: Max size allocated for the @data buffer. If the
* received data exceeds this value, we log an
* error.
- * @size Actual size of data received from firmware.
- * @error Returns 0 for success, negative error code for a
+ * @size: Actual size of data received from firmware.
+ * @error: Returns 0 for success, negative error code for a
* failure in function process_recv().
- * @received Set to true on receiving a valid firmware
+ * @received: Set to true on receiving a valid firmware
* response to host command
- * @wait_queue Wait queue for Host firmware loading where the
+ * @wait_queue: Wait queue for Host firmware loading where the
* client sends message to ISH firmware and waits
* for response
*/
@@ -195,13 +199,13 @@ struct response_info {
wait_queue_head_t wait_queue;
};
-/**
+/*
* struct ishtp_cl_data - Encapsulate per ISH-TP Client Data.
* @work_ishtp_reset: Work queue for reset handling.
* @work_fw_load: Work queue for host firmware loading.
- * @flag_retry Flag for indicating host firmware loading should
+ * @flag_retry: Flag for indicating host firmware loading should
* be retried.
- * @retry_count Count the number of retries.
+ * @retry_count: Count the number of retries.
*
* This structure is used to store data per client.
*/
@@ -240,8 +244,8 @@ struct ishtp_cl_data {
/**
* get_firmware_variant() - Gets the filename of firmware image to be
* loaded based on platform variant.
- * @client_data Client data instance.
- * @filename Returns firmware filename.
+ * @client_data: Client data instance.
+ * @filename: Returns firmware filename.
*
* Queries the firmware-name device property string.
*
@@ -264,13 +268,14 @@ static int get_firmware_variant(struct ishtp_cl_data *client_data,
}
/**
- * loader_cl_send() Send message from host to firmware
+ * loader_cl_send() - Send message from host to firmware
+ *
* @client_data: Client data instance
- * @out_msg Message buffer to be sent to firmware
- * @out_size Size of out going message
- * @in_msg Message buffer where the incoming data copied.
+ * @out_msg: Message buffer to be sent to firmware
+ * @out_size: Size of out going message
+ * @in_msg: Message buffer where the incoming data copied.
* This buffer is allocated by calling
- * @in_size Max size of incoming message
+ * @in_size: Max size of incoming message
*
* Return: Number of bytes copied in the in_msg on success, negative
* error code on failure.
@@ -435,7 +440,7 @@ end:
/**
* loader_cl_event_cb() - bus driver callback for incoming message
- * @device: Pointer to the ishtp client device for which this
+ * @cl_device: Pointer to the ishtp client device for which this
* message is targeted
*
* Remove the packet from the list and process the message by calling
@@ -455,7 +460,7 @@ static void loader_cl_event_cb(struct ishtp_cl_device *cl_device)
/**
* ish_query_loader_prop() - Query ISH Shim firmware loader
* @client_data: Client data instance
- * @fw: Poiner to firmware data struct in host memory
+ * @fw: Pointer to firmware data struct in host memory
* @fw_info: Loader firmware properties
*
* This function queries the ISH Shim firmware loader for capabilities.
@@ -536,7 +541,7 @@ static int ish_query_loader_prop(struct ishtp_cl_data *client_data,
}
/**
- * ish_fw_xfer_ishtp() Loads ISH firmware using ishtp interface
+ * ish_fw_xfer_ishtp() - Loads ISH firmware using ishtp interface
* @client_data: Client data instance
* @fw: Pointer to firmware data struct in host memory
*
@@ -630,7 +635,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data,
const struct firmware *fw,
const struct shim_fw_info fw_info)
{
- int rv;
+ int rv = 0;
void *dma_buf;
dma_addr_t dma_buf_phy;
u32 fragment_offset, fragment_size, payload_max_size;
@@ -656,21 +661,12 @@ 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_coherent(devc, payload_max_size, &dma_buf_phy, GFP_KERNEL);
if (!dma_buf) {
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;
@@ -690,14 +686,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data,
ldr_xfer_dma_frag.fragment.size = fragment_size;
memcpy(dma_buf, &fw->data[fragment_offset], fragment_size);
- dma_sync_single_for_device(devc, dma_buf_phy,
- payload_max_size,
- DMA_TO_DEVICE);
-
- /*
- * Flush cache here because the dma_sync_single_for_device()
- * does not do for x86.
- */
+ /* Flush cache to be sure the data is in main memory. */
clflush_cache_range(dma_buf, payload_max_size);
dev_dbg(cl_data_to_dev(client_data),
@@ -720,20 +709,13 @@ 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);
- 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_coherent(devc, payload_max_size, dma_buf, dma_buf_phy);
return rv;
}
/**
- * ish_fw_start() Start executing ISH main firmware
+ * ish_fw_start() - Start executing ISH main firmware
* @client_data: client data instance
*
* This function sends message to Shim firmware loader to start
@@ -756,7 +738,7 @@ static int ish_fw_start(struct ishtp_cl_data *client_data)
}
/**
- * load_fw_from_host() Loads ISH firmware from host
+ * load_fw_from_host() - Loads ISH firmware from host
* @client_data: Client data instance
*
* This function loads the ISH firmware to ISH SRAM and starts execution
@@ -811,7 +793,7 @@ static int load_fw_from_host(struct ishtp_cl_data *client_data)
if (rv < 0)
goto end_err_fw_release;
- /* Step 3: Start ISH main firmware exeuction */
+ /* Step 3: Start ISH main firmware execution */
rv = ish_fw_start(client_data);
if (rv < 0)
@@ -858,43 +840,22 @@ static void load_fw_from_host_handler(struct work_struct *work)
*
* Return: 0 for success, negative error code for failure
*/
-static int loader_init(struct ishtp_cl *loader_ishtp_cl, int reset)
+static int loader_init(struct ishtp_cl *loader_ishtp_cl, bool reset)
{
int rv;
- struct ishtp_fw_client *fw_client;
struct ishtp_cl_data *client_data =
ishtp_get_client_data(loader_ishtp_cl);
dev_dbg(cl_data_to_dev(client_data), "reset flag: %d\n", reset);
- rv = ishtp_cl_link(loader_ishtp_cl);
- if (rv < 0) {
- dev_err(cl_data_to_dev(client_data), "ishtp_cl_link failed\n");
- return rv;
- }
-
- /* Connect to firmware client */
- ishtp_set_tx_ring_size(loader_ishtp_cl, LOADER_CL_TX_RING_SIZE);
- ishtp_set_rx_ring_size(loader_ishtp_cl, LOADER_CL_RX_RING_SIZE);
-
- fw_client =
- ishtp_fw_cl_get_client(ishtp_get_ishtp_device(loader_ishtp_cl),
- &loader_ishtp_guid);
- if (!fw_client) {
- dev_err(cl_data_to_dev(client_data),
- "ISH client uuid not found\n");
- rv = -ENOENT;
- goto err_cl_unlink;
- }
-
- ishtp_cl_set_fw_client_id(loader_ishtp_cl,
- ishtp_get_fw_client_id(fw_client));
- ishtp_set_connection_state(loader_ishtp_cl, ISHTP_CL_CONNECTING);
-
- rv = ishtp_cl_connect(loader_ishtp_cl);
+ rv = ishtp_cl_establish_connection(loader_ishtp_cl,
+ &loader_ishtp_id_table[0].guid,
+ LOADER_CL_TX_RING_SIZE,
+ LOADER_CL_RX_RING_SIZE,
+ reset);
if (rv < 0) {
dev_err(cl_data_to_dev(client_data), "Client connect fail\n");
- goto err_cl_unlink;
+ goto err_cl_disconnect;
}
dev_dbg(cl_data_to_dev(client_data), "Client connected\n");
@@ -903,17 +864,14 @@ static int loader_init(struct ishtp_cl *loader_ishtp_cl, int reset)
return 0;
-err_cl_unlink:
- ishtp_cl_unlink(loader_ishtp_cl);
+err_cl_disconnect:
+ ishtp_cl_destroy_connection(loader_ishtp_cl, reset);
return rv;
}
static void loader_deinit(struct ishtp_cl *loader_ishtp_cl)
{
- ishtp_set_connection_state(loader_ishtp_cl, ISHTP_CL_DISCONNECTING);
- ishtp_cl_disconnect(loader_ishtp_cl);
- ishtp_cl_unlink(loader_ishtp_cl);
- ishtp_cl_flush_queues(loader_ishtp_cl);
+ ishtp_cl_destroy_connection(loader_ishtp_cl, false);
/* Disband and free all Tx and Rx client-level rings */
ishtp_cl_free(loader_ishtp_cl);
@@ -932,19 +890,7 @@ static void reset_handler(struct work_struct *work)
loader_ishtp_cl = client_data->loader_ishtp_cl;
cl_device = client_data->cl_device;
- /* Unlink, flush queues & start again */
- ishtp_cl_unlink(loader_ishtp_cl);
- ishtp_cl_flush_queues(loader_ishtp_cl);
- ishtp_cl_free(loader_ishtp_cl);
-
- loader_ishtp_cl = ishtp_cl_allocate(cl_device);
- if (!loader_ishtp_cl)
- return;
-
- ishtp_set_drvdata(cl_device, loader_ishtp_cl);
- ishtp_set_client_data(loader_ishtp_cl, client_data);
- client_data->loader_ishtp_cl = loader_ishtp_cl;
- client_data->cl_device = cl_device;
+ ishtp_cl_destroy_connection(loader_ishtp_cl, true);
rv = loader_init(loader_ishtp_cl, 1);
if (rv < 0) {
@@ -992,7 +938,7 @@ static int loader_ishtp_cl_probe(struct ishtp_cl_device *cl_device)
INIT_WORK(&client_data->work_fw_load,
load_fw_from_host_handler);
- rv = loader_init(loader_ishtp_cl, 0);
+ rv = loader_init(loader_ishtp_cl, false);
if (rv < 0) {
ishtp_cl_free(loader_ishtp_cl);
return rv;
@@ -1015,7 +961,7 @@ static int loader_ishtp_cl_probe(struct ishtp_cl_device *cl_device)
*
* Return: 0
*/
-static int loader_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
+static void loader_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
{
struct ishtp_cl_data *client_data;
struct ishtp_cl *loader_ishtp_cl = ishtp_get_drvdata(cl_device);
@@ -1032,8 +978,6 @@ static int loader_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
cancel_work_sync(&client_data->work_ishtp_reset);
loader_deinit(loader_ishtp_cl);
ishtp_put_device(cl_device);
-
- return 0;
}
/**
@@ -1058,7 +1002,7 @@ static int loader_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
static struct ishtp_cl_driver loader_ishtp_cl_driver = {
.name = "ish-loader",
- .guid = &loader_ishtp_guid,
+ .id = loader_ishtp_id_table,
.probe = loader_ishtp_cl_probe,
.remove = loader_ishtp_cl_remove,
.reset = loader_ishtp_cl_reset,
@@ -1084,4 +1028,3 @@ MODULE_DESCRIPTION("ISH ISH-TP Host firmware Loader Client Driver");
MODULE_AUTHOR("Rushikesh S Kadam <rushikesh.s.kadam@intel.com>");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("ishtp:*");