diff options
author | Thorsten Leemhuis <fedora@leemhuis.info> | 2018-04-12 12:58:29 +0200 |
---|---|---|
committer | Thorsten Leemhuis <fedora@leemhuis.info> | 2018-04-12 12:58:29 +0200 |
commit | 81dccd5a6e8233ec7cd8f406f5ae6f205cb1a30d (patch) | |
tree | e4c20c4e3dd4daa476cdbdacd021187806074a9d | |
parent | e7dc2ec924aef9df70453f676835c42dc68bfc84 (diff) | |
parent | 326828aa4ac885ea1e440e2633f66c29582769ed (diff) | |
download | kernel-81dccd5a6e8233ec7cd8f406f5ae6f205cb1a30d.tar.gz kernel-81dccd5a6e8233ec7cd8f406f5ae6f205cb1a30d.tar.xz kernel-81dccd5a6e8233ec7cd8f406f5ae6f205cb1a30d.zip |
Merge remote-tracking branch 'origin/stabilization' into stabilization-user-thl-vanilla-fedora
-rw-r--r-- | arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch | 100 | ||||
-rw-r--r-- | arm64-Revert-allwinner-a64-pine64-Use-dcdc1-regulato.patch | 41 | ||||
-rw-r--r-- | arm64-thunderx-crypto-zip-fixes.patch | 403 | ||||
-rw-r--r-- | bcm2837-lan78xx-fixes.patch | 355 | ||||
-rw-r--r-- | ipmi-fixes.patch | 2460 | ||||
-rw-r--r-- | kernel.spec | 52 |
6 files changed, 3250 insertions, 161 deletions
diff --git a/arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch b/arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch deleted file mode 100644 index b55dec0cb..000000000 --- a/arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch +++ /dev/null @@ -1,100 +0,0 @@ -From bb3e08008c0e48fd4f51a0f0957eecae61a24d69 Mon Sep 17 00:00:00 2001 -From: Peter Robinson <pbrobinson@gmail.com> -Date: Tue, 1 Nov 2016 09:35:30 +0000 -Subject: [PATCH] Revert "mmc: omap_hsmmc: Use dma_request_chan() for - requesting DMA channel" - -This reverts commit 81eef6ca92014845d40e3f1310e42b7010303acc. ---- - drivers/mmc/host/omap_hsmmc.c | 50 ++++++++++++++++++++++++++++++++++--------- - 1 file changed, 40 insertions(+), 10 deletions(-) - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 24ebc9a..3563321 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -32,6 +32,7 @@ - #include <linux/of_irq.h> - #include <linux/of_gpio.h> - #include <linux/of_device.h> -+#include <linux/omap-dmaengine.h> - #include <linux/mmc/host.h> - #include <linux/mmc/core.h> - #include <linux/mmc/mmc.h> -@@ -1992,6 +1993,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev) - struct resource *res; - int ret, irq; - const struct of_device_id *match; -+ dma_cap_mask_t mask; -+ unsigned tx_req, rx_req; - const struct omap_mmc_of_data *data; - void __iomem *base; - -@@ -2121,17 +2124,44 @@ static int omap_hsmmc_probe(struct platform_device *pdev) - - omap_hsmmc_conf_bus_power(host); - -- host->rx_chan = dma_request_chan(&pdev->dev, "rx"); -- if (IS_ERR(host->rx_chan)) { -- dev_err(mmc_dev(host->mmc), "RX DMA channel request failed\n"); -- ret = PTR_ERR(host->rx_chan); -+ if (!pdev->dev.of_node) { -+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); -+ if (!res) { -+ dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n"); -+ ret = -ENXIO; -+ goto err_irq; -+ } -+ tx_req = res->start; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); -+ if (!res) { -+ dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n"); -+ ret = -ENXIO; -+ goto err_irq; -+ } -+ rx_req = res->start; -+ } -+ -+ dma_cap_zero(mask); -+ dma_cap_set(DMA_SLAVE, mask); -+ -+ host->rx_chan = -+ dma_request_slave_channel_compat(mask, omap_dma_filter_fn, -+ &rx_req, &pdev->dev, "rx"); -+ -+ if (!host->rx_chan) { -+ dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel\n"); -+ ret = -ENXIO; - goto err_irq; - } - -- host->tx_chan = dma_request_chan(&pdev->dev, "tx"); -- if (IS_ERR(host->tx_chan)) { -- dev_err(mmc_dev(host->mmc), "TX DMA channel request failed\n"); -- ret = PTR_ERR(host->tx_chan); -+ host->tx_chan = -+ dma_request_slave_channel_compat(mask, omap_dma_filter_fn, -+ &tx_req, &pdev->dev, "tx"); -+ -+ if (!host->tx_chan) { -+ dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel\n"); -+ ret = -ENXIO; - goto err_irq; - } - -@@ -2189,9 +2219,9 @@ err_slot_name: - mmc_remove_host(mmc); - err_irq: - device_init_wakeup(&pdev->dev, false); -- if (!IS_ERR_OR_NULL(host->tx_chan)) -+ if (host->tx_chan) - dma_release_channel(host->tx_chan); -- if (!IS_ERR_OR_NULL(host->rx_chan)) -+ if (host->rx_chan) - dma_release_channel(host->rx_chan); - pm_runtime_dont_use_autosuspend(host->dev); - pm_runtime_put_sync(host->dev); --- -2.9.3 - diff --git a/arm64-Revert-allwinner-a64-pine64-Use-dcdc1-regulato.patch b/arm64-Revert-allwinner-a64-pine64-Use-dcdc1-regulato.patch deleted file mode 100644 index 33f9271b7..000000000 --- a/arm64-Revert-allwinner-a64-pine64-Use-dcdc1-regulato.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 90e388ca5d8bbee022f9ed5fc24137b31579fa6e Mon Sep 17 00:00:00 2001 -From: Peter Robinson <pbrobinson@gmail.com> -Date: Wed, 22 Nov 2017 15:52:36 +0000 -Subject: [PATCH] Revert "arm64: allwinner: a64: pine64: Use dcdc1 regulator - for mmc0" - -This reverts commit 3f241bfa60bdc9c4fde63fa6664a8ce00fd668c6. ---- - arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -index d06e34b5d192..caf8b6fbe5e3 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -@@ -61,6 +61,13 @@ - chosen { - stdout-path = "serial0:115200n8"; - }; -+ -+ reg_vcc3v3: vcc3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; - }; - - &ehci0 { -@@ -84,7 +91,7 @@ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; -- vmmc-supply = <®_dcdc1>; -+ vmmc-supply = <®_vcc3v3>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; - cd-inverted; - disable-wp; --- -2.14.3 - diff --git a/arm64-thunderx-crypto-zip-fixes.patch b/arm64-thunderx-crypto-zip-fixes.patch new file mode 100644 index 000000000..7f970ee30 --- /dev/null +++ b/arm64-thunderx-crypto-zip-fixes.patch @@ -0,0 +1,403 @@ +From patchwork Mon Apr 9 15:45:50 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,1/5] crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK +From: Jan Glauber <jglauber@cavium.com> +X-Patchwork-Id: 10331719 +Message-Id: <20180409154554.7578-2-jglauber@cavium.com> +To: Herbert Xu <herbert@gondor.apana.org.au> +Cc: "David S . Miller" <davem@davemloft.net>, + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa <Mahipal.Challa@cavium.com>, + Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>, + stable <stable@vger.kernel.org> +Date: Mon, 9 Apr 2018 17:45:50 +0200 + +Enabling virtual mapped kernel stacks breaks the thunderx_zip +driver. On compression or decompression the executing CPU hangs +in an endless loop. The reason for this is the usage of __pa +by the driver which does no longer work for an address that is +not part of the 1:1 mapping. + +The zip driver allocates a result struct on the stack and needs +to tell the hardware the physical address within this struct +that is used to signal the completion of the request. + +As the hardware gets the wrong address after the broken __pa +conversion it writes to an arbitrary address. The zip driver then +waits forever for the completion byte to contain a non-zero value. + +Allocating the result struct from 1:1 mapped memory resolves this +bug. + +Signed-off-by: Jan Glauber <jglauber@cavium.com> +Reviewed-by: Robert Richter <rrichter@cavium.com> +Cc: stable <stable@vger.kernel.org> # 4.14 +--- + drivers/crypto/cavium/zip/zip_crypto.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/crypto/cavium/zip/zip_crypto.c b/drivers/crypto/cavium/zip/zip_crypto.c +index 8df4d26cf9d4..b92b6e7e100f 100644 +--- a/drivers/crypto/cavium/zip/zip_crypto.c ++++ b/drivers/crypto/cavium/zip/zip_crypto.c +@@ -124,7 +124,7 @@ int zip_compress(const u8 *src, unsigned int slen, + struct zip_kernel_ctx *zip_ctx) + { + struct zip_operation *zip_ops = NULL; +- struct zip_state zip_state; ++ struct zip_state *zip_state; + struct zip_device *zip = NULL; + int ret; + +@@ -135,20 +135,23 @@ int zip_compress(const u8 *src, unsigned int slen, + if (!zip) + return -ENODEV; + +- memset(&zip_state, 0, sizeof(struct zip_state)); ++ zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC); ++ if (!zip_state) ++ return -ENOMEM; ++ + zip_ops = &zip_ctx->zip_comp; + + zip_ops->input_len = slen; + zip_ops->output_len = *dlen; + memcpy(zip_ops->input, src, slen); + +- ret = zip_deflate(zip_ops, &zip_state, zip); ++ ret = zip_deflate(zip_ops, zip_state, zip); + + if (!ret) { + *dlen = zip_ops->output_len; + memcpy(dst, zip_ops->output, *dlen); + } +- ++ kfree(zip_state); + return ret; + } + +@@ -157,7 +160,7 @@ int zip_decompress(const u8 *src, unsigned int slen, + struct zip_kernel_ctx *zip_ctx) + { + struct zip_operation *zip_ops = NULL; +- struct zip_state zip_state; ++ struct zip_state *zip_state; + struct zip_device *zip = NULL; + int ret; + +@@ -168,7 +171,10 @@ int zip_decompress(const u8 *src, unsigned int slen, + if (!zip) + return -ENODEV; + +- memset(&zip_state, 0, sizeof(struct zip_state)); ++ zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC); ++ if (!zip_state) ++ return -ENOMEM; ++ + zip_ops = &zip_ctx->zip_decomp; + memcpy(zip_ops->input, src, slen); + +@@ -179,13 +185,13 @@ int zip_decompress(const u8 *src, unsigned int slen, + zip_ops->input_len = slen; + zip_ops->output_len = *dlen; + +- ret = zip_inflate(zip_ops, &zip_state, zip); ++ ret = zip_inflate(zip_ops, zip_state, zip); + + if (!ret) { + *dlen = zip_ops->output_len; + memcpy(dst, zip_ops->output, *dlen); + } +- ++ kfree(zip_state); + return ret; + } + +From patchwork Mon Apr 9 15:45:51 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,2/5] crypto: thunderx_zip: Limit result reading attempts +From: Jan Glauber <jglauber@cavium.com> +X-Patchwork-Id: 10331705 +Message-Id: <20180409154554.7578-3-jglauber@cavium.com> +To: Herbert Xu <herbert@gondor.apana.org.au> +Cc: "David S . Miller" <davem@davemloft.net>, + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa <Mahipal.Challa@cavium.com>, + Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>, + stable <stable@vger.kernel.org> +Date: Mon, 9 Apr 2018 17:45:51 +0200 + +After issuing a request an endless loop was used to read the +completion state from memory which is asynchronously updated +by the ZIP coprocessor. + +Add an upper bound to the retry attempts to prevent a CPU getting stuck +forever in case of an error. Additionally, add a read memory barrier +and a small delay between the reading attempts. + +Signed-off-by: Jan Glauber <jglauber@cavium.com> +Reviewed-by: Robert Richter <rrichter@cavium.com> +Cc: stable <stable@vger.kernel.org> # 4.14 +--- + drivers/crypto/cavium/zip/common.h | 21 +++++++++++++++++++++ + drivers/crypto/cavium/zip/zip_deflate.c | 4 ++-- + drivers/crypto/cavium/zip/zip_inflate.c | 4 ++-- + 3 files changed, 25 insertions(+), 4 deletions(-) + +diff --git a/drivers/crypto/cavium/zip/common.h b/drivers/crypto/cavium/zip/common.h +index dc451e0a43c5..58fb3ed6e644 100644 +--- a/drivers/crypto/cavium/zip/common.h ++++ b/drivers/crypto/cavium/zip/common.h +@@ -46,8 +46,10 @@ + #ifndef __COMMON_H__ + #define __COMMON_H__ + ++#include <linux/delay.h> + #include <linux/init.h> + #include <linux/interrupt.h> ++#include <linux/io.h> + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/pci.h> +@@ -149,6 +151,25 @@ struct zip_operation { + u32 sizeofzops; + }; + ++static inline int zip_poll_result(union zip_zres_s *result) ++{ ++ int retries = 1000; ++ ++ while (!result->s.compcode) { ++ if (!--retries) { ++ pr_err("ZIP ERR: request timed out"); ++ return -ETIMEDOUT; ++ } ++ udelay(10); ++ /* ++ * Force re-reading of compcode which is updated ++ * by the ZIP coprocessor. ++ */ ++ rmb(); ++ } ++ return 0; ++} ++ + /* error messages */ + #define zip_err(fmt, args...) pr_err("ZIP ERR:%s():%d: " \ + fmt "\n", __func__, __LINE__, ## args) +diff --git a/drivers/crypto/cavium/zip/zip_deflate.c b/drivers/crypto/cavium/zip/zip_deflate.c +index 9a944b8c1e29..d7133f857d67 100644 +--- a/drivers/crypto/cavium/zip/zip_deflate.c ++++ b/drivers/crypto/cavium/zip/zip_deflate.c +@@ -129,8 +129,8 @@ int zip_deflate(struct zip_operation *zip_ops, struct zip_state *s, + /* Stats update for compression requests submitted */ + atomic64_inc(&zip_dev->stats.comp_req_submit); + +- while (!result_ptr->s.compcode) +- continue; ++ /* Wait for completion or error */ ++ zip_poll_result(result_ptr); + + /* Stats update for compression requests completed */ + atomic64_inc(&zip_dev->stats.comp_req_complete); +diff --git a/drivers/crypto/cavium/zip/zip_inflate.c b/drivers/crypto/cavium/zip/zip_inflate.c +index 50cbdd83dbf2..7e0d73e2f89e 100644 +--- a/drivers/crypto/cavium/zip/zip_inflate.c ++++ b/drivers/crypto/cavium/zip/zip_inflate.c +@@ -143,8 +143,8 @@ int zip_inflate(struct zip_operation *zip_ops, struct zip_state *s, + /* Decompression requests submitted stats update */ + atomic64_inc(&zip_dev->stats.decomp_req_submit); + +- while (!result_ptr->s.compcode) +- continue; ++ /* Wait for completion or error */ ++ zip_poll_result(result_ptr); + + /* Decompression requests completed stats update */ + atomic64_inc(&zip_dev->stats.decomp_req_complete); +From patchwork Mon Apr 9 15:45:52 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,3/5] crypto: thunderx_zip: Prevent division by zero +From: Jan Glauber <jglauber@cavium.com> +X-Patchwork-Id: 10331709 +Message-Id: <20180409154554.7578-4-jglauber@cavium.com> +To: Herbert Xu <herbert@gondor.apana.org.au> +Cc: "David S . Miller" <davem@davemloft.net>, + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa <Mahipal.Challa@cavium.com>, + Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com> +Date: Mon, 9 Apr 2018 17:45:52 +0200 + +Avoid two potential divisions by zero when calculating average +values for the zip statistics. + +Signed-off-by: Jan Glauber <jglauber@cavium.com> +Reviewed-by: Robert Richter <rrichter@cavium.com> +--- + drivers/crypto/cavium/zip/zip_main.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c +index 1cd8aa488185..79b449e0f955 100644 +--- a/drivers/crypto/cavium/zip/zip_main.c ++++ b/drivers/crypto/cavium/zip/zip_main.c +@@ -482,10 +482,11 @@ static int zip_show_stats(struct seq_file *s, void *unused) + atomic64_add(val, &st->pending_req); + } + +- avg_chunk = (atomic64_read(&st->comp_in_bytes) / +- atomic64_read(&st->comp_req_complete)); +- avg_cr = (atomic64_read(&st->comp_in_bytes) / +- atomic64_read(&st->comp_out_bytes)); ++ val = atomic64_read(&st->comp_req_complete); ++ avg_chunk = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0; ++ ++ val = atomic64_read(&st->comp_out_bytes); ++ avg_cr = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0; + seq_printf(s, " ZIP Device %d Stats\n" + "-----------------------------------\n" + "Comp Req Submitted : \t%lld\n" +From patchwork Mon Apr 9 15:45:53 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,4/5] crypto: thunderx_zip: Fix statistics pending request value +From: Jan Glauber <jglauber@cavium.com> +X-Patchwork-Id: 10331711 +Message-Id: <20180409154554.7578-5-jglauber@cavium.com> +To: Herbert Xu <herbert@gondor.apana.org.au> +Cc: "David S . Miller" <davem@davemloft.net>, + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa <Mahipal.Challa@cavium.com>, + Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com> +Date: Mon, 9 Apr 2018 17:45:53 +0200 + +The pending request counter was read from the wrong register. While +at it, there is no need to use an atomic for it as it is only read +localy in a loop. + +Signed-off-by: Jan Glauber <jglauber@cavium.com> +Reviewed-by: Robert Richter <rrichter@cavium.com> +--- + drivers/crypto/cavium/zip/zip_main.c | 13 +++++-------- + drivers/crypto/cavium/zip/zip_main.h | 1 - + 2 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c +index 79b449e0f955..ae5b20c695ca 100644 +--- a/drivers/crypto/cavium/zip/zip_main.c ++++ b/drivers/crypto/cavium/zip/zip_main.c +@@ -469,6 +469,8 @@ static int zip_show_stats(struct seq_file *s, void *unused) + struct zip_stats *st; + + for (index = 0; index < MAX_ZIP_DEVICES; index++) { ++ u64 pending = 0; ++ + if (zip_dev[index]) { + zip = zip_dev[index]; + st = &zip->stats; +@@ -476,10 +478,8 @@ static int zip_show_stats(struct seq_file *s, void *unused) + /* Get all the pending requests */ + for (q = 0; q < ZIP_NUM_QUEUES; q++) { + val = zip_reg_read((zip->reg_base + +- ZIP_DBG_COREX_STA(q))); +- val = (val >> 32); +- val = val & 0xffffff; +- atomic64_add(val, &st->pending_req); ++ ZIP_DBG_QUEX_STA(q))); ++ pending += val >> 32 & 0xffffff; + } + + val = atomic64_read(&st->comp_req_complete); +@@ -514,10 +514,7 @@ static int zip_show_stats(struct seq_file *s, void *unused) + (u64)atomic64_read(&st->decomp_in_bytes), + (u64)atomic64_read(&st->decomp_out_bytes), + (u64)atomic64_read(&st->decomp_bad_reqs), +- (u64)atomic64_read(&st->pending_req)); +- +- /* Reset pending requests count */ +- atomic64_set(&st->pending_req, 0); ++ pending); + } + } + return 0; +diff --git a/drivers/crypto/cavium/zip/zip_main.h b/drivers/crypto/cavium/zip/zip_main.h +index 64e051f60784..e1e4fa92ce80 100644 +--- a/drivers/crypto/cavium/zip/zip_main.h ++++ b/drivers/crypto/cavium/zip/zip_main.h +@@ -74,7 +74,6 @@ struct zip_stats { + atomic64_t comp_req_complete; + atomic64_t decomp_req_submit; + atomic64_t decomp_req_complete; +- atomic64_t pending_req; + atomic64_t comp_in_bytes; + atomic64_t comp_out_bytes; + atomic64_t decomp_in_bytes; +From patchwork Mon Apr 9 15:45:54 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,5/5] crypto: thunderx_zip: Fix smp_processor_id() warnings +From: Jan Glauber <jglauber@cavium.com> +X-Patchwork-Id: 10331715 +Message-Id: <20180409154554.7578-6-jglauber@cavium.com> +To: Herbert Xu <herbert@gondor.apana.org.au> +Cc: "David S . Miller" <davem@davemloft.net>, + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa <Mahipal.Challa@cavium.com>, + Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com> +Date: Mon, 9 Apr 2018 17:45:54 +0200 + +Switch to raw_smp_processor_id() to prevent a number of +warnings from kernel debugging. We do not care about +preemption here, as the CPU number is only used as a +poor mans load balancing or device selection. If preemption +happens during a compress/decompress operation a small performance +hit will occur but everything will continue to work, so just +ignore it. + +Signed-off-by: Jan Glauber <jglauber@cavium.com> +Reviewed-by: Robert Richter <rrichter@cavium.com> +--- + drivers/crypto/cavium/zip/zip_device.c | 4 ++-- + drivers/crypto/cavium/zip/zip_main.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/crypto/cavium/zip/zip_device.c b/drivers/crypto/cavium/zip/zip_device.c +index ccf21fb91513..f174ec29ed69 100644 +--- a/drivers/crypto/cavium/zip/zip_device.c ++++ b/drivers/crypto/cavium/zip/zip_device.c +@@ -87,12 +87,12 @@ u32 zip_load_instr(union zip_inst_s *instr, + * Distribute the instructions between the enabled queues based on + * the CPU id. + */ +- if (smp_processor_id() % 2 == 0) ++ if (raw_smp_processor_id() % 2 == 0) + queue = 0; + else + queue = 1; + +- zip_dbg("CPU Core: %d Queue number:%d", smp_processor_id(), queue); ++ zip_dbg("CPU Core: %d Queue number:%d", raw_smp_processor_id(), queue); + + /* Take cmd buffer lock */ + spin_lock(&zip_dev->iq[queue].lock); +diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c +index ae5b20c695ca..be055b9547f6 100644 +--- a/drivers/crypto/cavium/zip/zip_main.c ++++ b/drivers/crypto/cavium/zip/zip_main.c +@@ -113,7 +113,7 @@ struct zip_device *zip_get_device(int node) + */ + int zip_get_node_id(void) + { +- return cpu_to_node(smp_processor_id()); ++ return cpu_to_node(raw_smp_processor_id()); + } + + /* Initializes the ZIP h/w sub-system */ diff --git a/bcm2837-lan78xx-fixes.patch b/bcm2837-lan78xx-fixes.patch index f877ac15b..1cb1dea08 100644 --- a/bcm2837-lan78xx-fixes.patch +++ b/bcm2837-lan78xx-fixes.patch @@ -106,3 +106,358 @@ index 60a604cc7647..a21039852f8d 100644 addr_lo = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24); addr_hi = addr[4] | (addr[5] << 8); +From b5284e5d2d3562dac311443969a538b7fecb9848 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.org> +Date: Wed, 28 Mar 2018 12:18:13 +0100 +Subject: [PATCH 1/5] lan78xx: Ignore DT MAC address if already valid + +The patch to set the lan78xx MAC address from DT does so regardless of +whether or not the interface already has a valid address. As the +initialisation function is called from the reset handler when the +interface is brought up, it is impossible to change the MAC address +in a way that persists across the interface being brought up. + +Fix the problem by moving the DT reading code after the check for a +valid address. + +See: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=209309 + +Signed-off-by: Phil Elwell <phil@raspberrypi.org> +--- + drivers/net/usb/lan78xx.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index b43b16b6e7ee..97ee7d3f749d 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1641,14 +1641,6 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev) + u32 addr_lo, addr_hi; + int ret; + u8 addr[6]; +- const u8 *mac_addr; +- +- /* maybe the boot loader passed the MAC address in devicetree */ +- mac_addr = of_get_mac_address(dev->udev->dev.of_node); +- if (mac_addr) { +- ether_addr_copy(addr, mac_addr); +- goto set_mac_addr; +- } + + ret = lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); + ret = lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); +@@ -1661,6 +1653,15 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev) + addr[5] = (addr_hi >> 8) & 0xFF; + + if (!is_valid_ether_addr(addr)) { ++ const u8 *mac_addr; ++ ++ /* maybe the boot loader passed the MAC address in devicetree */ ++ mac_addr = of_get_mac_address(dev->udev->dev.of_node); ++ if (mac_addr) { ++ ether_addr_copy(addr, mac_addr); ++ goto set_mac_addr; ++ } ++ + /* reading mac address from EEPROM or OTP */ + if ((lan78xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, + addr) == 0) || +-- +2.17.0 + +From 2c5d6ac9133cbfed05b97b34246121bddaf2aea4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.org> +Date: Wed, 4 Apr 2018 16:34:24 +0100 +Subject: [PATCH 2/5] net: lan78xx: Allow for VLAN headers in timeout. + +The frame abort timeout being set by lan78xx_set_rx_max_frame_length +didn't account for any VLAN headers, resulting in very low +throughput if used with tagged VLANs. +Use VLAN_ETH_HLEN instead of ETH_HLEN to correct for this. + +See https://github.com/raspberrypi/linux/issues/2458 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> +--- + drivers/net/usb/lan78xx.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 97ee7d3f749d..5fd7b8569cba 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2193,7 +2193,7 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu) + if ((ll_mtu % dev->maxpacket) == 0) + return -EDOM; + +- ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); ++ ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); + + netdev->mtu = new_mtu; + +@@ -2488,7 +2488,8 @@ static int lan78xx_reset(struct lan78xx_net *dev) + buf |= FCT_TX_CTL_EN_; + ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf); + +- ret = lan78xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); ++ ret = lan78xx_set_rx_max_frame_length(dev, ++ dev->net->mtu + VLAN_ETH_HLEN); + + ret = lan78xx_read_reg(dev, MAC_RX, &buf); + buf |= MAC_RX_RXEN_; +-- +2.17.0 + +From 833315351413d94d7db407847448dfeddfafe127 Mon Sep 17 00:00:00 2001 +From: Peter Robinson <pbrobinson@gmail.com> +Date: Mon, 9 Apr 2018 17:51:35 +0100 +Subject: [PATCH 3/5] lan78xx: Connect phy early + +When using wicked with a lan78xx device attached to the system, we +end up with ethtool commands issued on the device before an ifup +got issued. That lead to the following crash: + + Unable to handle kernel NULL pointer dereference at virtual address 0000039c + pgd = ffff800035b30000 + [0000039c] *pgd=0000000000000000 + Internal error: Oops: 96000004 [#1] SMP + Modules linked in: [...] + Supported: Yes + CPU: 3 PID: 638 Comm: wickedd Tainted: G E 4.12.14-0-default #1 + Hardware name: raspberrypi rpi/rpi, BIOS 2018.03-rc2 02/21/2018 + task: ffff800035e74180 task.stack: ffff800036718000 + PC is at phy_ethtool_ksettings_get+0x20/0x98 + LR is at lan78xx_get_link_ksettings+0x44/0x60 [lan78xx] + pc : [<ffff0000086f7f30>] lr : [<ffff000000dcca84>] pstate: 20000005 + sp : ffff80003671bb20 + x29: ffff80003671bb20 x28: ffff800035e74180 + x27: ffff000008912000 x26: 000000000000001d + x25: 0000000000000124 x24: ffff000008f74d00 + x23: 0000004000114809 x22: 0000000000000000 + x21: ffff80003671bbd0 x20: 0000000000000000 + x19: ffff80003671bbd0 x18: 000000000000040d + x17: 0000000000000001 x16: 0000000000000000 + x15: 0000000000000000 x14: ffffffffffffffff + x13: 0000000000000000 x12: 0000000000000020 + x11: 0101010101010101 x10: fefefefefefefeff + x9 : 7f7f7f7f7f7f7f7f x8 : fefefeff31677364 + x7 : 0000000080808080 x6 : ffff80003671bc9c + x5 : ffff80003671b9f8 x4 : ffff80002c296190 + x3 : 0000000000000000 x2 : 0000000000000000 + x1 : ffff80003671bbd0 x0 : ffff80003671bc00 + Process wickedd (pid: 638, stack limit = 0xffff800036718000) + Call trace: + Exception stack(0xffff80003671b9e0 to 0xffff80003671bb20) + b9e0: ffff80003671bc00 ffff80003671bbd0 0000000000000000 0000000000000000 + ba00: ffff80002c296190 ffff80003671b9f8 ffff80003671bc9c 0000000080808080 + ba20: fefefeff31677364 7f7f7f7f7f7f7f7f fefefefefefefeff 0101010101010101 + ba40: 0000000000000020 0000000000000000 ffffffffffffffff 0000000000000000 + ba60: 0000000000000000 0000000000000001 000000000000040d ffff80003671bbd0 + ba80: 0000000000000000 ffff80003671bbd0 0000000000000000 0000004000114809 + baa0: ffff000008f74d00 0000000000000124 000000000000001d ffff000008912000 + bac0: ffff800035e74180 ffff80003671bb20 ffff000000dcca84 ffff80003671bb20 + bae0: ffff0000086f7f30 0000000020000005 ffff80002c296000 ffff800035223900 + bb00: 0000ffffffffffff 0000000000000000 ffff80003671bb20 ffff0000086f7f30 + [<ffff0000086f7f30>] phy_ethtool_ksettings_get+0x20/0x98 + [<ffff000000dcca84>] lan78xx_get_link_ksettings+0x44/0x60 [lan78xx] + [<ffff0000087cbc40>] ethtool_get_settings+0x68/0x210 + [<ffff0000087cc0d4>] dev_ethtool+0x214/0x2180 + [<ffff0000087e5008>] dev_ioctl+0x400/0x630 + [<ffff00000879dd00>] sock_do_ioctl+0x70/0x88 + [<ffff00000879f5f8>] sock_ioctl+0x208/0x368 + [<ffff0000082cde10>] do_vfs_ioctl+0xb0/0x848 + [<ffff0000082ce634>] SyS_ioctl+0x8c/0xa8 + Exception stack(0xffff80003671bec0 to 0xffff80003671c000) + bec0: 0000000000000009 0000000000008946 0000fffff4e841d0 0000aa0032687465 + bee0: 0000aaaafa2319d4 0000fffff4e841d4 0000000032687465 0000000032687465 + bf00: 000000000000001d 7f7fff7f7f7f7f7f 72606b622e71ff4c 7f7f7f7f7f7f7f7f + bf20: 0101010101010101 0000000000000020 ffffffffffffffff 0000ffff7f510c68 + bf40: 0000ffff7f6a9d18 0000ffff7f44ce30 000000000000040d 0000ffff7f6f98f0 + bf60: 0000fffff4e842c0 0000000000000001 0000aaaafa2c2e00 0000ffff7f6ab000 + bf80: 0000fffff4e842c0 0000ffff7f62a000 0000aaaafa2b9f20 0000aaaafa2c2e00 + bfa0: 0000fffff4e84818 0000fffff4e841a0 0000ffff7f5ad0cc 0000fffff4e841a0 + bfc0: 0000ffff7f44ce3c 0000000080000000 0000000000000009 000000000000001d + bfe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + +The culprit is quite simple: The driver tries to access the phy left and right, +but only actually has a working reference to it when the device is up. + +The fix thus is quite simple too: Get a reference to the phy on probe already +and keep it even when the device is going down. + +With this patch applied, I can successfully run wicked on my system and bring +the interface up and down as many times as I want, without getting NULL pointer +dereferences in between. + +Signed-off-by: Alexander Graf <agraf@suse.de> +--- + drivers/net/usb/lan78xx.c | 34 ++++++++++++++++++---------------- + 1 file changed, 18 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 5fd7b8569cba..60fa1257721c 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2094,10 +2094,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) + + dev->fc_autoneg = phydev->autoneg; + +- phy_start(phydev); +- +- netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); +- + return 0; + + error: +@@ -2541,9 +2537,9 @@ static int lan78xx_open(struct net_device *net) + if (ret < 0) + goto done; + +- ret = lan78xx_phy_init(dev); +- if (ret < 0) +- goto done; ++ phy_start(net->phydev); ++ ++ netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); + + /* for Link Check */ + if (dev->urb_intr) { +@@ -2604,13 +2600,8 @@ static int lan78xx_stop(struct net_device *net) + if (timer_pending(&dev->stat_monitor)) + del_timer_sync(&dev->stat_monitor); + +- phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); +- phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); +- +- phy_stop(net->phydev); +- phy_disconnect(net->phydev); +- +- net->phydev = NULL; ++ if (net->phydev) ++ phy_stop(net->phydev); + + clear_bit(EVENT_DEV_OPEN, &dev->flags); + netif_stop_queue(net); +@@ -3525,8 +3516,13 @@ static void lan78xx_disconnect(struct usb_interface *intf) + return; + + udev = interface_to_usbdev(intf); +- + net = dev->net; ++ ++ phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); ++ phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); ++ ++ phy_disconnect(net->phydev); ++ + unregister_netdev(net); + + cancel_delayed_work_sync(&dev->wq); +@@ -3682,8 +3678,14 @@ static int lan78xx_probe(struct usb_interface *intf, + pm_runtime_set_autosuspend_delay(&udev->dev, + DEFAULT_AUTOSUSPEND_DELAY); + ++ ret = lan78xx_phy_init(dev); ++ if (ret < 0) ++ goto out4; ++ + return 0; + ++out4: ++ unregister_netdev(netdev); + out3: + lan78xx_unbind(dev, intf); + out2: +@@ -4031,7 +4033,7 @@ static int lan78xx_reset_resume(struct usb_interface *intf) + + lan78xx_reset(dev); + +- lan78xx_phy_init(dev); ++ phy_start(dev->net->phydev); + + return lan78xx_resume(intf); + } +-- +2.17.0 + +From 7b4cc4a0af02c0d798007a143efa7509711d52d7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.org> +Date: Wed, 4 Apr 2018 16:39:44 +0100 +Subject: [PATCH 4/5] lan78xx: Don't reset the interface on open + +With Alexander Graf's patch ("lan78xx: Connect phy early") applied, +the call to lan78xx_reset within lan78xx_open prevents the phy +interrupt from being generated (even though the link is up). + +Avoid this issue by removing the lan78xx_reset call. + +See: https://github.com/raspberrypi/linux/issues/2437 + https://github.com/raspberrypi/linux/issues/2442 + https://github.com/raspberrypi/linux/issues/2457 +--- + drivers/net/usb/lan78xx.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 60fa1257721c..293ed1847932 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2533,10 +2533,6 @@ static int lan78xx_open(struct net_device *net) + if (ret < 0) + goto out; + +- ret = lan78xx_reset(dev); +- if (ret < 0) +- goto done; +- + phy_start(net->phydev); + + netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); +-- +2.17.0 + +From ddbd11509f01c388b968872aeabf630654275b0a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.org> +Date: Mon, 9 Apr 2018 14:31:54 +0100 +Subject: [PATCH 5/5] net: lan78xx: Request s/w csum check on VLAN tagged + packets. + +There appears to be some issue in the LAN78xx where the checksum +computed on a VLAN tagged packet is incorrect, or at least not +in the form that the kernel is after. This is most easily shown +by pinging a device via a VLAN tagged interface and it will dump +out the error message and stack trace from netdev_rx_csum_fault. +It has also been seen with standard TCP and UDP packets. + +Until this is fully understood, request that the network stack +computes the checksum on packets signalled as having a VLAN tag +applied. + +See https://github.com/raspberrypi/linux/issues/2458 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> +--- + drivers/net/usb/lan78xx.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 293ed1847932..44cabda17bb6 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2937,8 +2937,12 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev, + struct sk_buff *skb, + u32 rx_cmd_a, u32 rx_cmd_b) + { ++ /* Checksum offload appears to be flawed if used with VLANs. ++ * Elect for sw checksum check instead. ++ */ + if (!(dev->net->features & NETIF_F_RXCSUM) || +- unlikely(rx_cmd_a & RX_CMD_A_ICSM_)) { ++ unlikely(rx_cmd_a & RX_CMD_A_ICSM_) || ++ (rx_cmd_a & RX_CMD_A_FVTG_)) { + skb->ip_summed = CHECKSUM_NONE; + } else { + skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT_)); +-- +2.17.0 + diff --git a/ipmi-fixes.patch b/ipmi-fixes.patch new file mode 100644 index 000000000..b1838efa0 --- /dev/null +++ b/ipmi-fixes.patch @@ -0,0 +1,2460 @@ +From 20d60f61c58e8c937f3653819816dd203e6e3cb4 Mon Sep 17 00:00:00 2001 +From: Haiyue Wang <haiyue.wang@linux.intel.com> +Date: Fri, 2 Feb 2018 10:16:10 +0800 +Subject: [PATCH 1/9] ipmi: add a KCS IPMI BMC driver + +Provides a device driver for the KCS (Keyboard Controller Style) +IPMI interface which meets the requirement of the BMC (Baseboard +Management Controllers) side for handling the IPMI request from +host system software. + +Signed-off-by: Haiyue Wang <haiyue.wang@linux.intel.com> +[Removed the selectability of IPMI_KCS_BMC, as it doesn't do much + good to have it by itself.] +Signed-off-by: Corey Minyard <cminyard@mvista.com> +--- + drivers/char/ipmi/Kconfig | 3 + + drivers/char/ipmi/Makefile | 1 + + drivers/char/ipmi/kcs_bmc.c | 464 ++++++++++++++++++++++++++++++++++++++++++ + drivers/char/ipmi/kcs_bmc.h | 106 ++++++++++ + include/uapi/linux/ipmi_bmc.h | 14 ++ + 5 files changed, 588 insertions(+) + create mode 100644 drivers/char/ipmi/kcs_bmc.c + create mode 100644 drivers/char/ipmi/kcs_bmc.h + create mode 100644 include/uapi/linux/ipmi_bmc.h + +diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig +index 3544abc0f9f9..7641b8a2f632 100644 +--- a/drivers/char/ipmi/Kconfig ++++ b/drivers/char/ipmi/Kconfig +@@ -96,6 +96,9 @@ config IPMI_POWEROFF + + endif # IPMI_HANDLER + ++config IPMI_KCS_BMC ++ tristate ++ + config ASPEED_BT_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + depends on REGMAP && REGMAP_MMIO && MFD_SYSCON +diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile +index 33b899fcf14a..2abccb30016a 100644 +--- a/drivers/char/ipmi/Makefile ++++ b/drivers/char/ipmi/Makefile +@@ -21,4 +21,5 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o + obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o + obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o + obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o ++obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o + obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c +new file mode 100644 +index 000000000000..3a3498afa427 +--- /dev/null ++++ b/drivers/char/ipmi/kcs_bmc.c +@@ -0,0 +1,464 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2015-2018, Intel Corporation. ++ ++#define pr_fmt(fmt) "kcs-bmc: " fmt ++ ++#include <linux/errno.h> ++#include <linux/io.h> ++#include <linux/ipmi_bmc.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/poll.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++ ++#include "kcs_bmc.h" ++ ++#define KCS_MSG_BUFSIZ 1000 ++ ++#define KCS_ZERO_DATA 0 ++ ++ ++/* IPMI 2.0 - Table 9-1, KCS Interface Status Register Bits */ ++#define KCS_STATUS_STATE(state) (state << 6) ++#define KCS_STATUS_STATE_MASK GENMASK(7, 6) ++#define KCS_STATUS_CMD_DAT BIT(3) ++#define KCS_STATUS_SMS_ATN BIT(2) ++#define KCS_STATUS_IBF BIT(1) ++#define KCS_STATUS_OBF BIT(0) ++ ++/* IPMI 2.0 - Table 9-2, KCS Interface State Bits */ ++enum kcs_states { ++ IDLE_STATE = 0, ++ READ_STATE = 1, ++ WRITE_STATE = 2, ++ ERROR_STATE = 3, ++}; ++ ++/* IPMI 2.0 - Table 9-3, KCS Interface Control Codes */ ++#define KCS_CMD_GET_STATUS_ABORT 0x60 ++#define KCS_CMD_WRITE_START 0x61 ++#define KCS_CMD_WRITE_END 0x62 ++#define KCS_CMD_READ_BYTE 0x68 ++ ++static inline u8 read_data(struct kcs_bmc *kcs_bmc) ++{ ++ return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr); ++} ++ ++static inline void write_data(struct kcs_bmc *kcs_bmc, u8 data) ++{ ++ kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data); ++} ++ ++static inline u8 read_status(struct kcs_bmc *kcs_bmc) ++{ ++ return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str); ++} ++ ++static inline void write_status(struct kcs_bmc *kcs_bmc, u8 data) ++{ ++ kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data); ++} ++ ++static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8 val) ++{ ++ u8 tmp = read_status(kcs_bmc); ++ ++ tmp &= ~mask; ++ tmp |= val & mask; ++ ++ write_status(kcs_bmc, tmp); ++} ++ ++static inline void set_state(struct kcs_bmc *kcs_bmc, u8 state) ++{ ++ update_status_bits(kcs_bmc, KCS_STATUS_STATE_MASK, ++ KCS_STATUS_STATE(state)); ++} ++ ++static void kcs_force_abort(struct kcs_bmc *kcs_bmc) ++{ ++ set_state(kcs_bmc, ERROR_STATE); ++ read_data(kcs_bmc); ++ write_data(kcs_bmc, KCS_ZERO_DATA); ++ ++ kcs_bmc->phase = KCS_PHASE_ERROR; ++ kcs_bmc->data_in_avail = false; ++ kcs_bmc->data_in_idx = 0; ++} ++ ++static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc) ++{ ++ u8 data; ++ ++ switch (kcs_bmc->phase) { ++ case KCS_PHASE_WRITE_START: ++ kcs_bmc->phase = KCS_PHASE_WRITE_DATA; ++ ++ case KCS_PHASE_WRITE_DATA: ++ if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) { ++ set_state(kcs_bmc, WRITE_STATE); ++ write_data(kcs_bmc, KCS_ZERO_DATA); ++ kcs_bmc->data_in[kcs_bmc->data_in_idx++] = ++ read_data(kcs_bmc); ++ } else { ++ kcs_force_abort(kcs_bmc); ++ kcs_bmc->error = KCS_LENGTH_ERROR; ++ } ++ break; ++ ++ case KCS_PHASE_WRITE_END_CMD: ++ if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) { ++ set_state(kcs_bmc, READ_STATE); ++ kcs_bmc->data_in[kcs_bmc->data_in_idx++] = ++ read_data(kcs_bmc); ++ kcs_bmc->phase = KCS_PHASE_WRITE_DONE; ++ kcs_bmc->data_in_avail = true; ++ wake_up_interruptible(&kcs_bmc->queue); ++ } else { ++ kcs_force_abort(kcs_bmc); ++ kcs_bmc->error = KCS_LENGTH_ERROR; ++ } ++ break; ++ ++ case KCS_PHASE_READ: ++ if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) ++ set_state(kcs_bmc, IDLE_STATE); ++ ++ data = read_data(kcs_bmc); ++ if (data != KCS_CMD_READ_BYTE) { ++ set_state(kcs_bmc, ERROR_STATE); ++ write_data(kcs_bmc, KCS_ZERO_DATA); ++ break; ++ } ++ ++ if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) { ++ write_data(kcs_bmc, KCS_ZERO_DATA); ++ kcs_bmc->phase = KCS_PHASE_IDLE; ++ break; ++ } ++ ++ write_data(kcs_bmc, ++ kcs_bmc->data_out[kcs_bmc->data_out_idx++]); ++ break; ++ ++ case KCS_PHASE_ABORT_ERROR1: ++ set_state(kcs_bmc, READ_STATE); ++ read_data(kcs_bmc); ++ write_data(kcs_bmc, kcs_bmc->error); ++ kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2; ++ break; ++ ++ case KCS_PHASE_ABORT_ERROR2: ++ set_state(kcs_bmc, IDLE_STATE); ++ read_data(kcs_bmc); ++ write_data(kcs_bmc, KCS_ZERO_DATA); ++ kcs_bmc->phase = KCS_PHASE_IDLE; ++ break; ++ ++ default: ++ kcs_force_abort(kcs_bmc); ++ break; ++ } ++} ++ ++static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc) ++{ ++ u8 cmd; ++ ++ set_state(kcs_bmc, WRITE_STATE); ++ write_data(kcs_bmc, KCS_ZERO_DATA); ++ ++ cmd = read_data(kcs_bmc); ++ switch (cmd) { ++ case KCS_CMD_WRITE_START: ++ kcs_bmc->phase = KCS_PHASE_WRITE_START; ++ kcs_bmc->error = KCS_NO_ERROR; ++ kcs_bmc->data_in_avail = false; ++ kcs_bmc->data_in_idx = 0; ++ break; ++ ++ case KCS_CMD_WRITE_END: ++ if (kcs_bmc->phase != KCS_PHASE_WRITE_DATA) { ++ kcs_force_abort(kcs_bmc); ++ break; ++ } ++ ++ kcs_bmc->phase = KCS_PHASE_WRITE_END_CMD; ++ break; ++ ++ case KCS_CMD_GET_STATUS_ABORT: ++ if (kcs_bmc->error == KCS_NO_ERROR) ++ kcs_bmc->error = KCS_ABORTED_BY_COMMAND; ++ ++ kcs_bmc->phase = KCS_PHASE_ABORT_ERROR1; ++ kcs_bmc->data_in_avail = false; ++ kcs_bmc->data_in_idx = 0; ++ break; ++ ++ default: ++ kcs_force_abort(kcs_bmc); ++ kcs_bmc->error = KCS_ILLEGAL_CONTROL_CODE; ++ break; ++ } ++} ++ ++int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) ++{ ++ unsigned long flags; ++ int ret = 0; ++ u8 status; ++ ++ spin_lock_irqsave(&kcs_bmc->lock, flags); ++ ++ if (!kcs_bmc->running) { ++ kcs_force_abort(kcs_bmc); ++ ret = -ENODEV; ++ goto out_unlock; ++ } ++ ++ status = read_status(kcs_bmc) & (KCS_STATUS_IBF | KCS_STATUS_CMD_DAT); ++ ++ switch (status) { ++ case KCS_STATUS_IBF | KCS_STATUS_CMD_DAT: ++ kcs_bmc_handle_cmd(kcs_bmc); ++ break; ++ ++ case KCS_STATUS_IBF: ++ kcs_bmc_handle_data(kcs_bmc); ++ break; ++ ++ default: ++ ret = -ENODATA; ++ break; ++ } ++ ++out_unlock: ++ spin_unlock_irqrestore(&kcs_bmc->lock, flags); ++ ++ return ret; ++} ++EXPORT_SYMBOL(kcs_bmc_handle_event); ++ ++static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp) ++{ ++ return container_of(filp->private_data, struct kcs_bmc, miscdev); ++} ++ ++static int kcs_bmc_open(struct inode *inode, struct file *filp) ++{ ++ struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ int ret = 0; ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ if (!kcs_bmc->running) ++ kcs_bmc->running = 1; ++ else ++ ret = -EBUSY; ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++ return ret; ++} ++ ++static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait) ++{ ++ struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ unsigned int mask = 0; ++ ++ poll_wait(filp, &kcs_bmc->queue, wait); ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ if (kcs_bmc->data_in_avail) ++ mask |= POLLIN; ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++ return mask; ++} ++ ++static ssize_t kcs_bmc_read(struct file *filp, char *buf, ++ size_t count, loff_t *offset) ++{ ++ struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ bool data_avail; ++ size_t data_len; ++ ssize_t ret; ++ ++ if (!(filp->f_flags & O_NONBLOCK)) ++ wait_event_interruptible(kcs_bmc->queue, ++ kcs_bmc->data_in_avail); ++ ++ mutex_lock(&kcs_bmc->mutex); ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ data_avail = kcs_bmc->data_in_avail; ++ if (data_avail) { ++ data_len = kcs_bmc->data_in_idx; ++ memcpy(kcs_bmc->kbuffer, kcs_bmc->data_in, data_len); ++ } ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++ if (!data_avail) { ++ ret = -EAGAIN; ++ goto out_unlock; ++ } ++ ++ if (count < data_len) { ++ pr_err("channel=%u with too large data : %zu\n", ++ kcs_bmc->channel, data_len); ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ kcs_force_abort(kcs_bmc); ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++ ret = -EOVERFLOW; ++ goto out_unlock; ++ } ++ ++ if (copy_to_user(buf, kcs_bmc->kbuffer, data_len)) { ++ ret = -EFAULT; ++ goto out_unlock; ++ } ++ ++ ret = data_len; ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ if (kcs_bmc->phase == KCS_PHASE_WRITE_DONE) { ++ kcs_bmc->phase = KCS_PHASE_WAIT_READ; ++ kcs_bmc->data_in_avail = false; ++ kcs_bmc->data_in_idx = 0; ++ } else { ++ ret = -EAGAIN; ++ } ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++out_unlock: ++ mutex_unlock(&kcs_bmc->mutex); ++ ++ return ret; ++} ++ ++static ssize_t kcs_bmc_write(struct file *filp, const char *buf, ++ size_t count, loff_t *offset) ++{ ++ struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ ssize_t ret; ++ ++ /* a minimum response size '3' : netfn + cmd + ccode */ ++ if (count < 3 || count > KCS_MSG_BUFSIZ) ++ return -EINVAL; ++ ++ mutex_lock(&kcs_bmc->mutex); ++ ++ if (copy_from_user(kcs_bmc->kbuffer, buf, count)) { ++ ret = -EFAULT; ++ goto out_unlock; ++ } ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ if (kcs_bmc->phase == KCS_PHASE_WAIT_READ) { ++ kcs_bmc->phase = KCS_PHASE_READ; ++ kcs_bmc->data_out_idx = 1; ++ kcs_bmc->data_out_len = count; ++ memcpy(kcs_bmc->data_out, kcs_bmc->kbuffer, count); ++ write_data(kcs_bmc, kcs_bmc->data_out[0]); ++ ret = count; ++ } else { ++ ret = -EINVAL; ++ } ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++out_unlock: ++ mutex_unlock(&kcs_bmc->mutex); ++ ++ return ret; ++} ++ ++static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ long ret = 0; ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ ++ switch (cmd) { ++ case IPMI_BMC_IOCTL_SET_SMS_ATN: ++ update_status_bits(kcs_bmc, KCS_STATUS_SMS_ATN, ++ KCS_STATUS_SMS_ATN); ++ break; ++ ++ case IPMI_BMC_IOCTL_CLEAR_SMS_ATN: ++ update_status_bits(kcs_bmc, KCS_STATUS_SMS_ATN, ++ 0); ++ break; ++ ++ case IPMI_BMC_IOCTL_FORCE_ABORT: ++ kcs_force_abort(kcs_bmc); ++ break; ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++ return ret; ++} ++ ++static int kcs_bmc_release(struct inode *inode, struct file *filp) ++{ ++ struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ ++ spin_lock_irq(&kcs_bmc->lock); ++ kcs_bmc->running = 0; ++ kcs_force_abort(kcs_bmc); ++ spin_unlock_irq(&kcs_bmc->lock); ++ ++ return 0; ++} ++ ++static const struct file_operations kcs_bmc_fops = { ++ .owner = THIS_MODULE, ++ .open = kcs_bmc_open, ++ .read = kcs_bmc_read, ++ .write = kcs_bmc_write, ++ .release = kcs_bmc_release, ++ .poll = kcs_bmc_poll, ++ .unlocked_ioctl = kcs_bmc_ioctl, ++}; ++ ++struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel) ++{ ++ struct kcs_bmc *kcs_bmc; ++ ++ kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL); ++ if (!kcs_bmc) ++ return NULL; ++ ++ dev_set_name(dev, "ipmi-kcs%u", channel); ++ ++ spin_lock_init(&kcs_bmc->lock); ++ kcs_bmc->channel = channel; ++ ++ mutex_init(&kcs_bmc->mutex); ++ init_waitqueue_head(&kcs_bmc->queue); ++ ++ kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); ++ kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); ++ kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); ++ if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer) ++ return NULL; ++ ++ kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; ++ kcs_bmc->miscdev.name = dev_name(dev); ++ kcs_bmc->miscdev.fops = &kcs_bmc_fops; ++ ++ return kcs_bmc; ++} ++EXPORT_SYMBOL(kcs_bmc_alloc); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>"); ++MODULE_DESCRIPTION("KCS BMC to handle the IPMI request from system software"); +diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h +new file mode 100644 +index 000000000000..c19501db0236 +--- /dev/null ++++ b/drivers/char/ipmi/kcs_bmc.h +@@ -0,0 +1,106 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2015-2018, Intel Corporation. ++ ++#ifndef __KCS_BMC_H__ ++#define __KCS_BMC_H__ ++ ++#include <linux/miscdevice.h> ++ ++/* Different phases of the KCS BMC module : ++ * KCS_PHASE_IDLE : ++ * BMC should not be expecting nor sending any data. ++ * KCS_PHASE_WRITE_START : ++ * BMC is receiving a WRITE_START command from system software. ++ * KCS_PHASE_WRITE_DATA : ++ * BMC is receiving a data byte from system software. ++ * KCS_PHASE_WRITE_END_CMD : ++ * BMC is waiting a last data byte from system software. ++ * KCS_PHASE_WRITE_DONE : ++ * BMC has received the whole request from system software. ++ * KCS_PHASE_WAIT_READ : ++ * BMC is waiting the response from the upper IPMI service. ++ * KCS_PHASE_READ : ++ * BMC is transferring the response to system software. ++ * KCS_PHASE_ABORT_ERROR1 : ++ * BMC is waiting error status request from system software. ++ * KCS_PHASE_ABORT_ERROR2 : ++ * BMC is waiting for idle status afer error from system software. ++ * KCS_PHASE_ERROR : ++ * BMC has detected a protocol violation at the interface level. ++ */ ++enum kcs_phases { ++ KCS_PHASE_IDLE, ++ ++ KCS_PHASE_WRITE_START, ++ KCS_PHASE_WRITE_DATA, ++ KCS_PHASE_WRITE_END_CMD, ++ KCS_PHASE_WRITE_DONE, ++ ++ KCS_PHASE_WAIT_READ, ++ KCS_PHASE_READ, ++ ++ KCS_PHASE_ABORT_ERROR1, ++ KCS_PHASE_ABORT_ERROR2, ++ KCS_PHASE_ERROR ++}; ++ ++/* IPMI 2.0 - Table 9-4, KCS Interface Status Codes */ ++enum kcs_errors { ++ KCS_NO_ERROR = 0x00, ++ KCS_ABORTED_BY_COMMAND = 0x01, ++ KCS_ILLEGAL_CONTROL_CODE = 0x02, ++ KCS_LENGTH_ERROR = 0x06, ++ KCS_UNSPECIFIED_ERROR = 0xFF ++}; ++ ++/* IPMI 2.0 - 9.5, KCS Interface Registers ++ * @idr : Input Data Register ++ * @odr : Output Data Register ++ * @str : Status Register ++ */ ++struct kcs_ioreg { ++ u32 idr; ++ u32 odr; ++ u32 str; ++}; ++ ++struct kcs_bmc { ++ spinlock_t lock; ++ ++ u32 channel; ++ int running; ++ ++ /* Setup by BMC KCS controller driver */ ++ struct kcs_ioreg ioreg; ++ u8 (*io_inputb)(struct kcs_bmc *kcs_bmc, u32 reg); ++ void (*io_outputb)(struct kcs_bmc *kcs_bmc, u32 reg, u8 b); ++ ++ enum kcs_phases phase; ++ enum kcs_errors error; ++ ++ wait_queue_head_t queue; ++ bool data_in_avail; ++ int data_in_idx; ++ u8 *data_in; ++ ++ int data_out_idx; ++ int data_out_len; ++ u8 *data_out; ++ ++ struct mutex mutex; ++ u8 *kbuffer; ++ ++ struct miscdevice miscdev; ++ ++ unsigned long priv[]; ++}; ++ ++static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc) ++{ ++ return kcs_bmc->priv; ++} ++ ++int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc); ++struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, ++ u32 channel); ++#endif +diff --git a/include/uapi/linux/ipmi_bmc.h b/include/uapi/linux/ipmi_bmc.h +new file mode 100644 +index 000000000000..2f9f97e6123a +--- /dev/null ++++ b/include/uapi/linux/ipmi_bmc.h +@@ -0,0 +1,14 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2015-2018, Intel Corporation. ++ ++#ifndef _UAPI_LINUX_IPMI_BMC_H ++#define _UAPI_LINUX_IPMI_BMC_H ++ ++#include <linux/ioctl.h> ++ ++#define __IPMI_BMC_IOCTL_MAGIC 0xB1 ++#define IPMI_BMC_IOCTL_SET_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x00) ++#define IPMI_BMC_IOCTL_CLEAR_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01) ++#define IPMI_BMC_IOCTL_FORCE_ABORT _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02) ++ ++#endif /* _UAPI_LINUX_KCS_BMC_H */ +-- +2.14.3 + + +From be2ed207e3745392478e85afa0bb02acdf44c966 Mon Sep 17 00:00:00 2001 +From: Haiyue Wang <haiyue.wang@linux.intel.com> +Date: Fri, 2 Feb 2018 10:16:11 +0800 +Subject: [PATCH 2/9] ipmi: add an Aspeed KCS IPMI BMC driver + +The KCS (Keyboard Controller Style) interface is used to perform in-band +IPMI communication between a server host and its BMC (BaseBoard Management +Controllers). + +This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500) +as a character device. Such SOCs are commonly used as BMCs and this driver +implements the BMC side of the KCS interface. + +Signed-off-by: Haiyue Wang <haiyue.wang@linux.intel.com> +Signed-off-by: Corey Minyard <cminyard@mvista.com> +--- + .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt | 25 ++ + drivers/char/ipmi/Kconfig | 12 + + drivers/char/ipmi/Makefile | 1 + + drivers/char/ipmi/kcs_bmc_aspeed.c | 319 +++++++++++++++++++++ + 4 files changed, 357 insertions(+) + create mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt + create mode 100644 drivers/char/ipmi/kcs_bmc_aspeed.c + +diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt +new file mode 100644 +index 000000000000..d98a9bf45d6c +--- /dev/null ++++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt +@@ -0,0 +1,25 @@ ++* Aspeed KCS (Keyboard Controller Style) IPMI interface ++ ++The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs ++(Baseboard Management Controllers) and the KCS interface can be ++used to perform in-band IPMI communication with their host. ++ ++Required properties: ++- compatible : should be one of ++ "aspeed,ast2400-kcs-bmc" ++ "aspeed,ast2500-kcs-bmc" ++- interrupts : interrupt generated by the controller ++- kcs_chan : The LPC channel number in the controller ++- kcs_addr : The host CPU IO map address ++ ++ ++Example: ++ ++ kcs3: kcs3@0 { ++ compatible = "aspeed,ast2500-kcs-bmc"; ++ reg = <0x0 0x80>; ++ interrupts = <8>; ++ kcs_chan = <3>; ++ kcs_addr = <0xCA2>; ++ status = "okay"; ++ }; +diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig +index 7641b8a2f632..3bda116c8aa0 100644 +--- a/drivers/char/ipmi/Kconfig ++++ b/drivers/char/ipmi/Kconfig +@@ -99,6 +99,18 @@ endif # IPMI_HANDLER + config IPMI_KCS_BMC + tristate + ++config ASPEED_KCS_IPMI_BMC ++ depends on ARCH_ASPEED || COMPILE_TEST ++ select IPMI_KCS_BMC ++ select REGMAP_MMIO ++ tristate "Aspeed KCS IPMI BMC driver" ++ help ++ Provides a driver for the KCS (Keyboard Controller Style) IPMI ++ interface found on Aspeed SOCs (AST2400 and AST2500). ++ ++ The driver implements the BMC side of the KCS contorller, it ++ provides the access of KCS IO space for BMC side. ++ + config ASPEED_BT_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + depends on REGMAP && REGMAP_MMIO && MFD_SYSCON +diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile +index 2abccb30016a..21e9e872d973 100644 +--- a/drivers/char/ipmi/Makefile ++++ b/drivers/char/ipmi/Makefile +@@ -23,3 +23,4 @@ obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o + obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o + obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o + obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o ++obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o +diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c +new file mode 100644 +index 000000000000..0c4d1a36dae4 +--- /dev/null ++++ b/drivers/char/ipmi/kcs_bmc_aspeed.c +@@ -0,0 +1,319 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2015-2018, Intel Corporation. ++ ++#define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt ++ ++#include <linux/atomic.h> ++#include <linux/errno.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/mfd/syscon.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/platform_device.h> ++#include <linux/poll.h> ++#include <linux/regmap.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/timer.h> ++ ++#include "kcs_bmc.h" ++ ++ ++#define DEVICE_NAME "ast-kcs-bmc" ++ ++#define KCS_CHANNEL_MAX 4 ++ ++/* mapped to lpc-bmc@0 IO space */ ++#define LPC_HICR0 0x000 ++#define LPC_HICR0_LPC3E BIT(7) ++#define LPC_HICR0_LPC2E BIT(6) ++#define LPC_HICR0_LPC1E BIT(5) ++#define LPC_HICR2 0x008 ++#define LPC_HICR2_IBFIF3 BIT(3) ++#define LPC_HICR2_IBFIF2 BIT(2) ++#define LPC_HICR2_IBFIF1 BIT(1) ++#define LPC_HICR4 0x010 ++#define LPC_HICR4_LADR12AS BIT(7) ++#define LPC_HICR4_KCSENBL BIT(2) ++#define LPC_LADR3H 0x014 ++#define LPC_LADR3L 0x018 ++#define LPC_LADR12H 0x01C ++#define LPC_LADR12L 0x020 ++#define LPC_IDR1 0x024 ++#define LPC_IDR2 0x028 ++#define LPC_IDR3 0x02C ++#define LPC_ODR1 0x030 ++#define LPC_ODR2 0x034 ++#define LPC_ODR3 0x038 ++#define LPC_STR1 0x03C ++#define LPC_STR2 0x040 ++#define LPC_STR3 0x044 ++ ++/* mapped to lpc-host@80 IO space */ ++#define LPC_HICRB 0x080 ++#define LPC_HICRB_IBFIF4 BIT(1) ++#define LPC_HICRB_LPC4E BIT(0) ++#define LPC_LADR4 0x090 ++#define LPC_IDR4 0x094 ++#define LPC_ODR4 0x098 ++#define LPC_STR4 0x09C ++ ++struct aspeed_kcs_bmc { ++ struct regmap *map; ++}; ++ ++ ++static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) ++{ ++ struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); ++ u32 val = 0; ++ int rc; ++ ++ rc = regmap_read(priv->map, reg, &val); ++ WARN(rc != 0, "regmap_read() failed: %d\n", rc); ++ ++ return rc == 0 ? (u8) val : 0; ++} ++ ++static void aspeed_kcs_outb(struct kcs_bmc *kcs_bmc, u32 reg, u8 data) ++{ ++ struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); ++ int rc; ++ ++ rc = regmap_write(priv->map, reg, data); ++ WARN(rc != 0, "regmap_write() failed: %d\n", rc); ++} ++ ++ ++/* ++ * AST_usrGuide_KCS.pdf ++ * 2. Background: ++ * we note D for Data, and C for Cmd/Status, default rules are ++ * A. KCS1 / KCS2 ( D / C:X / X+4 ) ++ * D / C : CA0h / CA4h ++ * D / C : CA8h / CACh ++ * B. KCS3 ( D / C:XX2h / XX3h ) ++ * D / C : CA2h / CA3h ++ * D / C : CB2h / CB3h ++ * C. KCS4 ++ * D / C : CA4h / CA5h ++ */ ++static void aspeed_kcs_set_address(struct kcs_bmc *kcs_bmc, u16 addr) ++{ ++ struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); ++ ++ switch (kcs_bmc->channel) { ++ case 1: ++ regmap_update_bits(priv->map, LPC_HICR4, ++ LPC_HICR4_LADR12AS, 0); ++ regmap_write(priv->map, LPC_LADR12H, addr >> 8); ++ regmap_write(priv->map, LPC_LADR12L, addr & 0xFF); ++ break; ++ ++ case 2: ++ regmap_update_bits(priv->map, LPC_HICR4, ++ LPC_HICR4_LADR12AS, LPC_HICR4_LADR12AS); ++ regmap_write(priv->map, LPC_LADR12H, addr >> 8); ++ regmap_write(priv->map, LPC_LADR12L, addr & 0xFF); ++ break; ++ ++ case 3: ++ regmap_write(priv->map, LPC_LADR3H, addr >> 8); ++ regmap_write(priv->map, LPC_LADR3L, addr & 0xFF); ++ break; ++ ++ case 4: ++ regmap_write(priv->map, LPC_LADR4, ((addr + 1) << 16) | ++ addr); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void aspeed_kcs_enable_channel(struct kcs_bmc *kcs_bmc, bool enable) ++{ ++ struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); ++ ++ switch (kcs_bmc->channel) { ++ case 1: ++ if (enable) { ++ regmap_update_bits(priv->map, LPC_HICR2, ++ LPC_HICR2_IBFIF1, LPC_HICR2_IBFIF1); ++ regmap_update_bits(priv->map, LPC_HICR0, ++ LPC_HICR0_LPC1E, LPC_HICR0_LPC1E); ++ } else { ++ regmap_update_bits(priv->map, LPC_HICR0, ++ LPC_HICR0_LPC1E, 0); ++ regmap_update_bits(priv->map, LPC_HICR2, ++ LPC_HICR2_IBFIF1, 0); ++ } ++ break; ++ ++ case 2: ++ if (enable) { ++ regmap_update_bits(priv->map, LPC_HICR2, ++ LPC_HICR2_IBFIF2, LPC_HICR2_IBFIF2); ++ regmap_update_bits(priv->map, LPC_HICR0, ++ LPC_HICR0_LPC2E, LPC_HICR0_LPC2E); ++ } else { ++ regmap_update_bits(priv->map, LPC_HICR0, ++ LPC_HICR0_LPC2E, 0); ++ regmap_update_bits(priv->map, LPC_HICR2, ++ LPC_HICR2_IBFIF2, 0); ++ } ++ break; ++ ++ case 3: ++ if (enable) { ++ regmap_update_bits(priv->map, LPC_HICR2, ++ LPC_HICR2_IBFIF3, LPC_HICR2_IBFIF3); ++ regmap_update_bits(priv->map, LPC_HICR0, ++ LPC_HICR0_LPC3E, LPC_HICR0_LPC3E); ++ regmap_update_bits(priv->map, LPC_HICR4, ++ LPC_HICR4_KCSENBL, LPC_HICR4_KCSENBL); ++ } else { ++ regmap_update_bits(priv->map, LPC_HICR0, ++ LPC_HICR0_LPC3E, 0); ++ regmap_update_bits(priv->map, LPC_HICR4, ++ LPC_HICR4_KCSENBL, 0); ++ regmap_update_bits(priv->map, LPC_HICR2, ++ LPC_HICR2_IBFIF3, 0); ++ } ++ break; ++ ++ case 4: ++ if (enable) ++ regmap_update_bits(priv->map, LPC_HICRB, ++ LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E, ++ LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E); ++ else ++ regmap_update_bits(priv->map, LPC_HICRB, ++ LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E, ++ 0); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static irqreturn_t aspeed_kcs_irq(int irq, void *arg) ++{ ++ struct kcs_bmc *kcs_bmc = arg; ++ ++ if (!kcs_bmc_handle_event(kcs_bmc)) ++ return IRQ_HANDLED; ++ ++ return IRQ_NONE; ++} ++ ++static int aspeed_kcs_config_irq(struct kcs_bmc *kcs_bmc, ++ struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ int irq; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ return devm_request_irq(dev, irq, aspeed_kcs_irq, IRQF_SHARED, ++ dev_name(dev), kcs_bmc); ++} ++ ++static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = { ++ { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 }, ++ { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 }, ++ { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 }, ++ { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }, ++}; ++ ++static int aspeed_kcs_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct aspeed_kcs_bmc *priv; ++ struct kcs_bmc *kcs_bmc; ++ u32 chan, addr; ++ int rc; ++ ++ rc = of_property_read_u32(dev->of_node, "kcs_chan", &chan); ++ if ((rc != 0) || (chan == 0 || chan > KCS_CHANNEL_MAX)) { ++ dev_err(dev, "no valid 'kcs_chan' configured\n"); ++ return -ENODEV; ++ } ++ ++ rc = of_property_read_u32(dev->of_node, "kcs_addr", &addr); ++ if (rc) { ++ dev_err(dev, "no valid 'kcs_addr' configured\n"); ++ return -ENODEV; ++ } ++ ++ kcs_bmc = kcs_bmc_alloc(dev, sizeof(*priv), chan); ++ if (!kcs_bmc) ++ return -ENOMEM; ++ ++ priv = kcs_bmc_priv(kcs_bmc); ++ priv->map = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(priv->map)) { ++ dev_err(dev, "Couldn't get regmap\n"); ++ return -ENODEV; ++ } ++ ++ kcs_bmc->ioreg = ast_kcs_bmc_ioregs[chan - 1]; ++ kcs_bmc->io_inputb = aspeed_kcs_inb; ++ kcs_bmc->io_outputb = aspeed_kcs_outb; ++ ++ dev_set_drvdata(dev, kcs_bmc); ++ ++ aspeed_kcs_set_address(kcs_bmc, addr); ++ aspeed_kcs_enable_channel(kcs_bmc, true); ++ rc = aspeed_kcs_config_irq(kcs_bmc, pdev); ++ if (rc) ++ return rc; ++ ++ rc = misc_register(&kcs_bmc->miscdev); ++ if (rc) { ++ dev_err(dev, "Unable to register device\n"); ++ return rc; ++ } ++ ++ pr_info("channel=%u addr=0x%x idr=0x%x odr=0x%x str=0x%x\n", ++ chan, addr, ++ kcs_bmc->ioreg.idr, kcs_bmc->ioreg.odr, kcs_bmc->ioreg.str); ++ ++ return 0; ++} ++ ++static int aspeed_kcs_remove(struct platform_device *pdev) ++{ ++ struct kcs_bmc *kcs_bmc = dev_get_drvdata(&pdev->dev); ++ ++ misc_deregister(&kcs_bmc->miscdev); ++ ++ return 0; ++} ++ ++static const struct of_device_id ast_kcs_bmc_match[] = { ++ { .compatible = "aspeed,ast2400-kcs-bmc" }, ++ { .compatible = "aspeed,ast2500-kcs-bmc" }, ++ { } ++}; ++ ++static struct platform_driver ast_kcs_bmc_driver = { ++ .driver = { ++ .name = DEVICE_NAME, ++ .of_match_table = ast_kcs_bmc_match, ++ }, ++ .probe = aspeed_kcs_probe, ++ .remove = aspeed_kcs_remove, ++}; ++ ++module_platform_driver(ast_kcs_bmc_driver); ++ ++MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>"); ++MODULE_DESCRIPTION("Aspeed device interface to the KCS BMC device"); +-- +2.14.3 + + +From aaf1bbe90a36a6d11dbedc4a99b24096963280c8 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" <garsilva@embeddedor.com> +Date: Wed, 14 Feb 2018 11:30:29 -0600 +Subject: [PATCH 3/9] ipmi: kcs_bmc: mark expected switch fall-through in + kcs_bmc_handle_data + +In preparation to enabling -Wimplicit-fallthrough, mark switch cases +where we are expecting to fall through. + +Addresses-Coverity-ID: 1465255 ("Missing break in switch") +Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com> +Cc: Haiyue Wang <haiyue.wang@linux.intel.com> +Signed-off-by: Corey Minyard <cminyard@mvista.com> +--- + drivers/char/ipmi/kcs_bmc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c +index 3a3498afa427..6476bfb79f44 100644 +--- a/drivers/char/ipmi/kcs_bmc.c ++++ b/drivers/char/ipmi/kcs_bmc.c +@@ -95,6 +95,7 @@ static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc) + switch (kcs_bmc->phase) { + case KCS_PHASE_WRITE_START: + kcs_bmc->phase = KCS_PHASE_WRITE_DATA; ++ /* fall through */ + + case KCS_PHASE_WRITE_DATA: + if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) { +-- +2.14.3 + + +From 364993a95888916b8906f655c8654aa60877a35b Mon Sep 17 00:00:00 2001 +From: Aishwarya Pant <aishpant@gmail.com> +Date: Sat, 24 Feb 2018 14:36:45 +0530 +Subject: [PATCH 4/9] char/ipmi: add documentation for sysfs interface + +This is an attempt to document the sysfs interface for the IPMI drivers. +Descriptions were collected from v2.0 of the IPMI specification and from +code comments. + +Signed-off-by: Aishwarya Pant <aishpant@gmail.com> +Signed-off-by: Corey Minyard <cminyard@mvista.com> +--- + .../ABI/testing/sysfs-devices-platform-ipmi | 238 +++++++++++++++++++++ + 1 file changed, 238 insertions(+) + create mode 100644 Documentation/ABI/testing/sysfs-devices-platform-ipmi + +diff --git a/Documentation/ABI/testing/sysfs-devices-platform-ipmi b/Documentation/ABI/testing/sysfs-devices-platform-ipmi +new file mode 100644 +index 000000000000..2a781e7513b7 +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-devices-platform-ipmi +@@ -0,0 +1,238 @@ ++What: /sys/devices/platform/ipmi_bmc.*/firmware_revision ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) The major and minor revision of the firmware. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/aux_firmware_revision ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Holds additional information about the firmware revision, ++ such as boot block or internal data structure version numbers. ++ The meanings of the numbers are specific to the vendor ++ identified by Manufacturer ID. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/revision ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Device revision. Useful for identifying if significant ++ hardware changes have been made to the implementation of the ++ management controller. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/provides_device_sdrs ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Indicates whether device provides device sensor data ++ records (1) or not (0). ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/device_id ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Device id is specified by the manufacturer identified by ++ the Manufacturer ID field. This field allows controller specific ++ software to identify the unique application command, OEM ++ fields, and functionality that are provided by the controller ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/additional_device_support ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Lists the IPMI ‘logical device’ commands and functions ++ that the controller supports that are in addition to the ++ mandatory IPM and Application commands. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/ipmi_version ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Displays the IPMI Command Specification Version. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/manufacturer_id ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Identifies the manufacturer responsible for the ++ specification of functionality of the vendor (OEM)-specific ++ commands, codes, and interfaces used in the controller. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/product_id ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Displays a number that identifies a particular system, ++ module, add-in card, or board set. The number is specified ++ according to the manufacturer given by Manufacturer ID. ++ ++For detailed definitions of the above attributes, refer to section 20.1 'Get ++Device ID Command' of the IPMI specification v2.0. ++ ++ ++What: /sys/devices/platform/ipmi_bmc.*/guid ++Date: Mar, 2006 ++KernelVersion: v2.6.17 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) A GUID (Globally Unique ID), also referred to as a UUID ++ (Universally Unique Identifier), for the management controller, ++ as described in section 20.8 'Get Device GUID Command' of the ++ IPMI specification v2.0. ++ ++ ++What: /sys/devices/platform/ipmi_si.*/type ++Date: Sep, 2017 ++KernelVersion: v4.15 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) The device interface for IPMI "kcs", "smic", "bt" or ++ "invalid" ++ ++What: /sys/devices/platform/ipmi_si.*/idles ++What: /sys/devices/platform/ipmi_si.*/watchdog_pretimeouts ++What: /sys/devices/platform/ipmi_si.*/complete_transactions ++What: /sys/devices/platform/ipmi_si.*/events ++What: /sys/devices/platform/ipmi_si.*/interrupts ++What: /sys/devices/platform/ipmi_si.*/hosed_count ++What: /sys/devices/platform/ipmi_si.*/long_timeouts ++What: /sys/devices/platform/ipmi_si.*/flag_fetches ++What: /sys/devices/platform/ipmi_si.*/attentions ++What: /sys/devices/platform/ipmi_si.*/incoming_messages ++What: /sys/devices/platform/ipmi_si.*/short_timeouts ++Date: Sep, 2017 ++KernelVersion: v4.15 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ ++ idles: (RO) Number of times the interface was ++ idle while being polled. ++ ++ watchdog_pretimeouts: (RO) Number of watchdog pretimeouts. ++ ++ complete_transactions: (RO) Number of completed messages. ++ ++ events: (RO) Number of IPMI events received from ++ the hardware. ++ ++ interrupts: (RO) Number of interrupts the driver ++ handled. ++ ++ hosed_count: (RO) Number of times the hardware didn't ++ follow the state machine. ++ ++ long_timeouts: (RO) Number of times the driver ++ requested a timer while nothing was in ++ progress. ++ ++ flag_fetches: (RO) Number of times the driver ++ requested flags from the hardware. ++ ++ attentions: (RO) Number of time the driver got an ++ ATTN from the hardware. ++ ++ incoming_messages: (RO) Number of asynchronous messages ++ received. ++ ++ short_timeouts: (RO) Number of times the driver ++ requested a timer while an operation was ++ in progress. ++ ++ ++What: /sys/devices/platform/ipmi_si.*/interrupts_enabled ++Date: Sep, 2017 ++KernelVersion: v4.15 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Indicates whether interrupts are enabled or not. The driver ++ disables interrupts when it gets into a situation where it ++ cannot handle messages due to lack of memory. Once that ++ situation clears up, it will re-enable interrupts. ++ ++ ++What: /sys/devices/platform/ipmi_si.*/params ++Date: Sep, 2017 ++KernelVersion: v4.15 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ [to be documented] ++ ++ ++What: /sys/devices/platform/dmi-ipmi-ssif.*/type ++Date: Sep, 2017 ++KernelVersion: v4.15 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ (RO) Shows the IMPI device interface type - "ssif" here. ++ ++ ++What: /sys/devices/platform/dmi-ipmi-ssif.*/hosed ++What: /sys/devices/platform/dmi-ipmi-ssif.*/alerts ++What: /sys/devices/platform/dmi-ipmi-ssif.*/sent_messages ++What: /sys/devices/platform/dmi-ipmi-ssif.*/sent_messages_parts ++What: /sys/devices/platform/dmi-ipmi-ssif.*/received_messages ++What: /sys/devices/platform/dmi-ipmi-ssif.*/received_message_parts ++What: /sys/devices/platform/dmi-ipmi-ssif.*/events ++What: /sys/devices/platform/dmi-ipmi-ssif.*/watchdog_pretimeouts ++What: /sys/devices/platform/dmi-ipmi-ssif.*/flag_fetches ++What: /sys/devices/platform/dmi-ipmi-ssif.*/send_retries ++What: /sys/devices/platform/dmi-ipmi-ssif.*/receive_retries ++What: /sys/devices/platform/dmi-ipmi-ssif.*/send_errors ++What: /sys/devices/platform/dmi-ipmi-ssif.*/receive_errors ++Date: Sep, 2017 ++KernelVersion: v4.15 ++Contact: openipmi-developer@lists.sourceforge.net ++Description: ++ hosed: (RO) Number of times the hardware didn't ++ follow the state machine. ++ ++ alerts: (RO) Number of alerts received. ++ ++ sent_messages: (RO) Number of total messages sent. ++ ++ sent_message_parts: (RO) Number of message parts sent. ++ Messages may be broken into parts if ++ they are long. ++ ++ receieved_messages: (RO) Number of message responses ++ received. ++ ++ received_message_parts: (RO) Number of message fragments ++ received. ++ ++ events: (RO) Number of received events. ++ ++ watchdog_pretimeouts: (RO) Number of watchdog pretimeouts. ++ ++ flag_fetches: (RO) Number of times a flag fetch was ++ requested. ++ ++ send_retries: (RO) Number of time a message was ++ retried. ++ ++ receive_retries: (RO) Number of times the receive of a ++ message was retried. ++ ++ send_errors: (RO) Number of times the send of a ++ message failed. ++ ++ receive_errors: (RO) Number of errors in receiving ++ messages. +-- +2.14.3 + + +From 3b6d082f0dfc2b7b9def494d2ab67fd4d3862ea1 Mon Sep 17 00:00:00 2001 +From: Haiyue Wang <haiyue.wang@linux.intel.com> +Date: Mon, 26 Feb 2018 23:48:14 +0800 +Subject: [PATCH 5/9] ipmi: kcs_bmc: coding-style fixes and use new poll type + +Many for coding-style fixes, and update the poll API with the new +type '__poll_t', this is new commit from linux-4.16-rc1. + +Signed-off-by: Haiyue Wang <haiyue.wang@linux.intel.com> +Signed-off-by: Corey Minyard <cminyard@mvista.com> +--- + drivers/char/ipmi/kcs_bmc.c | 32 +++++++++++++++++--------------- + drivers/char/ipmi/kcs_bmc.h | 36 +++++++++++++++++++----------------- + drivers/char/ipmi/kcs_bmc_aspeed.c | 9 +++++---- + include/uapi/linux/ipmi_bmc.h | 8 +++++--- + 4 files changed, 46 insertions(+), 39 deletions(-) + +diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c +index 6476bfb79f44..fbfc05e3f3d1 100644 +--- a/drivers/char/ipmi/kcs_bmc.c ++++ b/drivers/char/ipmi/kcs_bmc.c +@@ -1,5 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 +-// Copyright (c) 2015-2018, Intel Corporation. ++/* ++ * Copyright (c) 2015-2018, Intel Corporation. ++ */ + + #define pr_fmt(fmt) "kcs-bmc: " fmt + +@@ -242,14 +244,14 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) + } + EXPORT_SYMBOL(kcs_bmc_handle_event); + +-static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp) ++static inline struct kcs_bmc *to_kcs_bmc(struct file *filp) + { + return container_of(filp->private_data, struct kcs_bmc, miscdev); + } + + static int kcs_bmc_open(struct inode *inode, struct file *filp) + { +- struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + int ret = 0; + + spin_lock_irq(&kcs_bmc->lock); +@@ -262,25 +264,25 @@ static int kcs_bmc_open(struct inode *inode, struct file *filp) + return ret; + } + +-static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait) ++static __poll_t kcs_bmc_poll(struct file *filp, poll_table *wait) + { +- struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); +- unsigned int mask = 0; ++ struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); ++ __poll_t mask = 0; + + poll_wait(filp, &kcs_bmc->queue, wait); + + spin_lock_irq(&kcs_bmc->lock); + if (kcs_bmc->data_in_avail) +- mask |= POLLIN; ++ mask |= EPOLLIN; + spin_unlock_irq(&kcs_bmc->lock); + + return mask; + } + +-static ssize_t kcs_bmc_read(struct file *filp, char *buf, +- size_t count, loff_t *offset) ++static ssize_t kcs_bmc_read(struct file *filp, char __user *buf, ++ size_t count, loff_t *ppos) + { +- struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + bool data_avail; + size_t data_len; + ssize_t ret; +@@ -339,10 +341,10 @@ static ssize_t kcs_bmc_read(struct file *filp, char *buf, + return ret; + } + +-static ssize_t kcs_bmc_write(struct file *filp, const char *buf, +- size_t count, loff_t *offset) ++static ssize_t kcs_bmc_write(struct file *filp, const char __user *buf, ++ size_t count, loff_t *ppos) + { +- struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + ssize_t ret; + + /* a minimum response size '3' : netfn + cmd + ccode */ +@@ -378,7 +380,7 @@ static ssize_t kcs_bmc_write(struct file *filp, const char *buf, + static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) + { +- struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + long ret = 0; + + spin_lock_irq(&kcs_bmc->lock); +@@ -410,7 +412,7 @@ static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, + + static int kcs_bmc_release(struct inode *inode, struct file *filp) + { +- struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); ++ struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + + spin_lock_irq(&kcs_bmc->lock); + kcs_bmc->running = 0; +diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h +index c19501db0236..eb9ea4ce78b8 100644 +--- a/drivers/char/ipmi/kcs_bmc.h ++++ b/drivers/char/ipmi/kcs_bmc.h +@@ -1,31 +1,33 @@ +-// SPDX-License-Identifier: GPL-2.0 +-// Copyright (c) 2015-2018, Intel Corporation. ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2015-2018, Intel Corporation. ++ */ + + #ifndef __KCS_BMC_H__ + #define __KCS_BMC_H__ + + #include <linux/miscdevice.h> + +-/* Different phases of the KCS BMC module : +- * KCS_PHASE_IDLE : ++/* Different phases of the KCS BMC module. ++ * KCS_PHASE_IDLE: + * BMC should not be expecting nor sending any data. +- * KCS_PHASE_WRITE_START : ++ * KCS_PHASE_WRITE_START: + * BMC is receiving a WRITE_START command from system software. +- * KCS_PHASE_WRITE_DATA : ++ * KCS_PHASE_WRITE_DATA: + * BMC is receiving a data byte from system software. +- * KCS_PHASE_WRITE_END_CMD : ++ * KCS_PHASE_WRITE_END_CMD: + * BMC is waiting a last data byte from system software. +- * KCS_PHASE_WRITE_DONE : ++ * KCS_PHASE_WRITE_DONE: + * BMC has received the whole request from system software. +- * KCS_PHASE_WAIT_READ : ++ * KCS_PHASE_WAIT_READ: + * BMC is waiting the response from the upper IPMI service. +- * KCS_PHASE_READ : ++ * KCS_PHASE_READ: + * BMC is transferring the response to system software. +- * KCS_PHASE_ABORT_ERROR1 : ++ * KCS_PHASE_ABORT_ERROR1: + * BMC is waiting error status request from system software. +- * KCS_PHASE_ABORT_ERROR2 : ++ * KCS_PHASE_ABORT_ERROR2: + * BMC is waiting for idle status afer error from system software. +- * KCS_PHASE_ERROR : ++ * KCS_PHASE_ERROR: + * BMC has detected a protocol violation at the interface level. + */ + enum kcs_phases { +@@ -54,9 +56,9 @@ enum kcs_errors { + }; + + /* IPMI 2.0 - 9.5, KCS Interface Registers +- * @idr : Input Data Register +- * @odr : Output Data Register +- * @str : Status Register ++ * @idr: Input Data Register ++ * @odr: Output Data Register ++ * @str: Status Register + */ + struct kcs_ioreg { + u32 idr; +@@ -103,4 +105,4 @@ static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc) + int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc); + struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, + u32 channel); +-#endif ++#endif /* __KCS_BMC_H__ */ +diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c +index 0c4d1a36dae4..3c955946e647 100644 +--- a/drivers/char/ipmi/kcs_bmc_aspeed.c ++++ b/drivers/char/ipmi/kcs_bmc_aspeed.c +@@ -1,5 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 +-// Copyright (c) 2015-2018, Intel Corporation. ++/* ++ * Copyright (c) 2015-2018, Intel Corporation. ++ */ + + #define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt + +@@ -301,19 +303,18 @@ static const struct of_device_id ast_kcs_bmc_match[] = { + { .compatible = "aspeed,ast2500-kcs-bmc" }, + { } + }; ++MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match); + + static struct platform_driver ast_kcs_bmc_driver = { + .driver = { + .name = DEVICE_NAME, + .of_match_table = ast_kcs_bmc_match, + }, +- .probe = aspeed_kcs_probe, ++ .probe = aspeed_kcs_probe, + .remove = aspeed_kcs_remove, + }; +- + module_platform_driver(ast_kcs_bmc_driver); + +-MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match); + MODULE_LICENSE("GPL v2"); + MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>"); + MODULE_DESCRIPTION("Aspeed device interface to the KCS BMC device"); +diff --git a/include/uapi/linux/ipmi_bmc.h b/include/uapi/linux/ipmi_bmc.h +index 2f9f97e6123a..1670f0944227 100644 +--- a/include/uapi/linux/ipmi_bmc.h ++++ b/include/uapi/linux/ipmi_bmc.h +@@ -1,5 +1,7 @@ +-// SPDX-License-Identifier: GPL-2.0 +-// Copyright (c) 2015-2018, Intel Corporation. ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2015-2018, Intel Corporation. ++ */ + + #ifndef _UAPI_LINUX_IPMI_BMC_H + #define _UAPI_LINUX_IPMI_BMC_H +@@ -11,4 +13,4 @@ + #define IPMI_BMC_IOCTL_CLEAR_SMS_ATN _IO(__IPMI_BMC_IOCTL_MAGIC, 0x01) + #define IPMI_BMC_IOCTL_FORCE_ABORT _IO(__IPMI_BMC_IOCTL_MAGIC, 0x02) + +-#endif /* _UAPI_LINUX_KCS_BMC_H */ ++#endif /* _UAPI_LINUX_IPMI_BMC_H */ +-- +2.14.3 + + +From ad2575f8600d068edb10a9bef7f945482e3c5ca9 Mon Sep 17 00:00:00 2001 +From: Corey Minyard <cminyard@mvista.com> +Date: Mon, 26 Feb 2018 12:46:26 -0600 +Subject: [PATCH 6/9] ipmi:pci: Make the PCI defines consistent with normal + Linux ones + +Signed-off-by: Corey Minyard <cminyard@mvista.com> +--- + drivers/char/ipmi/ipmi_si_pci.c | 31 ++++++++++++++----------------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/drivers/char/ipmi/ipmi_si_pci.c b/drivers/char/ipmi/ipmi_si_pci.c +index 27dd11c49d21..ad4e20b94c08 100644 +--- a/drivers/char/ipmi/ipmi_si_pci.c ++++ b/drivers/char/ipmi/ipmi_si_pci.c +@@ -17,16 +17,12 @@ module_param_named(trypci, si_trypci, bool, 0); + MODULE_PARM_DESC(trypci, "Setting this to zero will disable the" + " default scan of the interfaces identified via pci"); + +-#define PCI_ERMC_CLASSCODE 0x0C0700 +-#define PCI_ERMC_CLASSCODE_MASK 0xffffff00 +-#define PCI_ERMC_CLASSCODE_TYPE_MASK 0xff +-#define PCI_ERMC_CLASSCODE_TYPE_SMIC 0x00 +-#define PCI_ERMC_CLASSCODE_TYPE_KCS 0x01 +-#define PCI_ERMC_CLASSCODE_TYPE_BT 0x02 ++#define PCI_CLASS_SERIAL_IPMI 0x0c07 ++#define PCI_CLASS_SERIAL_IPMI_SMIC 0x0c0700 ++#define PCI_CLASS_SERIAL_IPMI_KCS 0x0c0701 ++#define PCI_CLASS_SERIAL_IPMI_BT 0x0c0702 + +-#define PCI_HP_VENDOR_ID 0x103C +-#define PCI_MMC_DEVICE_ID 0x121A +-#define PCI_MMC_ADDR_CW 0x10 ++#define PCI_DEVICE_ID_HP_MMC 0x121A + + static void ipmi_pci_cleanup(struct si_sm_io *io) + { +@@ -69,28 +65,27 @@ static int ipmi_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { + int rv; +- int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; + struct si_sm_io io; + + memset(&io, 0, sizeof(io)); + io.addr_source = SI_PCI; + dev_info(&pdev->dev, "probing via PCI"); + +- switch (class_type) { +- case PCI_ERMC_CLASSCODE_TYPE_SMIC: ++ switch (pdev->class) { ++ case PCI_CLASS_SERIAL_IPMI_SMIC: + io.si_type = SI_SMIC; + break; + +- case PCI_ERMC_CLASSCODE_TYPE_KCS: ++ case PCI_CLASS_SERIAL_IPMI_KCS: + io.si_type = SI_KCS; + break; + +- case PCI_ERMC_CLASSCODE_TYPE_BT: ++ case PCI_CLASS_SERIAL_IPMI_BT: + io.si_type = SI_BT; + break; + + default: +- dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type); ++ dev_info(&pdev->dev, "Unknown IPMI class: %x\n", pdev->class); + return -ENOMEM; + } + +@@ -138,8 +133,10 @@ static void ipmi_pci_remove(struct pci_dev *pdev) + } + + static const struct pci_device_id ipmi_pci_devices[] = { +- { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, +- { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, ++ { PCI_VDEVICE(HP, PCI_DEVICE_ID_HP_MMC) }, ++ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_IPMI_SMIC, ~0) }, ++ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_IPMI_KCS, ~0) }, ++ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_IPMI_BT, ~0) }, + { 0, } + }; + MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); +-- +2.14.3 + + +From 243ac21035176ac9692c1308a9f3b8f6a4e5d733 Mon Sep 17 00:00:00 2001 +From: Corey Minyard <cminyard@mvista.com> +Date: Tue, 20 Feb 2018 07:30:22 -0600 +Subject: [PATCH 8/9] ipmi: Add or fix SPDX-License-Identifier in all files + +And get rid of the license text that is no longer necessary. + +Signed-off-by: Corey Minyard <cminyard@mvista.com> +Cc: Kees Cook <keescook@chromium.org> +Cc: Alistair Popple <alistair@popple.id.au> +Cc: Jeremy Kerr <jk@ozlabs.org> +Cc: Joel Stanley <joel@jms.id.au> +Cc: Rocky Craig <rocky.craig@hp.com> +--- + drivers/char/ipmi/bt-bmc.c | 6 +----- + drivers/char/ipmi/ipmi_bt_sm.c | 22 ++-------------------- + drivers/char/ipmi/ipmi_devintf.c | 22 +--------------------- + drivers/char/ipmi/ipmi_dmi.c | 2 +- + drivers/char/ipmi/ipmi_dmi.h | 2 +- + drivers/char/ipmi/ipmi_kcs_sm.c | 22 +--------------------- + drivers/char/ipmi/ipmi_msghandler.c | 22 +--------------------- + drivers/char/ipmi/ipmi_powernv.c | 6 +----- + drivers/char/ipmi/ipmi_poweroff.c | 22 +--------------------- + drivers/char/ipmi/ipmi_si.h | 1 + + drivers/char/ipmi/ipmi_si_hardcode.c | 1 + + drivers/char/ipmi/ipmi_si_hotmod.c | 1 + + drivers/char/ipmi/ipmi_si_intf.c | 22 +--------------------- + drivers/char/ipmi/ipmi_si_mem_io.c | 1 + + drivers/char/ipmi/ipmi_si_parisc.c | 1 + + drivers/char/ipmi/ipmi_si_pci.c | 1 + + drivers/char/ipmi/ipmi_si_platform.c | 1 + + drivers/char/ipmi/ipmi_si_port_io.c | 1 + + drivers/char/ipmi/ipmi_si_sm.h | 22 +--------------------- + drivers/char/ipmi/ipmi_smic_sm.c | 24 ++---------------------- + drivers/char/ipmi/ipmi_ssif.c | 6 +----- + drivers/char/ipmi/ipmi_watchdog.c | 22 +--------------------- + include/linux/ipmi-fru.h | 3 +-- + include/linux/ipmi.h | 21 +-------------------- + include/linux/ipmi_smi.h | 21 +-------------------- + include/uapi/linux/ipmi.h | 20 -------------------- + include/uapi/linux/ipmi_msgdefs.h | 20 -------------------- + 27 files changed, 27 insertions(+), 288 deletions(-) + +diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c +index c95b93b7598b..40b9927c072c 100644 +--- a/drivers/char/ipmi/bt-bmc.c ++++ b/drivers/char/ipmi/bt-bmc.c +@@ -1,10 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * Copyright (c) 2015-2016, IBM Corporation. +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. + */ + + #include <linux/atomic.h> +diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c +index feafdab734ae..fd4ea8d87d4b 100644 +--- a/drivers/char/ipmi/ipmi_bt_sm.c ++++ b/drivers/char/ipmi/ipmi_bt_sm.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_bt_sm.c + * +@@ -5,26 +6,7 @@ + * of the driver architecture at http://sourceforge.net/projects/openipmi + * + * Author: Rocky Craig <first.last@hp.com> +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. */ ++ */ + + #include <linux/kernel.h> /* For printk. */ + #include <linux/string.h> +diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c +index 5f1bc9174735..8ecfd47806fa 100644 +--- a/drivers/char/ipmi/ipmi_devintf.c ++++ b/drivers/char/ipmi/ipmi_devintf.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_devintf.c + * +@@ -8,27 +9,6 @@ + * source@mvista.com + * + * Copyright 2002 MontaVista Software Inc. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #include <linux/module.h> +diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c +index f1df63bc859a..e2c143861b1e 100644 +--- a/drivers/char/ipmi/ipmi_dmi.c ++++ b/drivers/char/ipmi/ipmi_dmi.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: GPL-2.0+ + /* + * A hack to create a platform device from a DMI entry. This will + * allow autoloading of the IPMI drive based on SMBIOS entries. +diff --git a/drivers/char/ipmi/ipmi_dmi.h b/drivers/char/ipmi/ipmi_dmi.h +index 6c21018e3668..8d2b094db8e6 100644 +--- a/drivers/char/ipmi/ipmi_dmi.h ++++ b/drivers/char/ipmi/ipmi_dmi.h +@@ -1,4 +1,4 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ ++/* SPDX-License-Identifier: GPL-2.0+ */ + /* + * DMI defines for use by IPMI + */ +diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c +index 1da61af7f576..f4ea9f47230a 100644 +--- a/drivers/char/ipmi/ipmi_kcs_sm.c ++++ b/drivers/char/ipmi/ipmi_kcs_sm.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_kcs_sm.c + * +@@ -8,27 +9,6 @@ + * source@mvista.com + * + * Copyright 2002 MontaVista Software Inc. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + /* +diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c +index e0b0d7e2d976..361148938801 100644 +--- a/drivers/char/ipmi/ipmi_msghandler.c ++++ b/drivers/char/ipmi/ipmi_msghandler.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_msghandler.c + * +@@ -8,27 +9,6 @@ + * source@mvista.com + * + * Copyright 2002 MontaVista Software Inc. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #include <linux/module.h> +diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c +index bcf493d8e238..e96500372ce2 100644 +--- a/drivers/char/ipmi/ipmi_powernv.c ++++ b/drivers/char/ipmi/ipmi_powernv.c +@@ -1,12 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * PowerNV OPAL IPMI driver + * + * Copyright 2014 IBM Corp. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the Free +- * Software Foundation; either version 2 of the License, or (at your option) +- * any later version. + */ + + #define pr_fmt(fmt) "ipmi-powernv: " fmt +diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c +index 38e6af1c8e38..07fa366bc8f0 100644 +--- a/drivers/char/ipmi/ipmi_poweroff.c ++++ b/drivers/char/ipmi/ipmi_poweroff.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_poweroff.c + * +@@ -9,27 +10,6 @@ + * source@mvista.com + * + * Copyright 2002,2004 MontaVista Software Inc. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include <linux/module.h> + #include <linux/moduleparam.h> +diff --git a/drivers/char/ipmi/ipmi_si.h b/drivers/char/ipmi/ipmi_si.h +index 17ce5f7b89ab..52f6152d1fcb 100644 +--- a/drivers/char/ipmi/ipmi_si.h ++++ b/drivers/char/ipmi/ipmi_si.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ + /* + * ipmi_si.h + * +diff --git a/drivers/char/ipmi/ipmi_si_hardcode.c b/drivers/char/ipmi/ipmi_si_hardcode.c +index fa9a4780de36..10219f24546b 100644 +--- a/drivers/char/ipmi/ipmi_si_hardcode.c ++++ b/drivers/char/ipmi/ipmi_si_hardcode.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + + #include <linux/moduleparam.h> + #include "ipmi_si.h" +diff --git a/drivers/char/ipmi/ipmi_si_hotmod.c b/drivers/char/ipmi/ipmi_si_hotmod.c +index fc03b9be2f3d..a98ca42a50b1 100644 +--- a/drivers/char/ipmi/ipmi_si_hotmod.c ++++ b/drivers/char/ipmi/ipmi_si_hotmod.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_si_hotmod.c + * +diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c +index 6768cb2dd740..5141ccf0b958 100644 +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_si.c + * +@@ -10,27 +11,6 @@ + * + * Copyright 2002 MontaVista Software Inc. + * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com> +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + /* +diff --git a/drivers/char/ipmi/ipmi_si_mem_io.c b/drivers/char/ipmi/ipmi_si_mem_io.c +index 8796396ecd0f..1b869d530884 100644 +--- a/drivers/char/ipmi/ipmi_si_mem_io.c ++++ b/drivers/char/ipmi/ipmi_si_mem_io.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + + #include <linux/io.h> + #include "ipmi_si.h" +diff --git a/drivers/char/ipmi/ipmi_si_parisc.c b/drivers/char/ipmi/ipmi_si_parisc.c +index 6b10f0e18a95..f3c99820f564 100644 +--- a/drivers/char/ipmi/ipmi_si_parisc.c ++++ b/drivers/char/ipmi/ipmi_si_parisc.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + + #include <linux/module.h> + #include <asm/hardware.h> /* for register_parisc_driver() stuff */ +diff --git a/drivers/char/ipmi/ipmi_si_pci.c b/drivers/char/ipmi/ipmi_si_pci.c +index ad4e20b94c08..b1c055540b26 100644 +--- a/drivers/char/ipmi/ipmi_si_pci.c ++++ b/drivers/char/ipmi/ipmi_si_pci.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_si_pci.c + * +diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c +index f4214870d726..3d45bf1ee5bc 100644 +--- a/drivers/char/ipmi/ipmi_si_platform.c ++++ b/drivers/char/ipmi/ipmi_si_platform.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_si_platform.c + * +diff --git a/drivers/char/ipmi/ipmi_si_port_io.c b/drivers/char/ipmi/ipmi_si_port_io.c +index e5ce174fbeeb..ef6dffcea9fa 100644 +--- a/drivers/char/ipmi/ipmi_si_port_io.c ++++ b/drivers/char/ipmi/ipmi_si_port_io.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + + #include <linux/io.h> + #include "ipmi_si.h" +diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h +index aa8d88ab4433..aaddf047d923 100644 +--- a/drivers/char/ipmi/ipmi_si_sm.h ++++ b/drivers/char/ipmi/ipmi_si_sm.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ + /* + * ipmi_si_sm.h + * +@@ -11,27 +12,6 @@ + * source@mvista.com + * + * Copyright 2002 MontaVista Software Inc. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #include <linux/ipmi.h> +diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c +index 8f7c73ff58f2..466a5aac5298 100644 +--- a/drivers/char/ipmi/ipmi_smic_sm.c ++++ b/drivers/char/ipmi/ipmi_smic_sm.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_smic_sm.c + * +@@ -18,28 +19,7 @@ + * copyright notice: + * (c) Copyright 2001 Grant Grundler (c) Copyright + * 2001 Hewlett-Packard Company +- * +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. */ ++ */ + + #include <linux/kernel.h> /* For printk. */ + #include <linux/string.h> +diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c +index f929e72bdac8..9d3b0fa27560 100644 +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_ssif.c + * +@@ -13,11 +14,6 @@ + * + * Copyright 2003 Intel Corporation + * Copyright 2005 MontaVista Software +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. + */ + + /* +diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c +index a58acdcf7414..22bc287eac2d 100644 +--- a/drivers/char/ipmi/ipmi_watchdog.c ++++ b/drivers/char/ipmi/ipmi_watchdog.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * ipmi_watchdog.c + * +@@ -8,27 +9,6 @@ + * source@mvista.com + * + * Copyright 2002 MontaVista Software Inc. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #include <linux/module.h> +diff --git a/include/linux/ipmi-fru.h b/include/linux/ipmi-fru.h +index 4d3a76380e32..05c9422624c6 100644 +--- a/include/linux/ipmi-fru.h ++++ b/include/linux/ipmi-fru.h +@@ -1,9 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ + /* + * Copyright (C) 2012 CERN (www.cern.ch) + * Author: Alessandro Rubini <rubini@gnudd.com> + * +- * Released according to the GNU GPL, version 2 or any later version. +- * + * This work is part of the White Rabbit project, a research effort led + * by CERN, the European Institute for Nuclear Research. + */ +diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h +index f4ffacf4fe9d..8b0626cec980 100644 +--- a/include/linux/ipmi.h ++++ b/include/linux/ipmi.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ + /* + * ipmi.h + * +@@ -9,26 +10,6 @@ + * + * Copyright 2002 MontaVista Software Inc. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __LINUX_IPMI_H + #define __LINUX_IPMI_H +diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h +index 5be51281e14d..af457b5a689e 100644 +--- a/include/linux/ipmi_smi.h ++++ b/include/linux/ipmi_smi.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ + /* + * ipmi_smi.h + * +@@ -9,26 +10,6 @@ + * + * Copyright 2002 MontaVista Software Inc. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #ifndef __LINUX_IPMI_SMI_H +diff --git a/include/uapi/linux/ipmi.h b/include/uapi/linux/ipmi.h +index b076f7a47407..32d148309b16 100644 +--- a/include/uapi/linux/ipmi.h ++++ b/include/uapi/linux/ipmi.h +@@ -10,26 +10,6 @@ + * + * Copyright 2002 MontaVista Software Inc. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #ifndef _UAPI__LINUX_IPMI_H +diff --git a/include/uapi/linux/ipmi_msgdefs.h b/include/uapi/linux/ipmi_msgdefs.h +index 17f349459587..c2b23a9fdf3d 100644 +--- a/include/uapi/linux/ipmi_msgdefs.h ++++ b/include/uapi/linux/ipmi_msgdefs.h +@@ -10,26 +10,6 @@ + * + * Copyright 2002 MontaVista Software Inc. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #ifndef __LINUX_IPMI_MSGDEFS_H +-- +2.14.3 + + +From 426fa6179dae677134dfb37b21d057819418515b Mon Sep 17 00:00:00 2001 +From: Corey Minyard <cminyard@mvista.com> +Date: Wed, 28 Feb 2018 08:09:49 -0600 +Subject: [PATCH 9/9] ipmi: Fix some error cleanup issues + +device_remove_group() was called on any cleanup, even if the +device attrs had not been added yet. That can occur in certain +error scenarios, so add a flag to know if it has been added. + +Also make sure we remove the dev if we added it ourselves. + +Signed-off-by: Corey Minyard <cminyard@mvista.com> +Cc: stable@vger.kernel.org # 4.15 +--- + drivers/char/ipmi/ipmi_si_intf.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c +index 5141ccf0b958..2b9f434775d4 100644 +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -232,6 +232,9 @@ struct smi_info { + /* Default driver model device. */ + struct platform_device *pdev; + ++ /* Have we added the device group to the device? */ ++ bool dev_group_added; ++ + /* Counters and things for the proc filesystem. */ + atomic_t stats[SI_NUM_STATS]; + +@@ -2007,8 +2010,8 @@ int ipmi_si_add_smi(struct si_sm_io *io) + if (initialized) { + rv = try_smi_init(new_smi); + if (rv) { +- mutex_unlock(&smi_infos_lock); + cleanup_one_si(new_smi); ++ mutex_unlock(&smi_infos_lock); + return rv; + } + } +@@ -2167,6 +2170,7 @@ static int try_smi_init(struct smi_info *new_smi) + rv); + goto out_err_stop_timer; + } ++ new_smi->dev_group_added = true; + + rv = ipmi_register_smi(&handlers, + new_smi, +@@ -2220,7 +2224,10 @@ static int try_smi_init(struct smi_info *new_smi) + return 0; + + out_err_remove_attrs: +- device_remove_group(new_smi->io.dev, &ipmi_si_dev_attr_group); ++ if (new_smi->dev_group_added) { ++ device_remove_group(new_smi->io.dev, &ipmi_si_dev_attr_group); ++ new_smi->dev_group_added = false; ++ } + dev_set_drvdata(new_smi->io.dev, NULL); + + out_err_stop_timer: +@@ -2268,6 +2275,7 @@ static int try_smi_init(struct smi_info *new_smi) + else + platform_device_put(new_smi->pdev); + new_smi->pdev = NULL; ++ new_smi->io.dev = NULL; + } + + kfree(init_name); +@@ -2364,8 +2372,10 @@ static void cleanup_one_si(struct smi_info *to_clean) + } + } + +- device_remove_group(to_clean->io.dev, &ipmi_si_dev_attr_group); +- dev_set_drvdata(to_clean->io.dev, NULL); ++ if (to_clean->dev_group_added) ++ device_remove_group(to_clean->io.dev, &ipmi_si_dev_attr_group); ++ if (to_clean->io.dev) ++ dev_set_drvdata(to_clean->io.dev, NULL); + + list_del(&to_clean->link); + +-- +2.14.3 + diff --git a/kernel.spec b/kernel.spec index 9c6b6d4ab..acc61cb35 100644 --- a/kernel.spec +++ b/kernel.spec @@ -575,48 +575,46 @@ Patch300: arm64-Add-option-of-13-for-FORCE_MAX_ZONEORDER.patch # http://www.spinics.net/lists/linux-tegra/msg26029.html Patch301: usb-phy-tegra-Add-38.4MHz-clock-table-entry.patch -# Fix OMAP4 (pandaboard) -Patch302: arm-revert-mmc-omap_hsmmc-Use-dma_request_chan-for-reque.patch - # http://patchwork.ozlabs.org/patch/587554/ -Patch303: ARM-tegra-usb-no-reset.patch - -Patch304: arm64-Revert-allwinner-a64-pine64-Use-dcdc1-regulato.patch +Patch302: ARM-tegra-usb-no-reset.patch # https://patchwork.kernel.org/patch/9820417/ -Patch305: qcom-msm89xx-fixes.patch +Patch303: qcom-msm89xx-fixes.patch # https://patchwork.kernel.org/patch/10173115/ -Patch306: arm-dts-imx6qdl-udoo-Disable-usbh1-to-avoid-kernel-hang.patch +Patch304: arm-dts-imx6qdl-udoo-Disable-usbh1-to-avoid-kernel-hang.patch # http://patches.linaro.org/patch/131764/ -Patch307: wcn36xx-Fix-firmware-crash-due-to-corrupted-buffer-address.patch +Patch305: wcn36xx-Fix-firmware-crash-due-to-corrupted-buffer-address.patch # https://patchwork.kernel.org/patch/10245303/ -Patch308: wcn36xx-reduce-verbosity-of-drivers-messages.patch +Patch306: wcn36xx-reduce-verbosity-of-drivers-messages.patch # https://www.spinics.net/lists/arm-kernel/msg632925.html -Patch309: arm-crypto-sunxi-ss-Add-MODULE_ALIAS-to-sun4i-ss.patch +Patch307: arm-crypto-sunxi-ss-Add-MODULE_ALIAS-to-sun4i-ss.patch # Fix USB on the RPi https://patchwork.kernel.org/patch/9879371/ -Patch310: bcm283x-dma-mapping-skip-USB-devices-when-configuring-DMA-during-probe.patch +Patch308: bcm283x-dma-mapping-skip-USB-devices-when-configuring-DMA-during-probe.patch # https://www.spinics.net/lists/arm-kernel/msg621982.html -Patch311: bcm283x-Fix-probing-of-bcm2835-i2s.patch +Patch309: bcm283x-Fix-probing-of-bcm2835-i2s.patch # https://www.spinics.net/lists/arm-kernel/msg633942.html -Patch312: mmc-sdhci-iproc-Disable-preset-values-for-BCM2835.patch +Patch310: mmc-sdhci-iproc-Disable-preset-values-for-BCM2835.patch # https://www.spinics.net/lists/arm-kernel/msg633945.html -Patch313: bcm2835-hwrng-Handle-deferred-clock-properly.patch +Patch311: bcm2835-hwrng-Handle-deferred-clock-properly.patch -Patch314: bcm283x-clk-audio-fixes.patch +Patch312: bcm283x-clk-audio-fixes.patch + +# https://marc.info/?l=linux-kernel&m=152328880417846&w=2 +Patch313: arm64-thunderx-crypto-zip-fixes.patch # Enabling Patches for the RPi3+ -Patch330: bcm2837-rpi-initial-support-for-the-3.patch -Patch331: bcm2837-gpio-expander.patch -Patch332: bcm2837-enable-pmu.patch -Patch333: bcm2837-lan78xx-fixes.patch +Patch320: bcm2837-rpi-initial-support-for-the-3.patch +Patch321: bcm2837-gpio-expander.patch +Patch322: bcm2837-enable-pmu.patch +Patch323: bcm2837-lan78xx-fixes.patch # 400 - IBM (ppc/s390x) patches @@ -634,6 +632,10 @@ Patch503: v3-2-2-Input-synaptics---Lenovo-X1-Carbon-5-should-use-SMBUS-RMI.patch # rhbz 1558977 Patch504: sunrpc-remove-incorrect-HMAC-request-initialization.patch +# In v4.17 +# rhbz 1549316 +Patch505: ipmi-fixes.patch + # END OF PATCH DEFINITIONS %endif @@ -1886,6 +1888,16 @@ fi # # %changelog +* Mon Apr 09 2018 Jeremy Cline <jeremy@jcline.org> +- Include the KCS IPMI BMC driver that's in F27 + +* Mon Apr 9 2018 Peter Robinson <pbrobinson@fedoraproject.org> +- More fixes for Raspberry Pi 3+ lan78xx ethernet interface +- Fixes for Cavium ThunderX ZIP driver stability + +* Mon Apr 09 2018 Jeremy Cline <jeremy@jcline.org> - 4.16.1-200 +- Linux v4.16.1 + * Thu Apr 05 2018 Jeremy Cline <jeremy@jcline.org> - 4.16.0-200 - Linux v4.16 |