From: Cosmo Chou <chou.cosmo@xxxxxxxxx> Implement GPIO-based alert mechanism in the SSIF BMC driver to notify the host when a response is ready. This improves host-BMC communication efficiency by providing immediate notification, potentially reducing host polling overhead. Signed-off-by: Cosmo Chou <chou.cosmo@xxxxxxxxx> --- drivers/char/ipmi/ssif_bmc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/char/ipmi/ssif_bmc.c b/drivers/char/ipmi/ssif_bmc.c index a14fafc583d4..73be166b0042 100644 --- a/drivers/char/ipmi/ssif_bmc.c +++ b/drivers/char/ipmi/ssif_bmc.c @@ -17,6 +17,7 @@ #include <linux/spinlock.h> #include <linux/timer.h> #include <linux/jiffies.h> +#include <linux/gpio/consumer.h> #include <linux/ipmi_ssif_bmc.h> #define DEVICE_NAME "ipmi-ssif-host" @@ -102,6 +103,7 @@ struct ssif_bmc_ctx { struct ssif_part_buffer part_buf; struct ipmi_ssif_msg response; struct ipmi_ssif_msg request; + struct gpio_desc *alert; }; static inline struct ssif_bmc_ctx *to_ssif_bmc(struct file *file) @@ -222,6 +224,9 @@ static ssize_t ssif_bmc_write(struct file *file, const char __user *buf, size_t /* Clean old request buffer */ memset(&ssif_bmc->request, 0, sizeof(struct ipmi_ssif_msg)); + + if (!IS_ERR(ssif_bmc->alert)) + gpiod_set_value(ssif_bmc->alert, 1); exit: spin_unlock_irqrestore(&ssif_bmc->lock, flags); @@ -584,6 +589,9 @@ static void process_smbus_cmd(struct ssif_bmc_ctx *ssif_bmc, u8 *val) memset(&ssif_bmc->part_buf.payload[0], 0, MAX_PAYLOAD_PER_TRANSACTION); if (*val == SSIF_IPMI_SINGLEPART_WRITE || *val == SSIF_IPMI_MULTIPART_WRITE_START) { + if (!IS_ERR(ssif_bmc->alert)) + gpiod_set_value(ssif_bmc->alert, 0); + /* * The response maybe not come in-time, causing host SSIF driver * to timeout and resend a new request. In such case check for @@ -640,6 +648,8 @@ static void on_read_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) calculate_response_part_pec(&ssif_bmc->part_buf); ssif_bmc->part_buf.index = 0; *val = ssif_bmc->part_buf.length; + if (!IS_ERR(ssif_bmc->alert)) + gpiod_set_value(ssif_bmc->alert, 0); } static void on_read_processed_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) @@ -808,6 +818,11 @@ static int ssif_bmc_probe(struct i2c_client *client) if (!ssif_bmc) return -ENOMEM; + /* Request GPIO for alerting the host that response is ready */ + ssif_bmc->alert = devm_gpiod_get(&client->dev, "alert", GPIOD_ASIS); + if (!IS_ERR(ssif_bmc->alert)) + gpiod_direction_output(ssif_bmc->alert, 0); + spin_lock_init(&ssif_bmc->lock); init_waitqueue_head(&ssif_bmc->wait_queue); -- 2.31.1