Pull i2c updates from Wolfram Sang: "I2C Core: - prevent double-free of an fwnode if it is a software node - use recent helpers instead of custom ACPI or outdated OF ones - add a more elaborate description of a message flag Cleanups and refactorings: - lpi2c, riic, st, stm32f7: general improvements - riic: support more flexible IRQ configurations - tegra: fix documentation Improvements: - lpi2c: improve register polling and add atomic transfer - imx: use guarded spinlocks New hardware support: - Samsung Exynos 2200 - Renesas RZ/T2H (R9A09G077), RZ/N2H (R9A09G087) DT binding: - rk3x: enable power domains - nxp: support clock property" * tag 'i2c-for-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: core: Fix double-free of fwnode in i2c_unregister_device() i2c: lpi2c: implement xfer_atomic callback i2c: lpi2c: use readl_poll_timeout() for register polling dt-bindings: i2c: i2c-rk3x: Allow use of a power-domain dt-bindings: i2c: exynos5: add samsung,exynos2200-hsi2c compatible i2c: lpi2c: convert to use secs_to_jiffies() i2c: st: Use min() to improve code i2c: imx: use guard to take spinlock i2c: stm32f7: Use str_on_off() helper dt-bindings: i2c: nxp,pnx-i2c: allow clocks property i2c: riic: Add support for RZ/T2H SoC i2c: riic: Move generic compatible string to end of array i2c: riic: Pass IRQ desc array as part of OF data dt-bindings: i2c: renesas,riic: Document RZ/T2H and RZ/N2H support dt-bindings: i2c: renesas,riic: Move ref for i2c-controller.yaml to the end i2c: tegra: Add missing kernel-doc for dma_dev member i2c: Clarify behavior of I2C_M_RD flag i2c: mux: pca954x: Use dev_fwnode() i2c: acpi: Replace custom code with device_match_acpi_handle()
Unified · Split
| @@ -36,6 +36,7 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | - items: |
| 37 | 37 | - enum: |
| 38 | 38 | - google,gs101-hsi2c |
| 39 | + - samsung,exynos2200-hsi2c | |
| 39 | 40 | - samsung,exynos850-hsi2c |
| 40 | 41 | - const: samsung,exynosautov9-hsi2c |
| 41 | 42 | - const: samsung,exynos5-hsi2c # Exynos5250 and Exynos5420 |
| @@ -105,6 +105,9 @@ properties: · 104 unmodified lines | ||
| 105 | 105 | (t(f) in the I2C specification). If not specified we will use the SCL |
| 106 | 106 | value since they are the same in nearly all cases. |
| 107 | 107 | |
| 108 | + power-domains: | |
| 109 | + maxItems: 1 | |
| 110 | + | |
| 108 | 111 | required: |
| 109 | 112 | - compatible |
| 110 | 113 | - reg |
| @@ -22,6 +22,9 @@ properties: · 21 unmodified lines | ||
| 22 | 22 | interrupts: |
| 23 | 23 | maxItems: 1 |
| 24 | 24 | |
| 25 | + clocks: | |
| 26 | + maxItems: 1 | |
| 27 | + | |
| 25 | 28 | clock-frequency: |
| 26 | 29 | default: 100000 |
| 27 | 30 | |
| @@ -10,9 +10,6 @@ maintainers: · 9 unmodified lines | ||
| 10 | 10 | - Chris Brandt <chris.brandt@renesas.com> |
| 11 | 11 | - Wolfram Sang <wsa+renesas@sang-engineering.com> |
| 12 | 12 | |
| 13 | −allOf: | |
| 14 | − - $ref: /schemas/i2c/i2c-controller.yaml# | |
| 15 | − | |
| 16 | 13 | properties: |
| 17 | 14 | compatible: |
| 18 | 15 | oneOf: |
| @@ -32,32 +29,50 @@ properties: · 13 unmodified lines | ||
| 32 | 29 | - renesas,riic-r9a09g056 # RZ/V2N |
| 33 | 30 | - const: renesas,riic-r9a09g057 # RZ/V2H(P) |
| 34 | 31 | |
| 35 | − - const: renesas,riic-r9a09g057 # RZ/V2H(P) | |
| 32 | + - enum: | |
| 33 | + - renesas,riic-r9a09g057 # RZ/V2H(P) | |
| 34 | + - renesas,riic-r9a09g077 # RZ/T2H | |
| 35 | + | |
| 36 | + - items: | |
| 37 | + - const: renesas,riic-r9a09g087 # RZ/N2H | |
| 38 | + - const: renesas,riic-r9a09g077 # RZ/T2H | |
| 36 | 39 | |
| 37 | 40 | reg: |
| 38 | 41 | maxItems: 1 |
| 39 | 42 | |
| 40 | 43 | interrupts: |
| 41 | − items: | |
| 42 | − - description: Transmit End Interrupt | |
| 43 | − - description: Receive Data Full Interrupt | |
| 44 | − - description: Transmit Data Empty Interrupt | |
| 45 | − - description: Stop Condition Detection Interrupt | |
| 46 | − - description: Start Condition Detection Interrupt | |
| 47 | − - description: NACK Reception Interrupt | |
| 48 | − - description: Arbitration-Lost Interrupt | |
| 49 | − - description: Timeout Interrupt | |
| 44 | + oneOf: | |
| 45 | + - items: | |
| 46 | + - description: Transmit End Interrupt | |
| 47 | + - description: Receive Data Full Interrupt | |
| 48 | + - description: Transmit Data Empty Interrupt | |
| 49 | + - description: Stop Condition Detection Interrupt | |
| 50 | + - description: Start Condition Detection Interrupt | |
| 51 | + - description: NACK Reception Interrupt | |
| 52 | + - description: Arbitration-Lost Interrupt | |
| 53 | + - description: Timeout Interrupt | |
| 54 | + - items: | |
| 55 | + - description: Transfer Error Or Event Generation | |
| 56 | + - description: Receive Data Full Interrupt | |
| 57 | + - description: Transmit Data Empty Interrupt | |
| 58 | + - description: Transmit End Interrupt | |
| 50 | 59 | |
| 51 | 60 | interrupt-names: |
| 52 | − items: | |
| 53 | − - const: tei | |
| 54 | − - const: ri | |
| 55 | − - const: ti | |
| 56 | − - const: spi | |
| 57 | − - const: sti | |
| 58 | − - const: naki | |
| 59 | − - const: ali | |
| 60 | − - const: tmoi | |
| 61 | + oneOf: | |
| 62 | + - items: | |
| 63 | + - const: tei | |
| 64 | + - const: ri | |
| 65 | + - const: ti | |
| 66 | + - const: spi | |
| 67 | + - const: sti | |
| 68 | + - const: naki | |
| 69 | + - const: ali | |
| 70 | + - const: tmoi | |
| 71 | + - items: | |
| 72 | + - const: eei | |
| 73 | + - const: rxi | |
| 74 | + - const: txi | |
| 75 | + - const: tei | |
| 61 | 76 | |
| 62 | 77 | clock-frequency: |
| 63 | 78 | description: |
| @@ -84,18 +99,40 @@ required: · 20 unmodified lines | ||
| 84 | 99 | - '#address-cells' |
| 85 | 100 | - '#size-cells' |
| 86 | 101 | |
| 87 | −if: | |
| 88 | − properties: | |
| 89 | − compatible: | |
| 90 | − contains: | |
| 91 | − enum: | |
| 92 | − - renesas,riic-r9a07g043 | |
| 93 | − - renesas,riic-r9a07g044 | |
| 94 | − - renesas,riic-r9a07g054 | |
| 95 | − - renesas,riic-r9a09g057 | |
| 96 | −then: | |
| 97 | − required: | |
| 98 | − - resets | |
| 102 | +allOf: | |
| 103 | + - $ref: /schemas/i2c/i2c-controller.yaml# | |
| 104 | + | |
| 105 | + - if: | |
| 106 | + properties: | |
| 107 | + compatible: | |
| 108 | + contains: | |
| 109 | + const: renesas,riic-r9a09g077 | |
| 110 | + then: | |
| 111 | + properties: | |
| 112 | + interrupts: | |
| 113 | + maxItems: 4 | |
| 114 | + interrupt-names: | |
| 115 | + maxItems: 4 | |
| 116 | + resets: false | |
| 117 | + else: | |
| 118 | + properties: | |
| 119 | + interrupts: | |
| 120 | + minItems: 8 | |
| 121 | + interrupt-names: | |
| 122 | + minItems: 8 | |
| 123 | + | |
| 124 | + - if: | |
| 125 | + properties: | |
| 126 | + compatible: | |
| 127 | + contains: | |
| 128 | + enum: | |
| 129 | + - renesas,riic-r9a07g043 | |
| 130 | + - renesas,riic-r9a07g044 | |
| 131 | + - renesas,riic-r9a07g054 | |
| 132 | + - renesas,riic-r9a09g057 | |
| 133 | + then: | |
| 134 | + required: | |
| 135 | + - resets | |
| 99 | 136 | |
| 100 | 137 | unevaluatedProperties: false |
| 101 | 138 | |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/init.h> |
| 17 | 17 | #include <linux/interrupt.h> |
| 18 | 18 | #include <linux/io.h> |
| 19 | +#include <linux/iopoll.h> | |
| 19 | 20 | #include <linux/kernel.h> |
| 20 | 21 | #include <linux/module.h> |
| 21 | 22 | #include <linux/of.h> |
| @@ -187,41 +188,48 @@ struct lpi2c_imx_struct { · 165 unmodified lines | ||
| 187 | 188 | struct i2c_client *target; |
| 188 | 189 | }; |
| 189 | 190 | |
| 191 | +#define lpi2c_imx_read_msr_poll_timeout(atomic, val, cond) \ | |
| 192 | + (atomic ? readl_poll_timeout_atomic(lpi2c_imx->base + LPI2C_MSR, val, \ | |
| 193 | + cond, 0, 500000) : \ | |
| 194 | + readl_poll_timeout(lpi2c_imx->base + LPI2C_MSR, val, cond, \ | |
| 195 | + 0, 500000)) | |
| 196 | + | |
| 190 | 197 | static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx, |
| 191 | 198 | unsigned int enable) |
| 192 | 199 | { |
| 193 | 200 | writel(enable, lpi2c_imx->base + LPI2C_MIER); |
| 194 | 201 | } |
| 195 | 202 | |
| 196 | −static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx) | |
| 203 | +static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx, bool atomic) | |
| 197 | 204 | { |
| 198 | − unsigned long orig_jiffies = jiffies; | |
| 199 | 205 | unsigned int temp; |
| 206 | + int err; | |
| 200 | 207 | |
| 201 | − while (1) { | |
| 202 | − temp = readl(lpi2c_imx->base + LPI2C_MSR); | |
| 203 | − | |
| 204 | − /* check for arbitration lost, clear if set */ | |
| 205 | − if (temp & MSR_ALF) { | |
| 206 | − writel(temp, lpi2c_imx->base + LPI2C_MSR); | |
| 207 | − return -EAGAIN; | |
| 208 | − } | |
| 208 | + err = lpi2c_imx_read_msr_poll_timeout(atomic, temp, | |
| 209 | + temp & (MSR_ALF | MSR_BBF | MSR_MBF)); | |
| 209 | 210 | |
| 210 | − if (temp & (MSR_BBF | MSR_MBF)) | |
| 211 | − break; | |
| 211 | + /* check for arbitration lost, clear if set */ | |
| 212 | + if (temp & MSR_ALF) { | |
| 213 | + writel(temp, lpi2c_imx->base + LPI2C_MSR); | |
| 214 | + return -EAGAIN; | |
| 215 | + } | |
| 212 | 216 | |
| 213 | − if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { | |
| 214 | − dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n"); | |
| 215 | − if (lpi2c_imx->adapter.bus_recovery_info) | |
| 216 | − i2c_recover_bus(&lpi2c_imx->adapter); | |
| 217 | − return -ETIMEDOUT; | |
| 218 | − } | |
| 219 | − schedule(); | |
| 217 | + /* check for bus not busy */ | |
| 218 | + if (err) { | |
| 219 | + dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n"); | |
| 220 | + if (lpi2c_imx->adapter.bus_recovery_info) | |
| 221 | + i2c_recover_bus(&lpi2c_imx->adapter); | |
| 222 | + return -ETIMEDOUT; | |
| 220 | 223 | } |
| 221 | 224 | |
| 222 | 225 | return 0; |
| 223 | 226 | } |
| 224 | 227 | |
| 228 | +static u32 lpi2c_imx_txfifo_cnt(struct lpi2c_imx_struct *lpi2c_imx) | |
| 229 | +{ | |
| 230 | + return readl(lpi2c_imx->base + LPI2C_MFSR) & 0xff; | |
| 231 | +} | |
| 232 | + | |
| 225 | 233 | static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx) |
| 226 | 234 | { |
| 227 | 235 | unsigned int bitrate = lpi2c_imx->bitrate; |
| @@ -242,7 +250,7 @@ static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx) · 14 unmodified lines | ||
| 242 | 250 | } |
| 243 | 251 | |
| 244 | 252 | static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx, |
| 245 | − struct i2c_msg *msgs) | |
| 253 | + struct i2c_msg *msgs, bool atomic) | |
| 246 | 254 | { |
| 247 | 255 | unsigned int temp; |
| 248 | 256 | |
| @@ -254,30 +262,23 @@ static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx, · 5 unmodified lines | ||
| 254 | 262 | temp = i2c_8bit_addr_from_msg(msgs) | (GEN_START << 8); |
| 255 | 263 | writel(temp, lpi2c_imx->base + LPI2C_MTDR); |
| 256 | 264 | |
| 257 | − return lpi2c_imx_bus_busy(lpi2c_imx); | |
| 265 | + return lpi2c_imx_bus_busy(lpi2c_imx, atomic); | |
| 258 | 266 | } |
| 259 | 267 | |
| 260 | −static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx) | |
| 268 | +static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx, bool atomic) | |
| 261 | 269 | { |
| 262 | − unsigned long orig_jiffies = jiffies; | |
| 263 | 270 | unsigned int temp; |
| 271 | + int err; | |
| 264 | 272 | |
| 265 | 273 | writel(GEN_STOP << 8, lpi2c_imx->base + LPI2C_MTDR); |
| 266 | 274 | |
| 267 | − do { | |
| 268 | − temp = readl(lpi2c_imx->base + LPI2C_MSR); | |
| 269 | − if (temp & MSR_SDF) | |
| 270 | − break; | |
| 271 | − | |
| 272 | − if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { | |
| 273 | − dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n"); | |
| 274 | − if (lpi2c_imx->adapter.bus_recovery_info) | |
| 275 | − i2c_recover_bus(&lpi2c_imx->adapter); | |
| 276 | − break; | |
| 277 | − } | |
| 278 | − schedule(); | |
| 275 | + err = lpi2c_imx_read_msr_poll_timeout(atomic, temp, temp & MSR_SDF); | |
| 279 | 276 | |
| 280 | − } while (1); | |
| 277 | + if (err) { | |
| 278 | + dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n"); | |
| 279 | + if (lpi2c_imx->adapter.bus_recovery_info) | |
| 280 | + i2c_recover_bus(&lpi2c_imx->adapter); | |
| 281 | + } | |
| 281 | 282 | } |
| 282 | 283 | |
| 283 | 284 | /* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */ |
| @@ -391,28 +392,25 @@ static int lpi2c_imx_pio_msg_complete(struct lpi2c_imx_struct *lpi2c_imx) · 107 unmodified lines | ||
| 391 | 392 | return time_left ? 0 : -ETIMEDOUT; |
| 392 | 393 | } |
| 393 | 394 | |
| 394 | −static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx) | |
| 395 | +static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx, bool atomic) | |
| 395 | 396 | { |
| 396 | − unsigned long orig_jiffies = jiffies; | |
| 397 | − u32 txcnt; | |
| 398 | − | |
| 399 | − do { | |
| 400 | − txcnt = readl(lpi2c_imx->base + LPI2C_MFSR) & 0xff; | |
| 397 | + unsigned int temp; | |
| 398 | + int err; | |
| 401 | 399 | |
| 402 | − if (readl(lpi2c_imx->base + LPI2C_MSR) & MSR_NDF) { | |
| 403 | − dev_dbg(&lpi2c_imx->adapter.dev, "NDF detected\n"); | |
| 404 | − return -EIO; | |
| 405 | − } | |
| 400 | + err = lpi2c_imx_read_msr_poll_timeout(atomic, temp, | |
| 401 | + (temp & MSR_NDF) || !lpi2c_imx_txfifo_cnt(lpi2c_imx)); | |
| 406 | 402 | |
| 407 | − if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { | |
| 408 | − dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n"); | |
| 409 | − if (lpi2c_imx->adapter.bus_recovery_info) | |
| 410 | − i2c_recover_bus(&lpi2c_imx->adapter); | |
| 411 | − return -ETIMEDOUT; | |
| 412 | − } | |
| 413 | − schedule(); | |
| 403 | + if (temp & MSR_NDF) { | |
| 404 | + dev_dbg(&lpi2c_imx->adapter.dev, "NDF detected\n"); | |
| 405 | + return -EIO; | |
| 406 | + } | |
| 414 | 407 | |
| 415 | − } while (txcnt); | |
| 408 | + if (err) { | |
| 409 | + dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n"); | |
| 410 | + if (lpi2c_imx->adapter.bus_recovery_info) | |
| 411 | + i2c_recover_bus(&lpi2c_imx->adapter); | |
| 412 | + return -ETIMEDOUT; | |
| 413 | + } | |
| 416 | 414 | |
| 417 | 415 | return 0; |
| 418 | 416 | } |
| @@ -436,7 +434,7 @@ static void lpi2c_imx_set_rx_watermark(struct lpi2c_imx_struct *lpi2c_imx) · 17 unmodified lines | ||
| 436 | 434 | writel(temp << 16, lpi2c_imx->base + LPI2C_MFCR); |
| 437 | 435 | } |
| 438 | 436 | |
| 439 | −static void lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx) | |
| 437 | +static bool lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomic) | |
| 440 | 438 | { |
| 441 | 439 | unsigned int data, txcnt; |
| 442 | 440 | |
| @@ -451,13 +449,19 @@ static void lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx) · 8 unmodified lines | ||
| 451 | 449 | txcnt++; |
| 452 | 450 | } |
| 453 | 451 | |
| 454 | − if (lpi2c_imx->delivered < lpi2c_imx->msglen) | |
| 455 | − lpi2c_imx_intctrl(lpi2c_imx, MIER_TDIE | MIER_NDIE); | |
| 456 | − else | |
| 452 | + if (lpi2c_imx->delivered < lpi2c_imx->msglen) { | |
| 453 | + if (!atomic) | |
| 454 | + lpi2c_imx_intctrl(lpi2c_imx, MIER_TDIE | MIER_NDIE); | |
| 455 | + return false; | |
| 456 | + } | |
| 457 | + | |
| 458 | + if (!atomic) | |
| 457 | 459 | complete(&lpi2c_imx->complete); |
| 460 | + | |
| 461 | + return true; | |
| 458 | 462 | } |
| 459 | 463 | |
| 460 | −static void lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx) | |
| 464 | +static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomic) | |
| 461 | 465 | { |
| 462 | 466 | unsigned int blocklen, remaining; |
| 463 | 467 | unsigned int temp, data; |
| @@ -482,8 +486,9 @@ static void lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx) · 18 unmodified lines | ||
| 482 | 486 | remaining = lpi2c_imx->msglen - lpi2c_imx->delivered; |
| 483 | 487 | |
| 484 | 488 | if (!remaining) { |
| 485 | − complete(&lpi2c_imx->complete); | |
| 486 | − return; | |
| 489 | + if (!atomic) | |
| 490 | + complete(&lpi2c_imx->complete); | |
| 491 | + return true; | |
| 487 | 492 | } |
| 488 | 493 | |
| 489 | 494 | /* not finished, still waiting for rx data */ |
| @@ -501,7 +506,10 @@ static void lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx) · 11 unmodified lines | ||
| 501 | 506 | writel(temp, lpi2c_imx->base + LPI2C_MTDR); |
| 502 | 507 | } |
| 503 | 508 | |
| 504 | − lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE); | |
| 509 | + if (!atomic) | |
| 510 | + lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE); | |
| 511 | + | |
| 512 | + return false; | |
| 505 | 513 | } |
| 506 | 514 | |
| 507 | 515 | static void lpi2c_imx_write(struct lpi2c_imx_struct *lpi2c_imx, |
| @@ -509,11 +517,29 @@ static void lpi2c_imx_write(struct lpi2c_imx_struct *lpi2c_imx, · 1 unmodified line | ||
| 509 | 517 | { |
| 510 | 518 | lpi2c_imx->tx_buf = msgs->buf; |
| 511 | 519 | lpi2c_imx_set_tx_watermark(lpi2c_imx); |
| 512 | − lpi2c_imx_write_txfifo(lpi2c_imx); | |
| 520 | + lpi2c_imx_write_txfifo(lpi2c_imx, false); | |
| 513 | 521 | } |
| 514 | 522 | |
| 515 | −static void lpi2c_imx_read(struct lpi2c_imx_struct *lpi2c_imx, | |
| 516 | − struct i2c_msg *msgs) | |
| 523 | +static int lpi2c_imx_write_atomic(struct lpi2c_imx_struct *lpi2c_imx, | |
| 524 | + struct i2c_msg *msgs) | |
| 525 | +{ | |
| 526 | + u32 temp; | |
| 527 | + int err; | |
| 528 | + | |
| 529 | + lpi2c_imx->tx_buf = msgs->buf; | |
| 530 | + | |
| 531 | + err = lpi2c_imx_read_msr_poll_timeout(true, temp, | |
| 532 | + (temp & MSR_NDF) || | |
| 533 | + lpi2c_imx_write_txfifo(lpi2c_imx, true)); | |
| 534 | + | |
| 535 | + if (temp & MSR_NDF) | |
| 536 | + return -EIO; | |
| 537 | + | |
| 538 | + return err; | |
| 539 | +} | |
| 540 | + | |
| 541 | +static void lpi2c_imx_read_init(struct lpi2c_imx_struct *lpi2c_imx, | |
| 542 | + struct i2c_msg *msgs) | |
| 517 | 543 | { |
| 518 | 544 | unsigned int temp; |
| 519 | 545 | |
| @@ -524,8 +550,43 @@ static void lpi2c_imx_read(struct lpi2c_imx_struct *lpi2c_imx, · 4 unmodified lines | ||
| 524 | 550 | temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1; |
| 525 | 551 | temp |= (RECV_DATA << 8); |
| 526 | 552 | writel(temp, lpi2c_imx->base + LPI2C_MTDR); |
| 553 | +} | |
| 554 | + | |
| 555 | +static bool lpi2c_imx_read_chunk_atomic(struct lpi2c_imx_struct *lpi2c_imx) | |
| 556 | +{ | |
| 557 | + u32 rxcnt; | |
| 558 | + | |
| 559 | + rxcnt = (readl(lpi2c_imx->base + LPI2C_MFSR) >> 16) & 0xFF; | |
| 560 | + if (!rxcnt) | |
| 561 | + return false; | |
| 562 | + | |
| 563 | + if (!lpi2c_imx_read_rxfifo(lpi2c_imx, true)) | |
| 564 | + return false; | |
| 565 | + | |
| 566 | + return true; | |
| 567 | +} | |
| 568 | + | |
| 569 | +static int lpi2c_imx_read_atomic(struct lpi2c_imx_struct *lpi2c_imx, | |
| 570 | + struct i2c_msg *msgs) | |
| 571 | +{ | |
| 572 | + u32 temp; | |
| 573 | + int tmo_us; | |
| 574 | + | |
| 575 | + tmo_us = 1000000; | |
| 576 | + do { | |
| 577 | + if (lpi2c_imx_read_chunk_atomic(lpi2c_imx)) | |
| 578 | + return 0; | |
| 579 | + | |
| 580 | + temp = readl(lpi2c_imx->base + LPI2C_MSR); | |
| 527 | 581 | |
| 528 | − lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE); | |
| 582 | + if (temp & MSR_NDF) | |
| 583 | + return -EIO; | |
| 584 | + | |
| 585 | + udelay(100); | |
| 586 | + tmo_us -= 100; | |
| 587 | + } while (tmo_us > 0); | |
| 588 | + | |
| 589 | + return -ETIMEDOUT; | |
| 529 | 590 | } |
| 530 | 591 | |
| 531 | 592 | static bool is_use_dma(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg) |
| @@ -545,14 +606,27 @@ static int lpi2c_imx_pio_xfer(struct lpi2c_imx_struct *lpi2c_imx, · 13 unmodified lines | ||
| 545 | 606 | { |
| 546 | 607 | reinit_completion(&lpi2c_imx->complete); |
| 547 | 608 | |
| 548 | − if (msg->flags & I2C_M_RD) | |
| 549 | − lpi2c_imx_read(lpi2c_imx, msg); | |
| 550 | − else | |
| 609 | + if (msg->flags & I2C_M_RD) { | |
| 610 | + lpi2c_imx_read_init(lpi2c_imx, msg); | |
| 611 | + lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE); | |
| 612 | + } else { | |
| 551 | 613 | lpi2c_imx_write(lpi2c_imx, msg); |
| 614 | + } | |
| 552 | 615 | |
| 553 | 616 | return lpi2c_imx_pio_msg_complete(lpi2c_imx); |
| 554 | 617 | } |
| 555 | 618 | |
| 619 | +static int lpi2c_imx_pio_xfer_atomic(struct lpi2c_imx_struct *lpi2c_imx, | |
| 620 | + struct i2c_msg *msg) | |
| 621 | +{ | |
| 622 | + if (msg->flags & I2C_M_RD) { | |
| 623 | + lpi2c_imx_read_init(lpi2c_imx, msg); | |
| 624 | + return lpi2c_imx_read_atomic(lpi2c_imx, msg); | |
| 625 | + } | |
| 626 | + | |
| 627 | + return lpi2c_imx_write_atomic(lpi2c_imx, msg); | |
| 628 | +} | |
| 629 | + | |
| 556 | 630 | static int lpi2c_imx_dma_timeout_calculate(struct lpi2c_imx_struct *lpi2c_imx) |
| 557 | 631 | { |
| 558 | 632 | unsigned long time = 0; |
| @@ -563,7 +637,7 @@ static int lpi2c_imx_dma_timeout_calculate(struct lpi2c_imx_struct *lpi2c_imx) · 4 unmodified lines | ||
| 563 | 637 | time += 1; |
| 564 | 638 | |
| 565 | 639 | /* Double calculated time */ |
| 566 | − return msecs_to_jiffies(time * MSEC_PER_SEC); | |
| 640 | + return secs_to_jiffies(time); | |
| 567 | 641 | } |
| 568 | 642 | |
| 569 | 643 | static int lpi2c_imx_alloc_rx_cmd_buf(struct lpi2c_imx_struct *lpi2c_imx) |
| @@ -947,8 +1021,8 @@ disable_dma: · 377 unmodified lines | ||
| 947 | 1021 | return ret; |
| 948 | 1022 | } |
| 949 | 1023 | |
| 950 | −static int lpi2c_imx_xfer(struct i2c_adapter *adapter, | |
| 951 | − struct i2c_msg *msgs, int num) | |
| 1024 | +static int lpi2c_imx_xfer_common(struct i2c_adapter *adapter, | |
| 1025 | + struct i2c_msg *msgs, int num, bool atomic) | |
| 952 | 1026 | { |
| 953 | 1027 | struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(adapter); |
| 954 | 1028 | unsigned int temp; |
| @@ -959,7 +1033,7 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter, · 4 unmodified lines | ||
| 959 | 1033 | return result; |
| 960 | 1034 | |
| 961 | 1035 | for (i = 0; i < num; i++) { |
| 962 | − result = lpi2c_imx_start(lpi2c_imx, &msgs[i]); | |
| 1036 | + result = lpi2c_imx_start(lpi2c_imx, &msgs[i], atomic); | |
| 963 | 1037 | if (result) |
| 964 | 1038 | goto disable; |
| 965 | 1039 | |
| @@ -971,28 +1045,33 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter, · 5 unmodified lines | ||
| 971 | 1045 | lpi2c_imx->tx_buf = NULL; |
| 972 | 1046 | lpi2c_imx->delivered = 0; |
| 973 | 1047 | lpi2c_imx->msglen = msgs[i].len; |
| 974 | − init_completion(&lpi2c_imx->complete); | |
| 975 | 1048 | |
| 976 | − if (is_use_dma(lpi2c_imx, &msgs[i])) { | |
| 977 | − result = lpi2c_imx_dma_xfer(lpi2c_imx, &msgs[i]); | |
| 978 | − if (result && lpi2c_imx->dma->using_pio_mode) | |
| 979 | − result = lpi2c_imx_pio_xfer(lpi2c_imx, &msgs[i]); | |
| 1049 | + if (atomic) { | |
| 1050 | + result = lpi2c_imx_pio_xfer_atomic(lpi2c_imx, &msgs[i]); | |
| 980 | 1051 | } else { |
| 981 | − result = lpi2c_imx_pio_xfer(lpi2c_imx, &msgs[i]); | |
| 1052 | + init_completion(&lpi2c_imx->complete); | |
| 1053 | + | |
| 1054 | + if (is_use_dma(lpi2c_imx, &msgs[i])) { | |
| 1055 | + result = lpi2c_imx_dma_xfer(lpi2c_imx, &msgs[i]); | |
| 1056 | + if (result && lpi2c_imx->dma->using_pio_mode) | |
| 1057 | + result = lpi2c_imx_pio_xfer(lpi2c_imx, &msgs[i]); | |
| 1058 | + } else { | |
| 1059 | + result = lpi2c_imx_pio_xfer(lpi2c_imx, &msgs[i]); | |
| 1060 | + } | |
| 982 | 1061 | } |
| 983 | 1062 | |
| 984 | 1063 | if (result) |
| 985 | 1064 | goto stop; |
| 986 | 1065 | |
| 987 | 1066 | if (!(msgs[i].flags & I2C_M_RD)) { |
| 988 | − result = lpi2c_imx_txfifo_empty(lpi2c_imx); | |
| 1067 | + result = lpi2c_imx_txfifo_empty(lpi2c_imx, atomic); | |
| 989 | 1068 | if (result) |
| 990 | 1069 | goto stop; |
| 991 | 1070 | } |
| 992 | 1071 | } |
| 993 | 1072 | |
| 994 | 1073 | stop: |
| 995 | − lpi2c_imx_stop(lpi2c_imx); | |
| 1074 | + lpi2c_imx_stop(lpi2c_imx, atomic); | |
| 996 | 1075 | |
| 997 | 1076 | temp = readl(lpi2c_imx->base + LPI2C_MSR); |
| 998 | 1077 | if ((temp & MSR_NDF) && !result) |
| @@ -1008,6 +1087,16 @@ disable: · 9 unmodified lines | ||
| 1008 | 1087 | return (result < 0) ? result : num; |
| 1009 | 1088 | } |
| 1010 | 1089 | |
| 1090 | +static int lpi2c_imx_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | |
| 1091 | +{ | |
| 1092 | + return lpi2c_imx_xfer_common(adapter, msgs, num, false); | |
| 1093 | +} | |
| 1094 | + | |
| 1095 | +static int lpi2c_imx_xfer_atomic(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | |
| 1096 | +{ | |
| 1097 | + return lpi2c_imx_xfer_common(adapter, msgs, num, true); | |
| 1098 | +} | |
| 1099 | + | |
| 1011 | 1100 | static irqreturn_t lpi2c_imx_target_isr(struct lpi2c_imx_struct *lpi2c_imx, |
| 1012 | 1101 | u32 ssr, u32 sier_filter) |
| 1013 | 1102 | { |
| @@ -1070,9 +1159,9 @@ static irqreturn_t lpi2c_imx_master_isr(struct lpi2c_imx_struct *lpi2c_imx) · 56 unmodified lines | ||
| 1070 | 1159 | if (temp & MSR_NDF) |
| 1071 | 1160 | complete(&lpi2c_imx->complete); |
| 1072 | 1161 | else if (temp & MSR_RDF) |
| 1073 | − lpi2c_imx_read_rxfifo(lpi2c_imx); | |
| 1162 | + lpi2c_imx_read_rxfifo(lpi2c_imx, false); | |
| 1074 | 1163 | else if (temp & MSR_TDF) |
| 1075 | − lpi2c_imx_write_txfifo(lpi2c_imx); | |
| 1164 | + lpi2c_imx_write_txfifo(lpi2c_imx, false); | |
| 1076 | 1165 | |
| 1077 | 1166 | return IRQ_HANDLED; |
| 1078 | 1167 | } |
| @@ -1269,6 +1358,7 @@ static u32 lpi2c_imx_func(struct i2c_adapter *adapter) · 190 unmodified lines | ||
| 1269 | 1358 | |
| 1270 | 1359 | static const struct i2c_algorithm lpi2c_imx_algo = { |
| 1271 | 1360 | .xfer = lpi2c_imx_xfer, |
| 1361 | + .xfer_atomic = lpi2c_imx_xfer_atomic, | |
| 1272 | 1362 | .functionality = lpi2c_imx_func, |
| 1273 | 1363 | .reg_target = lpi2c_imx_register_target, |
| 1274 | 1364 | .unreg_target = lpi2c_imx_unregister_target, |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <linux/acpi.h> |
| 25 | 25 | #include <linux/clk.h> |
| 26 | +#include <linux/cleanup.h> | |
| 26 | 27 | #include <linux/completion.h> |
| 27 | 28 | #include <linux/delay.h> |
| 28 | 29 | #include <linux/dma-mapping.h> |
| @@ -891,13 +892,13 @@ static enum hrtimer_restart i2c_imx_slave_timeout(struct hrtimer *t) · 862 unmodified lines | ||
| 891 | 892 | struct imx_i2c_struct *i2c_imx = container_of(t, struct imx_i2c_struct, |
| 892 | 893 | slave_timer); |
| 893 | 894 | unsigned int ctl, status; |
| 894 | − unsigned long flags; | |
| 895 | 895 | |
| 896 | − spin_lock_irqsave(&i2c_imx->slave_lock, flags); | |
| 896 | + guard(spinlock_irqsave)(&i2c_imx->slave_lock); | |
| 897 | + | |
| 897 | 898 | status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); |
| 898 | 899 | ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); |
| 899 | 900 | i2c_imx_slave_handle(i2c_imx, status, ctl); |
| 900 | − spin_unlock_irqrestore(&i2c_imx->slave_lock, flags); | |
| 901 | + | |
| 901 | 902 | return HRTIMER_NORESTART; |
| 902 | 903 | } |
| 903 | 904 | |
| @@ -1126,32 +1127,26 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id) · 222 unmodified lines | ||
| 1126 | 1127 | { |
| 1127 | 1128 | struct imx_i2c_struct *i2c_imx = dev_id; |
| 1128 | 1129 | unsigned int ctl, status; |
| 1129 | − unsigned long flags; | |
| 1130 | 1130 | |
| 1131 | − spin_lock_irqsave(&i2c_imx->slave_lock, flags); | |
| 1132 | − status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); | |
| 1133 | − ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); | |
| 1131 | + scoped_guard(spinlock_irqsave, &i2c_imx->slave_lock) { | |
| 1132 | + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); | |
| 1133 | + ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); | |
| 1134 | + | |
| 1135 | + if (!(status & I2SR_IIF)) | |
| 1136 | + return IRQ_NONE; | |
| 1134 | 1137 | |
| 1135 | − if (status & I2SR_IIF) { | |
| 1136 | 1138 | i2c_imx_clear_irq(i2c_imx, I2SR_IIF); |
| 1139 | + | |
| 1137 | 1140 | if (i2c_imx->slave) { |
| 1138 | − if (!(ctl & I2CR_MSTA)) { | |
| 1139 | − irqreturn_t ret; | |
| 1140 | − | |
| 1141 | − ret = i2c_imx_slave_handle(i2c_imx, | |
| 1142 | − status, ctl); | |
| 1143 | − spin_unlock_irqrestore(&i2c_imx->slave_lock, | |
| 1144 | − flags); | |
| 1145 | − return ret; | |
| 1146 | − } | |
| 1141 | + if (!(ctl & I2CR_MSTA)) | |
| 1142 | + return i2c_imx_slave_handle(i2c_imx, | |
| 1143 | + status, ctl); | |
| 1144 | + | |
| 1147 | 1145 | i2c_imx_slave_finish_op(i2c_imx); |
| 1148 | 1146 | } |
| 1149 | − spin_unlock_irqrestore(&i2c_imx->slave_lock, flags); | |
| 1150 | − return i2c_imx_master_isr(i2c_imx, status); | |
| 1151 | 1147 | } |
| 1152 | − spin_unlock_irqrestore(&i2c_imx->slave_lock, flags); | |
| 1153 | 1148 | |
| 1154 | − return IRQ_NONE; | |
| 1149 | + return i2c_imx_master_isr(i2c_imx, status); | |
| 1155 | 1150 | } |
| 1156 | 1151 | |
| 1157 | 1152 | static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx, |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | #define ICIER_SPIE BIT(3) |
| 80 | 80 | |
| 81 | 81 | #define ICSR2_NACKF BIT(4) |
| 82 | +#define ICSR2_STOP BIT(3) | |
| 82 | 83 | |
| 83 | 84 | #define ICBR_RESERVED GENMASK(7, 5) /* Should be 1 on writes */ |
| 84 | 85 | |
| @@ -102,6 +103,8 @@ enum riic_reg_list { · 17 unmodified lines | ||
| 102 | 103 | |
| 103 | 104 | struct riic_of_data { |
| 104 | 105 | const u8 *regs; |
| 106 | + const struct riic_irq_desc *irqs; | |
| 107 | + u8 num_irqs; | |
| 105 | 108 | bool fast_mode_plus; |
| 106 | 109 | }; |
| 107 | 110 | |
| @@ -324,6 +327,19 @@ static irqreturn_t riic_stop_isr(int irq, void *data) · 216 unmodified lines | ||
| 324 | 327 | return IRQ_HANDLED; |
| 325 | 328 | } |
| 326 | 329 | |
| 330 | +static irqreturn_t riic_eei_isr(int irq, void *data) | |
| 331 | +{ | |
| 332 | + u8 icsr2 = riic_readb(data, RIIC_ICSR2); | |
| 333 | + | |
| 334 | + if (icsr2 & ICSR2_NACKF) | |
| 335 | + return riic_tend_isr(irq, data); | |
| 336 | + | |
| 337 | + if (icsr2 & ICSR2_STOP) | |
| 338 | + return riic_stop_isr(irq, data); | |
| 339 | + | |
| 340 | + return IRQ_NONE; | |
| 341 | +} | |
| 342 | + | |
| 327 | 343 | static u32 riic_func(struct i2c_adapter *adap) |
| 328 | 344 | { |
| 329 | 345 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
| @@ -495,6 +511,13 @@ static const struct riic_irq_desc riic_irqs[] = { · 165 unmodified lines | ||
| 495 | 511 | { .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" }, |
| 496 | 512 | }; |
| 497 | 513 | |
| 514 | +static const struct riic_irq_desc riic_rzt2h_irqs[] = { | |
| 515 | + { .res_num = 0, .isr = riic_eei_isr, .name = "riic-eei" }, | |
| 516 | + { .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rxi" }, | |
| 517 | + { .res_num = 2, .isr = riic_tdre_isr, .name = "riic-txi" }, | |
| 518 | + { .res_num = 3, .isr = riic_tend_isr, .name = "riic-tei" }, | |
| 519 | +}; | |
| 520 | + | |
| 498 | 521 | static int riic_i2c_probe(struct platform_device *pdev) |
| 499 | 522 | { |
| 500 | 523 | struct device *dev = &pdev->dev; |
| @@ -520,21 +543,23 @@ static int riic_i2c_probe(struct platform_device *pdev) · 19 unmodified lines | ||
| 520 | 543 | return dev_err_probe(dev, PTR_ERR(riic->rstc), |
| 521 | 544 | "failed to acquire deasserted reset\n"); |
| 522 | 545 | |
| 523 | − for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) { | |
| 546 | + riic->info = of_device_get_match_data(dev); | |
| 547 | + | |
| 548 | + for (i = 0; i < riic->info->num_irqs; i++) { | |
| 549 | + const struct riic_irq_desc *irq_desc; | |
| 524 | 550 | int irq; |
| 525 | 551 | |
| 526 | − irq = platform_get_irq(pdev, riic_irqs[i].res_num); | |
| 552 | + irq_desc = &riic->info->irqs[i]; | |
| 553 | + irq = platform_get_irq(pdev, irq_desc->res_num); | |
| 527 | 554 | if (irq < 0) |
| 528 | 555 | return irq; |
| 529 | 556 | |
| 530 | − ret = devm_request_irq(dev, irq, riic_irqs[i].isr, | |
| 531 | − 0, riic_irqs[i].name, riic); | |
| 557 | + ret = devm_request_irq(dev, irq, irq_desc->isr, 0, irq_desc->name, riic); | |
| 532 | 558 | if (ret) |
| 533 | 559 | return dev_err_probe(dev, ret, "failed to request irq %s\n", |
| 534 | − riic_irqs[i].name); | |
| 560 | + irq_desc->name); | |
| 535 | 561 | } |
| 536 | 562 | |
| 537 | − riic->info = of_device_get_match_data(dev); | |
| 538 | 563 | |
| 539 | 564 | adap = &riic->adapter; |
| 540 | 565 | i2c_set_adapdata(adap, riic); |
| @@ -606,11 +631,15 @@ static const u8 riic_rz_a_regs[RIIC_REG_END] = { · 65 unmodified lines | ||
| 606 | 631 | |
| 607 | 632 | static const struct riic_of_data riic_rz_a_info = { |
| 608 | 633 | .regs = riic_rz_a_regs, |
| 634 | + .irqs = riic_irqs, | |
| 635 | + .num_irqs = ARRAY_SIZE(riic_irqs), | |
| 609 | 636 | .fast_mode_plus = true, |
| 610 | 637 | }; |
| 611 | 638 | |
| 612 | 639 | static const struct riic_of_data riic_rz_a1h_info = { |
| 613 | 640 | .regs = riic_rz_a_regs, |
| 641 | + .irqs = riic_irqs, | |
| 642 | + .num_irqs = ARRAY_SIZE(riic_irqs), | |
| 614 | 643 | }; |
| 615 | 644 | |
| 616 | 645 | static const u8 riic_rz_v2h_regs[RIIC_REG_END] = { |
| @@ -630,9 +659,17 @@ static const u8 riic_rz_v2h_regs[RIIC_REG_END] = { · 13 unmodified lines | ||
| 630 | 659 | |
| 631 | 660 | static const struct riic_of_data riic_rz_v2h_info = { |
| 632 | 661 | .regs = riic_rz_v2h_regs, |
| 662 | + .irqs = riic_irqs, | |
| 663 | + .num_irqs = ARRAY_SIZE(riic_irqs), | |
| 633 | 664 | .fast_mode_plus = true, |
| 634 | 665 | }; |
| 635 | 666 | |
| 667 | +static const struct riic_of_data riic_rz_t2h_info = { | |
| 668 | + .regs = riic_rz_v2h_regs, | |
| 669 | + .irqs = riic_rzt2h_irqs, | |
| 670 | + .num_irqs = ARRAY_SIZE(riic_rzt2h_irqs), | |
| 671 | +}; | |
| 672 | + | |
| 636 | 673 | static int riic_i2c_suspend(struct device *dev) |
| 637 | 674 | { |
| 638 | 675 | struct riic_dev *riic = dev_get_drvdata(dev); |
| @@ -683,10 +720,11 @@ static const struct dev_pm_ops riic_i2c_pm_ops = { · 44 unmodified lines | ||
| 683 | 720 | }; |
| 684 | 721 | |
| 685 | 722 | static const struct of_device_id riic_i2c_dt_ids[] = { |
| 686 | − { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info }, | |
| 687 | 723 | { .compatible = "renesas,riic-r7s72100", .data = &riic_rz_a1h_info, }, |
| 688 | 724 | { .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info }, |
| 689 | − { /* Sentinel */ }, | |
| 725 | + { .compatible = "renesas,riic-r9a09g077", .data = &riic_rz_t2h_info }, | |
| 726 | + { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info }, | |
| 727 | + { /* Sentinel */ } | |
| 690 | 728 | }; |
| 691 | 729 | |
| 692 | 730 | static struct platform_driver riic_i2c_driver = { |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/i2c.h> |
| 14 | 14 | #include <linux/interrupt.h> |
| 15 | 15 | #include <linux/io.h> |
| 16 | +#include <linux/minmax.h> | |
| 16 | 17 | #include <linux/module.h> |
| 17 | 18 | #include <linux/of_address.h> |
| 18 | 19 | #include <linux/of_irq.h> |
| @@ -422,12 +423,8 @@ static void st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev) · 403 unmodified lines | ||
| 422 | 423 | tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT); |
| 423 | 424 | tx_fstat &= SSC_TX_FSTAT_STATUS; |
| 424 | 425 | |
| 425 | − if (c->count < (SSC_TXFIFO_SIZE - tx_fstat)) | |
| 426 | − i = c->count; | |
| 427 | − else | |
| 428 | − i = SSC_TXFIFO_SIZE - tx_fstat; | |
| 429 | − | |
| 430 | − for (; i > 0; i--, c->count--, c->buf++) | |
| 426 | + for (i = min(c->count, SSC_TXFIFO_SIZE - tx_fstat); | |
| 427 | + i > 0; i--, c->count--, c->buf++) | |
| 431 | 428 | st_i2c_write_tx_fifo(i2c_dev, *c->buf); |
| 432 | 429 | } |
| 433 | 430 | |
| @@ -439,7 +436,7 @@ static void st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev) · 5 unmodified lines | ||
| 439 | 436 | * This functions fills the Tx FIFO with fixed pattern when |
| 440 | 437 | * in read mode to trigger clock. |
| 441 | 438 | */ |
| 442 | −static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max) | |
| 439 | +static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, u32 max) | |
| 443 | 440 | { |
| 444 | 441 | struct st_i2c_client *c = &i2c_dev->client; |
| 445 | 442 | u32 tx_fstat, sta; |
| @@ -452,12 +449,8 @@ static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max) · 6 unmodified lines | ||
| 452 | 449 | tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT); |
| 453 | 450 | tx_fstat &= SSC_TX_FSTAT_STATUS; |
| 454 | 451 | |
| 455 | − if (max < (SSC_TXFIFO_SIZE - tx_fstat)) | |
| 456 | − i = max; | |
| 457 | − else | |
| 458 | − i = SSC_TXFIFO_SIZE - tx_fstat; | |
| 459 | − | |
| 460 | − for (; i > 0; i--, c->xfered++) | |
| 452 | + for (i = min(max, SSC_TXFIFO_SIZE - tx_fstat); | |
| 453 | + i > 0; i--, c->xfered++) | |
| 461 | 454 | st_i2c_write_tx_fifo(i2c_dev, 0xff); |
| 462 | 455 | } |
| 463 | 456 | |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/regmap.h> |
| 35 | 35 | #include <linux/reset.h> |
| 36 | 36 | #include <linux/slab.h> |
| 37 | +#include <linux/string_choices.h> | |
| 37 | 38 | |
| 38 | 39 | #include "i2c-stm32.h" |
| 39 | 40 | |
| @@ -722,7 +723,7 @@ static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev, · 682 unmodified lines | ||
| 722 | 723 | dev_dbg(i2c_dev->dev, "I2C Rise(%i) and Fall(%i) Time\n", |
| 723 | 724 | setup->rise_time, setup->fall_time); |
| 724 | 725 | dev_dbg(i2c_dev->dev, "I2C Analog Filter(%s), DNF(%i)\n", |
| 725 | − (i2c_dev->analog_filter ? "On" : "Off"), i2c_dev->dnf); | |
| 726 | + str_on_off(i2c_dev->analog_filter), i2c_dev->dnf); | |
| 726 | 727 | |
| 727 | 728 | i2c_dev->bus_rate = setup->speed_freq; |
| 728 | 729 | |
| @@ -253,6 +253,7 @@ struct tegra_i2c_hw_feature { · 252 unmodified lines | ||
| 253 | 253 | * @dma_phys: handle to DMA resources |
| 254 | 254 | * @dma_buf: pointer to allocated DMA buffer |
| 255 | 255 | * @dma_buf_size: DMA buffer size |
| 256 | + * @dma_dev: DMA device used for transfers | |
| 256 | 257 | * @dma_mode: indicates active DMA transfer |
| 257 | 258 | * @dma_complete: DMA completion notifier |
| 258 | 259 | * @atomic_mode: indicates active atomic transfer |
| @@ -250,7 +250,7 @@ static int i2c_acpi_get_info(struct acpi_device *adev, · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | if (adapter) { |
| 252 | 252 | /* The adapter must match the one in I2cSerialBus() connector */ |
| 253 | − if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle) | |
| 253 | + if (!device_match_acpi_handle(&adapter->dev, lookup.adapter_handle)) | |
| 254 | 254 | return -ENODEV; |
| 255 | 255 | } else { |
| 256 | 256 | struct acpi_device *adapter_adev; |
| @@ -1066,7 +1066,13 @@ void i2c_unregister_device(struct i2c_client *client) · 1065 unmodified lines | ||
| 1066 | 1066 | of_node_clear_flag(to_of_node(fwnode), OF_POPULATED); |
| 1067 | 1067 | else if (is_acpi_device_node(fwnode)) |
| 1068 | 1068 | acpi_device_clear_enumerated(to_acpi_device_node(fwnode)); |
| 1069 | − fwnode_handle_put(fwnode); | |
| 1069 | + | |
| 1070 | + /* | |
| 1071 | + * If the primary fwnode is a software node it is free-ed by | |
| 1072 | + * device_remove_software_node() below, avoid double-free. | |
| 1073 | + */ | |
| 1074 | + if (!is_software_node(fwnode)) | |
| 1075 | + fwnode_handle_put(fwnode); | |
| 1070 | 1076 | |
| 1071 | 1077 | device_remove_software_node(&client->dev); |
| 1072 | 1078 | device_unregister(&client->dev); |
| @@ -442,8 +442,7 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc) · 441 unmodified lines | ||
| 442 | 442 | |
| 443 | 443 | raw_spin_lock_init(&data->lock); |
| 444 | 444 | |
| 445 | − data->irq = irq_domain_create_linear(of_fwnode_handle(client->dev.of_node), | |
| 446 | − data->chip->nchans, | |
| 445 | + data->irq = irq_domain_create_linear(dev_fwnode(&client->dev), data->chip->nchans, | |
| 447 | 446 | &irq_domain_simple_ops, data); |
| 448 | 447 | if (!data->irq) |
| 449 | 448 | return -ENODEV; |
| @@ -21,7 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | * |
| 22 | 22 | * @flags: |
| 23 | 23 | * Supported by all adapters: |
| 24 | − * %I2C_M_RD: read data (from slave to master). Guaranteed to be 0x0001! | |
| 24 | + * %I2C_M_RD: read data (from slave to master). Guaranteed to be 0x0001! If | |
| 25 | + * not set, the transaction is interpreted as write. | |
| 25 | 26 | * |
| 26 | 27 | * Optional: |
| 27 | 28 | * %I2C_M_DMA_SAFE: the buffer of this message is DMA safe. Makes only sense |