--- /dev/null
+From 5f57a6d1cf7a6e344e49e2d80124abe148c57468 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Thu, 15 Nov 2018 15:53:41 +0200
+Subject: mmc: sdhci: Fix data command CRC error handling
+
+[ Upstream commit 4bf780996669280171c9cd58196512849b93434e ]
+
+Existing data command CRC error handling is non-standard and does not work
+with some Intel host controllers. Specifically, the assumption that the host
+controller will continue operating normally after the error interrupt,
+is not valid. Change the driver to handle the error in the same manner
+as a data CRC error, taking care to ensure that the data line reset is
+done for single or multi-block transfers, and it is done before
+unmapping DMA.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci.c | 40 +++++++++++++++-------------------------
+ 1 file changed, 15 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 654051e00117..4bfaca33a477 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1078,8 +1078,7 @@ static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq)
+ return (!(host->flags & SDHCI_DEVICE_DEAD) &&
+ ((mrq->cmd && mrq->cmd->error) ||
+ (mrq->sbc && mrq->sbc->error) ||
+- (mrq->data && ((mrq->data->error && !mrq->data->stop) ||
+- (mrq->data->stop && mrq->data->stop->error))) ||
++ (mrq->data && mrq->data->stop && mrq->data->stop->error) ||
+ (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)));
+ }
+
+@@ -1131,6 +1130,16 @@ static void sdhci_finish_data(struct sdhci_host *host)
+ host->data = NULL;
+ host->data_cmd = NULL;
+
++ /*
++ * The controller needs a reset of internal state machines upon error
++ * conditions.
++ */
++ if (data->error) {
++ if (!host->cmd || host->cmd == data_cmd)
++ sdhci_do_reset(host, SDHCI_RESET_CMD);
++ sdhci_do_reset(host, SDHCI_RESET_DATA);
++ }
++
+ if ((host->flags & (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA)) ==
+ (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA))
+ sdhci_adma_table_post(host, data);
+@@ -1155,17 +1164,6 @@ static void sdhci_finish_data(struct sdhci_host *host)
+ if (data->stop &&
+ (data->error ||
+ !data->mrq->sbc)) {
+-
+- /*
+- * The controller needs a reset of internal state machines
+- * upon error conditions.
+- */
+- if (data->error) {
+- if (!host->cmd || host->cmd == data_cmd)
+- sdhci_do_reset(host, SDHCI_RESET_CMD);
+- sdhci_do_reset(host, SDHCI_RESET_DATA);
+- }
+-
+ /*
+ * 'cap_cmd_during_tfr' request must not use the command line
+ * after mmc_command_done() has been called. It is upper layer's
+@@ -2642,7 +2640,7 @@ static void sdhci_timeout_data_timer(struct timer_list *t)
+ * *
+ \*****************************************************************************/
+
+-static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
++static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
+ {
+ if (!host->cmd) {
+ /*
+@@ -2665,20 +2663,12 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
+ else
+ host->cmd->error = -EILSEQ;
+
+- /*
+- * If this command initiates a data phase and a response
+- * CRC error is signalled, the card can start transferring
+- * data - the card may have received the command without
+- * error. We must not terminate the mmc_request early.
+- *
+- * If the card did not receive the command or returned an
+- * error which prevented it sending data, the data phase
+- * will time out.
+- */
++ /* Treat data command CRC error the same as data CRC error */
+ if (host->cmd->data &&
+ (intmask & (SDHCI_INT_CRC | SDHCI_INT_TIMEOUT)) ==
+ SDHCI_INT_CRC) {
+ host->cmd = NULL;
++ *intmask_p |= SDHCI_INT_DATA_CRC;
+ return;
+ }
+
+@@ -2906,7 +2896,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
+ }
+
+ if (intmask & SDHCI_INT_CMD_MASK)
+- sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
++ sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK, &intmask);
+
+ if (intmask & SDHCI_INT_DATA_MASK)
+ sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
+--
+2.19.1
+
--- /dev/null
+From 413bdc69fdc13745967d82cfe3bb59a03949b522 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Thu, 15 Nov 2018 15:53:43 +0200
+Subject: mmc: sdhci: Handle auto-command errors
+
+[ Upstream commit af849c86109d79222e549826068bbf4e7f9a2472 ]
+
+If the host controller supports auto-commands then enable the auto-command
+error interrupt and handle it. In the case of auto-CMD23, the error is
+treated the same as manual CMD23 error. In the case of auto-CMD12,
+commands-during-transfer are not permitted, so the error handling is
+treated the same as a data error.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci.c | 35 +++++++++++++++++++++++++++++++++++
+ drivers/mmc/host/sdhci.h | 7 ++++++-
+ 2 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 0eb05a42a857..c749d3dc1d36 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -841,6 +841,11 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+ else
+ host->ier = (host->ier & ~dma_irqs) | pio_irqs;
+
++ if (host->flags & (SDHCI_AUTO_CMD23 | SDHCI_AUTO_CMD12))
++ host->ier |= SDHCI_INT_AUTO_CMD_ERR;
++ else
++ host->ier &= ~SDHCI_INT_AUTO_CMD_ERR;
++
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+ }
+@@ -2642,6 +2647,21 @@ static void sdhci_timeout_data_timer(struct timer_list *t)
+
+ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
+ {
++ /* Handle auto-CMD12 error */
++ if (intmask & SDHCI_INT_AUTO_CMD_ERR && host->data_cmd) {
++ struct mmc_request *mrq = host->data_cmd->mrq;
++ u16 auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS);
++ int data_err_bit = (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT) ?
++ SDHCI_INT_DATA_TIMEOUT :
++ SDHCI_INT_DATA_CRC;
++
++ /* Treat auto-CMD12 error the same as data error */
++ if (!mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) {
++ *intmask_p |= data_err_bit;
++ return;
++ }
++ }
++
+ if (!host->cmd) {
+ /*
+ * SDHCI recovers from errors by resetting the cmd and data
+@@ -2676,6 +2696,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
+ return;
+ }
+
++ /* Handle auto-CMD23 error */
++ if (intmask & SDHCI_INT_AUTO_CMD_ERR) {
++ struct mmc_request *mrq = host->cmd->mrq;
++ u16 auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS);
++ int err = (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT) ?
++ -ETIMEDOUT :
++ -EILSEQ;
++
++ if (mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) {
++ mrq->sbc->error = err;
++ sdhci_finish_mrq(host, mrq);
++ return;
++ }
++ }
++
+ if (intmask & SDHCI_INT_RESPONSE)
+ sdhci_finish_command(host);
+ }
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 33a7728c71fa..0f8c4f3ccafc 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -151,7 +151,8 @@
+ #define SDHCI_INT_ERROR_MASK 0xFFFF8000
+
+ #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
+- SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
++ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \
++ SDHCI_INT_AUTO_CMD_ERR)
+ #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
+ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
+ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
+@@ -167,6 +168,10 @@
+ #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE)
+
+ #define SDHCI_AUTO_CMD_STATUS 0x3C
++#define SDHCI_AUTO_CMD_TIMEOUT 0x00000002
++#define SDHCI_AUTO_CMD_CRC 0x00000004
++#define SDHCI_AUTO_CMD_END_BIT 0x00000008
++#define SDHCI_AUTO_CMD_INDEX 0x00000010
+
+ #define SDHCI_HOST_CONTROL2 0x3E
+ #define SDHCI_CTRL_UHS_MASK 0x0007
+--
+2.19.1
+
--- /dev/null
+From b3ae298f6e483715caedab75330d743afce08c82 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Thu, 15 Nov 2018 15:53:42 +0200
+Subject: mmc: sdhci: Rename SDHCI_ACMD12_ERR and SDHCI_INT_ACMD12ERR
+
+[ Upstream commit 869f8a69bb3a4aec4eb914a330d4ba53a9eed495 ]
+
+The SDHCI_ACMD12_ERR register is used for auto-CMD23 and auto-CMD12
+errors, as is the SDHCI_INT_ACMD12ERR interrupt bit. Rename them to
+SDHCI_AUTO_CMD_STATUS and SDHCI_INT_AUTO_CMD_ERR respectively.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 12 ++++++------
+ drivers/mmc/host/sdhci.c | 4 ++--
+ drivers/mmc/host/sdhci.h | 4 ++--
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 8dae12b841b3..629860f7327c 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -429,7 +429,7 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
+ val = readl(host->ioaddr + ESDHC_MIX_CTRL);
+ else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING)
+ /* the std tuning bits is in ACMD12_ERR for imx6sl */
+- val = readl(host->ioaddr + SDHCI_ACMD12_ERR);
++ val = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+ }
+
+ if (val & ESDHC_MIX_CTRL_EXE_TUNE)
+@@ -494,7 +494,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
+ }
+ writel(new_val , host->ioaddr + ESDHC_MIX_CTRL);
+ } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
+- u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
++ u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+ u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+ if (val & SDHCI_CTRL_TUNED_CLK) {
+ v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
+@@ -512,7 +512,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
+ v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
+ }
+
+- writel(v, host->ioaddr + SDHCI_ACMD12_ERR);
++ writel(v, host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+ writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+ }
+ return;
+@@ -957,9 +957,9 @@ static void esdhc_reset_tuning(struct sdhci_host *host)
+ writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL);
+ writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
+ } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
+- ctrl = readl(host->ioaddr + SDHCI_ACMD12_ERR);
++ ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+ ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
+- writel(ctrl, host->ioaddr + SDHCI_ACMD12_ERR);
++ writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+ }
+ }
+ }
+@@ -1319,7 +1319,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+
+ /* clear tuning bits in case ROM has set it already */
+ writel(0x0, host->ioaddr + ESDHC_MIX_CTRL);
+- writel(0x0, host->ioaddr + SDHCI_ACMD12_ERR);
++ writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+ writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
+ }
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 4bfaca33a477..0eb05a42a857 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -82,8 +82,8 @@ void sdhci_dumpregs(struct sdhci_host *host)
+ SDHCI_DUMP("Int enab: 0x%08x | Sig enab: 0x%08x\n",
+ sdhci_readl(host, SDHCI_INT_ENABLE),
+ sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
+- SDHCI_DUMP("AC12 err: 0x%08x | Slot int: 0x%08x\n",
+- sdhci_readw(host, SDHCI_ACMD12_ERR),
++ SDHCI_DUMP("ACmd stat: 0x%08x | Slot int: 0x%08x\n",
++ sdhci_readw(host, SDHCI_AUTO_CMD_STATUS),
+ sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
+ SDHCI_DUMP("Caps: 0x%08x | Caps_1: 0x%08x\n",
+ sdhci_readl(host, SDHCI_CAPABILITIES),
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index f0bd36ce3817..33a7728c71fa 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -144,7 +144,7 @@
+ #define SDHCI_INT_DATA_CRC 0x00200000
+ #define SDHCI_INT_DATA_END_BIT 0x00400000
+ #define SDHCI_INT_BUS_POWER 0x00800000
+-#define SDHCI_INT_ACMD12ERR 0x01000000
++#define SDHCI_INT_AUTO_CMD_ERR 0x01000000
+ #define SDHCI_INT_ADMA_ERROR 0x02000000
+
+ #define SDHCI_INT_NORMAL_MASK 0x00007FFF
+@@ -166,7 +166,7 @@
+
+ #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE)
+
+-#define SDHCI_ACMD12_ERR 0x3C
++#define SDHCI_AUTO_CMD_STATUS 0x3C
+
+ #define SDHCI_HOST_CONTROL2 0x3E
+ #define SDHCI_CTRL_UHS_MASK 0x0007
+--
+2.19.1
+
--- /dev/null
+From b5bd1454d57987f08da63c87e72fbd80bb75b718 Mon Sep 17 00:00:00 2001
+From: Masahiro Yamada <yamada.masahiro@socionext.com>
+Date: Thu, 22 Nov 2018 13:28:42 +0900
+Subject: modpost: file2alias: check prototype of handler
+
+[ Upstream commit f880eea68fe593342fa6e09be9bb661f3c297aec ]
+
+Use specific prototype instead of an opaque pointer so that the
+compiler can catch function prototype mismatch.
+
+Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Reviewed-by: Mathieu Malaterre <malat@debian.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/file2alias.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index 9f3ebde7a0cd..7f40b6aab689 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -47,7 +47,7 @@ typedef struct {
+ struct devtable {
+ const char *device_id; /* name of table, __mod_<name>__*_device_table. */
+ unsigned long id_size;
+- void *function;
++ int (*do_entry)(const char *filename, void *symval, char *alias);
+ };
+
+ /* Define a variable f that holds the value of field f of struct devid
+@@ -1288,12 +1288,11 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol)
+ static void do_table(void *symval, unsigned long size,
+ unsigned long id_size,
+ const char *device_id,
+- void *function,
++ int (*do_entry)(const char *filename, void *symval, char *alias),
+ struct module *mod)
+ {
+ unsigned int i;
+ char alias[500];
+- int (*do_entry)(const char *, void *entry, char *alias) = function;
+
+ device_id_check(mod->name, device_id, size, id_size, symval);
+ /* Leave last one: it's the terminator. */
+@@ -1410,7 +1409,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
+
+ if (sym_is(name, namelen, p->device_id)) {
+ do_table(symval, sym->st_size, p->id_size,
+- p->device_id, p->function, mod);
++ p->device_id, p->do_entry, mod);
+ break;
+ }
+ }
+--
+2.19.1
+
--- /dev/null
+From 00032cc74576ada61fb8057f08b655d703b9c9f1 Mon Sep 17 00:00:00 2001
+From: Masahiro Yamada <yamada.masahiro@socionext.com>
+Date: Thu, 22 Nov 2018 13:28:41 +0900
+Subject: modpost: file2alias: go back to simple devtable lookup
+
+[ Upstream commit ec91e78d378cc5d4b43805a1227d8e04e5dfa17d ]
+
+Commit e49ce14150c6 ("modpost: use linker section to generate table.")
+was not so cool as we had expected first; it ended up with ugly section
+hacks when commit dd2a3acaecd7 ("mod/file2alias: make modpost compile
+on darwin again") came in.
+
+Given a certain degree of unknowledge about the link stage of host
+programs, I really want to see simple, stupid table lookup so that
+this works in the same way regardless of the underlying executable
+format.
+
+Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Acked-by: Mathieu Malaterre <malat@debian.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/file2alias.c | 144 +++++++++++++--------------------------
+ 1 file changed, 49 insertions(+), 95 deletions(-)
+
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index 7be43697ff84..9f3ebde7a0cd 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -50,46 +50,6 @@ struct devtable {
+ void *function;
+ };
+
+-#define ___cat(a,b) a ## b
+-#define __cat(a,b) ___cat(a,b)
+-
+-/* we need some special handling for this host tool running eventually on
+- * Darwin. The Mach-O section handling is a bit different than ELF section
+- * handling. The differnces in detail are:
+- * a) we have segments which have sections
+- * b) we need a API call to get the respective section symbols */
+-#if defined(__MACH__)
+-#include <mach-o/getsect.h>
+-
+-#define INIT_SECTION(name) do { \
+- unsigned long name ## _len; \
+- char *__cat(pstart_,name) = getsectdata("__TEXT", \
+- #name, &__cat(name,_len)); \
+- char *__cat(pstop_,name) = __cat(pstart_,name) + \
+- __cat(name, _len); \
+- __cat(__start_,name) = (void *)__cat(pstart_,name); \
+- __cat(__stop_,name) = (void *)__cat(pstop_,name); \
+- } while (0)
+-#define SECTION(name) __attribute__((section("__TEXT, " #name)))
+-
+-struct devtable **__start___devtable, **__stop___devtable;
+-#else
+-#define INIT_SECTION(name) /* no-op for ELF */
+-#define SECTION(name) __attribute__((section(#name)))
+-
+-/* We construct a table of pointers in an ELF section (pointers generally
+- * go unpadded by gcc). ld creates boundary syms for us. */
+-extern struct devtable *__start___devtable[], *__stop___devtable[];
+-#endif /* __MACH__ */
+-
+-#if !defined(__used)
+-# if __GNUC__ == 3 && __GNUC_MINOR__ < 3
+-# define __used __attribute__((__unused__))
+-# else
+-# define __used __attribute__((__used__))
+-# endif
+-#endif
+-
+ /* Define a variable f that holds the value of field f of struct devid
+ * based at address m.
+ */
+@@ -102,16 +62,6 @@ extern struct devtable *__start___devtable[], *__stop___devtable[];
+ #define DEF_FIELD_ADDR(m, devid, f) \
+ typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f)
+
+-/* Add a table entry. We test function type matches while we're here. */
+-#define ADD_TO_DEVTABLE(device_id, type, function) \
+- static struct devtable __cat(devtable,__LINE__) = { \
+- device_id + 0*sizeof((function)((const char *)NULL, \
+- (void *)NULL, \
+- (char *)NULL)), \
+- SIZE_##type, (function) }; \
+- static struct devtable *SECTION(__devtable) __used \
+- __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
+-
+ #define ADD(str, sep, cond, field) \
+ do { \
+ strcat(str, sep); \
+@@ -431,7 +381,6 @@ static int do_hid_entry(const char *filename,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("hid", hid_device_id, do_hid_entry);
+
+ /* Looks like: ieee1394:venNmoNspNverN */
+ static int do_ieee1394_entry(const char *filename,
+@@ -456,7 +405,6 @@ static int do_ieee1394_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("ieee1394", ieee1394_device_id, do_ieee1394_entry);
+
+ /* Looks like: pci:vNdNsvNsdNbcNscNiN. */
+ static int do_pci_entry(const char *filename,
+@@ -500,7 +448,6 @@ static int do_pci_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("pci", pci_device_id, do_pci_entry);
+
+ /* looks like: "ccw:tNmNdtNdmN" */
+ static int do_ccw_entry(const char *filename,
+@@ -524,7 +471,6 @@ static int do_ccw_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("ccw", ccw_device_id, do_ccw_entry);
+
+ /* looks like: "ap:tN" */
+ static int do_ap_entry(const char *filename,
+@@ -535,7 +481,6 @@ static int do_ap_entry(const char *filename,
+ sprintf(alias, "ap:t%02X*", dev_type);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("ap", ap_device_id, do_ap_entry);
+
+ /* looks like: "css:tN" */
+ static int do_css_entry(const char *filename,
+@@ -546,7 +491,6 @@ static int do_css_entry(const char *filename,
+ sprintf(alias, "css:t%01X", type);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("css", css_device_id, do_css_entry);
+
+ /* Looks like: "serio:tyNprNidNexN" */
+ static int do_serio_entry(const char *filename,
+@@ -566,7 +510,6 @@ static int do_serio_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry);
+
+ /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or
+ * "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if)
+@@ -604,7 +547,6 @@ static int do_acpi_entry(const char *filename,
+ }
+ return 1;
+ }
+-ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry);
+
+ /* looks like: "pnp:dD" */
+ static void do_pnp_device_entry(void *symval, unsigned long size,
+@@ -725,7 +667,6 @@ static int do_pcmcia_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry);
+
+ static int do_vio_entry(const char *filename, void *symval,
+ char *alias)
+@@ -745,7 +686,6 @@ static int do_vio_entry(const char *filename, void *symval,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("vio", vio_device_id, do_vio_entry);
+
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+@@ -818,7 +758,6 @@ static int do_input_entry(const char *filename, void *symval,
+ do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("input", input_device_id, do_input_entry);
+
+ static int do_eisa_entry(const char *filename, void *symval,
+ char *alias)
+@@ -830,7 +769,6 @@ static int do_eisa_entry(const char *filename, void *symval,
+ strcat(alias, "*");
+ return 1;
+ }
+-ADD_TO_DEVTABLE("eisa", eisa_device_id, do_eisa_entry);
+
+ /* Looks like: parisc:tNhvNrevNsvN */
+ static int do_parisc_entry(const char *filename, void *symval,
+@@ -850,7 +788,6 @@ static int do_parisc_entry(const char *filename, void *symval,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("parisc", parisc_device_id, do_parisc_entry);
+
+ /* Looks like: sdio:cNvNdN. */
+ static int do_sdio_entry(const char *filename,
+@@ -867,7 +804,6 @@ static int do_sdio_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("sdio", sdio_device_id, do_sdio_entry);
+
+ /* Looks like: ssb:vNidNrevN. */
+ static int do_ssb_entry(const char *filename,
+@@ -884,7 +820,6 @@ static int do_ssb_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("ssb", ssb_device_id, do_ssb_entry);
+
+ /* Looks like: bcma:mNidNrevNclN. */
+ static int do_bcma_entry(const char *filename,
+@@ -903,7 +838,6 @@ static int do_bcma_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("bcma", bcma_device_id, do_bcma_entry);
+
+ /* Looks like: virtio:dNvN */
+ static int do_virtio_entry(const char *filename, void *symval,
+@@ -919,7 +853,6 @@ static int do_virtio_entry(const char *filename, void *symval,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("virtio", virtio_device_id, do_virtio_entry);
+
+ /*
+ * Looks like: vmbus:guid
+@@ -942,7 +875,6 @@ static int do_vmbus_entry(const char *filename, void *symval,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry);
+
+ /* Looks like: rpmsg:S */
+ static int do_rpmsg_entry(const char *filename, void *symval,
+@@ -953,7 +885,6 @@ static int do_rpmsg_entry(const char *filename, void *symval,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("rpmsg", rpmsg_device_id, do_rpmsg_entry);
+
+ /* Looks like: i2c:S */
+ static int do_i2c_entry(const char *filename, void *symval,
+@@ -964,7 +895,6 @@ static int do_i2c_entry(const char *filename, void *symval,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("i2c", i2c_device_id, do_i2c_entry);
+
+ /* Looks like: spi:S */
+ static int do_spi_entry(const char *filename, void *symval,
+@@ -975,7 +905,6 @@ static int do_spi_entry(const char *filename, void *symval,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("spi", spi_device_id, do_spi_entry);
+
+ static const struct dmifield {
+ const char *prefix;
+@@ -1030,7 +959,6 @@ static int do_dmi_entry(const char *filename, void *symval,
+ strcat(alias, ":");
+ return 1;
+ }
+-ADD_TO_DEVTABLE("dmi", dmi_system_id, do_dmi_entry);
+
+ static int do_platform_entry(const char *filename,
+ void *symval, char *alias)
+@@ -1039,7 +967,6 @@ static int do_platform_entry(const char *filename,
+ sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("platform", platform_device_id, do_platform_entry);
+
+ static int do_mdio_entry(const char *filename,
+ void *symval, char *alias)
+@@ -1064,7 +991,6 @@ static int do_mdio_entry(const char *filename,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("mdio", mdio_device_id, do_mdio_entry);
+
+ /* Looks like: zorro:iN. */
+ static int do_zorro_entry(const char *filename, void *symval,
+@@ -1075,7 +1001,6 @@ static int do_zorro_entry(const char *filename, void *symval,
+ ADD(alias, "i", id != ZORRO_WILDCARD, id);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("zorro", zorro_device_id, do_zorro_entry);
+
+ /* looks like: "pnp:dD" */
+ static int do_isapnp_entry(const char *filename,
+@@ -1091,7 +1016,6 @@ static int do_isapnp_entry(const char *filename,
+ (function >> 12) & 0x0f, (function >> 8) & 0x0f);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("isapnp", isapnp_device_id, do_isapnp_entry);
+
+ /* Looks like: "ipack:fNvNdN". */
+ static int do_ipack_entry(const char *filename,
+@@ -1107,7 +1031,6 @@ static int do_ipack_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("ipack", ipack_device_id, do_ipack_entry);
+
+ /*
+ * Append a match expression for a single masked hex digit.
+@@ -1178,7 +1101,6 @@ static int do_amba_entry(const char *filename,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry);
+
+ /*
+ * looks like: "mipscdmm:tN"
+@@ -1194,7 +1116,6 @@ static int do_mips_cdmm_entry(const char *filename,
+ sprintf(alias, "mipscdmm:t%02X*", type);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("mipscdmm", mips_cdmm_device_id, do_mips_cdmm_entry);
+
+ /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,*
+ * All fields are numbers. It would be nicer to use strings for vendor
+@@ -1219,7 +1140,6 @@ static int do_x86cpu_entry(const char *filename, void *symval,
+ sprintf(alias + strlen(alias), "%04X*", feature);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);
+
+ /* LOOKS like cpu:type:*:feature:*FEAT* */
+ static int do_cpu_entry(const char *filename, void *symval, char *alias)
+@@ -1229,7 +1149,6 @@ static int do_cpu_entry(const char *filename, void *symval, char *alias)
+ sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry);
+
+ /* Looks like: mei:S:uuid:N:* */
+ static int do_mei_entry(const char *filename, void *symval,
+@@ -1248,7 +1167,6 @@ static int do_mei_entry(const char *filename, void *symval,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("mei", mei_cl_device_id, do_mei_entry);
+
+ /* Looks like: rapidio:vNdNavNadN */
+ static int do_rio_entry(const char *filename,
+@@ -1268,7 +1186,6 @@ static int do_rio_entry(const char *filename,
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry);
+
+ /* Looks like: ulpi:vNpN */
+ static int do_ulpi_entry(const char *filename, void *symval,
+@@ -1281,7 +1198,6 @@ static int do_ulpi_entry(const char *filename, void *symval,
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry);
+
+ /* Looks like: hdaudio:vNrNaN */
+ static int do_hda_entry(const char *filename, void *symval, char *alias)
+@@ -1298,7 +1214,6 @@ static int do_hda_entry(const char *filename, void *symval, char *alias)
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry);
+
+ /* Looks like: sdw:mNpN */
+ static int do_sdw_entry(const char *filename, void *symval, char *alias)
+@@ -1313,7 +1228,6 @@ static int do_sdw_entry(const char *filename, void *symval, char *alias)
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("sdw", sdw_device_id, do_sdw_entry);
+
+ /* Looks like: fsl-mc:vNdN */
+ static int do_fsl_mc_entry(const char *filename, void *symval,
+@@ -1325,7 +1239,6 @@ static int do_fsl_mc_entry(const char *filename, void *symval,
+ sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("fslmc", fsl_mc_device_id, do_fsl_mc_entry);
+
+ /* Looks like: tbsvc:kSpNvNrN */
+ static int do_tbsvc_entry(const char *filename, void *symval, char *alias)
+@@ -1350,7 +1263,6 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias)
+ add_wildcard(alias);
+ return 1;
+ }
+-ADD_TO_DEVTABLE("tbsvc", tb_service_id, do_tbsvc_entry);
+
+ /* Looks like: typec:idNmN */
+ static int do_typec_entry(const char *filename, void *symval, char *alias)
+@@ -1363,7 +1275,6 @@ static int do_typec_entry(const char *filename, void *symval, char *alias)
+
+ return 1;
+ }
+-ADD_TO_DEVTABLE("typec", typec_device_id, do_typec_entry);
+
+ /* Does namelen bytes of name exactly match the symbol? */
+ static bool sym_is(const char *name, unsigned namelen, const char *symbol)
+@@ -1396,6 +1307,48 @@ static void do_table(void *symval, unsigned long size,
+ }
+ }
+
++static const struct devtable devtable[] = {
++ {"hid", SIZE_hid_device_id, do_hid_entry},
++ {"ieee1394", SIZE_ieee1394_device_id, do_ieee1394_entry},
++ {"pci", SIZE_pci_device_id, do_pci_entry},
++ {"ccw", SIZE_ccw_device_id, do_ccw_entry},
++ {"ap", SIZE_ap_device_id, do_ap_entry},
++ {"css", SIZE_css_device_id, do_css_entry},
++ {"serio", SIZE_serio_device_id, do_serio_entry},
++ {"acpi", SIZE_acpi_device_id, do_acpi_entry},
++ {"pcmcia", SIZE_pcmcia_device_id, do_pcmcia_entry},
++ {"vio", SIZE_vio_device_id, do_vio_entry},
++ {"input", SIZE_input_device_id, do_input_entry},
++ {"eisa", SIZE_eisa_device_id, do_eisa_entry},
++ {"parisc", SIZE_parisc_device_id, do_parisc_entry},
++ {"sdio", SIZE_sdio_device_id, do_sdio_entry},
++ {"ssb", SIZE_ssb_device_id, do_ssb_entry},
++ {"bcma", SIZE_bcma_device_id, do_bcma_entry},
++ {"virtio", SIZE_virtio_device_id, do_virtio_entry},
++ {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry},
++ {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry},
++ {"i2c", SIZE_i2c_device_id, do_i2c_entry},
++ {"spi", SIZE_spi_device_id, do_spi_entry},
++ {"dmi", SIZE_dmi_system_id, do_dmi_entry},
++ {"platform", SIZE_platform_device_id, do_platform_entry},
++ {"mdio", SIZE_mdio_device_id, do_mdio_entry},
++ {"zorro", SIZE_zorro_device_id, do_zorro_entry},
++ {"isapnp", SIZE_isapnp_device_id, do_isapnp_entry},
++ {"ipack", SIZE_ipack_device_id, do_ipack_entry},
++ {"amba", SIZE_amba_id, do_amba_entry},
++ {"mipscdmm", SIZE_mips_cdmm_device_id, do_mips_cdmm_entry},
++ {"x86cpu", SIZE_x86_cpu_id, do_x86cpu_entry},
++ {"cpu", SIZE_cpu_feature, do_cpu_entry},
++ {"mei", SIZE_mei_cl_device_id, do_mei_entry},
++ {"rapidio", SIZE_rio_device_id, do_rio_entry},
++ {"ulpi", SIZE_ulpi_device_id, do_ulpi_entry},
++ {"hdaudio", SIZE_hda_device_id, do_hda_entry},
++ {"sdw", SIZE_sdw_device_id, do_sdw_entry},
++ {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry},
++ {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry},
++ {"typec", SIZE_typec_device_id, do_typec_entry},
++};
++
+ /* Create MODULE_ALIAS() statements.
+ * At this time, we cannot write the actual output C source yet,
+ * so we write into the mod->dev_table_buf buffer. */
+@@ -1450,13 +1403,14 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
+ else if (sym_is(name, namelen, "pnp_card"))
+ do_pnp_card_entries(symval, sym->st_size, mod);
+ else {
+- struct devtable **p;
+- INIT_SECTION(__devtable);
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(devtable); i++) {
++ const struct devtable *p = &devtable[i];
+
+- for (p = __start___devtable; p < __stop___devtable; p++) {
+- if (sym_is(name, namelen, (*p)->device_id)) {
+- do_table(symval, sym->st_size, (*p)->id_size,
+- (*p)->device_id, (*p)->function, mod);
++ if (sym_is(name, namelen, p->device_id)) {
++ do_table(symval, sym->st_size, p->id_size,
++ p->device_id, p->function, mod);
+ break;
+ }
+ }
+--
+2.19.1
+
--- /dev/null
+From e69355eedd1fd6dc336bc458634efc20a1abb98c Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Mon, 22 Apr 2019 16:08:21 -0700
+Subject: nfit/ars: Allow root to busy-poll the ARS state machine
+
+commit 5479b2757f26fe9908fc341d105b2097fe820b6f upstream.
+
+The ARS implementation implements exponential back-off on the poll
+interval to prevent high-frequency access to the DIMM / platform
+interface. Depending on when the ARS completes the poll interval may
+exceed the completion event by minutes. Allow root to reset the timeout
+each time it probes the status. A one-second timeout is still enforced,
+but root can otherwise can control the poll interval.
+
+Fixes: bc6ba8085842 ("nfit, address-range-scrub: rework and simplify ARS...")
+Cc: <stable@vger.kernel.org>
+Reported-by: Erwin Tsaur <erwin.tsaur@oracle.com>
+Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/nfit/core.c | 8 ++++++++
+ drivers/acpi/nfit/nfit.h | 1 +
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index 6b5a3c3b4458..4b489d14a680 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1314,6 +1314,13 @@ static ssize_t scrub_show(struct device *dev,
+ busy = test_bit(ARS_BUSY, &acpi_desc->scrub_flags)
+ && !test_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
+ rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, busy ? "+\n" : "\n");
++ /* Allow an admin to poll the busy state at a higher rate */
++ if (busy && capable(CAP_SYS_RAWIO) && !test_and_set_bit(ARS_POLL,
++ &acpi_desc->scrub_flags)) {
++ acpi_desc->scrub_tmo = 1;
++ mod_delayed_work(nfit_wq, &acpi_desc->dwork, HZ);
++ }
++
+ mutex_unlock(&acpi_desc->init_mutex);
+ device_unlock(dev);
+ return rc;
+@@ -3075,6 +3082,7 @@ static void acpi_nfit_scrub(struct work_struct *work)
+ else
+ notify_ars_done(acpi_desc);
+ memset(acpi_desc->ars_status, 0, acpi_desc->max_ars);
++ clear_bit(ARS_POLL, &acpi_desc->scrub_flags);
+ mutex_unlock(&acpi_desc->init_mutex);
+ }
+
+diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
+index 94710e579598..b5fd3522abc7 100644
+--- a/drivers/acpi/nfit/nfit.h
++++ b/drivers/acpi/nfit/nfit.h
+@@ -184,6 +184,7 @@ struct nfit_mem {
+ enum scrub_flags {
+ ARS_BUSY,
+ ARS_CANCEL,
++ ARS_POLL,
+ };
+
+ struct acpi_nfit_desc {
+--
+2.19.1
+
--- /dev/null
+From 9281279f81f6ab6cc0486ac7b874c01e562772ba Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Mon, 22 Apr 2019 16:08:26 -0700
+Subject: nfit/ars: Avoid stale ARS results
+
+commit 78153dd45e7e0596ba32b15d02bda08e1513111e upstream.
+
+Gate ARS result consumption on whether the OS issued start-ARS since the
+previous consumption. The BIOS may only clear its result buffers after a
+successful start-ARS.
+
+Fixes: 0caeef63e6d2 ("libnvdimm: Add a poison list and export badblocks")
+Cc: <stable@vger.kernel.org>
+Reported-by: Krzysztof Rusocki <krzysztof.rusocki@intel.com>
+Reported-by: Vishal Verma <vishal.l.verma@intel.com>
+Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/nfit/core.c | 17 ++++++++++++++++-
+ drivers/acpi/nfit/nfit.h | 1 +
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index 4b489d14a680..925dbc751322 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -2540,7 +2540,10 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc,
+
+ if (rc < 0)
+ return rc;
+- return cmd_rc;
++ if (cmd_rc < 0)
++ return cmd_rc;
++ set_bit(ARS_VALID, &acpi_desc->scrub_flags);
++ return 0;
+ }
+
+ static int ars_continue(struct acpi_nfit_desc *acpi_desc)
+@@ -2633,6 +2636,17 @@ static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
+ */
+ if (ars_status->out_length < 44)
+ return 0;
++
++ /*
++ * Ignore potentially stale results that are only refreshed
++ * after a start-ARS event.
++ */
++ if (!test_and_clear_bit(ARS_VALID, &acpi_desc->scrub_flags)) {
++ dev_dbg(acpi_desc->dev, "skip %d stale records\n",
++ ars_status->num_records);
++ return 0;
++ }
++
+ for (i = 0; i < ars_status->num_records; i++) {
+ /* only process full records */
+ if (ars_status->out_length
+@@ -3117,6 +3131,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
+ struct nfit_spa *nfit_spa;
+ int rc;
+
++ set_bit(ARS_VALID, &acpi_desc->scrub_flags);
+ list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
+ switch (nfit_spa_type(nfit_spa->spa)) {
+ case NFIT_SPA_VOLATILE:
+diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
+index b5fd3522abc7..68848fc4b7c9 100644
+--- a/drivers/acpi/nfit/nfit.h
++++ b/drivers/acpi/nfit/nfit.h
+@@ -184,6 +184,7 @@ struct nfit_mem {
+ enum scrub_flags {
+ ARS_BUSY,
+ ARS_CANCEL,
++ ARS_VALID,
+ ARS_POLL,
+ };
+
+--
+2.19.1
+
--- /dev/null
+From 75ae1120a27aad2a2f89cf994ca9fbb599da9c07 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Mon, 22 Apr 2019 16:08:16 -0700
+Subject: nfit/ars: Introduce scrub_flags
+
+commit e34b8252a3d2893ca55c82dbfcdaa302fa03d400 upstream.
+
+In preparation for introducing new flags to gate whether ARS results are
+stale, or poll the completion state, convert the existing flags to an
+unsigned long with enumerated values. This conversion allows the flags
+to be atomically updated outside of ->init_mutex.
+
+Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/nfit/core.c | 30 +++++++++++++++++-------------
+ drivers/acpi/nfit/nfit.h | 8 ++++++--
+ 2 files changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index b5237a506464..6b5a3c3b4458 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1298,19 +1298,23 @@ static ssize_t scrub_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct nvdimm_bus_descriptor *nd_desc;
++ struct acpi_nfit_desc *acpi_desc;
+ ssize_t rc = -ENXIO;
++ bool busy;
+
+ device_lock(dev);
+ nd_desc = dev_get_drvdata(dev);
+- if (nd_desc) {
+- struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
+-
+- mutex_lock(&acpi_desc->init_mutex);
+- rc = sprintf(buf, "%d%s", acpi_desc->scrub_count,
+- acpi_desc->scrub_busy
+- && !acpi_desc->cancel ? "+\n" : "\n");
+- mutex_unlock(&acpi_desc->init_mutex);
++ if (!nd_desc) {
++ device_unlock(dev);
++ return rc;
+ }
++ acpi_desc = to_acpi_desc(nd_desc);
++
++ mutex_lock(&acpi_desc->init_mutex);
++ busy = test_bit(ARS_BUSY, &acpi_desc->scrub_flags)
++ && !test_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
++ rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, busy ? "+\n" : "\n");
++ mutex_unlock(&acpi_desc->init_mutex);
+ device_unlock(dev);
+ return rc;
+ }
+@@ -2960,7 +2964,7 @@ static unsigned int __acpi_nfit_scrub(struct acpi_nfit_desc *acpi_desc,
+
+ lockdep_assert_held(&acpi_desc->init_mutex);
+
+- if (acpi_desc->cancel)
++ if (test_bit(ARS_CANCEL, &acpi_desc->scrub_flags))
+ return 0;
+
+ if (query_rc == -EBUSY) {
+@@ -3034,7 +3038,7 @@ static void __sched_ars(struct acpi_nfit_desc *acpi_desc, unsigned int tmo)
+ {
+ lockdep_assert_held(&acpi_desc->init_mutex);
+
+- acpi_desc->scrub_busy = 1;
++ set_bit(ARS_BUSY, &acpi_desc->scrub_flags);
+ /* note this should only be set from within the workqueue */
+ if (tmo)
+ acpi_desc->scrub_tmo = tmo;
+@@ -3050,7 +3054,7 @@ static void notify_ars_done(struct acpi_nfit_desc *acpi_desc)
+ {
+ lockdep_assert_held(&acpi_desc->init_mutex);
+
+- acpi_desc->scrub_busy = 0;
++ clear_bit(ARS_BUSY, &acpi_desc->scrub_flags);
+ acpi_desc->scrub_count++;
+ if (acpi_desc->scrub_count_state)
+ sysfs_notify_dirent(acpi_desc->scrub_count_state);
+@@ -3322,7 +3326,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
+ struct nfit_spa *nfit_spa;
+
+ mutex_lock(&acpi_desc->init_mutex);
+- if (acpi_desc->cancel) {
++ if (test_bit(ARS_CANCEL, &acpi_desc->scrub_flags)) {
+ mutex_unlock(&acpi_desc->init_mutex);
+ return 0;
+ }
+@@ -3401,7 +3405,7 @@ void acpi_nfit_shutdown(void *data)
+ mutex_unlock(&acpi_desc_lock);
+
+ mutex_lock(&acpi_desc->init_mutex);
+- acpi_desc->cancel = 1;
++ set_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
+ cancel_delayed_work_sync(&acpi_desc->dwork);
+ mutex_unlock(&acpi_desc->init_mutex);
+
+diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
+index df31a2721573..94710e579598 100644
+--- a/drivers/acpi/nfit/nfit.h
++++ b/drivers/acpi/nfit/nfit.h
+@@ -181,6 +181,11 @@ struct nfit_mem {
+ bool has_lsw;
+ };
+
++enum scrub_flags {
++ ARS_BUSY,
++ ARS_CANCEL,
++};
++
+ struct acpi_nfit_desc {
+ struct nvdimm_bus_descriptor nd_desc;
+ struct acpi_table_header acpi_header;
+@@ -202,8 +207,7 @@ struct acpi_nfit_desc {
+ unsigned int max_ars;
+ unsigned int scrub_count;
+ unsigned int scrub_mode;
+- unsigned int scrub_busy:1;
+- unsigned int cancel:1;
++ unsigned long scrub_flags;
+ unsigned long dimm_cmd_force_en;
+ unsigned long bus_cmd_force_en;
+ unsigned long bus_nfit_cmd_force_en;
+--
+2.19.1
+
--- /dev/null
+From af4dd31d1c94ed50e7981a474479ba8425b71fe9 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Mon, 22 Apr 2019 16:08:10 -0700
+Subject: nfit/ars: Remove ars_start_flags
+
+commit 317a992ab9266b86b774b9f6b0f87eb4f59879a1 upstream.
+
+The ars_start_flags property of 'struct acpi_nfit_desc' is no longer
+used since ARS_REQ_SHORT and ARS_REQ_LONG were added.
+
+Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/nfit/core.c | 10 +++++-----
+ drivers/acpi/nfit/nfit.h | 1 -
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index df2175b1169a..b5237a506464 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -2539,11 +2539,11 @@ static int ars_continue(struct acpi_nfit_desc *acpi_desc)
+ struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
+ struct nd_cmd_ars_status *ars_status = acpi_desc->ars_status;
+
+- memset(&ars_start, 0, sizeof(ars_start));
+- ars_start.address = ars_status->restart_address;
+- ars_start.length = ars_status->restart_length;
+- ars_start.type = ars_status->type;
+- ars_start.flags = acpi_desc->ars_start_flags;
++ ars_start = (struct nd_cmd_ars_start) {
++ .address = ars_status->restart_address,
++ .length = ars_status->restart_length,
++ .type = ars_status->type,
++ };
+ rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_START, &ars_start,
+ sizeof(ars_start), &cmd_rc);
+ if (rc < 0)
+diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
+index 02c10de50386..df31a2721573 100644
+--- a/drivers/acpi/nfit/nfit.h
++++ b/drivers/acpi/nfit/nfit.h
+@@ -194,7 +194,6 @@ struct acpi_nfit_desc {
+ struct list_head idts;
+ struct nvdimm_bus *nvdimm_bus;
+ struct device *dev;
+- u8 ars_start_flags;
+ struct nd_cmd_ars_status *ars_status;
+ struct nfit_spa *scrub_spa;
+ struct delayed_work dwork;
+--
+2.19.1
+
net-ip-defrag-encapsulate-rbtree-defrag-code-into-ca.patch
net-ip6-defrag-use-rbtrees-for-ipv6-defrag.patch
net-ip6-defrag-use-rbtrees-in-nf_conntrack_reasm.c.patch
+nfit-ars-remove-ars_start_flags.patch
+nfit-ars-introduce-scrub_flags.patch
+nfit-ars-allow-root-to-busy-poll-the-ars-state-machi.patch
+nfit-ars-avoid-stale-ars-results.patch
+mmc-sdhci-fix-data-command-crc-error-handling.patch
+mmc-sdhci-rename-sdhci_acmd12_err-and-sdhci_int_acmd.patch
+mmc-sdhci-handle-auto-command-errors.patch
+modpost-file2alias-go-back-to-simple-devtable-lookup.patch
+modpost-file2alias-check-prototype-of-handler.patch
+tpm-tpm_i2c_atmel-return-e2big-when-the-transfer-is-.patch
+tpm-fix-the-type-of-the-return-value-in-calc_tpm2_ev.patch
--- /dev/null
+From cc995a27167cc9414456caf884d87ae602620487 Mon Sep 17 00:00:00 2001
+From: Yue Haibing <yuehaibing@huawei.com>
+Date: Tue, 23 Apr 2019 16:05:18 +0300
+Subject: tpm: Fix the type of the return value in calc_tpm2_event_size()
+
+commit b9d0a85d6b2e76630cfd4c475ee3af4109bfd87a upstream
+
+calc_tpm2_event_size() has an invalid signature because
+it returns a 'size_t' where as its signature says that
+it returns 'int'.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 4d23cc323cdb ("tpm: add securityfs support for TPM 2.0 firmware event log")
+Suggested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/eventlog/tpm2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c
+index 1b8fa9de2cac..41b9f6c92da7 100644
+--- a/drivers/char/tpm/eventlog/tpm2.c
++++ b/drivers/char/tpm/eventlog/tpm2.c
+@@ -37,8 +37,8 @@
+ *
+ * Returns size of the event. If it is an invalid event, returns 0.
+ */
+-static int calc_tpm2_event_size(struct tcg_pcr_event2 *event,
+- struct tcg_pcr_event *event_header)
++static size_t calc_tpm2_event_size(struct tcg_pcr_event2 *event,
++ struct tcg_pcr_event *event_header)
+ {
+ struct tcg_efi_specid_event *efispecid;
+ struct tcg_event_field *event_field;
+--
+2.19.1
+
--- /dev/null
+From 809befd36173149c8de060a32b9cb431a5cfc43d Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Date: Fri, 8 Feb 2019 18:30:59 +0200
+Subject: tpm/tpm_i2c_atmel: Return -E2BIG when the transfer is incomplete
+
+[ Upstream commit 442601e87a4769a8daba4976ec3afa5222ca211d ]
+
+Return -E2BIG when the transfer is incomplete. The upper layer does
+not retry, so not doing that is incorrect behaviour.
+
+Cc: stable@vger.kernel.org
+Fixes: a2871c62e186 ("tpm: Add support for Atmel I2C TPMs")
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/tpm_i2c_atmel.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
+index 32a8e27c5382..cc4e642d3180 100644
+--- a/drivers/char/tpm/tpm_i2c_atmel.c
++++ b/drivers/char/tpm/tpm_i2c_atmel.c
+@@ -69,6 +69,10 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
+ if (status < 0)
+ return status;
+
++ /* The upper layer does not support incomplete sends. */
++ if (status != len)
++ return -E2BIG;
++
+ return 0;
+ }
+
+--
+2.19.1
+