Skip to content

Commit 96a8233

Browse files
committed
[drivers][i2c] Serialize bus control with transfers
Hold the bus mutex while dispatching control commands and changing max_hz. Use a common unlock path and propagate mutex errors as in rt_i2c_transfer. Document the thread-context requirement. Fixes #11524
1 parent 005d291 commit 96a8233

2 files changed

Lines changed: 22 additions & 6 deletions

File tree

‎components/drivers/i2c/dev_i2c_core.c‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,24 @@ rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
100100
int cmd,
101101
void *args)
102102
{
103-
rt_err_t ret;
103+
rt_err_t ret = RT_EOK;
104+
rt_err_t err;
105+
106+
/* Serialize configuration changes with transfers on this bus. */
107+
err = rt_mutex_take(&bus->lock, RT_WAITING_FOREVER);
108+
if (err != RT_EOK)
109+
{
110+
return err;
111+
}
104112

105113
switch (cmd)
106114
{
107115
case RT_I2C_CTRL_SET_MAX_HZ:
108116
{
109117
if (args == RT_NULL)
110118
{
111-
return -RT_ERROR;
119+
ret = -RT_ERROR;
120+
break;
112121
}
113122

114123
rt_uint32_t max_hz = *(rt_uint32_t *)args;
@@ -118,7 +127,7 @@ rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
118127
}
119128
else
120129
{
121-
return -RT_ERROR;
130+
ret = -RT_ERROR;
122131
}
123132
break;
124133
}
@@ -127,17 +136,21 @@ rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
127136
if(bus->ops->i2c_bus_control)
128137
{
129138
ret = bus->ops->i2c_bus_control(bus, cmd, args);
130-
return ret;
131139
}
132140
else
133141
{
134142
LOG_E("I2C bus operation not supported");
135-
return -RT_EINVAL;
143+
ret = -RT_EINVAL;
136144
}
137145
break;
138146
}
139147
}
140-
return RT_EOK;
148+
err = rt_mutex_release(&bus->lock);
149+
if (err != RT_EOK)
150+
{
151+
return err;
152+
}
153+
return ret;
141154
}
142155

143156
rt_ssize_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,

‎components/drivers/include/drivers/dev_i2c.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ rt_ssize_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
369369
/**
370370
* @brief I2C Control
371371
*
372+
* @note This function takes the bus mutex and must be called from thread context.
373+
* Configuration changes are serialized with transfers on the same bus.
374+
*
372375
* @param bus the I2C bus device
373376
* @param cmd the I2C control command
374377
* @param args the I2C control arguments

0 commit comments

Comments
 (0)