Re: [PATCH v4 2/5] platform: arm64: Add driver for EC found on Qualcomm reference devices
From: Anvesh Jain P
Date: Mon Mar 16 2026 - 05:44:00 EST
On 3/14/2026 12:35 AM, Krzysztof Kozlowski wrote:
> On 13/03/2026 11:29, Anvesh Jain P wrote:
>> +
>> +static irqreturn_t qcom_ec_irq(int irq, void *data)
>> +{
>> + struct qcom_ec *ec = data;
>> + struct device *dev = &ec->client->dev;
>> + int val;
>> +
>> + val = i2c_smbus_read_byte_data(ec->client, EC_SCI_EVT_READ_CMD);
>> + if (val < 0) {
>> + dev_err(dev, "Failed to read EC SCI Event: %d\n", val);
>
> ratelimit
>
>> + return IRQ_HANDLED;
>> + }
>> +
>> + switch (val) {
>> + case EC_FAN1_STATUS_CHANGE_EVT:
>> + dev_dbg(dev, "Fan1 status changed\n");
>
> ratelimit everywhere further. You are in interrupt handler so imagine
> same interrupt keep happening because of constant overheat.
>
Agreed. I will switch to dev_err_ratelimited() and dev_dbg_ratelimited()
throughout the IRQ handler to prevent log spam during potential
interrupt storms.
>> + break;
>> + case EC_FAN2_STATUS_CHANGE_EVT:
>> + dev_dbg(dev, "Fan2 status changed\n");
>> + break;
>> + case EC_FAN1_SPEED_CHANGE_EVT:
>> + dev_dbg(dev, "Fan1 speed crossed low/high trip point\n");
>> + break;
>> + case EC_FAN2_SPEED_CHANGE_EVT:
>> + dev_dbg(dev, "Fan2 speed crossed low/high trip point\n");
>> + break;
>> + case EC_NEW_LUT_SET_EVT:
>> + dev_dbg(dev, "New LUT set\n");
>> + break;
>> + case EC_FAN_PROFILE_SWITCH_EVT:
>> + dev_dbg(dev, "FAN Profile switched\n");
>> + break;
>> + case EC_THERMISTOR_1_THRESHOLD_CROSS_EVT:
>> + dev_dbg(dev, "Thermistor 1 threshold crossed\n");
>> + break;
>> + case EC_THERMISTOR_2_THRESHOLD_CROSS_EVT:
>> + dev_dbg(dev, "Thermistor 2 threshold crossed\n");
>> + break;
>> + case EC_THERMISTOR_3_THRESHOLD_CROSS_EVT:
>> + dev_dbg(dev, "Thermistor 3 threshold crossed\n");
>> + break;
>> + case EC_RECOVERED_FROM_RESET_EVT:
>> + dev_dbg(dev, "EC recovered from reset\n");
>> + break;
>> + default:
>> + dev_dbg(dev, "Unknown EC event: %d\n", val);
>> + break;
>> + }
>> +
>
>
> ...
>
>> +
>> + ret = devm_request_threaded_irq(dev, client->irq, NULL, qcom_ec_irq,
>> + IRQF_ONESHOT, "qcom_ec", ec);
>> + if (ret < 0)
>> + return dev_err_probe(dev, ret, "Failed to get irq\n");
>
> No need for message, just return ret.
>
Will do. I'll drop the message and just return ret.
>> +
>> + i2c_set_clientdata(client, ec);
>> +
>> + ret = qcom_ec_read_fw_version(dev);
>> + if (ret < 0)
>> + return dev_err_probe(dev, ret, "Failed to read ec firmware version\n");
>> +
>> + ret = qcom_ec_thermal_capabilities(dev);
>> + if (ret < 0)
>> + return dev_err_probe(dev, ret, "Failed to read thermal capabilities\n");
>> +
>> + ret = qcom_ec_sci_evt_control(dev, true);
>> + if (ret < 0)
>> + return dev_err_probe(dev, ret, "Failed to enable SCI events\n");
>> +
>> + ec->ec_cdev = devm_kcalloc(dev, ec->thermal_cap.fan_cnt, sizeof(*ec->ec_cdev), GFP_KERNEL);
>> + if (!ec->ec_cdev)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < ec->thermal_cap.fan_cnt; i++) {
>> + struct qcom_ec_cooling_dev *ec_cdev = &ec->ec_cdev[i];
>> + char name[EC_FAN_NAME_SIZE];
>> +
>> + snprintf(name, EC_FAN_NAME_SIZE, "qcom_ec_fan_%d", i);
>> + ec_cdev->fan_id = i + 1;
>> + ec_cdev->parent_dev = dev;
>> +
>> + ec_cdev->cdev = thermal_cooling_device_register(name, ec_cdev,
>> + &qcom_ec_thermal_ops);
>> + if (IS_ERR(ec_cdev->cdev)) {
>> + dev_err_probe(dev, PTR_ERR(cdev),
>> + "Thermal cooling device registration failed\n");
>> + ret = -EINVAL;
>
> Why do you override actual return code?
>
I'll fix this to propagate the actual error code.
>> + goto unroll_cooling_dev;
>> + }
>> + }
>> +
>> + return 0;
>> +
>> +unroll_cooling_dev:
>> + for (i--; i >= 0; i--) {
>> + struct qcom_ec_cooling_dev *ec_cdev = &ec->ec_cdev[i];
>> +
>> + if (ec_cdev->cdev) {
>> + thermal_cooling_device_unregister(ec_cdev->cdev);
>> + ec_cdev->cdev = NULL;
>> + }
>> + }
>> +
>> + return ret;
>> +}
>
>
> Best regards,
> Krzysztof
Thanks for the review.
--
Best Regards,
Anvesh