diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 18:50:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 18:50:03 +0000 |
commit | 01a69402cf9d38ff180345d55c2ee51c7e89fbc7 (patch) | |
tree | b406c5242a088c4f59c6e4b719b783f43aca6ae9 /drivers/platform/chrome | |
parent | Adding upstream version 6.7.12. (diff) | |
download | linux-01a69402cf9d38ff180345d55c2ee51c7e89fbc7.tar.xz linux-01a69402cf9d38ff180345d55c2ee51c7e89fbc7.zip |
Adding upstream version 6.8.9.upstream/6.8.9
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/platform/chrome')
-rw-r--r-- | drivers/platform/chrome/cros_ec_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_ishtp.c | 74 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_sensorhub_ring.c | 74 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_uart.c | 33 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_vbc.c | 12 | ||||
-rw-r--r-- | drivers/platform/chrome/wilco_ec/event.c | 4 | ||||
-rw-r--r-- | drivers/platform/chrome/wilco_ec/telemetry.c | 6 |
7 files changed, 96 insertions, 109 deletions
diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c index 091fdc154d..6bf6f0e7b5 100644 --- a/drivers/platform/chrome/cros_ec_debugfs.c +++ b/drivers/platform/chrome/cros_ec_debugfs.c @@ -454,7 +454,7 @@ static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info) debug_info->panicinfo_blob.data = data; debug_info->panicinfo_blob.size = ret; - debugfs_create_blob("panicinfo", S_IFREG | 0444, debug_info->dir, + debugfs_create_blob("panicinfo", 0444, debug_info->dir, &debug_info->panicinfo_blob); return 0; diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c index cb2031cf71..5ac37bd024 100644 --- a/drivers/platform/chrome/cros_ec_ishtp.c +++ b/drivers/platform/chrome/cros_ec_ishtp.c @@ -367,55 +367,33 @@ static void ish_event_cb(struct ishtp_cl_device *cl_device) /** * cros_ish_init() - Init function for ISHTP client * @cros_ish_cl: ISHTP client instance + * @reset: true if called from reset handler * * This function complete the initializtion of the client. * * Return: 0 for success, negative error code for failure. */ -static int cros_ish_init(struct ishtp_cl *cros_ish_cl) +static int cros_ish_init(struct ishtp_cl *cros_ish_cl, bool reset) { int rv; - struct ishtp_device *dev; - struct ishtp_fw_client *fw_client; struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl); - rv = ishtp_cl_link(cros_ish_cl); - if (rv) { - dev_err(cl_data_to_dev(client_data), - "ishtp_cl_link failed\n"); - return rv; - } - - dev = ishtp_get_ishtp_device(cros_ish_cl); - - /* Connect to firmware client */ - ishtp_set_tx_ring_size(cros_ish_cl, CROS_ISH_CL_TX_RING_SIZE); - ishtp_set_rx_ring_size(cros_ish_cl, CROS_ISH_CL_RX_RING_SIZE); - - fw_client = ishtp_fw_cl_get_client(dev, &cros_ec_ishtp_id_table[0].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(cros_ish_cl, - ishtp_get_fw_client_id(fw_client)); - ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_CONNECTING); - - rv = ishtp_cl_connect(cros_ish_cl); + rv = ishtp_cl_establish_connection(cros_ish_cl, + &cros_ec_ishtp_id_table[0].guid, + CROS_ISH_CL_TX_RING_SIZE, + CROS_ISH_CL_RX_RING_SIZE, + reset); if (rv) { dev_err(cl_data_to_dev(client_data), "client connect fail\n"); - goto err_cl_unlink; + goto err_cl_disconnect; } ishtp_register_event_cb(client_data->cl_device, ish_event_cb); return 0; -err_cl_unlink: - ishtp_cl_unlink(cros_ish_cl); +err_cl_disconnect: + ishtp_cl_destroy_connection(cros_ish_cl, reset); return rv; } @@ -427,10 +405,7 @@ err_cl_unlink: */ static void cros_ish_deinit(struct ishtp_cl *cros_ish_cl) { - ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_DISCONNECTING); - ishtp_cl_disconnect(cros_ish_cl); - ishtp_cl_unlink(cros_ish_cl); - ishtp_cl_flush_queues(cros_ish_cl); + ishtp_cl_destroy_connection(cros_ish_cl, false); /* Disband and free all Tx and Rx client-level rings */ ishtp_cl_free(cros_ish_cl); @@ -592,7 +567,6 @@ static void reset_handler(struct work_struct *work) int rv; struct device *dev; struct ishtp_cl *cros_ish_cl; - struct ishtp_cl_device *cl_device; struct ishtp_cl_data *client_data = container_of(work, struct ishtp_cl_data, work_ishtp_reset); @@ -600,26 +574,11 @@ static void reset_handler(struct work_struct *work) down_write(&init_lock); cros_ish_cl = client_data->cros_ish_cl; - cl_device = client_data->cl_device; - /* Unlink, flush queues & start again */ - ishtp_cl_unlink(cros_ish_cl); - ishtp_cl_flush_queues(cros_ish_cl); - ishtp_cl_free(cros_ish_cl); - - cros_ish_cl = ishtp_cl_allocate(cl_device); - if (!cros_ish_cl) { - up_write(&init_lock); - return; - } - - ishtp_set_drvdata(cl_device, cros_ish_cl); - ishtp_set_client_data(cros_ish_cl, client_data); - client_data->cros_ish_cl = cros_ish_cl; + ishtp_cl_destroy_connection(cros_ish_cl, true); - rv = cros_ish_init(cros_ish_cl); + rv = cros_ish_init(cros_ish_cl, true); if (rv) { - ishtp_cl_free(cros_ish_cl); dev_err(cl_data_to_dev(client_data), "Reset Failed\n"); up_write(&init_lock); return; @@ -672,7 +631,7 @@ static int cros_ec_ishtp_probe(struct ishtp_cl_device *cl_device) INIT_WORK(&client_data->work_ec_evt, ish_evt_handler); - rv = cros_ish_init(cros_ish_cl); + rv = cros_ish_init(cros_ish_cl, false); if (rv) goto end_ishtp_cl_init_error; @@ -690,10 +649,7 @@ static int cros_ec_ishtp_probe(struct ishtp_cl_device *cl_device) return 0; end_cros_ec_dev_init_error: - ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_DISCONNECTING); - ishtp_cl_disconnect(cros_ish_cl); - ishtp_cl_unlink(cros_ish_cl); - ishtp_cl_flush_queues(cros_ish_cl); + ishtp_cl_destroy_connection(cros_ish_cl, false); ishtp_put_device(cl_device); end_ishtp_cl_init_error: ishtp_cl_free(cros_ish_cl); diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c index 71948dade0..1205219515 100644 --- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c +++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c @@ -103,7 +103,7 @@ EXPORT_SYMBOL_GPL(cros_ec_sensorhub_unregister_push_data); * @sensorhub: Sensor Hub object * @on: true when events are requested. * - * To be called before sleeping or when noone is listening. + * To be called before sleeping or when no one is listening. * Return: 0 on success, or an error when we can not communicate with the EC. * */ @@ -133,33 +133,61 @@ int cros_ec_sensorhub_ring_fifo_enable(struct cros_ec_sensorhub *sensorhub, return ret; } -static int cros_ec_sensor_ring_median_cmp(const void *pv1, const void *pv2) +static void cros_ec_sensor_ring_median_swap(s64 *a, s64 *b) { - s64 v1 = *(s64 *)pv1; - s64 v2 = *(s64 *)pv2; - - if (v1 > v2) - return 1; - else if (v1 < v2) - return -1; - else - return 0; + s64 tmp = *a; + *a = *b; + *b = tmp; } /* * cros_ec_sensor_ring_median: Gets median of an array of numbers * - * For now it's implemented using an inefficient > O(n) sort then return - * the middle element. A more optimal method would be something like - * quickselect, but given that n = 64 we can probably live with it in the - * name of clarity. + * It's implemented using the quickselect algorithm, which achieves an + * average time complexity of O(n) the middle element. In the worst case, + * the runtime of quickselect could regress to O(n^2). To mitigate this, + * algorithms like median-of-medians exist, which can guarantee O(n) even + * in the worst case. However, these algorithms come with a higher + * overhead and are more complex to implement, making quickselect a + * pragmatic choice for our use case. * - * Warning: the input array gets modified (sorted)! + * Warning: the input array gets modified! */ static s64 cros_ec_sensor_ring_median(s64 *array, size_t length) { - sort(array, length, sizeof(s64), cros_ec_sensor_ring_median_cmp, NULL); - return array[length / 2]; + int lo = 0; + int hi = length - 1; + + while (lo <= hi) { + int mid = lo + (hi - lo) / 2; + int pivot, i; + + if (array[lo] > array[mid]) + cros_ec_sensor_ring_median_swap(&array[lo], &array[mid]); + if (array[lo] > array[hi]) + cros_ec_sensor_ring_median_swap(&array[lo], &array[hi]); + if (array[mid] < array[hi]) + cros_ec_sensor_ring_median_swap(&array[mid], &array[hi]); + + pivot = array[hi]; + i = lo - 1; + + for (int j = lo; j < hi; j++) + if (array[j] < pivot) + cros_ec_sensor_ring_median_swap(&array[++i], &array[j]); + + /* The pivot's index corresponds to i+1. */ + cros_ec_sensor_ring_median_swap(&array[i + 1], &array[hi]); + if (i + 1 == length / 2) + return array[i + 1]; + if (i + 1 > length / 2) + hi = i; + else + lo = i + 2; + } + + /* Should never reach here. */ + return -1; } /* @@ -175,8 +203,8 @@ static s64 cros_ec_sensor_ring_median(s64 *array, size_t length) * * While a and b are recorded at accurate times (due to the EC real time * nature); c is pretty untrustworthy, even though it's recorded the - * first thing in ec_irq_handler(). There is a very good change we'll get - * added lantency due to: + * first thing in ec_irq_handler(). There is a very good chance we'll get + * added latency due to: * other irqs * ddrfreq * cpuidle @@ -511,7 +539,7 @@ cros_ec_sensor_ring_process_event(struct cros_ec_sensorhub *sensorhub, * ringbuffer. * * This is the new spreading code, assumes every sample's timestamp - * preceeds the sample. Run if tight_timestamps == true. + * precedes the sample. Run if tight_timestamps == true. * * Sometimes the EC receives only one interrupt (hence timestamp) for * a batch of samples. Only the first sample will have the correct @@ -595,7 +623,7 @@ cros_ec_sensor_ring_spread_add(struct cros_ec_sensorhub *sensorhub, } else { /* * Push first sample in the batch to the, - * kifo, it's guaranteed to be correct, the + * kfifo, it's guaranteed to be correct, the * rest will follow later on. */ sample_idx = 1; @@ -701,7 +729,7 @@ done_with_this_batch: * last_out --> * * - * We spread time for the samples using perod p = (current - TS1)/4. + * We spread time for the samples using period p = (current - TS1)/4. * between TS1 and TS2: [TS1+p/4, TS1+2p/4, TS1+3p/4, current_timestamp]. * */ diff --git a/drivers/platform/chrome/cros_ec_uart.c b/drivers/platform/chrome/cros_ec_uart.c index 788246559b..eb5eddeb73 100644 --- a/drivers/platform/chrome/cros_ec_uart.c +++ b/drivers/platform/chrome/cros_ec_uart.c @@ -81,9 +81,8 @@ struct cros_ec_uart { struct response_info response; }; -static int cros_ec_uart_rx_bytes(struct serdev_device *serdev, - const u8 *data, - size_t count) +static ssize_t cros_ec_uart_rx_bytes(struct serdev_device *serdev, + const u8 *data, size_t count) { struct ec_host_response *host_response; struct cros_ec_device *ec_dev = serdev_device_get_drvdata(serdev); @@ -264,12 +263,6 @@ static int cros_ec_uart_probe(struct serdev_device *serdev) if (!ec_dev) return -ENOMEM; - ret = devm_serdev_device_open(dev, serdev); - if (ret) { - dev_err(dev, "Unable to open UART device"); - return ret; - } - serdev_device_set_drvdata(serdev, ec_dev); init_waitqueue_head(&ec_uart->response.wait_queue); @@ -281,14 +274,6 @@ static int cros_ec_uart_probe(struct serdev_device *serdev) return ret; } - ret = serdev_device_set_baudrate(serdev, ec_uart->baudrate); - if (ret < 0) { - dev_err(dev, "Failed to set up host baud rate (%d)", ret); - return ret; - } - - serdev_device_set_flow_control(serdev, ec_uart->flowcontrol); - /* Initialize ec_dev for cros_ec */ ec_dev->phys_name = dev_name(dev); ec_dev->dev = dev; @@ -302,6 +287,20 @@ static int cros_ec_uart_probe(struct serdev_device *serdev) serdev_device_set_client_ops(serdev, &cros_ec_uart_client_ops); + ret = devm_serdev_device_open(dev, serdev); + if (ret) { + dev_err(dev, "Unable to open UART device"); + return ret; + } + + ret = serdev_device_set_baudrate(serdev, ec_uart->baudrate); + if (ret < 0) { + dev_err(dev, "Failed to set up host baud rate (%d)", ret); + return ret; + } + + serdev_device_set_flow_control(serdev, ec_uart->flowcontrol); + return cros_ec_register(ec_dev); } diff --git a/drivers/platform/chrome/cros_ec_vbc.c b/drivers/platform/chrome/cros_ec_vbc.c index 2e4af10c76..274ea0c64b 100644 --- a/drivers/platform/chrome/cros_ec_vbc.c +++ b/drivers/platform/chrome/cros_ec_vbc.c @@ -20,10 +20,14 @@ static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct cros_ec_dev *ec = to_cros_ec_dev(dev); struct cros_ec_device *ecdev = ec->ec_dev; - struct ec_params_vbnvcontext *params; struct cros_ec_command *msg; + /* + * This should be a pointer to the same type as op field in + * struct ec_params_vbnvcontext. + */ + uint32_t *params_op; int err; - const size_t para_sz = sizeof(params->op); + const size_t para_sz = sizeof(*params_op); const size_t resp_sz = sizeof(struct ec_response_vbnvcontext); const size_t payload = max(para_sz, resp_sz); @@ -32,8 +36,8 @@ static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, return -ENOMEM; /* NB: we only kmalloc()ated enough space for the op field */ - params = (struct ec_params_vbnvcontext *)msg->data; - params->op = EC_VBNV_CONTEXT_OP_READ; + params_op = (uint32_t *)msg->data; + *params_op = EC_VBNV_CONTEXT_OP_READ; msg->version = EC_VER_VBNV_CONTEXT; msg->command = EC_CMD_VBNV_CONTEXT; diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c index f80a7c83cf..13291fb421 100644 --- a/drivers/platform/chrome/wilco_ec/event.c +++ b/drivers/platform/chrome/wilco_ec/event.c @@ -495,7 +495,7 @@ static int event_device_add(struct acpi_device *adev) free_dev_data: hangup_device(dev_data); free_minor: - ida_simple_remove(&event_ida, minor); + ida_free(&event_ida, minor); return error; } @@ -504,7 +504,7 @@ static void event_device_remove(struct acpi_device *adev) struct event_device_data *dev_data = adev->driver_data; cdev_device_del(&dev_data->cdev, &dev_data->dev); - ida_simple_remove(&event_ida, MINOR(dev_data->dev.devt)); + ida_free(&event_ida, MINOR(dev_data->dev.devt)); hangup_device(dev_data); } diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c b/drivers/platform/chrome/wilco_ec/telemetry.c index 253098bace..b7c616f3d1 100644 --- a/drivers/platform/chrome/wilco_ec/telemetry.c +++ b/drivers/platform/chrome/wilco_ec/telemetry.c @@ -372,7 +372,7 @@ static int telem_device_probe(struct platform_device *pdev) dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); if (!dev_data) { - ida_simple_remove(&telem_ida, minor); + ida_free(&telem_ida, minor); return -ENOMEM; } @@ -393,7 +393,7 @@ static int telem_device_probe(struct platform_device *pdev) error = cdev_device_add(&dev_data->cdev, &dev_data->dev); if (error) { put_device(&dev_data->dev); - ida_simple_remove(&telem_ida, minor); + ida_free(&telem_ida, minor); return error; } @@ -405,7 +405,7 @@ static void telem_device_remove(struct platform_device *pdev) struct telem_device_data *dev_data = platform_get_drvdata(pdev); cdev_device_del(&dev_data->cdev, &dev_data->dev); - ida_simple_remove(&telem_ida, MINOR(dev_data->dev.devt)); + ida_free(&telem_ida, MINOR(dev_data->dev.devt)); put_device(&dev_data->dev); } |