From d358d0fc3f999a5874756ce971c951a0cec8ea5a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 2 Jun 2018 15:35:14 +0200 Subject: [PATCH] 4.4-stable patches added patches: asoc-intel-sst-remove-redundant-variable-dma_dev_name.patch cfg80211-further-limit-wiphy-names-to-64-bytes.patch dmaengine-usb-dmac-fix-endless-loop-in-usb_dmac_chan_terminate_all.patch i2c-rcar-check-master-irqs-before-slave-irqs.patch i2c-rcar-don-t-issue-stop-when-hw-does-it-automatically.patch i2c-rcar-init-new-messages-in-irq.patch i2c-rcar-make-sure-clocks-are-on-when-doing-clock-calculation.patch i2c-rcar-refactor-setup-of-a-msg.patch i2c-rcar-remove-spinlock.patch i2c-rcar-remove-unused-ioerror-state.patch i2c-rcar-revoke-start-request-early.patch i2c-rcar-rework-hw-init.patch irda-fix-overly-long-udelay.patch rtlwifi-rtl8192cu-remove-variable-self-assignment-in-rf.c.patch tcp-avoid-integer-overflows-in-tcp_rcv_space_adjust.patch --- ...move-redundant-variable-dma_dev_name.patch | 44 ++++ ...urther-limit-wiphy-names-to-64-bytes.patch | 41 ++++ ...-loop-in-usb_dmac_chan_terminate_all.patch | 43 ++++ ...-check-master-irqs-before-slave-irqs.patch | 58 ++++++ ...e-stop-when-hw-does-it-automatically.patch | 35 ++++ .../i2c-rcar-init-new-messages-in-irq.patch | 192 ++++++++++++++++++ ...-are-on-when-doing-clock-calculation.patch | 88 ++++++++ .../i2c-rcar-refactor-setup-of-a-msg.patch | 59 ++++++ queue-4.4/i2c-rcar-remove-spinlock.patch | 109 ++++++++++ ...i2c-rcar-remove-unused-ioerror-state.patch | 41 ++++ .../i2c-rcar-revoke-start-request-early.patch | 96 +++++++++ queue-4.4/i2c-rcar-rework-hw-init.patch | 64 ++++++ queue-4.4/irda-fix-overly-long-udelay.patch | 44 ++++ ...ove-variable-self-assignment-in-rf.c.patch | 44 ++++ queue-4.4/series | 15 ++ ...er-overflows-in-tcp_rcv_space_adjust.patch | 77 +++++++ 16 files changed, 1050 insertions(+) create mode 100644 queue-4.4/asoc-intel-sst-remove-redundant-variable-dma_dev_name.patch create mode 100644 queue-4.4/cfg80211-further-limit-wiphy-names-to-64-bytes.patch create mode 100644 queue-4.4/dmaengine-usb-dmac-fix-endless-loop-in-usb_dmac_chan_terminate_all.patch create mode 100644 queue-4.4/i2c-rcar-check-master-irqs-before-slave-irqs.patch create mode 100644 queue-4.4/i2c-rcar-don-t-issue-stop-when-hw-does-it-automatically.patch create mode 100644 queue-4.4/i2c-rcar-init-new-messages-in-irq.patch create mode 100644 queue-4.4/i2c-rcar-make-sure-clocks-are-on-when-doing-clock-calculation.patch create mode 100644 queue-4.4/i2c-rcar-refactor-setup-of-a-msg.patch create mode 100644 queue-4.4/i2c-rcar-remove-spinlock.patch create mode 100644 queue-4.4/i2c-rcar-remove-unused-ioerror-state.patch create mode 100644 queue-4.4/i2c-rcar-revoke-start-request-early.patch create mode 100644 queue-4.4/i2c-rcar-rework-hw-init.patch create mode 100644 queue-4.4/irda-fix-overly-long-udelay.patch create mode 100644 queue-4.4/rtlwifi-rtl8192cu-remove-variable-self-assignment-in-rf.c.patch create mode 100644 queue-4.4/tcp-avoid-integer-overflows-in-tcp_rcv_space_adjust.patch diff --git a/queue-4.4/asoc-intel-sst-remove-redundant-variable-dma_dev_name.patch b/queue-4.4/asoc-intel-sst-remove-redundant-variable-dma_dev_name.patch new file mode 100644 index 00000000000..716bf70df7e --- /dev/null +++ b/queue-4.4/asoc-intel-sst-remove-redundant-variable-dma_dev_name.patch @@ -0,0 +1,44 @@ +From 271ef65b5882425d500e969e875c98e47a6b0c86 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Thu, 19 Oct 2017 14:33:52 +0200 +Subject: ASoC: Intel: sst: remove redundant variable dma_dev_name + +From: Colin Ian King + +commit 271ef65b5882425d500e969e875c98e47a6b0c86 upstream. + +The pointer dma_dev_name is assigned but never read, it is redundant +and can therefore be removed. + +Cleans up clang warning: +sound/soc/intel/common/sst-firmware.c:288:3: warning: Value stored to +'dma_dev_name' is never read + +Signed-off-by: Colin Ian King +Acked-by: Pierre-Louis Bossart +Signed-off-by: Mark Brown +Cc: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/intel/common/sst-firmware.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/sound/soc/intel/common/sst-firmware.c ++++ b/sound/soc/intel/common/sst-firmware.c +@@ -260,7 +260,6 @@ int sst_dma_new(struct sst_dsp *sst) + struct sst_pdata *sst_pdata = sst->pdata; + struct sst_dma *dma; + struct resource mem; +- const char *dma_dev_name; + int ret = 0; + + if (sst->pdata->resindex_dma_base == -1) +@@ -271,7 +270,6 @@ int sst_dma_new(struct sst_dsp *sst) + * is attached to the ADSP IP. */ + switch (sst->pdata->dma_engine) { + case SST_DMA_TYPE_DW: +- dma_dev_name = "dw_dmac"; + break; + default: + dev_err(sst->dev, "error: invalid DMA engine %d\n", diff --git a/queue-4.4/cfg80211-further-limit-wiphy-names-to-64-bytes.patch b/queue-4.4/cfg80211-further-limit-wiphy-names-to-64-bytes.patch new file mode 100644 index 00000000000..8f2371c9060 --- /dev/null +++ b/queue-4.4/cfg80211-further-limit-wiphy-names-to-64-bytes.patch @@ -0,0 +1,41 @@ +From 814596495dd2b9d4aab92d8f89cf19060d25d2ea Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 14 May 2018 20:09:24 -0700 +Subject: cfg80211: further limit wiphy names to 64 bytes + +From: Eric Biggers + +commit 814596495dd2b9d4aab92d8f89cf19060d25d2ea upstream. + +wiphy names were recently limited to 128 bytes by commit a7cfebcb7594 +("cfg80211: limit wiphy names to 128 bytes"). As it turns out though, +this isn't sufficient because dev_vprintk_emit() needs the syslog header +string "SUBSYSTEM=ieee80211\0DEVICE=+ieee80211:$devname" to fit into 128 +bytes. This triggered the "device/subsystem name too long" WARN when +the device name was >= 90 bytes. As before, this was reproduced by +syzbot by sending an HWSIM_CMD_NEW_RADIO command to the MAC80211_HWSIM +generic netlink family. + +Fix it by further limiting wiphy names to 64 bytes. + +Reported-by: syzbot+e64565577af34b3768dc@syzkaller.appspotmail.com +Fixes: a7cfebcb7594 ("cfg80211: limit wiphy names to 128 bytes") +Signed-off-by: Eric Biggers +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + include/uapi/linux/nl80211.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2195,7 +2195,7 @@ enum nl80211_attrs { + #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS + #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS + +-#define NL80211_WIPHY_NAME_MAXLEN 128 ++#define NL80211_WIPHY_NAME_MAXLEN 64 + + #define NL80211_MAX_SUPP_RATES 32 + #define NL80211_MAX_SUPP_HT_RATES 77 diff --git a/queue-4.4/dmaengine-usb-dmac-fix-endless-loop-in-usb_dmac_chan_terminate_all.patch b/queue-4.4/dmaengine-usb-dmac-fix-endless-loop-in-usb_dmac_chan_terminate_all.patch new file mode 100644 index 00000000000..433fb825452 --- /dev/null +++ b/queue-4.4/dmaengine-usb-dmac-fix-endless-loop-in-usb_dmac_chan_terminate_all.patch @@ -0,0 +1,43 @@ +From d9f5efade2cfd729138a7cafb46d01044da40f5e Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Thu, 12 Nov 2015 13:37:40 +0900 +Subject: dmaengine: usb-dmac: fix endless loop in usb_dmac_chan_terminate_all() + +From: Yoshihiro Shimoda + +commit d9f5efade2cfd729138a7cafb46d01044da40f5e upstream. + +This patch fixes an issue that list_for_each_entry() in +usb_dmac_chan_terminate_all() is possible to cause endless loop because +this will move own desc to the desc_freed. So, this driver should use +list_for_each_entry_safe() instead of list_for_each_entry(). + +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Vinod Koul +Signed-off-by: Biju Das +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/sh/usb-dmac.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/dma/sh/usb-dmac.c ++++ b/drivers/dma/sh/usb-dmac.c +@@ -448,7 +448,7 @@ usb_dmac_prep_slave_sg(struct dma_chan * + static int usb_dmac_chan_terminate_all(struct dma_chan *chan) + { + struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan); +- struct usb_dmac_desc *desc; ++ struct usb_dmac_desc *desc, *_desc; + unsigned long flags; + LIST_HEAD(head); + LIST_HEAD(list); +@@ -459,7 +459,7 @@ static int usb_dmac_chan_terminate_all(s + if (uchan->desc) + uchan->desc = NULL; + list_splice_init(&uchan->desc_got, &list); +- list_for_each_entry(desc, &list, node) ++ list_for_each_entry_safe(desc, _desc, &list, node) + list_move_tail(&desc->node, &uchan->desc_freed); + spin_unlock_irqrestore(&uchan->vc.lock, flags); + vchan_dma_desc_free_list(&uchan->vc, &head); diff --git a/queue-4.4/i2c-rcar-check-master-irqs-before-slave-irqs.patch b/queue-4.4/i2c-rcar-check-master-irqs-before-slave-irqs.patch new file mode 100644 index 00000000000..3171fc9fee4 --- /dev/null +++ b/queue-4.4/i2c-rcar-check-master-irqs-before-slave-irqs.patch @@ -0,0 +1,58 @@ +From c3be0af15959e11fa535d5332ab3d7cf34abd09b Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:48 +0100 +Subject: i2c: rcar: check master irqs before slave irqs + +From: Wolfram Sang + +commit c3be0af15959e11fa535d5332ab3d7cf34abd09b upstream. + +Due to the HW design, master IRQs are timing critical, so give them +precedence over slave IRQ. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Biju Das +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -432,19 +432,17 @@ static bool rcar_i2c_slave_irq(struct rc + static irqreturn_t rcar_i2c_irq(int irq, void *ptr) + { + struct rcar_i2c_priv *priv = ptr; +- irqreturn_t result = IRQ_HANDLED; + u32 msr; + +- if (rcar_i2c_slave_irq(priv)) +- goto exit; +- + msr = rcar_i2c_read(priv, ICMSR); + + /* Only handle interrupts that are currently enabled */ + msr &= rcar_i2c_read(priv, ICMIER); + if (!msr) { +- result = IRQ_NONE; +- goto exit; ++ if (rcar_i2c_slave_irq(priv)) ++ return IRQ_HANDLED; ++ ++ return IRQ_NONE; + } + + /* Arbitration lost */ +@@ -481,8 +479,7 @@ out: + wake_up(&priv->wait); + } + +-exit: +- return result; ++ return IRQ_HANDLED; + } + + static int rcar_i2c_master_xfer(struct i2c_adapter *adap, diff --git a/queue-4.4/i2c-rcar-don-t-issue-stop-when-hw-does-it-automatically.patch b/queue-4.4/i2c-rcar-don-t-issue-stop-when-hw-does-it-automatically.patch new file mode 100644 index 00000000000..ba571255f2d --- /dev/null +++ b/queue-4.4/i2c-rcar-don-t-issue-stop-when-hw-does-it-automatically.patch @@ -0,0 +1,35 @@ +From d89667b14f9d13b684287f6189ca209af5feee43 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:47 +0100 +Subject: i2c: rcar: don't issue stop when HW does it automatically + +From: Wolfram Sang + +commit d89667b14f9d13b684287f6189ca209af5feee43 upstream. + +The manual says (55.4.8.6) that HW does automatically send STOP after +NACK was received. My measuerments confirm that. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Biju Das +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -455,8 +455,8 @@ static irqreturn_t rcar_i2c_irq(int irq, + + /* Nack */ + if (msr & MNR) { +- /* go to stop phase */ +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); ++ /* HW automatically sends STOP after received NACK */ ++ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); + rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); + rcar_i2c_flags_set(priv, ID_NACK); + goto out; diff --git a/queue-4.4/i2c-rcar-init-new-messages-in-irq.patch b/queue-4.4/i2c-rcar-init-new-messages-in-irq.patch new file mode 100644 index 00000000000..92624d9c10e --- /dev/null +++ b/queue-4.4/i2c-rcar-init-new-messages-in-irq.patch @@ -0,0 +1,192 @@ +From cc21d0b4b62e41e5013d763adade5ea4462c33a4 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:46 +0100 +Subject: i2c: rcar: init new messages in irq + +From: Wolfram Sang + +commit cc21d0b4b62e41e5013d763adade5ea4462c33a4 upstream. + +Setting up new messages was done in process context while handling a +message was in interrupt context. Because of the HW design, this IP core +is sensitive to timing, so the context switches were too expensive. Move +this setup to interrupt context as well. + +In my test setup, this fixed the occasional 'data byte sent twice' issue +which a number of people have seen. It also fixes to send REP_START +after a read message which was wrongly send as a STOP + START sequence +before. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Chris Paterson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 90 ++++++++++++++++++++---------------------- + 1 file changed, 43 insertions(+), 47 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -267,10 +267,17 @@ static void rcar_i2c_prepare_msg(struct + rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND); + } + ++static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) ++{ ++ priv->msg++; ++ priv->msgs_left--; ++ rcar_i2c_prepare_msg(priv); ++} ++ + /* + * interrupt functions + */ +-static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) ++static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) + { + struct i2c_msg *msg = priv->msg; + +@@ -280,7 +287,7 @@ static int rcar_i2c_irq_send(struct rcar + * Do nothing + */ + if (!(msr & MDE)) +- return 0; ++ return; + + /* + * If address transfer phase finished, +@@ -309,29 +316,23 @@ static int rcar_i2c_irq_send(struct rcar + * [ICRXTX] -> [SHIFT] -> [I2C bus] + */ + +- if (priv->flags & ID_LAST_MSG) ++ if (priv->flags & ID_LAST_MSG) { + /* + * If current msg is the _LAST_ msg, + * prepare stop condition here. + * ID_DONE will be set on STOP irq. + */ + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); +- else +- /* +- * If current msg is _NOT_ last msg, +- * it doesn't call stop phase. +- * thus, there is no STOP irq. +- * return ID_DONE here. +- */ +- return ID_DONE; ++ } else { ++ rcar_i2c_next_msg(priv); ++ return; ++ } + } + + rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND); +- +- return 0; + } + +-static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) ++static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) + { + struct i2c_msg *msg = priv->msg; + +@@ -341,7 +342,7 @@ static int rcar_i2c_irq_recv(struct rcar + * Do nothing + */ + if (!(msr & MDR)) +- return 0; ++ return; + + if (msr & MAT) { + /* +@@ -367,9 +368,10 @@ static int rcar_i2c_irq_recv(struct rcar + else + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); + +- rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); +- +- return 0; ++ if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) ++ rcar_i2c_next_msg(priv); ++ else ++ rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); + } + + static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) +@@ -462,14 +464,15 @@ static irqreturn_t rcar_i2c_irq(int irq, + + /* Stop */ + if (msr & MST) { ++ priv->msgs_left--; /* The last message also made it */ + rcar_i2c_flags_set(priv, ID_DONE); + goto out; + } + + if (rcar_i2c_is_recv(priv)) +- rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); ++ rcar_i2c_irq_recv(priv, msr); + else +- rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr)); ++ rcar_i2c_irq_send(priv, msr); + + out: + if (rcar_i2c_flags_has(priv, ID_DONE)) { +@@ -501,35 +504,28 @@ static int rcar_i2c_master_xfer(struct i + /* This HW can't send STOP after address phase */ + if (msgs[i].len == 0) { + ret = -EOPNOTSUPP; +- break; +- } +- +- /* init each data */ +- priv->msg = &msgs[i]; +- priv->msgs_left = num - i; +- +- rcar_i2c_prepare_msg(priv); +- +- time_left = wait_event_timeout(priv->wait, +- rcar_i2c_flags_has(priv, ID_DONE), +- adap->timeout); +- if (!time_left) { +- rcar_i2c_init(priv); +- ret = -ETIMEDOUT; +- break; +- } +- +- if (rcar_i2c_flags_has(priv, ID_NACK)) { +- ret = -ENXIO; +- break; +- } +- +- if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { +- ret = -EAGAIN; +- break; ++ goto out; + } ++ } + +- ret = i + 1; /* The number of transfer */ ++ /* init data */ ++ priv->msg = msgs; ++ priv->msgs_left = num; ++ ++ rcar_i2c_prepare_msg(priv); ++ ++ time_left = wait_event_timeout(priv->wait, ++ rcar_i2c_flags_has(priv, ID_DONE), ++ num * adap->timeout); ++ if (!time_left) { ++ rcar_i2c_init(priv); ++ ret = -ETIMEDOUT; ++ } else if (rcar_i2c_flags_has(priv, ID_NACK)) { ++ ret = -ENXIO; ++ } else if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { ++ ret = -EAGAIN; ++ } else { ++ ret = num - priv->msgs_left; /* The number of transfer */ + } + out: + pm_runtime_put(dev); diff --git a/queue-4.4/i2c-rcar-make-sure-clocks-are-on-when-doing-clock-calculation.patch b/queue-4.4/i2c-rcar-make-sure-clocks-are-on-when-doing-clock-calculation.patch new file mode 100644 index 00000000000..68f693e198d --- /dev/null +++ b/queue-4.4/i2c-rcar-make-sure-clocks-are-on-when-doing-clock-calculation.patch @@ -0,0 +1,88 @@ +From e43e0df13f8528ca55ed79f469c4b2af897fa796 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:41 +0100 +Subject: i2c: rcar: make sure clocks are on when doing clock calculation + +From: Wolfram Sang + +commit e43e0df13f8528ca55ed79f469c4b2af897fa796 upstream. + +When calculating the bus speed, the clock should be on, of course. Most +bootloaders left them on, so this went unnoticed so far. + +Move the ioremapping out of this clock-enabled-block and prepare for +adding hw initialization there, too. + +Reported-by: Kuninori Morimoto +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Chris Paterson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -650,19 +650,23 @@ static int rcar_i2c_probe(struct platfor + return PTR_ERR(priv->clk); + } + ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ priv->io = devm_ioremap_resource(dev, res); ++ if (IS_ERR(priv->io)) ++ return PTR_ERR(priv->io); ++ + bus_speed = 100000; /* default 100 kHz */ + of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); + + priv->devtype = (enum rcar_i2c_type)of_match_device(rcar_i2c_dt_ids, dev)->data; + ++ pm_runtime_enable(dev); ++ pm_runtime_get_sync(dev); + ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); + if (ret < 0) +- return ret; ++ goto out_pm_put; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->io = devm_ioremap_resource(dev, res); +- if (IS_ERR(priv->io)) +- return PTR_ERR(priv->io); ++ pm_runtime_put(dev); + + irq = platform_get_irq(pdev, 0); + init_waitqueue_head(&priv->wait); +@@ -682,22 +686,26 @@ static int rcar_i2c_probe(struct platfor + dev_name(dev), priv); + if (ret < 0) { + dev_err(dev, "cannot get irq %d\n", irq); +- return ret; ++ goto out_pm_disable; + } + +- pm_runtime_enable(dev); + platform_set_drvdata(pdev, priv); + + ret = i2c_add_numbered_adapter(adap); + if (ret < 0) { + dev_err(dev, "reg adap failed: %d\n", ret); +- pm_runtime_disable(dev); +- return ret; ++ goto out_pm_disable; + } + + dev_info(dev, "probed\n"); + + return 0; ++ ++ out_pm_put: ++ pm_runtime_put(dev); ++ out_pm_disable: ++ pm_runtime_disable(dev); ++ return ret; + } + + static int rcar_i2c_remove(struct platform_device *pdev) diff --git a/queue-4.4/i2c-rcar-refactor-setup-of-a-msg.patch b/queue-4.4/i2c-rcar-refactor-setup-of-a-msg.patch new file mode 100644 index 00000000000..e5b17bb621e --- /dev/null +++ b/queue-4.4/i2c-rcar-refactor-setup-of-a-msg.patch @@ -0,0 +1,59 @@ +From b9d0684c79c4b9d30ce0d47d3270493dd0e76e59 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:45 +0100 +Subject: i2c: rcar: refactor setup of a msg + +From: Wolfram Sang + +commit b9d0684c79c4b9d30ce0d47d3270493dd0e76e59 upstream. + +We want to reuse this function later. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Chris Paterson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -106,7 +106,8 @@ enum rcar_i2c_type { + struct rcar_i2c_priv { + void __iomem *io; + struct i2c_adapter adap; +- struct i2c_msg *msg; ++ struct i2c_msg *msg; ++ int msgs_left; + struct clk *clk; + + wait_queue_head_t wait; +@@ -255,6 +256,11 @@ static void rcar_i2c_prepare_msg(struct + { + int read = !!rcar_i2c_is_recv(priv); + ++ priv->pos = 0; ++ priv->flags = 0; ++ if (priv->msgs_left == 1) ++ rcar_i2c_flags_set(priv, ID_LAST_MSG); ++ + rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); + rcar_i2c_write(priv, ICMSR, 0); + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); +@@ -499,11 +505,8 @@ static int rcar_i2c_master_xfer(struct i + } + + /* init each data */ +- priv->msg = &msgs[i]; +- priv->pos = 0; +- priv->flags = 0; +- if (i == num - 1) +- rcar_i2c_flags_set(priv, ID_LAST_MSG); ++ priv->msg = &msgs[i]; ++ priv->msgs_left = num - i; + + rcar_i2c_prepare_msg(priv); + diff --git a/queue-4.4/i2c-rcar-remove-spinlock.patch b/queue-4.4/i2c-rcar-remove-spinlock.patch new file mode 100644 index 00000000000..ac3a5b21bb1 --- /dev/null +++ b/queue-4.4/i2c-rcar-remove-spinlock.patch @@ -0,0 +1,109 @@ +From ff2316b87a336bff940939cd9fc56287ed48e578 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:44 +0100 +Subject: i2c: rcar: remove spinlock + +From: Wolfram Sang + +commit ff2316b87a336bff940939cd9fc56287ed48e578 upstream. + +After making sure to reinit the HW and clear interrupts in the timeout +case, we know that interrupts are always disabled in the sections +protected by the spinlock. Thus, we can simply remove it which is a +preparation for further refactoring. While here, rename the timeout +variable to time_left which is way more readable. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Chris Paterson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 23 ++++------------------- + 1 file changed, 4 insertions(+), 19 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -33,7 +33,6 @@ + #include + #include + #include +-#include + + /* register offsets */ + #define ICSCR 0x00 /* slave ctrl */ +@@ -110,7 +109,6 @@ struct rcar_i2c_priv { + struct i2c_msg *msg; + struct clk *clk; + +- spinlock_t lock; + wait_queue_head_t wait; + + int pos; +@@ -429,9 +427,6 @@ static irqreturn_t rcar_i2c_irq(int irq, + irqreturn_t result = IRQ_HANDLED; + u32 msr; + +- /*-------------- spin lock -----------------*/ +- spin_lock(&priv->lock); +- + if (rcar_i2c_slave_irq(priv)) + goto exit; + +@@ -478,9 +473,6 @@ out: + } + + exit: +- spin_unlock(&priv->lock); +- /*-------------- spin unlock -----------------*/ +- + return result; + } + +@@ -490,9 +482,8 @@ static int rcar_i2c_master_xfer(struct i + { + struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); + struct device *dev = rcar_i2c_priv_to_dev(priv); +- unsigned long flags; + int i, ret; +- long timeout; ++ long time_left; + + pm_runtime_get_sync(dev); + +@@ -507,9 +498,6 @@ static int rcar_i2c_master_xfer(struct i + break; + } + +- /*-------------- spin lock -----------------*/ +- spin_lock_irqsave(&priv->lock, flags); +- + /* init each data */ + priv->msg = &msgs[i]; + priv->pos = 0; +@@ -519,13 +507,11 @@ static int rcar_i2c_master_xfer(struct i + + rcar_i2c_prepare_msg(priv); + +- spin_unlock_irqrestore(&priv->lock, flags); +- /*-------------- spin unlock -----------------*/ +- +- timeout = wait_event_timeout(priv->wait, ++ time_left = wait_event_timeout(priv->wait, + rcar_i2c_flags_has(priv, ID_DONE), + adap->timeout); +- if (!timeout) { ++ if (!time_left) { ++ rcar_i2c_init(priv); + ret = -ETIMEDOUT; + break; + } +@@ -656,7 +642,6 @@ static int rcar_i2c_probe(struct platfor + + irq = platform_get_irq(pdev, 0); + init_waitqueue_head(&priv->wait); +- spin_lock_init(&priv->lock); + + adap = &priv->adap; + adap->nr = pdev->id; diff --git a/queue-4.4/i2c-rcar-remove-unused-ioerror-state.patch b/queue-4.4/i2c-rcar-remove-unused-ioerror-state.patch new file mode 100644 index 00000000000..10c60a5381b --- /dev/null +++ b/queue-4.4/i2c-rcar-remove-unused-ioerror-state.patch @@ -0,0 +1,41 @@ +From 90f779e565bdc18dd4f79d81cf11f43a7266010b Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:43 +0100 +Subject: i2c: rcar: remove unused IOERROR state + +From: Wolfram Sang + +commit 90f779e565bdc18dd4f79d81cf11f43a7266010b upstream. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Chris Paterson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -94,7 +94,6 @@ + #define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF) + + #define ID_LAST_MSG (1 << 0) +-#define ID_IOERROR (1 << 1) + #define ID_DONE (1 << 2) + #define ID_ARBLOST (1 << 3) + #define ID_NACK (1 << 4) +@@ -541,11 +540,6 @@ static int rcar_i2c_master_xfer(struct i + break; + } + +- if (rcar_i2c_flags_has(priv, ID_IOERROR)) { +- ret = -EIO; +- break; +- } +- + ret = i + 1; /* The number of transfer */ + } + out: diff --git a/queue-4.4/i2c-rcar-revoke-start-request-early.patch b/queue-4.4/i2c-rcar-revoke-start-request-early.patch new file mode 100644 index 00000000000..b4a26b77d15 --- /dev/null +++ b/queue-4.4/i2c-rcar-revoke-start-request-early.patch @@ -0,0 +1,96 @@ +From 52df445f29b79006d8b2dcd129152987c0d3bd64 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:49 +0100 +Subject: i2c: rcar: revoke START request early + +From: Wolfram Sang + +commit 52df445f29b79006d8b2dcd129152987c0d3bd64 upstream. + +If we don't clear START generation as soon as possible, it may cause +another message to be generated, e.g. when receiving NACK in address +phase. To keep the race window as small as possible, we clear it right +at the beginning of the interrupt. We don't need any checks since we +always want to stop START and STOP generation on the next occasion after +we started it. + +This patch improves the situation but sadly does not completely fix it. +It is still to be researched if we can do better given this HW design. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Biju Das +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 23 +++++++---------------- + 1 file changed, 7 insertions(+), 16 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -83,6 +83,7 @@ + + #define RCAR_BUS_PHASE_START (MDBS | MIE | ESG) + #define RCAR_BUS_PHASE_DATA (MDBS | MIE) ++#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF) + #define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB) + + #define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE) +@@ -289,13 +290,6 @@ static void rcar_i2c_irq_send(struct rca + if (!(msr & MDE)) + return; + +- /* +- * If address transfer phase finished, +- * goto data phase. +- */ +- if (msr & MAT) +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); +- + if (priv->pos < msg->len) { + /* + * Prepare next data to ICRXTX register. +@@ -345,11 +339,7 @@ static void rcar_i2c_irq_recv(struct rca + return; + + if (msr & MAT) { +- /* +- * Address transfer phase finished, +- * but, there is no data at this point. +- * Do nothing. +- */ ++ /* Address transfer phase finished, but no data at this point. */ + } else if (priv->pos < msg->len) { + /* + * get received data +@@ -365,8 +355,6 @@ static void rcar_i2c_irq_recv(struct rca + */ + if (priv->pos + 1 >= msg->len) + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); +- else +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); + + if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) + rcar_i2c_next_msg(priv); +@@ -432,7 +420,11 @@ static bool rcar_i2c_slave_irq(struct rc + static irqreturn_t rcar_i2c_irq(int irq, void *ptr) + { + struct rcar_i2c_priv *priv = ptr; +- u32 msr; ++ u32 msr, val; ++ ++ /* Clear START or STOP as soon as we can */ ++ val = rcar_i2c_read(priv, ICMCR); ++ rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA); + + msr = rcar_i2c_read(priv, ICMSR); + +@@ -454,7 +446,6 @@ static irqreturn_t rcar_i2c_irq(int irq, + /* Nack */ + if (msr & MNR) { + /* HW automatically sends STOP after received NACK */ +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); + rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); + rcar_i2c_flags_set(priv, ID_NACK); + goto out; diff --git a/queue-4.4/i2c-rcar-rework-hw-init.patch b/queue-4.4/i2c-rcar-rework-hw-init.patch new file mode 100644 index 00000000000..645497ca5b6 --- /dev/null +++ b/queue-4.4/i2c-rcar-rework-hw-init.patch @@ -0,0 +1,64 @@ +From 2c78cdc1c06308a59d6ed4145cdba73fdeff8c0d Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 19 Nov 2015 16:56:42 +0100 +Subject: i2c: rcar: rework hw init + +From: Wolfram Sang + +commit 2c78cdc1c06308a59d6ed4145cdba73fdeff8c0d upstream. + +We don't need to init HW before every transfer since we know the HW +state then. HW init at probe time is enough. While here, add setting the +clock register which belongs to init HW. Also, set MDBS bit since not +setting it is prohibited according to the manual. + +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Fabrizio Castro +Reviewed-by: Chris Paterson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -144,9 +144,10 @@ static void rcar_i2c_init(struct rcar_i2 + { + /* reset master mode */ + rcar_i2c_write(priv, ICMIER, 0); +- rcar_i2c_write(priv, ICMCR, 0); ++ rcar_i2c_write(priv, ICMCR, MDBS); + rcar_i2c_write(priv, ICMSR, 0); +- rcar_i2c_write(priv, ICMAR, 0); ++ /* start clock */ ++ rcar_i2c_write(priv, ICCCR, priv->icccr); + } + + static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) +@@ -496,16 +497,6 @@ static int rcar_i2c_master_xfer(struct i + + pm_runtime_get_sync(dev); + +- /*-------------- spin lock -----------------*/ +- spin_lock_irqsave(&priv->lock, flags); +- +- rcar_i2c_init(priv); +- /* start clock */ +- rcar_i2c_write(priv, ICCCR, priv->icccr); +- +- spin_unlock_irqrestore(&priv->lock, flags); +- /*-------------- spin unlock -----------------*/ +- + ret = rcar_i2c_bus_barrier(priv); + if (ret < 0) + goto out; +@@ -666,6 +657,7 @@ static int rcar_i2c_probe(struct platfor + if (ret < 0) + goto out_pm_put; + ++ rcar_i2c_init(priv); + pm_runtime_put(dev); + + irq = platform_get_irq(pdev, 0); diff --git a/queue-4.4/irda-fix-overly-long-udelay.patch b/queue-4.4/irda-fix-overly-long-udelay.patch new file mode 100644 index 00000000000..fa4e7a3e7c1 --- /dev/null +++ b/queue-4.4/irda-fix-overly-long-udelay.patch @@ -0,0 +1,44 @@ +From c9bd28233b6d0d82ac3ba0215723be0a8262c39c Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 24 Nov 2016 17:26:22 +0100 +Subject: irda: fix overly long udelay() + +From: Arnd Bergmann + +commit c9bd28233b6d0d82ac3ba0215723be0a8262c39c upstream. + +irda_get_mtt() returns a hardcoded '10000' in some cases, +and with gcc-7, we get a build error because this triggers a +compile-time check in udelay(): + +drivers/net/irda/w83977af_ir.o: In function `w83977af_hard_xmit': +w83977af_ir.c:(.text.w83977af_hard_xmit+0x14c): undefined reference to `__bad_udelay' + +Older compilers did not run into this because they either did not +completely inline the irda_get_mtt() or did not consider the +10000 value a constant expression. + +The code has been wrong since the start of git history. + +Signed-off-by: Arnd Bergmann +Signed-off-by: David S. Miller +Cc: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/irda/w83977af_ir.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/irda/w83977af_ir.c ++++ b/drivers/net/irda/w83977af_ir.c +@@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(st + + mtt = irda_get_mtt(skb); + pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt); +- if (mtt) ++ if (mtt > 1000) ++ mdelay(mtt/1000); ++ else if (mtt) + udelay(mtt); + + /* Enable DMA interrupt */ diff --git a/queue-4.4/rtlwifi-rtl8192cu-remove-variable-self-assignment-in-rf.c.patch b/queue-4.4/rtlwifi-rtl8192cu-remove-variable-self-assignment-in-rf.c.patch new file mode 100644 index 00000000000..053ab5194fa --- /dev/null +++ b/queue-4.4/rtlwifi-rtl8192cu-remove-variable-self-assignment-in-rf.c.patch @@ -0,0 +1,44 @@ +From fb239c1209bb0f0b4830cc72507cc2f2d63fadbd Mon Sep 17 00:00:00 2001 +From: Matthias Kaehlcke +Date: Thu, 8 Feb 2018 16:57:12 -0800 +Subject: rtlwifi: rtl8192cu: Remove variable self-assignment in rf.c + +From: Matthias Kaehlcke + +commit fb239c1209bb0f0b4830cc72507cc2f2d63fadbd upstream. + +In _rtl92c_get_txpower_writeval_by_regulatory() the variable writeVal +is assigned to itself in an if ... else statement, apparently only to +document that the branch condition is handled and that a previously read +value should be returned unmodified. The self-assignment causes clang to +raise the following warning: + +drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c:304:13: + error: explicitly assigning value of variable of type 'u32' + (aka 'unsigned int') to itself [-Werror,-Wself-assign] + writeVal = writeVal; + +Delete the branch with the self-assignment. + +Signed-off-by: Matthias Kaehlcke +Acked-by: Larry Finger +Reviewed-by: Guenter Roeck +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c +@@ -304,9 +304,6 @@ static void _rtl92c_get_txpower_writeval + writeVal = 0x00000000; + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeVal = writeVal - 0x06060606; +- else if (rtlpriv->dm.dynamic_txhighpower_lvl == +- TXHIGHPWRLEVEL_BT2) +- writeVal = writeVal; + *(p_outwriteval + rf) = writeVal; + } + } diff --git a/queue-4.4/series b/queue-4.4/series index b05b71a350f..3d2ad783455 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -7,3 +7,18 @@ revert-ima-limit-file-hash-setting-by-user-to-fix-and-log-modes.patch input-elan_i2c_smbus-fix-corrupted-stack.patch tracing-fix-crash-when-freeing-instances-with-event-triggers.patch selinux-kasan-slab-out-of-bounds-in-xattr_getsecurity.patch +cfg80211-further-limit-wiphy-names-to-64-bytes.patch +rtlwifi-rtl8192cu-remove-variable-self-assignment-in-rf.c.patch +asoc-intel-sst-remove-redundant-variable-dma_dev_name.patch +irda-fix-overly-long-udelay.patch +tcp-avoid-integer-overflows-in-tcp_rcv_space_adjust.patch +i2c-rcar-make-sure-clocks-are-on-when-doing-clock-calculation.patch +i2c-rcar-rework-hw-init.patch +i2c-rcar-remove-unused-ioerror-state.patch +i2c-rcar-remove-spinlock.patch +i2c-rcar-refactor-setup-of-a-msg.patch +i2c-rcar-init-new-messages-in-irq.patch +i2c-rcar-don-t-issue-stop-when-hw-does-it-automatically.patch +i2c-rcar-check-master-irqs-before-slave-irqs.patch +i2c-rcar-revoke-start-request-early.patch +dmaengine-usb-dmac-fix-endless-loop-in-usb_dmac_chan_terminate_all.patch diff --git a/queue-4.4/tcp-avoid-integer-overflows-in-tcp_rcv_space_adjust.patch b/queue-4.4/tcp-avoid-integer-overflows-in-tcp_rcv_space_adjust.patch new file mode 100644 index 00000000000..066019e51df --- /dev/null +++ b/queue-4.4/tcp-avoid-integer-overflows-in-tcp_rcv_space_adjust.patch @@ -0,0 +1,77 @@ +From 607065bad9931e72207b0cac365d7d4abc06bd99 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 10 Dec 2017 17:55:03 -0800 +Subject: tcp: avoid integer overflows in tcp_rcv_space_adjust() + +From: Eric Dumazet + +commit 607065bad9931e72207b0cac365d7d4abc06bd99 upstream. + +When using large tcp_rmem[2] values (I did tests with 500 MB), +I noticed overflows while computing rcvwin. + +Lets fix this before the following patch. + +Signed-off-by: Eric Dumazet +Acked-by: Soheil Hassas Yeganeh +Acked-by: Wei Wang +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +[Backport: sysctl_tcp_rmem is not Namespace-ify'd in older kernels] +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/tcp.h | 2 +- + net/ipv4/tcp_input.c | 10 ++++++---- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/include/linux/tcp.h ++++ b/include/linux/tcp.h +@@ -324,7 +324,7 @@ struct tcp_sock { + + /* Receiver queue space */ + struct { +- int space; ++ u32 space; + u32 seq; + u32 time; + } rcvq_space; +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -557,8 +557,8 @@ static inline void tcp_rcv_rtt_measure_t + void tcp_rcv_space_adjust(struct sock *sk) + { + struct tcp_sock *tp = tcp_sk(sk); ++ u32 copied; + int time; +- int copied; + + time = tcp_time_stamp - tp->rcvq_space.time; + if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0) +@@ -580,12 +580,13 @@ void tcp_rcv_space_adjust(struct sock *s + + if (sysctl_tcp_moderate_rcvbuf && + !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) { +- int rcvwin, rcvmem, rcvbuf; ++ int rcvmem, rcvbuf; ++ u64 rcvwin; + + /* minimal window to cope with packet losses, assuming + * steady state. Add some cushion because of small variations. + */ +- rcvwin = (copied << 1) + 16 * tp->advmss; ++ rcvwin = ((u64)copied << 1) + 16 * tp->advmss; + + /* If rate increased by 25%, + * assume slow start, rcvwin = 3 * copied +@@ -605,7 +606,8 @@ void tcp_rcv_space_adjust(struct sock *s + while (tcp_win_from_space(rcvmem) < tp->advmss) + rcvmem += 128; + +- rcvbuf = min(rcvwin / tp->advmss * rcvmem, sysctl_tcp_rmem[2]); ++ do_div(rcvwin, tp->advmss); ++ rcvbuf = min_t(u64, rcvwin * rcvmem, sysctl_tcp_rmem[2]); + if (rcvbuf > sk->sk_rcvbuf) { + sk->sk_rcvbuf = rcvbuf; + -- 2.47.3