diff options
-rw-r--r-- | bcm283x-fixes.patch | 1003 | ||||
-rw-r--r-- | kernel.spec | 9 |
2 files changed, 1009 insertions, 3 deletions
diff --git a/bcm283x-fixes.patch b/bcm283x-fixes.patch new file mode 100644 index 000000000..b9f1b115a --- /dev/null +++ b/bcm283x-fixes.patch @@ -0,0 +1,1003 @@ +From e2474541032db65d02bf88b6a8c2f954654b443f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:08 +0200 +Subject: [PATCH 31155/39886] i2c: bcm2835: Fix hang for writing messages + larger than 16 bytes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Writing messages larger than the FIFO size results in a hang, rendering +the machine unusable. This is because the RXD status flag is set on the +first interrupt which results in bcm2835_drain_rxfifo() stealing bytes +from the buffer. The controller continues to trigger interrupts waiting +for the missing bytes, but bcm2835_fill_txfifo() has none to give. +In this situation wait_for_completion_timeout() apparently is unable to +stop the madness. + +The BCM2835 ARM Peripherals datasheet has this to say about the flags: + TXD: is set when the FIFO has space for at least one byte of data. + RXD: is set when the FIFO contains at least one byte of data. + TXW: is set during a write transfer and the FIFO is less than full. + RXR: is set during a read transfer and the FIFO is or more full. + +Implementing the logic from the downstream i2c-bcm2708 driver solved +the hang problem. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Reviewed-by: Martin Sperl <kernel@martin.sperl.org> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index d4f3239..f283b71 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -64,6 +64,7 @@ struct bcm2835_i2c_dev { + int irq; + struct i2c_adapter adapter; + struct completion completion; ++ struct i2c_msg *curr_msg; + u32 msg_err; + u8 *msg_buf; + size_t msg_buf_remaining; +@@ -126,14 +127,13 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + return IRQ_HANDLED; + } + +- if (val & BCM2835_I2C_S_RXD) { +- bcm2835_drain_rxfifo(i2c_dev); +- if (!(val & BCM2835_I2C_S_DONE)) +- return IRQ_HANDLED; +- } +- + if (val & BCM2835_I2C_S_DONE) { +- if (i2c_dev->msg_buf_remaining) ++ if (i2c_dev->curr_msg->flags & I2C_M_RD) { ++ bcm2835_drain_rxfifo(i2c_dev); ++ val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); ++ } ++ ++ if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) + i2c_dev->msg_err = BCM2835_I2C_S_LEN; + else + i2c_dev->msg_err = 0; +@@ -141,11 +141,16 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + return IRQ_HANDLED; + } + +- if (val & BCM2835_I2C_S_TXD) { ++ if (val & BCM2835_I2C_S_TXW) { + bcm2835_fill_txfifo(i2c_dev); + return IRQ_HANDLED; + } + ++ if (val & BCM2835_I2C_S_RXR) { ++ bcm2835_drain_rxfifo(i2c_dev); ++ return IRQ_HANDLED; ++ } ++ + return IRQ_NONE; + } + +@@ -155,6 +160,7 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, + u32 c; + unsigned long time_left; + ++ i2c_dev->curr_msg = msg; + i2c_dev->msg_buf = msg->buf; + i2c_dev->msg_buf_remaining = msg->len; + reinit_completion(&i2c_dev->completion); +-- +2.9.3 + +From d4030d75c7cbb434b2a3e5f6af5065879d2615a5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:09 +0200 +Subject: [PATCH 31156/39886] i2c: bcm2835: Protect against unexpected TXW/RXR + interrupts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If an unexpected TXW or RXR interrupt occurs (msg_buf_remaining == 0), +the driver has no way to fill/drain the FIFO to stop the interrupts. +In this case the controller has to be disabled and the transfer +completed to avoid hang. + +(CLKT | ERR) and DONE interrupts are completed in their own paths, and +the controller is disabled in the transfer function after completion. +Unite the code paths and do disabling inside the interrupt routine. + +Clear interrupt status bits in the united completion path instead of +trying to do it on every interrupt which isn't necessary. +Only CLKT, ERR and DONE can be cleared that way. + +Add the status value to the error value in case of TXW/RXR errors to +distinguish them from the other S_LEN error. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 40 +++++++++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 9 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index f283b71..d2ba1a4 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -50,8 +50,6 @@ + #define BCM2835_I2C_S_CLKT BIT(9) + #define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */ + +-#define BCM2835_I2C_BITMSK_S 0x03FF +- + #define BCM2835_I2C_CDIV_MIN 0x0002 + #define BCM2835_I2C_CDIV_MAX 0xFFFE + +@@ -111,20 +109,26 @@ static void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev) + } + } + ++/* ++ * Note about I2C_C_CLEAR on error: ++ * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in ++ * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through ++ * the state machine to send a NACK and a STOP. Since we're setting CLEAR ++ * without I2CEN, that NACK will be hanging around queued up for next time ++ * we start the engine. ++ */ ++ + static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + { + struct bcm2835_i2c_dev *i2c_dev = data; + u32 val, err; + + val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); +- val &= BCM2835_I2C_BITMSK_S; +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, val); + + err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR); + if (err) { + i2c_dev->msg_err = err; +- complete(&i2c_dev->completion); +- return IRQ_HANDLED; ++ goto complete; + } + + if (val & BCM2835_I2C_S_DONE) { +@@ -137,21 +141,38 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + i2c_dev->msg_err = BCM2835_I2C_S_LEN; + else + i2c_dev->msg_err = 0; +- complete(&i2c_dev->completion); +- return IRQ_HANDLED; ++ goto complete; + } + + if (val & BCM2835_I2C_S_TXW) { ++ if (!i2c_dev->msg_buf_remaining) { ++ i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; ++ goto complete; ++ } ++ + bcm2835_fill_txfifo(i2c_dev); + return IRQ_HANDLED; + } + + if (val & BCM2835_I2C_S_RXR) { ++ if (!i2c_dev->msg_buf_remaining) { ++ i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; ++ goto complete; ++ } ++ + bcm2835_drain_rxfifo(i2c_dev); + return IRQ_HANDLED; + } + + return IRQ_NONE; ++ ++complete: ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, BCM2835_I2C_S_CLKT | ++ BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE); ++ complete(&i2c_dev->completion); ++ ++ return IRQ_HANDLED; + } + + static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, +@@ -181,8 +202,9 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, + + time_left = wait_for_completion_timeout(&i2c_dev->completion, + BCM2835_I2C_TIMEOUT); +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); + if (!time_left) { ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, ++ BCM2835_I2C_C_CLEAR); + dev_err(i2c_dev->dev, "i2c transfer timed out\n"); + return -ETIMEDOUT; + } +-- +2.9.3 + +From 23c9540b3ad1d7473fe40df80074d0fb0bf04869 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:10 +0200 +Subject: [PATCH 31157/39886] i2c: bcm2835: Use dev_dbg logging on transfer + errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Writing to an AT24C32 generates on average 2x i2c transfer errors per +32-byte page write. Which amounts to a lot for a 4k write. This is due +to the fact that the chip doesn't respond during it's internal write +cycle when the at24 driver tries and retries the next write. +Only a handful drivers use dev_err() on transfer error, so switch to +dev_dbg() instead. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index d2ba1a4..54d510a 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -216,7 +216,7 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, + (msg->flags & I2C_M_IGNORE_NAK)) + return 0; + +- dev_err(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); ++ dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); + + if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) + return -EREMOTEIO; +-- +2.9.3 + +From 8d2cc5cc6ee5c0fc48a96bb29af55fc700f66fdf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:11 +0200 +Subject: [PATCH 31158/39886] i2c: bcm2835: Can't support I2C_M_IGNORE_NAK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The controller can't support this flag, so remove it. + +Documentation/i2c/i2c-protocol states that all of the message is sent: + +I2C_M_IGNORE_NAK: + Normally message is interrupted immediately if there is [NA] from the + client. Setting this flag treats any [NA] as [A], and all of + message is sent. + +>From the BCM2835 ARM Peripherals datasheet: + + The ERR field is set when the slave fails to acknowledge either + its address or a data byte written to it. + +So when the controller doesn't receive an ack, it sets ERR and raises +an interrupt. In other words, the whole message is not sent. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index 54d510a..565ef69 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -212,10 +212,6 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, + if (likely(!i2c_dev->msg_err)) + return 0; + +- if ((i2c_dev->msg_err & BCM2835_I2C_S_ERR) && +- (msg->flags & I2C_M_IGNORE_NAK)) +- return 0; +- + dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); + + if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) +-- +2.9.3 + +From ee05fea21b017b81a9477569b6a0c2d8e2946ac9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:12 +0200 +Subject: [PATCH 31159/39886] i2c: bcm2835: Add support for Repeated Start + Condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Documentation/i2c/i2c-protocol states that Combined transactions should +separate messages with a Start bit and end the whole transaction with a +Stop bit. This patch adds support for issuing only a Start between +messages instead of a Stop followed by a Start. + +This implementation differs from downstream i2c-bcm2708 in 2 respects: +- it uses an interrupt to detect that the transfer is active instead + of using polling. There is no interrupt for Transfer Active, but by + not prefilling the FIFO it's possible to use the TXW interrupt. +- when resetting/disabling the controller between transfers it writes + CLEAR to the control register instead of just zero. + Using just zero gave many errors. This might be the reason why + downstream had to disable this feature and make it available with a + module parameter. + +I have run thousands of transfers to a DS1307 (rtc), MMA8451 (accel) +and AT24C32 (eeprom) in parallel without problems. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Acked-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 101 ++++++++++++++++++++++++--------------- + 1 file changed, 63 insertions(+), 38 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index 565ef69..241e08a 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -63,6 +63,7 @@ struct bcm2835_i2c_dev { + struct i2c_adapter adapter; + struct completion completion; + struct i2c_msg *curr_msg; ++ int num_msgs; + u32 msg_err; + u8 *msg_buf; + size_t msg_buf_remaining; +@@ -110,6 +111,45 @@ static void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev) + } + + /* ++ * Repeated Start Condition (Sr) ++ * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it ++ * talks about reading from a slave with 10 bit address. This is achieved by ++ * issuing a write, poll the I2CS.TA flag and wait for it to be set, and then ++ * issue a read. ++ * A comment in https://github.com/raspberrypi/linux/issues/254 shows how the ++ * firmware actually does it using polling and says that it's a workaround for ++ * a problem in the state machine. ++ * It turns out that it is possible to use the TXW interrupt to know when the ++ * transfer is active, provided the FIFO has not been prefilled. ++ */ ++ ++static void bcm2835_i2c_start_transfer(struct bcm2835_i2c_dev *i2c_dev) ++{ ++ u32 c = BCM2835_I2C_C_ST | BCM2835_I2C_C_I2CEN; ++ struct i2c_msg *msg = i2c_dev->curr_msg; ++ bool last_msg = (i2c_dev->num_msgs == 1); ++ ++ if (!i2c_dev->num_msgs) ++ return; ++ ++ i2c_dev->num_msgs--; ++ i2c_dev->msg_buf = msg->buf; ++ i2c_dev->msg_buf_remaining = msg->len; ++ ++ if (msg->flags & I2C_M_RD) ++ c |= BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR; ++ else ++ c |= BCM2835_I2C_C_INTT; ++ ++ if (last_msg) ++ c |= BCM2835_I2C_C_INTD; ++ ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c); ++} ++ ++/* + * Note about I2C_C_CLEAR on error: + * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in + * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through +@@ -151,6 +191,12 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + } + + bcm2835_fill_txfifo(i2c_dev); ++ ++ if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) { ++ i2c_dev->curr_msg++; ++ bcm2835_i2c_start_transfer(i2c_dev); ++ } ++ + return IRQ_HANDLED; + } + +@@ -175,30 +221,25 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + return IRQ_HANDLED; + } + +-static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, +- struct i2c_msg *msg) ++static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], ++ int num) + { +- u32 c; ++ struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); + unsigned long time_left; ++ int i; + +- i2c_dev->curr_msg = msg; +- i2c_dev->msg_buf = msg->buf; +- i2c_dev->msg_buf_remaining = msg->len; +- reinit_completion(&i2c_dev->completion); +- +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); ++ for (i = 0; i < (num - 1); i++) ++ if (msgs[i].flags & I2C_M_RD) { ++ dev_warn_once(i2c_dev->dev, ++ "only one read message supported, has to be last\n"); ++ return -EOPNOTSUPP; ++ } + +- if (msg->flags & I2C_M_RD) { +- c = BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR; +- } else { +- c = BCM2835_I2C_C_INTT; +- bcm2835_fill_txfifo(i2c_dev); +- } +- c |= BCM2835_I2C_C_ST | BCM2835_I2C_C_INTD | BCM2835_I2C_C_I2CEN; ++ i2c_dev->curr_msg = msgs; ++ i2c_dev->num_msgs = num; ++ reinit_completion(&i2c_dev->completion); + +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c); ++ bcm2835_i2c_start_transfer(i2c_dev); + + time_left = wait_for_completion_timeout(&i2c_dev->completion, + BCM2835_I2C_TIMEOUT); +@@ -209,31 +250,15 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, + return -ETIMEDOUT; + } + +- if (likely(!i2c_dev->msg_err)) +- return 0; ++ if (!i2c_dev->msg_err) ++ return num; + + dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); + + if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) + return -EREMOTEIO; +- else +- return -EIO; +-} +- +-static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], +- int num) +-{ +- struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); +- int i; +- int ret = 0; +- +- for (i = 0; i < num; i++) { +- ret = bcm2835_i2c_xfer_msg(i2c_dev, &msgs[i]); +- if (ret) +- break; +- } + +- return ret ?: i; ++ return -EIO; + } + + static u32 bcm2835_i2c_func(struct i2c_adapter *adap) +-- +2.9.3 + +From e13e19e12f66401ce1e21ab491715835852babe7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:13 +0200 +Subject: [PATCH 31160/39886] i2c: bcm2835: Support i2c-dev ioctl I2C_TIMEOUT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use i2c_adapter->timeout for the completion timeout value. The core +default is 1 second. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index 241e08a..d2085dd 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -53,8 +53,6 @@ + #define BCM2835_I2C_CDIV_MIN 0x0002 + #define BCM2835_I2C_CDIV_MAX 0xFFFE + +-#define BCM2835_I2C_TIMEOUT (msecs_to_jiffies(1000)) +- + struct bcm2835_i2c_dev { + struct device *dev; + void __iomem *regs; +@@ -242,7 +240,7 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + bcm2835_i2c_start_transfer(i2c_dev); + + time_left = wait_for_completion_timeout(&i2c_dev->completion, +- BCM2835_I2C_TIMEOUT); ++ adap->timeout); + if (!time_left) { + bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, + BCM2835_I2C_C_CLEAR); +-- +2.9.3 + +From 9446f62e8e18057fceb179d947508df2f7253b26 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:14 +0200 +Subject: [PATCH 31161/39886] i2c: bcm2835: Add support for dynamic clock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Support a dynamic clock by reading the frequency and setting the +divisor in the transfer function instead of during probe. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Martin Sperl <kernel@martin.sperl.org> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 51 +++++++++++++++++++++++++--------------- + 1 file changed, 32 insertions(+), 19 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index d2085dd..c3436f6 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -58,6 +58,7 @@ struct bcm2835_i2c_dev { + void __iomem *regs; + struct clk *clk; + int irq; ++ u32 bus_clk_rate; + struct i2c_adapter adapter; + struct completion completion; + struct i2c_msg *curr_msg; +@@ -78,6 +79,30 @@ static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg) + return readl(i2c_dev->regs + reg); + } + ++static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev) ++{ ++ u32 divider; ++ ++ divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), ++ i2c_dev->bus_clk_rate); ++ /* ++ * Per the datasheet, the register is always interpreted as an even ++ * number, by rounding down. In other words, the LSB is ignored. So, ++ * if the LSB is set, increment the divider to avoid any issue. ++ */ ++ if (divider & 1) ++ divider++; ++ if ((divider < BCM2835_I2C_CDIV_MIN) || ++ (divider > BCM2835_I2C_CDIV_MAX)) { ++ dev_err_ratelimited(i2c_dev->dev, "Invalid clock-frequency\n"); ++ return -EINVAL; ++ } ++ ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider); ++ ++ return 0; ++} ++ + static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev) + { + u32 val; +@@ -224,7 +249,7 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + { + struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); + unsigned long time_left; +- int i; ++ int i, ret; + + for (i = 0; i < (num - 1); i++) + if (msgs[i].flags & I2C_M_RD) { +@@ -233,6 +258,10 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + return -EOPNOTSUPP; + } + ++ ret = bcm2835_i2c_set_divider(i2c_dev); ++ if (ret) ++ return ret; ++ + i2c_dev->curr_msg = msgs; + i2c_dev->num_msgs = num; + reinit_completion(&i2c_dev->completion); +@@ -282,7 +311,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) + { + struct bcm2835_i2c_dev *i2c_dev; + struct resource *mem, *irq; +- u32 bus_clk_rate, divider; + int ret; + struct i2c_adapter *adap; + +@@ -306,27 +334,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) + } + + ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", +- &bus_clk_rate); ++ &i2c_dev->bus_clk_rate); + if (ret < 0) { + dev_warn(&pdev->dev, + "Could not read clock-frequency property\n"); +- bus_clk_rate = 100000; +- } +- +- divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), bus_clk_rate); +- /* +- * Per the datasheet, the register is always interpreted as an even +- * number, by rounding down. In other words, the LSB is ignored. So, +- * if the LSB is set, increment the divider to avoid any issue. +- */ +- if (divider & 1) +- divider++; +- if ((divider < BCM2835_I2C_CDIV_MIN) || +- (divider > BCM2835_I2C_CDIV_MAX)) { +- dev_err(&pdev->dev, "Invalid clock-frequency\n"); +- return -ENODEV; ++ i2c_dev->bus_clk_rate = 100000; + } +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider); + + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { +-- +2.9.3 + +From f2a46926aba1f0c33944901d2420a6a887455ddc Mon Sep 17 00:00:00 2001 +From: Boris Brezillon <boris.brezillon@free-electrons.com> +Date: Tue, 22 Nov 2016 12:45:28 -0800 +Subject: [PATCH 08819/13183] clk: bcm2835: Fix ->fixed_divider of pllh_aux + +There is no fixed divider on pllh_aux. + +Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +--- + drivers/clk/bcm/clk-bcm2835.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 8c7763f..836d075 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1596,7 +1596,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_AUX, + .load_mask = CM_PLLH_LOADAUX, + .hold_mask = 0, +- .fixed_divider = 10), ++ .fixed_divider = 1), + [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( + .name = "pllh_pix", + .source_pll = "pllh", +-- +2.9.3 + +From 68af4fa8f39b542a6cde7ac19518d88e9b3099dc Mon Sep 17 00:00:00 2001 +From: Boris Brezillon <boris.brezillon@free-electrons.com> +Date: Thu, 1 Dec 2016 20:27:21 +0100 +Subject: [PATCH 11732/13183] clk: bcm2835: Avoid overwriting the div info when + disabling a pll_div clk + +bcm2835_pll_divider_off() is resetting the divider field in the A2W reg +to zero when disabling the clock. + +Make sure we preserve this value by reading the previous a2w_reg value +first and ORing the result with A2W_PLL_CHANNEL_DISABLE. + +Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") +Cc: <stable@vger.kernel.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +--- + drivers/clk/bcm/clk-bcm2835.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 836d075..2acaa77 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -751,7 +751,9 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw) + cprman_write(cprman, data->cm_reg, + (cprman_read(cprman, data->cm_reg) & + ~data->load_mask) | data->hold_mask); +- cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); ++ cprman_write(cprman, data->a2w_reg, ++ cprman_read(cprman, data->a2w_reg) | ++ A2W_PLL_CHANNEL_DISABLE); + spin_unlock(&cprman->regs_lock); + } + +-- +2.9.3 + +commit 84c39b8b7d46883f7a7514c7d55909831aa846fd +Author: Arvind Yadav <arvind.yadav.cs@gmail.com> +Date: Wed Sep 21 23:03:57 2016 +0530 + + clocksource/drivers/bcm2835_timer: Unmap region obtained by of_iomap + + Free memory mapping, if bcm2835_timer_init is not successful. + + Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com> + Reviewed-by: Eric Anholt <eric@anholt.net> + Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> + +diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c +index e71acf2..f2f29d2 100644 +--- a/drivers/clocksource/bcm2835_timer.c ++++ b/drivers/clocksource/bcm2835_timer.c +@@ -96,7 +96,7 @@ static int __init bcm2835_timer_init(struct device_node *node) + ret = of_property_read_u32(node, "clock-frequency", &freq); + if (ret) { + pr_err("Can't read clock-frequency"); +- return ret; ++ goto err_iounmap; + } + + system_clock = base + REG_COUNTER_LO; +@@ -108,13 +108,15 @@ static int __init bcm2835_timer_init(struct device_node *node) + irq = irq_of_parse_and_map(node, DEFAULT_TIMER); + if (irq <= 0) { + pr_err("Can't parse IRQ"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_iounmap; + } + + timer = kzalloc(sizeof(*timer), GFP_KERNEL); + if (!timer) { + pr_err("Can't allocate timer struct\n"); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto err_iounmap; + } + + timer->control = base + REG_CONTROL; +@@ -133,7 +135,7 @@ static int __init bcm2835_timer_init(struct device_node *node) + ret = setup_irq(irq, &timer->act); + if (ret) { + pr_err("Can't set up timer IRQ\n"); +- return ret; ++ goto err_iounmap; + } + + clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); +@@ -141,6 +143,10 @@ static int __init bcm2835_timer_init(struct device_node *node) + pr_info("bcm2835: system timer (irq = %d)\n", irq); + + return 0; ++ ++err_iounmap: ++ iounmap(base); ++ return ret; + } + CLOCKSOURCE_OF_DECLARE(bcm2835, "brcm,bcm2835-system-timer", + bcm2835_timer_init); +From 155e8b3b0ee320ae866b97dd31eba8a1f080a772 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon <boris.brezillon@free-electrons.com> +Date: Thu, 1 Dec 2016 22:00:19 +0100 +Subject: [PATCH 11733/13183] clk: bcm: Support rate change propagation on + bcm2835 clocks + +Some peripheral clocks, like the VEC (Video EnCoder) clock need to be set +to a precise rate (in our case 108MHz). With the current implementation, +where peripheral clocks are not allowed to forward rate change requests +to their parents, it is impossible to match this requirement unless the +bootloader has configured things correctly, or a specific rate has been +assigned through the DT (with the assigned-clk-rates property). + +Add a new field to struct bcm2835_clock_data to specify which parent +clocks accept rate change propagation, and support set rate propagation +in bcm2835_clock_determine_rate(). + +Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +--- + drivers/clk/bcm/clk-bcm2835.c | 67 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 63 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 2acaa77..df96fe6 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -436,6 +436,9 @@ struct bcm2835_clock_data { + const char *const *parents; + int num_mux_parents; + ++ /* Bitmap encoding which parents accept rate change propagation. */ ++ unsigned int set_rate_parent; ++ + u32 ctl_reg; + u32 div_reg; + +@@ -1017,10 +1020,60 @@ bcm2835_clk_is_pllc(struct clk_hw *hw) + return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0; + } + ++static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, ++ int parent_idx, ++ unsigned long rate, ++ u32 *div, ++ unsigned long *prate) ++{ ++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); ++ struct bcm2835_cprman *cprman = clock->cprman; ++ const struct bcm2835_clock_data *data = clock->data; ++ unsigned long best_rate; ++ u32 curdiv, mindiv, maxdiv; ++ struct clk_hw *parent; ++ ++ parent = clk_hw_get_parent_by_index(hw, parent_idx); ++ ++ if (!(BIT(parent_idx) & data->set_rate_parent)) { ++ *prate = clk_hw_get_rate(parent); ++ *div = bcm2835_clock_choose_div(hw, rate, *prate, true); ++ ++ return bcm2835_clock_rate_from_divisor(clock, *prate, ++ *div); ++ } ++ ++ if (data->frac_bits) ++ dev_warn(cprman->dev, ++ "frac bits are not used when propagating rate change"); ++ ++ /* clamp to min divider of 2 if we're dealing with a mash clock */ ++ mindiv = data->is_mash_clock ? 2 : 1; ++ maxdiv = BIT(data->int_bits) - 1; ++ ++ /* TODO: Be smart, and only test a subset of the available divisors. */ ++ for (curdiv = mindiv; curdiv <= maxdiv; curdiv++) { ++ unsigned long tmp_rate; ++ ++ tmp_rate = clk_hw_round_rate(parent, rate * curdiv); ++ tmp_rate /= curdiv; ++ if (curdiv == mindiv || ++ (tmp_rate > best_rate && tmp_rate <= rate)) ++ best_rate = tmp_rate; ++ ++ if (best_rate == rate) ++ break; ++ } ++ ++ *div = curdiv << CM_DIV_FRAC_BITS; ++ *prate = curdiv * best_rate; ++ ++ return best_rate; ++} ++ + static int bcm2835_clock_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) + { +- struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct clk_hw *parent, *best_parent = NULL; + bool current_parent_is_pllc; + unsigned long rate, best_rate = 0; +@@ -1048,9 +1101,8 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, + if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc) + continue; + +- prate = clk_hw_get_rate(parent); +- div = bcm2835_clock_choose_div(hw, req->rate, prate, true); +- rate = bcm2835_clock_rate_from_divisor(clock, prate, div); ++ rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, ++ &div, &prate); + if (rate > best_rate && rate <= req->rate) { + best_parent = parent; + best_prate = prate; +@@ -1262,6 +1314,13 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, + init.name = data->name; + init.flags = data->flags | CLK_IGNORE_UNUSED; + ++ /* ++ * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate ++ * rate changes on at least of the parents. ++ */ ++ if (data->set_rate_parent) ++ init.flags |= CLK_SET_RATE_PARENT; ++ + if (data->is_vpu_clock) { + init.ops = &bcm2835_vpu_clock_clk_ops; + } else { +-- +2.9.3 + +From d86d46af84855403c00018be1c3e7bc190f2a6cd Mon Sep 17 00:00:00 2001 +From: Boris Brezillon <boris.brezillon@free-electrons.com> +Date: Thu, 1 Dec 2016 22:00:20 +0100 +Subject: [PATCH 11734/13183] clk: bcm: Allow rate change propagation to + PLLH_AUX on VEC clock + +The VEC clock requires needs to be set at exactly 108MHz. Allow rate +change propagation on PLLH_AUX to match this requirement wihtout +impacting other IPs (PLLH is currently only used by the HDMI encoder, +which cannot be enabled when the VEC encoder is enabled). + +Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +--- + drivers/clk/bcm/clk-bcm2835.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index df96fe6..eaf82f4 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1861,7 +1861,12 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_VECCTL, + .div_reg = CM_VECDIV, + .int_bits = 4, +- .frac_bits = 0), ++ .frac_bits = 0, ++ /* ++ * Allow rate change propagation only on PLLH_AUX which is ++ * assigned index 7 in the parent array. ++ */ ++ .set_rate_parent = BIT(7)), + + /* dsi clocks */ + [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( +-- +2.9.3 + +From 2aab7a2055a1705c9e30920d95a596226999eb21 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon <boris.brezillon@free-electrons.com> +Date: Mon, 12 Dec 2016 09:00:53 +0100 +Subject: [PATCH 12092/13183] clk: bcm: Fix 'maybe-uninitialized' warning in + bcm2835_clock_choose_div_and_prate() + +best_rate is reported as potentially uninitialized by gcc. + +Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Fixes: 155e8b3b0ee3 ("clk: bcm: Support rate change propagation on bcm2835 clocks") +Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +--- + drivers/clk/bcm/clk-bcm2835.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index eaf82f4..0d14409 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1029,7 +1029,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; + const struct bcm2835_clock_data *data = clock->data; +- unsigned long best_rate; ++ unsigned long best_rate = 0; + u32 curdiv, mindiv, maxdiv; + struct clk_hw *parent; + +-- +2.9.3 + diff --git a/kernel.spec b/kernel.spec index 0a11be54e..e15666cd9 100644 --- a/kernel.spec +++ b/kernel.spec @@ -525,11 +525,13 @@ Patch431: bcm2837-initial-support.patch Patch432: bcm283x-vc4-fixes.patch -Patch433: AllWinner-net-emac.patch +Patch433: bcm283x-fixes.patch -Patch434: ARM-Drop-fixed-200-Hz-timer-requirement-from-Samsung-platforms.patch +Patch434: AllWinner-net-emac.patch -Patch435: imx6sx-Add-UDOO-Neo-support.patch +Patch435: ARM-Drop-fixed-200-Hz-timer-requirement-from-Samsung-platforms.patch + +Patch436: imx6sx-Add-UDOO-Neo-support.patch Patch460: lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch @@ -2173,6 +2175,7 @@ fi * Tue Dec 20 2016 Peter Robinson <pbrobinson@fedoraproject.org> - Update some ARM options - Enable some Qualcomm QDF2432 server platform options +- Add upstream bcm283x i2c and clock fixes * Thu Dec 15 2016 Laura Abbott <labbott@fedoraproject.org> - Linux v4.9 rebase |