88
99#include <generated/utsrelease.h>
1010#include <linux/bitops.h>
11+ #include <linux/completion.h>
12+ #include <linux/gpio/consumer.h>
1113#include <linux/i2c.h>
1214#include <linux/init.h>
1315#include <linux/module.h>
@@ -22,6 +24,7 @@ enum testunit_cmds {
2224 TU_CMD_SMBUS_HOST_NOTIFY ,
2325 TU_CMD_SMBUS_BLOCK_PROC_CALL ,
2426 TU_CMD_GET_VERSION_WITH_REP_START ,
27+ TU_CMD_SMBUS_ALERT_REQUEST ,
2528 TU_NUM_CMDS
2629};
2730
@@ -44,10 +47,37 @@ struct testunit_data {
4447 u8 read_idx ;
4548 struct i2c_client * client ;
4649 struct delayed_work worker ;
50+ struct gpio_desc * gpio ;
51+ struct completion alert_done ;
4752};
4853
4954static char tu_version_info [] = "v" UTS_RELEASE "\n\0" ;
5055
56+ static int i2c_slave_testunit_smbalert_cb (struct i2c_client * client ,
57+ enum i2c_slave_event event , u8 * val )
58+ {
59+ struct testunit_data * tu = i2c_get_clientdata (client );
60+
61+ switch (event ) {
62+ case I2C_SLAVE_READ_PROCESSED :
63+ gpiod_set_value (tu -> gpio , 0 );
64+ fallthrough ;
65+ case I2C_SLAVE_READ_REQUESTED :
66+ * val = tu -> regs [TU_REG_DATAL ];
67+ break ;
68+
69+ case I2C_SLAVE_STOP :
70+ complete (& tu -> alert_done );
71+ break ;
72+
73+ case I2C_SLAVE_WRITE_REQUESTED :
74+ case I2C_SLAVE_WRITE_RECEIVED :
75+ return - EOPNOTSUPP ;
76+ }
77+
78+ return 0 ;
79+ }
80+
5181static int i2c_slave_testunit_slave_cb (struct i2c_client * client ,
5282 enum i2c_slave_event event , u8 * val )
5383{
@@ -127,8 +157,10 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
127157static void i2c_slave_testunit_work (struct work_struct * work )
128158{
129159 struct testunit_data * tu = container_of (work , struct testunit_data , worker .work );
160+ unsigned long time_left ;
130161 struct i2c_msg msg ;
131162 u8 msgbuf [256 ];
163+ u16 orig_addr ;
132164 int ret = 0 ;
133165
134166 msg .addr = I2C_CLIENT_END ;
@@ -150,6 +182,26 @@ static void i2c_slave_testunit_work(struct work_struct *work)
150182 msgbuf [2 ] = tu -> regs [TU_REG_DATAH ];
151183 break ;
152184
185+ case TU_CMD_SMBUS_ALERT_REQUEST :
186+ i2c_slave_unregister (tu -> client );
187+ orig_addr = tu -> client -> addr ;
188+ tu -> client -> addr = 0x0c ;
189+ ret = i2c_slave_register (tu -> client , i2c_slave_testunit_smbalert_cb );
190+ if (ret )
191+ goto out_smbalert ;
192+
193+ reinit_completion (& tu -> alert_done );
194+ gpiod_set_value (tu -> gpio , 1 );
195+ time_left = wait_for_completion_timeout (& tu -> alert_done , HZ );
196+ if (!time_left )
197+ ret = - ETIMEDOUT ;
198+
199+ i2c_slave_unregister (tu -> client );
200+ out_smbalert :
201+ tu -> client -> addr = orig_addr ;
202+ i2c_slave_register (tu -> client , i2c_slave_testunit_slave_cb );
203+ break ;
204+
153205 default :
154206 break ;
155207 }
@@ -176,8 +228,15 @@ static int i2c_slave_testunit_probe(struct i2c_client *client)
176228
177229 tu -> client = client ;
178230 i2c_set_clientdata (client , tu );
231+ init_completion (& tu -> alert_done );
179232 INIT_DELAYED_WORK (& tu -> worker , i2c_slave_testunit_work );
180233
234+ tu -> gpio = devm_gpiod_get_index_optional (& client -> dev , NULL , 0 , GPIOD_OUT_LOW );
235+ if (gpiod_cansleep (tu -> gpio )) {
236+ dev_err (& client -> dev , "GPIO access which may sleep is not allowed\n" );
237+ return - EDEADLK ;
238+ }
239+
181240 if (sizeof (tu_version_info ) > TU_VERSION_MAX_LENGTH )
182241 tu_version_info [TU_VERSION_MAX_LENGTH - 1 ] = 0 ;
183242
0 commit comments