From: Alain Volmat <alain.volmat@st.com> To: <wsa@kernel.org>, <robh+dt@kernel.org> Cc: <mark.rutland@arm.com>, <pierre-yves.mordret@st.com>, <mcoquelin.stm32@gmail.com>, <alexandre.torgue@st.com>, <linux-i2c@vger.kernel.org>, <devicetree@vger.kernel.org>, <linux-stm32@st-md-mailman.stormreply.com>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org>, <fabrice.gasnier@st.com>, <alain.volmat@st.com> Subject: [PATCH v2 1/4] i2c: smbus: add core function handling SMBus host-notify Date: Thu, 25 Jun 2020 09:39:26 +0200 [thread overview] Message-ID: <1593070769-9106-2-git-send-email-alain.volmat@st.com> (raw) In-Reply-To: <1593070769-9106-1-git-send-email-alain.volmat@st.com> SMBus Host-Notify protocol, from the adapter point of view consist of receiving a message from a client, including the client address and some other data. It can be simply handled by creating a new slave device and registering a callback performing the parsing of the message received from the client. This commit introduces two new core functions * i2c_new_smbus_host_notify_device * i2c_free_smbus_host_notify_device that take care of registration of the new slave device and callback and will call i2c_handle_smbus_host_notify once a Host-Notify event is received. Signed-off-by: Alain Volmat <alain.volmat@st.com> --- v2: remove useless dev_err message in case of hnotify handling error prevent handling hnotify in case of a incomplete write drivers/i2c/i2c-core-smbus.c | 110 +++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c-smbus.h | 2 + 2 files changed, 112 insertions(+) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 56bb840142e3..3a37664fb5f6 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -708,3 +708,113 @@ int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter) } EXPORT_SYMBOL_GPL(of_i2c_setup_smbus_alert); #endif + +#if IS_ENABLED(CONFIG_I2C_SLAVE) +struct i2c_smbus_host_notify_status { + bool notify_start; + u8 addr; +}; + +static int i2c_smbus_host_notify_cb(struct i2c_client *client, + enum i2c_slave_event event, u8 *val) +{ + struct i2c_smbus_host_notify_status *status = client->dev.platform_data; + int ret; + + switch (event) { + case I2C_SLAVE_WRITE_REQUESTED: + status->notify_start = true; + break; + case I2C_SLAVE_WRITE_RECEIVED: + /* We only retrieve the first byte received (addr) + * since there is currently no support to retrieve the data + * parameter from the client. + */ + if (!status->notify_start) + break; + status->addr = *val; + status->notify_start = false; + break; + case I2C_SLAVE_STOP: + /* In case of incomplete write, don't handle host-notify */ + if (status->notify_start) { + status->notify_start = false; + break; + } + + ret = i2c_handle_smbus_host_notify(client->adapter, + status->addr); + if (ret < 0) + return ret; + break; + default: + /* Only handle necessary events */ + break; + } + + return 0; +} + +/** + * i2c_new_smbus_host_notify_device - get a client for SMBus host-notify support + * @adapter: the target adapter + * Context: can sleep + * + * Setup handling of the SMBus host-notify protocol on a given I2C bus segment. + * + * Handling is done by creating a device and its callback and handling data + * received via the SMBus host-notify address (0x8) + * + * This returns the client, which should be ultimately freed using + * i2c_free_smbus_host_notify_device(); or an ERRPTR to indicate an error. + */ +struct i2c_client *i2c_new_smbus_host_notify_device(struct i2c_adapter *adapter) +{ + struct i2c_board_info host_notify_board_info = { + I2C_BOARD_INFO("smbus_host_notify", 0x08), + .flags = I2C_CLIENT_SLAVE, + }; + struct i2c_smbus_host_notify_status *status; + struct i2c_client *client; + int ret; + + status = kzalloc(sizeof(struct i2c_smbus_host_notify_status), + GFP_KERNEL); + if (!status) + return ERR_PTR(-ENOMEM); + + host_notify_board_info.platform_data = status; + + client = i2c_new_client_device(adapter, &host_notify_board_info); + if (IS_ERR(client)) { + kfree(status); + return client; + } + + ret = i2c_slave_register(client, i2c_smbus_host_notify_cb); + if (ret) { + i2c_unregister_device(client); + kfree(status); + return ERR_PTR(ret); + } + + return client; +} +EXPORT_SYMBOL_GPL(i2c_new_smbus_host_notify_device); + +/** + * i2c_free_smbus_host_notify_device - free the client for SMBus host-notify + * support + * @client: the client to free + * Context: can sleep + * + * Free the i2c_client allocated via i2c_new_smbus_host_notify_device + */ +void i2c_free_smbus_host_notify_device(struct i2c_client *client) +{ + i2c_slave_unregister(client); + kfree(client->dev.platform_data); + i2c_unregister_device(client); +} +EXPORT_SYMBOL_GPL(i2c_free_smbus_host_notify_device); +#endif diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h index 1e4e0de4ef8b..974038a684ed 100644 --- a/include/linux/i2c-smbus.h +++ b/include/linux/i2c-smbus.h @@ -38,6 +38,8 @@ static inline int of_i2c_setup_smbus_alert(struct i2c_adapter *adap) return 0; } #endif +struct i2c_client *i2c_new_smbus_host_notify_device(struct i2c_adapter *adapter); +void i2c_free_smbus_host_notify_device(struct i2c_client *client); #if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_DMI) void i2c_register_spd(struct i2c_adapter *adap); -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Alain Volmat <alain.volmat@st.com> To: <wsa@kernel.org>, <robh+dt@kernel.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, alexandre.torgue@st.com, linux-kernel@vger.kernel.org, pierre-yves.mordret@st.com, alain.volmat@st.com, linux-i2c@vger.kernel.org, mcoquelin.stm32@gmail.com, fabrice.gasnier@st.com, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 1/4] i2c: smbus: add core function handling SMBus host-notify Date: Thu, 25 Jun 2020 09:39:26 +0200 [thread overview] Message-ID: <1593070769-9106-2-git-send-email-alain.volmat@st.com> (raw) In-Reply-To: <1593070769-9106-1-git-send-email-alain.volmat@st.com> SMBus Host-Notify protocol, from the adapter point of view consist of receiving a message from a client, including the client address and some other data. It can be simply handled by creating a new slave device and registering a callback performing the parsing of the message received from the client. This commit introduces two new core functions * i2c_new_smbus_host_notify_device * i2c_free_smbus_host_notify_device that take care of registration of the new slave device and callback and will call i2c_handle_smbus_host_notify once a Host-Notify event is received. Signed-off-by: Alain Volmat <alain.volmat@st.com> --- v2: remove useless dev_err message in case of hnotify handling error prevent handling hnotify in case of a incomplete write drivers/i2c/i2c-core-smbus.c | 110 +++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c-smbus.h | 2 + 2 files changed, 112 insertions(+) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 56bb840142e3..3a37664fb5f6 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -708,3 +708,113 @@ int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter) } EXPORT_SYMBOL_GPL(of_i2c_setup_smbus_alert); #endif + +#if IS_ENABLED(CONFIG_I2C_SLAVE) +struct i2c_smbus_host_notify_status { + bool notify_start; + u8 addr; +}; + +static int i2c_smbus_host_notify_cb(struct i2c_client *client, + enum i2c_slave_event event, u8 *val) +{ + struct i2c_smbus_host_notify_status *status = client->dev.platform_data; + int ret; + + switch (event) { + case I2C_SLAVE_WRITE_REQUESTED: + status->notify_start = true; + break; + case I2C_SLAVE_WRITE_RECEIVED: + /* We only retrieve the first byte received (addr) + * since there is currently no support to retrieve the data + * parameter from the client. + */ + if (!status->notify_start) + break; + status->addr = *val; + status->notify_start = false; + break; + case I2C_SLAVE_STOP: + /* In case of incomplete write, don't handle host-notify */ + if (status->notify_start) { + status->notify_start = false; + break; + } + + ret = i2c_handle_smbus_host_notify(client->adapter, + status->addr); + if (ret < 0) + return ret; + break; + default: + /* Only handle necessary events */ + break; + } + + return 0; +} + +/** + * i2c_new_smbus_host_notify_device - get a client for SMBus host-notify support + * @adapter: the target adapter + * Context: can sleep + * + * Setup handling of the SMBus host-notify protocol on a given I2C bus segment. + * + * Handling is done by creating a device and its callback and handling data + * received via the SMBus host-notify address (0x8) + * + * This returns the client, which should be ultimately freed using + * i2c_free_smbus_host_notify_device(); or an ERRPTR to indicate an error. + */ +struct i2c_client *i2c_new_smbus_host_notify_device(struct i2c_adapter *adapter) +{ + struct i2c_board_info host_notify_board_info = { + I2C_BOARD_INFO("smbus_host_notify", 0x08), + .flags = I2C_CLIENT_SLAVE, + }; + struct i2c_smbus_host_notify_status *status; + struct i2c_client *client; + int ret; + + status = kzalloc(sizeof(struct i2c_smbus_host_notify_status), + GFP_KERNEL); + if (!status) + return ERR_PTR(-ENOMEM); + + host_notify_board_info.platform_data = status; + + client = i2c_new_client_device(adapter, &host_notify_board_info); + if (IS_ERR(client)) { + kfree(status); + return client; + } + + ret = i2c_slave_register(client, i2c_smbus_host_notify_cb); + if (ret) { + i2c_unregister_device(client); + kfree(status); + return ERR_PTR(ret); + } + + return client; +} +EXPORT_SYMBOL_GPL(i2c_new_smbus_host_notify_device); + +/** + * i2c_free_smbus_host_notify_device - free the client for SMBus host-notify + * support + * @client: the client to free + * Context: can sleep + * + * Free the i2c_client allocated via i2c_new_smbus_host_notify_device + */ +void i2c_free_smbus_host_notify_device(struct i2c_client *client) +{ + i2c_slave_unregister(client); + kfree(client->dev.platform_data); + i2c_unregister_device(client); +} +EXPORT_SYMBOL_GPL(i2c_free_smbus_host_notify_device); +#endif diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h index 1e4e0de4ef8b..974038a684ed 100644 --- a/include/linux/i2c-smbus.h +++ b/include/linux/i2c-smbus.h @@ -38,6 +38,8 @@ static inline int of_i2c_setup_smbus_alert(struct i2c_adapter *adap) return 0; } #endif +struct i2c_client *i2c_new_smbus_host_notify_device(struct i2c_adapter *adapter); +void i2c_free_smbus_host_notify_device(struct i2c_client *client); #if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_DMI) void i2c_register_spd(struct i2c_adapter *adap); -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-06-25 7:40 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-06-25 7:39 [PATCH v2 0/4] stm32-f7: Addition of SMBus Alert / Host-notify features Alain Volmat 2020-06-25 7:39 ` Alain Volmat 2020-06-25 7:39 ` Alain Volmat [this message] 2020-06-25 7:39 ` [PATCH v2 1/4] i2c: smbus: add core function handling SMBus host-notify Alain Volmat 2020-07-01 10:49 ` Wolfram Sang 2020-07-01 10:49 ` Wolfram Sang 2020-07-02 11:23 ` Alain Volmat 2020-07-02 11:23 ` Alain Volmat 2020-06-25 7:39 ` [PATCH v2 2/4] i2c: addition of client hnotify reg/unreg callbacks Alain Volmat 2020-06-25 7:39 ` Alain Volmat 2020-06-25 7:39 ` [PATCH v2 3/4] dt-bindings: i2c-stm32: add SMBus Alert bindings Alain Volmat 2020-06-25 7:39 ` Alain Volmat 2020-06-30 19:41 ` Wolfram Sang 2020-06-30 19:41 ` Wolfram Sang 2020-07-14 2:30 ` Rob Herring 2020-07-14 2:30 ` Rob Herring 2020-07-21 6:22 ` Wolfram Sang 2020-07-21 6:22 ` Wolfram Sang 2020-06-25 7:39 ` [PATCH v2 4/4] i2c: stm32f7: Add SMBus-specific protocols support Alain Volmat 2020-06-25 7:39 ` Alain Volmat 2020-06-30 16:05 ` [PATCH v2 0/4] stm32-f7: Addition of SMBus Alert / Host-notify features Wolfram Sang 2020-06-30 16:05 ` Wolfram Sang 2020-07-01 9:21 ` Alain Volmat 2020-07-01 9:21 ` Alain Volmat 2020-07-01 9:28 ` Wolfram Sang 2020-07-01 9:28 ` Wolfram Sang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1593070769-9106-2-git-send-email-alain.volmat@st.com \ --to=alain.volmat@st.com \ --cc=alexandre.torgue@st.com \ --cc=devicetree@vger.kernel.org \ --cc=fabrice.gasnier@st.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-i2c@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-stm32@st-md-mailman.stormreply.com \ --cc=mark.rutland@arm.com \ --cc=mcoquelin.stm32@gmail.com \ --cc=pierre-yves.mordret@st.com \ --cc=robh+dt@kernel.org \ --cc=wsa@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.