Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: meson: implement the master_xfer_atomic callback

Boards with some of the 32-bit SoCs (mostly Meson8 and Meson8m2) use a
Ricoh RN5T618 PMU which acts as system power controller. The driver for
the system power controller may need to the I2C bus just before shutting
down or rebooting the system. At this stage the interrupts may be
disabled already.

Implement the master_xfer_atomic callback so the driver for the RN5T618
PMU can communicate properly with the PMU when shutting down or
rebooting the board. The CTRL register has a status bit which can be
polled to determine when processing has completed. According to the
public S805 datasheet the value 0 means "idle" and 1 means "running".

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
[wsa: converted some whitespace alignment]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Martin Blumenstingl and committed by
Wolfram Sang
fe402bd0 21575a7a

+65 -32
+65 -32
drivers/i2c/busses/i2c-meson.c
··· 10 10 #include <linux/i2c.h> 11 11 #include <linux/interrupt.h> 12 12 #include <linux/io.h> 13 + #include <linux/iopoll.h> 13 14 #include <linux/kernel.h> 14 15 #include <linux/module.h> 15 16 #include <linux/of.h> ··· 214 213 writel(i2c->tokens[1], i2c->regs + REG_TOK_LIST1); 215 214 } 216 215 216 + static void meson_i2c_transfer_complete(struct meson_i2c *i2c, u32 ctrl) 217 + { 218 + if (ctrl & REG_CTRL_ERROR) { 219 + /* 220 + * The bit is set when the IGNORE_NAK bit is cleared 221 + * and the device didn't respond. In this case, the 222 + * I2C controller automatically generates a STOP 223 + * condition. 224 + */ 225 + dev_dbg(i2c->dev, "error bit set\n"); 226 + i2c->error = -ENXIO; 227 + i2c->state = STATE_IDLE; 228 + } else { 229 + if (i2c->state == STATE_READ && i2c->count) 230 + meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos, 231 + i2c->count); 232 + 233 + i2c->pos += i2c->count; 234 + 235 + if (i2c->pos >= i2c->msg->len) 236 + i2c->state = STATE_IDLE; 237 + } 238 + } 239 + 217 240 static irqreturn_t meson_i2c_irq(int irqno, void *dev_id) 218 241 { 219 242 struct meson_i2c *i2c = dev_id; ··· 257 232 return IRQ_NONE; 258 233 } 259 234 260 - if (ctrl & REG_CTRL_ERROR) { 261 - /* 262 - * The bit is set when the IGNORE_NAK bit is cleared 263 - * and the device didn't respond. In this case, the 264 - * I2C controller automatically generates a STOP 265 - * condition. 266 - */ 267 - dev_dbg(i2c->dev, "error bit set\n"); 268 - i2c->error = -ENXIO; 269 - i2c->state = STATE_IDLE; 270 - complete(&i2c->done); 271 - goto out; 272 - } 235 + meson_i2c_transfer_complete(i2c, ctrl); 273 236 274 - if (i2c->state == STATE_READ && i2c->count) 275 - meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos, i2c->count); 276 - 277 - i2c->pos += i2c->count; 278 - 279 - if (i2c->pos >= i2c->msg->len) { 280 - i2c->state = STATE_IDLE; 237 + if (i2c->state == STATE_IDLE) { 281 238 complete(&i2c->done); 282 239 goto out; 283 240 } ··· 286 279 } 287 280 288 281 static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg, 289 - int last) 282 + int last, bool atomic) 290 283 { 291 284 unsigned long time_left, flags; 292 285 int ret = 0; 286 + u32 ctrl; 293 287 294 288 i2c->msg = msg; 295 289 i2c->last = last; ··· 308 300 309 301 i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; 310 302 meson_i2c_prepare_xfer(i2c); 311 - reinit_completion(&i2c->done); 303 + 304 + if (!atomic) 305 + reinit_completion(&i2c->done); 312 306 313 307 /* Start the transfer */ 314 308 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, REG_CTRL_START); 315 309 316 - time_left = msecs_to_jiffies(I2C_TIMEOUT_MS); 317 - time_left = wait_for_completion_timeout(&i2c->done, time_left); 310 + if (atomic) { 311 + ret = readl_poll_timeout_atomic(i2c->regs + REG_CTRL, ctrl, 312 + !(ctrl & REG_CTRL_STATUS), 313 + 10, I2C_TIMEOUT_MS * 1000); 314 + } else { 315 + time_left = msecs_to_jiffies(I2C_TIMEOUT_MS); 316 + time_left = wait_for_completion_timeout(&i2c->done, time_left); 317 + 318 + if (!time_left) 319 + ret = -ETIMEDOUT; 320 + } 318 321 319 322 /* 320 323 * Protect access to i2c struct and registers from interrupt ··· 334 315 */ 335 316 spin_lock_irqsave(&i2c->lock, flags); 336 317 318 + if (atomic && !ret) 319 + meson_i2c_transfer_complete(i2c, ctrl); 320 + 337 321 /* Abort any active operation */ 338 322 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); 339 323 340 - if (!time_left) { 324 + if (ret) 341 325 i2c->state = STATE_IDLE; 342 - ret = -ETIMEDOUT; 343 - } 344 326 345 327 if (i2c->error) 346 328 ret = i2c->error; ··· 351 331 return ret; 352 332 } 353 333 354 - static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, 355 - int num) 334 + static int meson_i2c_xfer_messages(struct i2c_adapter *adap, 335 + struct i2c_msg *msgs, int num, bool atomic) 356 336 { 357 337 struct meson_i2c *i2c = adap->algo_data; 358 338 int i, ret = 0; ··· 360 340 clk_enable(i2c->clk); 361 341 362 342 for (i = 0; i < num; i++) { 363 - ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1); 343 + ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1, atomic); 364 344 if (ret) 365 345 break; 366 346 } ··· 370 350 return ret ?: i; 371 351 } 372 352 353 + static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, 354 + int num) 355 + { 356 + return meson_i2c_xfer_messages(adap, msgs, num, false); 357 + } 358 + 359 + static int meson_i2c_xfer_atomic(struct i2c_adapter *adap, 360 + struct i2c_msg *msgs, int num) 361 + { 362 + return meson_i2c_xfer_messages(adap, msgs, num, true); 363 + } 364 + 373 365 static u32 meson_i2c_func(struct i2c_adapter *adap) 374 366 { 375 367 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 376 368 } 377 369 378 370 static const struct i2c_algorithm meson_i2c_algorithm = { 379 - .master_xfer = meson_i2c_xfer, 380 - .functionality = meson_i2c_func, 371 + .master_xfer = meson_i2c_xfer, 372 + .master_xfer_atomic = meson_i2c_xfer_atomic, 373 + .functionality = meson_i2c_func, 381 374 }; 382 375 383 376 static int meson_i2c_probe(struct platform_device *pdev)