From 7d444909a25ed4a9dbc546bf9528c8d2e3bf3752 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 3 Sep 2013 16:26:49 +0300 Subject: crypto: sha256_ssse3 - use correct module alias for sha224 Commit a710f761f (crypto: sha256_ssse3 - add sha224 support) attempted to add MODULE_ALIAS for SHA-224, but it ended up being "sha384", probably because mix-up with previous commit 340991e30 (crypto: sha512_ssse3 - add sha384 support). Patch corrects module alias to "sha224". Reported-by: Pierre-Mayeul Badaire Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/sha256_ssse3_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c index 50226c4b86e..85021a4a8e0 100644 --- a/arch/x86/crypto/sha256_ssse3_glue.c +++ b/arch/x86/crypto/sha256_ssse3_glue.c @@ -319,4 +319,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm, Supplemental SSE3 accelerated"); MODULE_ALIAS("sha256"); -MODULE_ALIAS("sha384"); +MODULE_ALIAS("sha224"); -- cgit v1.2.3-70-g09d2 From 58497204aaca75c53394ff2dee6603315b8a2ea4 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 3 Sep 2013 16:49:47 +0300 Subject: crypto: x86 - restore avx2_supported check Commit 3d387ef08c4 (Revert "crypto: blowfish - add AVX2/x86_64 implementation of blowfish cipher") reverted too much as it removed the 'assembler supports AVX2' check and therefore disabled remaining AVX2 implementations of Camellia and Serpent. Patch restores the check and enables these implementations. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 7d6ba9db1be..75b08e1e69d 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -3,6 +3,8 @@ # avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no) +avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ + $(comma)4)$(comma)%ymm2,yes,no) obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o -- cgit v1.2.3-70-g09d2 From ec795ad84c0a8c69723972eae31e60b0d94ab29a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 16 Sep 2013 09:34:19 -0600 Subject: ARM: tegra: remove tegra_chip_uid() Following commit f5b38c5 "crypto: tegra - use kernel entropy instead of ad-hoc", this function is no longer used. It's also only accurate for Tegra20 and not later SoCs. So, remove it. Signed-off-by: Stephen Warren Signed-off-by: Herbert Xu --- arch/arm/mach-tegra/fuse.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c index e035cd284a6..64652b37488 100644 --- a/arch/arm/mach-tegra/fuse.c +++ b/arch/arm/mach-tegra/fuse.c @@ -155,13 +155,3 @@ void tegra_init_fuse(void) tegra_sku_id, tegra_cpu_process_id, tegra_core_process_id); } - -unsigned long long tegra_chip_uid(void) -{ - unsigned long long lo, hi; - - lo = tegra_fuse_readl(FUSE_UID_LOW); - hi = tegra_fuse_readl(FUSE_UID_HIGH); - return (hi << 32ull) | lo; -} -EXPORT_SYMBOL(tegra_chip_uid); -- cgit v1.2.3-70-g09d2 From 801201aa25646291aa87ba97250f6614639eb2ea Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 20 Sep 2013 09:55:41 +0200 Subject: crypto: move x86 to the generic version of ablk_helper Move all users of ablk_helper under x86/ to the generic version and delete the x86 specific version. Acked-by: Jussi Kivilinna Signed-off-by: Ard Biesheuvel Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 1 - arch/x86/crypto/ablk_helper.c | 149 ----------------------------- arch/x86/crypto/aesni-intel_glue.c | 2 +- arch/x86/crypto/camellia_aesni_avx2_glue.c | 2 +- arch/x86/crypto/camellia_aesni_avx_glue.c | 2 +- arch/x86/crypto/cast5_avx_glue.c | 2 +- arch/x86/crypto/cast6_avx_glue.c | 2 +- arch/x86/crypto/serpent_avx2_glue.c | 2 +- arch/x86/crypto/serpent_avx_glue.c | 2 +- arch/x86/crypto/serpent_sse2_glue.c | 2 +- arch/x86/crypto/twofish_avx_glue.c | 2 +- arch/x86/include/asm/crypto/ablk_helper.h | 31 ------ arch/x86/include/asm/simd.h | 11 +++ crypto/Kconfig | 25 ++--- 14 files changed, 30 insertions(+), 205 deletions(-) delete mode 100644 arch/x86/crypto/ablk_helper.c delete mode 100644 arch/x86/include/asm/crypto/ablk_helper.h create mode 100644 arch/x86/include/asm/simd.h (limited to 'arch') diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 75b08e1e69d..e0fc24db234 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -6,7 +6,6 @@ avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no) avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ $(comma)4)$(comma)%ymm2,yes,no) -obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o diff --git a/arch/x86/crypto/ablk_helper.c b/arch/x86/crypto/ablk_helper.c deleted file mode 100644 index 43282fe04a8..00000000000 --- a/arch/x86/crypto/ablk_helper.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Shared async block cipher helpers - * - * Copyright (c) 2012 Jussi Kivilinna - * - * Based on aesni-intel_glue.c by: - * Copyright (C) 2008, Intel Corp. - * Author: Huang Ying - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int key_len) -{ - struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; - int err; - - crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) - & CRYPTO_TFM_REQ_MASK); - err = crypto_ablkcipher_setkey(child, key, key_len); - crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) - & CRYPTO_TFM_RES_MASK); - return err; -} -EXPORT_SYMBOL_GPL(ablk_set_key); - -int __ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->encrypt( - &desc, req->dst, req->src, req->nbytes); -} -EXPORT_SYMBOL_GPL(__ablk_encrypt); - -int ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_encrypt(cryptd_req); - } else { - return __ablk_encrypt(req); - } -} -EXPORT_SYMBOL_GPL(ablk_encrypt); - -int ablk_decrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_decrypt(cryptd_req); - } else { - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->decrypt( - &desc, req->dst, req->src, req->nbytes); - } -} -EXPORT_SYMBOL_GPL(ablk_decrypt); - -void ablk_exit(struct crypto_tfm *tfm) -{ - struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); - - cryptd_free_ablkcipher(ctx->cryptd_tfm); -} -EXPORT_SYMBOL_GPL(ablk_exit); - -int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name) -{ - struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); - struct cryptd_ablkcipher *cryptd_tfm; - - cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); - if (IS_ERR(cryptd_tfm)) - return PTR_ERR(cryptd_tfm); - - ctx->cryptd_tfm = cryptd_tfm; - tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + - crypto_ablkcipher_reqsize(&cryptd_tfm->base); - - return 0; -} -EXPORT_SYMBOL_GPL(ablk_init_common); - -int ablk_init(struct crypto_tfm *tfm) -{ - char drv_name[CRYPTO_MAX_ALG_NAME]; - - snprintf(drv_name, sizeof(drv_name), "__driver-%s", - crypto_tfm_alg_driver_name(tfm)); - - return ablk_init_common(tfm, drv_name); -} -EXPORT_SYMBOL_GPL(ablk_init); - -MODULE_LICENSE("GPL"); diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index f80e668785c..835488b745e 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/crypto/camellia_aesni_avx2_glue.c b/arch/x86/crypto/camellia_aesni_avx2_glue.c index 414fe5d7946..4209a76fcda 100644 --- a/arch/x86/crypto/camellia_aesni_avx2_glue.c +++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include #define CAMELLIA_AESNI_PARALLEL_BLOCKS 16 diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c index 37fd0c0a81e..87a041a10f4 100644 --- a/arch/x86/crypto/camellia_aesni_avx_glue.c +++ b/arch/x86/crypto/camellia_aesni_avx_glue.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include #define CAMELLIA_AESNI_PARALLEL_BLOCKS 16 diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c index c6631813dc1..e6a3700489b 100644 --- a/arch/x86/crypto/cast5_avx_glue.c +++ b/arch/x86/crypto/cast5_avx_glue.c @@ -26,13 +26,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #define CAST5_PARALLEL_BLOCKS 16 diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c index 8d0dfb86a55..09f3677393e 100644 --- a/arch/x86/crypto/cast6_avx_glue.c +++ b/arch/x86/crypto/cast6_avx_glue.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include #define CAST6_PARALLEL_BLOCKS 8 diff --git a/arch/x86/crypto/serpent_avx2_glue.c b/arch/x86/crypto/serpent_avx2_glue.c index 23aabc6c20a..2fae489b152 100644 --- a/arch/x86/crypto/serpent_avx2_glue.c +++ b/arch/x86/crypto/serpent_avx2_glue.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,6 @@ #include #include #include -#include #include #define SERPENT_AVX2_PARALLEL_BLOCKS 16 diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c index 9ae83cf8d21..ff487087097 100644 --- a/arch/x86/crypto/serpent_avx_glue.c +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,6 @@ #include #include #include -#include #include /* 8-way parallel cipher functions */ diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 97a356ece24..8c95f863730 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,6 @@ #include #include #include -#include #include static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c index a62ba541884..4e3c665be12 100644 --- a/arch/x86/crypto/twofish_avx_glue.c +++ b/arch/x86/crypto/twofish_avx_glue.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/include/asm/crypto/ablk_helper.h b/arch/x86/include/asm/crypto/ablk_helper.h deleted file mode 100644 index 4f93df50c23..00000000000 --- a/arch/x86/include/asm/crypto/ablk_helper.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Shared async block cipher helpers - */ - -#ifndef _CRYPTO_ABLK_HELPER_H -#define _CRYPTO_ABLK_HELPER_H - -#include -#include -#include - -struct async_helper_ctx { - struct cryptd_ablkcipher *cryptd_tfm; -}; - -extern int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int key_len); - -extern int __ablk_encrypt(struct ablkcipher_request *req); - -extern int ablk_encrypt(struct ablkcipher_request *req); - -extern int ablk_decrypt(struct ablkcipher_request *req); - -extern void ablk_exit(struct crypto_tfm *tfm); - -extern int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name); - -extern int ablk_init(struct crypto_tfm *tfm); - -#endif /* _CRYPTO_ABLK_HELPER_H */ diff --git a/arch/x86/include/asm/simd.h b/arch/x86/include/asm/simd.h new file mode 100644 index 00000000000..ee80b92f009 --- /dev/null +++ b/arch/x86/include/asm/simd.h @@ -0,0 +1,11 @@ + +#include + +/* + * may_use_simd - whether it is allowable at this time to issue SIMD + * instructions or access the SIMD register file + */ +static __must_check inline bool may_use_simd(void) +{ + return irq_fpu_usable(); +} diff --git a/crypto/Kconfig b/crypto/Kconfig index 8179ae62cec..7c0a4c5de07 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -174,11 +174,6 @@ config CRYPTO_TEST help Quick & dirty crypto test module. -config CRYPTO_ABLK_HELPER_X86 - tristate - depends on X86 - select CRYPTO_CRYPTD - config CRYPTO_ABLK_HELPER tristate select CRYPTO_CRYPTD @@ -699,7 +694,7 @@ config CRYPTO_AES_NI_INTEL select CRYPTO_AES_X86_64 if 64BIT select CRYPTO_AES_586 if !64BIT select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_ALGAPI select CRYPTO_GLUE_HELPER_X86 if 64BIT select CRYPTO_LRW @@ -883,7 +878,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX_X86_64 depends on CRYPTO select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_CAMELLIA_X86_64 select CRYPTO_LRW @@ -905,7 +900,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 depends on CRYPTO select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_CAMELLIA_X86_64 select CRYPTO_CAMELLIA_AESNI_AVX_X86_64 @@ -957,7 +952,7 @@ config CRYPTO_CAST5_AVX_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_CAST_COMMON select CRYPTO_CAST5 help @@ -980,7 +975,7 @@ config CRYPTO_CAST6_AVX_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_CAST_COMMON select CRYPTO_CAST6 @@ -1098,7 +1093,7 @@ config CRYPTO_SERPENT_SSE2_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW @@ -1120,7 +1115,7 @@ config CRYPTO_SERPENT_SSE2_586 depends on X86 && !64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW @@ -1142,7 +1137,7 @@ config CRYPTO_SERPENT_AVX_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW @@ -1164,7 +1159,7 @@ config CRYPTO_SERPENT_AVX2_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_SERPENT_AVX_X86_64 @@ -1280,7 +1275,7 @@ config CRYPTO_TWOFISH_AVX_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD - select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_ABLK_HELPER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 -- cgit v1.2.3-70-g09d2 From 16c0c4e1656c14ef9deac189a4240b5ca19c6919 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 1 Oct 2013 14:34:46 +0200 Subject: crypto: sha256_ssse3 - also test for BMI2 The AVX2 implementation also uses BMI2 instructions, but doesn't test for their availability. The assumption that AVX2 and BMI2 always go together is false. Some Haswells have AVX2 but not BMI2. Signed-off-by: Oliver Neukum Signed-off-by: Herbert Xu --- arch/x86/crypto/sha256_ssse3_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c index 85021a4a8e0..f248546da1c 100644 --- a/arch/x86/crypto/sha256_ssse3_glue.c +++ b/arch/x86/crypto/sha256_ssse3_glue.c @@ -281,7 +281,7 @@ static int __init sha256_ssse3_mod_init(void) /* allow AVX to override SSSE3, it's a little faster */ if (avx_usable()) { #ifdef CONFIG_AS_AVX2 - if (boot_cpu_has(X86_FEATURE_AVX2)) + if (boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_BMI2)) sha256_transform_asm = sha256_transform_rorx; else #endif -- cgit v1.2.3-70-g09d2 From db60d8da8f643586c95f8fc3e383954f8c57f1f3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 30 Oct 2013 18:22:30 +0530 Subject: dmanengine: fix edma driver to not define DMA_COMPLETE edma header defines DMA_COMPLETE, this causes issues as commit adfedd9a32e4 move DMA_SUCCESS to DMA_COMPLETE. edma should properly namespace its defines and needs a future fix Reported-by: Olof Johansson Signed-off-by: Vinod Koul --- arch/arm/common/edma.c | 4 ++-- drivers/dma/edma.c | 4 ++-- include/linux/platform_data/edma.h | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 8e1a0245907..41bca32409f 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -404,7 +404,7 @@ static irqreturn_t dma_irq_handler(int irq, void *data) BIT(slot)); if (edma_cc[ctlr]->intr_data[channel].callback) edma_cc[ctlr]->intr_data[channel].callback( - channel, DMA_COMPLETE, + channel, EDMA_DMA_COMPLETE, edma_cc[ctlr]->intr_data[channel].data); } } while (sh_ipr); @@ -459,7 +459,7 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) callback) { edma_cc[ctlr]->intr_data[k]. callback(k, - DMA_CC_ERROR, + EDMA_DMA_CC_ERROR, edma_cc[ctlr]->intr_data [k].data); } diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 29fa35807f0..cb69f3a674e 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -407,7 +407,7 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data) edma_pause(echan->ch_num); switch (ch_status) { - case DMA_COMPLETE: + case EDMA_DMA_COMPLETE: spin_lock_irqsave(&echan->vchan.lock, flags); edesc = echan->edesc; @@ -426,7 +426,7 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data) spin_unlock_irqrestore(&echan->vchan.lock, flags); break; - case DMA_CC_ERROR: + case EDMA_DMA_CC_ERROR: spin_lock_irqsave(&echan->vchan.lock, flags); edma_read_slot(EDMA_CHAN_SLOT(echan->slot[0]), &p); diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h index 179fb91bb5f..f50821cb64b 100644 --- a/include/linux/platform_data/edma.h +++ b/include/linux/platform_data/edma.h @@ -67,10 +67,10 @@ struct edmacc_param { #define ITCCHEN BIT(23) /*ch_status paramater of callback function possible values*/ -#define DMA_COMPLETE 1 -#define DMA_CC_ERROR 2 -#define DMA_TC1_ERROR 3 -#define DMA_TC2_ERROR 4 +#define EDMA_DMA_COMPLETE 1 +#define EDMA_DMA_CC_ERROR 2 +#define EDMA_DMA_TC1_ERROR 3 +#define EDMA_DMA_TC2_ERROR 4 enum address_mode { INCR = 0, -- cgit v1.2.3-70-g09d2 From f262f0f5cad0c9eca61d1d383e3b67b57dcbe5ea Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 5 Nov 2013 19:36:27 +0800 Subject: crypto: s390 - Fix aes-cbc IV corruption The cbc-aes-s390 algorithm incorrectly places the IV in the tfm data structure. As the tfm is shared between multiple threads, this introduces a possibility of data corruption. This patch fixes this by moving the parameter block containing the IV and key onto the stack (the block is 48 bytes long). The same bug exists elsewhere in the s390 crypto system and they will be fixed in subsequent patches. Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu --- arch/s390/crypto/aes_s390.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index b4dbade8ca2..2e4b5be31a1 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -35,7 +35,6 @@ static u8 *ctrblk; static char keylen_flag; struct s390_aes_ctx { - u8 iv[AES_BLOCK_SIZE]; u8 key[AES_MAX_KEY_SIZE]; long enc; long dec; @@ -441,30 +440,36 @@ static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, return aes_set_key(tfm, in_key, key_len); } -static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param, +static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, struct blkcipher_walk *walk) { + struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); int ret = blkcipher_walk_virt(desc, walk); unsigned int nbytes = walk->nbytes; + struct { + u8 iv[AES_BLOCK_SIZE]; + u8 key[AES_MAX_KEY_SIZE]; + } param; if (!nbytes) goto out; - memcpy(param, walk->iv, AES_BLOCK_SIZE); + memcpy(param.iv, walk->iv, AES_BLOCK_SIZE); + memcpy(param.key, sctx->key, sctx->key_len); do { /* only use complete blocks */ unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1); u8 *out = walk->dst.virt.addr; u8 *in = walk->src.virt.addr; - ret = crypt_s390_kmc(func, param, out, in, n); + ret = crypt_s390_kmc(func, ¶m, out, in, n); if (ret < 0 || ret != n) return -EIO; nbytes &= AES_BLOCK_SIZE - 1; ret = blkcipher_walk_done(desc, walk, nbytes); } while ((nbytes = walk->nbytes)); - memcpy(walk->iv, param, AES_BLOCK_SIZE); + memcpy(walk->iv, param.iv, AES_BLOCK_SIZE); out: return ret; @@ -481,7 +486,7 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc, return fallback_blk_enc(desc, dst, src, nbytes); blkcipher_walk_init(&walk, dst, src, nbytes); - return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk); + return cbc_aes_crypt(desc, sctx->enc, &walk); } static int cbc_aes_decrypt(struct blkcipher_desc *desc, @@ -495,7 +500,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc, return fallback_blk_dec(desc, dst, src, nbytes); blkcipher_walk_init(&walk, dst, src, nbytes); - return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk); + return cbc_aes_crypt(desc, sctx->dec, &walk); } static struct crypto_alg cbc_aes_alg = { -- cgit v1.2.3-70-g09d2 From 144b44b1355df48eac7fee4c7519f4be0aafa4a3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Nov 2013 00:30:16 -0500 Subject: tools / power turbostat: Support Silvermont Support the next generation Intel Atom processor mirco-architecture, formerly called Silvermont. The server version, formerly called "Avoton", is named the "Intel(R) Atom(TM) Processor C2000 Product Family". The client version, formerly called "Bay Trail", is named the "Intel Atom Processor Z3000 Series", as well as various "Intel Pentium Processor" and "Intel Celeron Processor" brands, depending on form-factor. Silvermont has a set of MSRs not far off from NHM, but the RAPL register set is a sub-set of those previously supported. Signed-off-by: Len Brown Signed-off-by: Rafael J. Wysocki --- arch/x86/include/uapi/asm/msr-index.h | 2 + tools/power/x86/turbostat/turbostat.c | 197 ++++++++++++++++++++++++---------- 2 files changed, 143 insertions(+), 56 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index bb0465090ae..940ed3fd889 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -147,6 +147,8 @@ #define MSR_PP1_ENERGY_STATUS 0x00000641 #define MSR_PP1_POLICY 0x00000642 +#define MSR_CORE_C1_RES 0x00000660 + #define MSR_AMD64_MC0_MASK 0xc0010044 #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index fe702076ca4..9d77f13c2d2 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2,7 +2,7 @@ * turbostat -- show CPU frequency and C-state residency * on modern Intel turbo-capable processors. * - * Copyright (c) 2012 Intel Corporation. + * Copyright (c) 2013 Intel Corporation. * Len Brown * * This program is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ unsigned int skip_c1; unsigned int do_nhm_cstates; unsigned int do_snb_cstates; unsigned int do_c8_c9_c10; +unsigned int do_slm_cstates; +unsigned int use_c1_residency_msr; unsigned int has_aperf; unsigned int has_epb; unsigned int units = 1000000000; /* Ghz etc */ @@ -81,6 +83,8 @@ double rapl_joule_counter_range; #define RAPL_DRAM (1 << 3) #define RAPL_PKG_PERF_STATUS (1 << 4) #define RAPL_DRAM_PERF_STATUS (1 << 5) +#define RAPL_PKG_POWER_INFO (1 << 6) +#define RAPL_CORE_POLICY (1 << 7) #define TJMAX_DEFAULT 100 #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -96,7 +100,7 @@ struct thread_data { unsigned long long tsc; unsigned long long aperf; unsigned long long mperf; - unsigned long long c1; /* derived */ + unsigned long long c1; unsigned long long extra_msr64; unsigned long long extra_delta64; unsigned long long extra_msr32; @@ -266,7 +270,7 @@ void print_header(void) outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); if (do_nhm_cstates) outp += sprintf(outp, " %%c1"); - if (do_nhm_cstates) + if (do_nhm_cstates && !do_slm_cstates) outp += sprintf(outp, " %%c3"); if (do_nhm_cstates) outp += sprintf(outp, " %%c6"); @@ -280,9 +284,9 @@ void print_header(void) if (do_snb_cstates) outp += sprintf(outp, " %%pc2"); - if (do_nhm_cstates) + if (do_nhm_cstates && !do_slm_cstates) outp += sprintf(outp, " %%pc3"); - if (do_nhm_cstates) + if (do_nhm_cstates && !do_slm_cstates) outp += sprintf(outp, " %%pc6"); if (do_snb_cstates) outp += sprintf(outp, " %%pc7"); @@ -480,7 +484,7 @@ int format_counters(struct thread_data *t, struct core_data *c, if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) goto done; - if (do_nhm_cstates) + if (do_nhm_cstates && !do_slm_cstates) outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc); if (do_nhm_cstates) outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc); @@ -499,9 +503,9 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_snb_cstates) outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); - if (do_nhm_cstates) + if (do_nhm_cstates && !do_slm_cstates) outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc); - if (do_nhm_cstates) + if (do_nhm_cstates && !do_slm_cstates) outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); if (do_snb_cstates) outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); @@ -648,17 +652,24 @@ delta_thread(struct thread_data *new, struct thread_data *old, } - /* - * As counter collection is not atomic, - * it is possible for mperf's non-halted cycles + idle states - * to exceed TSC's all cycles: show c1 = 0% in that case. - */ - if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc) - old->c1 = 0; - else { - /* normal case, derive c1 */ - old->c1 = old->tsc - old->mperf - core_delta->c3 + if (use_c1_residency_msr) { + /* + * Some models have a dedicated C1 residency MSR, + * which should be more accurate than the derivation below. + */ + } else { + /* + * As counter collection is not atomic, + * it is possible for mperf's non-halted cycles + idle states + * to exceed TSC's all cycles: show c1 = 0% in that case. + */ + if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc) + old->c1 = 0; + else { + /* normal case, derive c1 */ + old->c1 = old->tsc - old->mperf - core_delta->c3 - core_delta->c6 - core_delta->c7; + } } if (old->mperf == 0) { @@ -872,13 +883,21 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) return -5; + if (use_c1_residency_msr) { + if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1)) + return -6; + } + /* collect core counters only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) return 0; - if (do_nhm_cstates) { + if (do_nhm_cstates && !do_slm_cstates) { if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) return -6; + } + + if (do_nhm_cstates) { if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) return -7; } @@ -898,7 +917,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) return 0; - if (do_nhm_cstates) { + if (do_nhm_cstates && !do_slm_cstates) { if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) return -9; if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) @@ -977,7 +996,7 @@ void print_verbose_header(void) ratio, bclk, ratio * bclk); get_msr(0, MSR_IA32_POWER_CTL, &msr); - fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E: %sabled)\n", + fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", msr, msr & 0x2 ? "EN" : "DIS"); if (!do_ivt_turbo_ratio_limit) @@ -1046,25 +1065,28 @@ print_nhm_turbo_ratio_limits: switch(msr & 0x7) { case 0: - fprintf(stderr, "pc0"); + fprintf(stderr, do_slm_cstates ? "no pkg states" : "pc0"); break; case 1: - fprintf(stderr, do_snb_cstates ? "pc2" : "pc0"); + fprintf(stderr, do_slm_cstates ? "no pkg states" : do_snb_cstates ? "pc2" : "pc0"); break; case 2: - fprintf(stderr, do_snb_cstates ? "pc6-noret" : "pc3"); + fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc6-noret" : "pc3"); break; case 3: - fprintf(stderr, "pc6"); + fprintf(stderr, do_slm_cstates ? "invalid" : "pc6"); break; case 4: - fprintf(stderr, "pc7"); + fprintf(stderr, do_slm_cstates ? "pc4" : "pc7"); break; case 5: - fprintf(stderr, do_snb_cstates ? "pc7s" : "invalid"); + fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc7s" : "invalid"); + break; + case 6: + fprintf(stderr, do_slm_cstates ? "pc6" : "invalid"); break; case 7: - fprintf(stderr, "unlimited"); + fprintf(stderr, do_slm_cstates ? "pc7" : "unlimited"); break; default: fprintf(stderr, "invalid"); @@ -1460,6 +1482,8 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) case 0x3F: /* HSW */ case 0x45: /* HSW */ case 0x46: /* HSW */ + case 0x37: /* BYT */ + case 0x4D: /* AVN */ return 1; case 0x2E: /* Nehalem-EX Xeon - Beckton */ case 0x2F: /* Westmere-EX Xeon - Eagleton */ @@ -1532,14 +1556,33 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ +double get_tdp(model) +{ + unsigned long long msr; + + if (do_rapl & RAPL_PKG_POWER_INFO) + if (!get_msr(0, MSR_PKG_POWER_INFO, &msr)) + return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; + + switch (model) { + case 0x37: + case 0x4D: + return 30.0; + default: + return 135.0; + } +} + + /* * rapl_probe() * - * sets do_rapl + * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units */ void rapl_probe(unsigned int family, unsigned int model) { unsigned long long msr; + unsigned int time_unit; double tdp; if (!genuine_intel) @@ -1555,11 +1598,15 @@ void rapl_probe(unsigned int family, unsigned int model) case 0x3F: /* HSW */ case 0x45: /* HSW */ case 0x46: /* HSW */ - do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX; + do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; break; case 0x2D: case 0x3E: - do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS; + do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO; + break; + case 0x37: /* BYT */ + case 0x4D: /* AVN */ + do_rapl = RAPL_PKG | RAPL_CORES ; break; default: return; @@ -1570,19 +1617,22 @@ void rapl_probe(unsigned int family, unsigned int model) return; rapl_power_units = 1.0 / (1 << (msr & 0xF)); - rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); - rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF)); + if (model == 0x37) + rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000; + else + rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); - /* get TDP to determine energy counter range */ - if (get_msr(0, MSR_PKG_POWER_INFO, &msr)) - return; + time_unit = msr >> 16 & 0xF; + if (time_unit == 0) + time_unit = 0xA; - tdp = ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; + rapl_time_units = 1.0 / (1 << (time_unit)); - rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; + tdp = get_tdp(model); + rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; if (verbose) - fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range\n", rapl_joule_counter_range); + fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); return; } @@ -1668,7 +1718,6 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) { unsigned long long msr; int cpu; - double local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units; if (!do_rapl) return 0; @@ -1686,23 +1735,13 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) return -1; - local_rapl_power_units = 1.0 / (1 << (msr & 0xF)); - local_rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); - local_rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF)); - - if (local_rapl_power_units != rapl_power_units) - fprintf(stderr, "cpu%d, ERROR: Power units mis-match\n", cpu); - if (local_rapl_energy_units != rapl_energy_units) - fprintf(stderr, "cpu%d, ERROR: Energy units mis-match\n", cpu); - if (local_rapl_time_units != rapl_time_units) - fprintf(stderr, "cpu%d, ERROR: Time units mis-match\n", cpu); - if (verbose) { fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, - local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units); + rapl_power_units, rapl_energy_units, rapl_time_units); } - if (do_rapl & RAPL_PKG) { + if (do_rapl & RAPL_PKG_POWER_INFO) { + if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) return -5; @@ -1714,6 +1753,9 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units); + } + if (do_rapl & RAPL_PKG) { + if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr)) return -9; @@ -1749,12 +1791,16 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) print_power_limit_msr(cpu, msr, "DRAM Limit"); } - if (do_rapl & RAPL_CORES) { + if (do_rapl & RAPL_CORE_POLICY) { if (verbose) { if (get_msr(cpu, MSR_PP0_POLICY, &msr)) return -7; fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); + } + } + if (do_rapl & RAPL_CORES) { + if (verbose) { if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) return -9; @@ -1813,10 +1859,48 @@ int has_c8_c9_c10(unsigned int family, unsigned int model) } +int is_slm(unsigned int family, unsigned int model) +{ + if (!genuine_intel) + return 0; + switch (model) { + case 0x37: /* BYT */ + case 0x4D: /* AVN */ + return 1; + } + return 0; +} + +#define SLM_BCLK_FREQS 5 +double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0}; + +double slm_bclk(void) +{ + unsigned long long msr = 3; + unsigned int i; + double freq; + + if (get_msr(0, MSR_FSB_FREQ, &msr)) + fprintf(stderr, "SLM BCLK: unknown\n"); + + i = msr & 0xf; + if (i >= SLM_BCLK_FREQS) { + fprintf(stderr, "SLM BCLK[%d] invalid\n", i); + msr = 3; + } + freq = slm_freq_table[i]; + + fprintf(stderr, "SLM BCLK: %.1f Mhz\n", freq); + + return freq; +} + double discover_bclk(unsigned int family, unsigned int model) { if (is_snb(family, model)) return 100.00; + else if (is_slm(family, model)) + return slm_bclk(); else return 133.33; } @@ -1873,7 +1957,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", cpu, msr, target_c_local); - if (target_c_local < 85 || target_c_local > 120) + if (target_c_local < 85 || target_c_local > 127) goto guess; tcc_activation_temp = target_c_local; @@ -1970,6 +2054,7 @@ void check_cpuid() do_smi = do_nhm_cstates; do_snb_cstates = is_snb(family, model); do_c8_c9_c10 = has_c8_c9_c10(family, model); + do_slm_cstates = is_slm(family, model); bclk = discover_bclk(family, model); do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); @@ -2331,7 +2416,7 @@ int main(int argc, char **argv) cmdline(argc, argv); if (verbose) - fprintf(stderr, "turbostat v3.4 April 17, 2013" + fprintf(stderr, "turbostat v3.5 April 26, 2013" " - Len Brown \n"); turbostat_init(); -- cgit v1.2.3-70-g09d2 From 03aa254f1e3c3d902cd68763f8abc2387e82b4da Mon Sep 17 00:00:00 2001 From: Hongbo Zhang Date: Thu, 26 Sep 2013 17:33:42 +0800 Subject: DMA: Freescale: Add new 8-channel DMA engine device tree nodes Freescale QorIQ T4 and B4 introduce new 8-channel DMA engines, this patch adds the device tree nodes for them. Signed-off-by: Hongbo Zhang Acked-by: Mark Rutland Signed-off-by: Vinod Koul --- .../devicetree/bindings/powerpc/fsl/dma.txt | 70 ++++++++++++++++++ arch/powerpc/boot/dts/fsl/b4si-post.dtsi | 4 +- arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi | 82 ++++++++++++++++++++++ arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi | 82 ++++++++++++++++++++++ arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 4 +- 5 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi (limited to 'arch') diff --git a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt index 05841689c4a..7fc1b010fa7 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt @@ -128,6 +128,76 @@ Example: }; }; +** Freescale Elo3 DMA Controller + DMA controller which has same function as EloPlus except that Elo3 has 8 + channels while EloPlus has only 4, it is used in Freescale Txxx and Bxxx + series chips, such as t1040, t4240, b4860. + +Required properties: + +- compatible : must include "fsl,elo3-dma" +- reg : contains two entries for DMA General Status Registers, + i.e. DGSR0 which includes status for channel 1~4, and + DGSR1 for channel 5~8 +- ranges : describes the mapping between the address space of the + DMA channels and the address space of the DMA controller + +- DMA channel nodes: + - compatible : must include "fsl,eloplus-dma-channel" + - reg : DMA channel specific registers + - interrupts : interrupt specifier for DMA channel IRQ + - interrupt-parent : optional, if needed for interrupt mapping + +Example: +dma@100300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,elo3-dma"; + reg = <0x100300 0x4>, + <0x100600 0x4>; + ranges = <0x0 0x100100 0x500>; + dma-channel@0 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x0 0x80>; + interrupts = <28 2 0 0>; + }; + dma-channel@80 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x80 0x80>; + interrupts = <29 2 0 0>; + }; + dma-channel@100 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x100 0x80>; + interrupts = <30 2 0 0>; + }; + dma-channel@180 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x180 0x80>; + interrupts = <31 2 0 0>; + }; + dma-channel@300 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x300 0x80>; + interrupts = <76 2 0 0>; + }; + dma-channel@380 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x380 0x80>; + interrupts = <77 2 0 0>; + }; + dma-channel@400 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x400 0x80>; + interrupts = <78 2 0 0>; + }; + dma-channel@480 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x480 0x80>; + interrupts = <79 2 0 0>; + }; +}; + Note on DMA channel compatible properties: The compatible property must say "fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA driver (fsldma). Any DMA channel used by fsldma cannot be used by another diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi index 4c617bf8cdb..4f6e48277c4 100644 --- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi @@ -223,13 +223,13 @@ reg = <0xe2000 0x1000>; }; -/include/ "qoriq-dma-0.dtsi" +/include/ "elo3-dma-0.dtsi" dma@100300 { fsl,iommu-parent = <&pamu0>; fsl,liodn-reg = <&guts 0x580>; /* DMA1LIODNR */ }; -/include/ "qoriq-dma-1.dtsi" +/include/ "elo3-dma-1.dtsi" dma@101300 { fsl,iommu-parent = <&pamu0>; fsl,liodn-reg = <&guts 0x584>; /* DMA2LIODNR */ diff --git a/arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi b/arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi new file mode 100644 index 00000000000..3c210e0d520 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi @@ -0,0 +1,82 @@ +/* + * QorIQ Elo3 DMA device tree stub [ controller @ offset 0x100000 ] + * + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +dma0: dma@100300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,elo3-dma"; + reg = <0x100300 0x4>, + <0x100600 0x4>; + ranges = <0x0 0x100100 0x500>; + dma-channel@0 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x0 0x80>; + interrupts = <28 2 0 0>; + }; + dma-channel@80 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x80 0x80>; + interrupts = <29 2 0 0>; + }; + dma-channel@100 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x100 0x80>; + interrupts = <30 2 0 0>; + }; + dma-channel@180 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x180 0x80>; + interrupts = <31 2 0 0>; + }; + dma-channel@300 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x300 0x80>; + interrupts = <76 2 0 0>; + }; + dma-channel@380 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x380 0x80>; + interrupts = <77 2 0 0>; + }; + dma-channel@400 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x400 0x80>; + interrupts = <78 2 0 0>; + }; + dma-channel@480 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x480 0x80>; + interrupts = <79 2 0 0>; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi b/arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi new file mode 100644 index 00000000000..cccf3bb3822 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi @@ -0,0 +1,82 @@ +/* + * QorIQ Elo3 DMA device tree stub [ controller @ offset 0x101000 ] + * + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +dma1: dma@101300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,elo3-dma"; + reg = <0x101300 0x4>, + <0x101600 0x4>; + ranges = <0x0 0x101100 0x500>; + dma-channel@0 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x0 0x80>; + interrupts = <32 2 0 0>; + }; + dma-channel@80 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x80 0x80>; + interrupts = <33 2 0 0>; + }; + dma-channel@100 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x100 0x80>; + interrupts = <34 2 0 0>; + }; + dma-channel@180 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x180 0x80>; + interrupts = <35 2 0 0>; + }; + dma-channel@300 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x300 0x80>; + interrupts = <80 2 0 0>; + }; + dma-channel@380 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x380 0x80>; + interrupts = <81 2 0 0>; + }; + dma-channel@400 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x400 0x80>; + interrupts = <82 2 0 0>; + }; + dma-channel@480 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x480 0x80>; + interrupts = <83 2 0 0>; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi index 510afa362de..4143a9733cd 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi @@ -387,8 +387,8 @@ reg = <0xea000 0x4000>; }; -/include/ "qoriq-dma-0.dtsi" -/include/ "qoriq-dma-1.dtsi" +/include/ "elo3-dma-0.dtsi" +/include/ "elo3-dma-1.dtsi" /include/ "qoriq-espi-0.dtsi" spi@110000 { -- cgit v1.2.3-70-g09d2 From 7bd40c16ccb2cb6877dd00b0e66249c171e6fa43 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 12 Nov 2013 10:17:39 -0800 Subject: x86/early quirk: use gen6 stolen detection for VLV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've always been able to use either method on VLV, but it appears more recent BIOSes only support the gen6 method, so switch over to that. References: https://bugs.freedesktop.org/show_bug.cgi?id=71370 Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- arch/x86/kernel/early-quirks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 96f958d8cd4..bc4a088f902 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -330,8 +330,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = { INTEL_I915GM_IDS(gen3_stolen_size), INTEL_I945G_IDS(gen3_stolen_size), INTEL_I945GM_IDS(gen3_stolen_size), - INTEL_VLV_M_IDS(gen3_stolen_size), - INTEL_VLV_D_IDS(gen3_stolen_size), + INTEL_VLV_M_IDS(gen6_stolen_size), + INTEL_VLV_D_IDS(gen6_stolen_size), INTEL_PINEVIEW_IDS(gen3_stolen_size), INTEL_I965G_IDS(gen3_stolen_size), INTEL_G33_IDS(gen3_stolen_size), -- cgit v1.2.3-70-g09d2 From 83651bb988b169deae16608262e996eb718c6ab4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Nov 2013 10:58:30 +0000 Subject: ARM: Fix nommu.c build warning The 0-day kernel build robot found this new warning: arch/arm/mm/nommu.c:303:17: warning: 'struct proc_info_list' declared inside parameter list [enabled by default] arch/arm/mm/nommu.c:303:17: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] Fix it by including the appropriate header. Signed-off-by: Russell King --- arch/arm/mm/nommu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 5c668b7a31f..55764a7ef1f 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "mm.h" -- cgit v1.2.3-70-g09d2 From 10593b2e49327f7cd193fc2ba30fa3da322bda6a Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Thu, 7 Nov 2013 08:42:40 +0100 Subject: ARM: 7881/1: __fixup_smp read of SCU config should do byteswap in BE case Commit "bc41b8724f24b9a27d1dcc6c974b8f686b38d554 ARM: 7846/1: Update SMP_ON_UP code to detect A9MPCore with 1 CPU devices" added read of SCU config register into __fixup_smp function. Such read should be followed by byteswap, if kernel runs in BE mode. Signed-off-by: Victor Kamensky Acked-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/kernel/head.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 7801866e626..cd788d5b668 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -508,6 +508,7 @@ __fixup_smp: teq r0, #0x0 @ '0' on actual UP A9 hardware beq __fixup_smp_on_up @ So its an A9 UP ldr r0, [r0, #4] @ read SCU Config +ARM_BE8(rev r0, r0) @ byteswap if big endian and r0, r0, #0x3 @ number of CPUs teq r0, #0x0 @ is 1? movne pc, lr -- cgit v1.2.3-70-g09d2 From 139cc2ba7400dab80228a2bfa683e2f49cf5d3ff Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Thu, 7 Nov 2013 08:42:41 +0100 Subject: ARM: 7882/1: mm: fix __phys_to_virt to work with 64 bit phys_addr_t in BE case Make sure that inline assembler that expects 'r' operand receives 32 bit value. Before this fix in case of CONFIG_ARCH_PHYS_ADDR_T_64BIT and CONFIG_ARM_PATCH_PHYS_VIRT __phys_to_virt function passed 64 bit value to __pv_stub inline assembler where 'r' operand is expected. Compiler behavior in such case is not well specified. It worked in little endian case, but in big endian case incorrect code was generated, where compiler confused which part of 64 bit value it needed to modify. For example BE snippet looked like this: N:0x80904E08 : MOV r2,#0 N:0x80904E0C : SUB r2,r2,#0x81000000 when LE similar code looked like this N:0x808FCE2C : MOV r2,r0 N:0x808FCE30 : SUB r2,r2,#0xc0, 8 ; #0xc0000000 Note 'r0' register is va that have to be translated into phys To avoid this situation use explicit cast to 'unsigned long', which explicitly discard upper part of phys address and convert value to 32 bit. Also add comment so such cast will not be removed in the future. Signed-off-by: Victor Kamensky Acked-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/include/asm/memory.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 4dd21457ef9..9ecccc86504 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -226,7 +226,14 @@ static inline phys_addr_t __virt_to_phys(unsigned long x) static inline unsigned long __phys_to_virt(phys_addr_t x) { unsigned long t; - __pv_stub(x, t, "sub", __PV_BITS_31_24); + + /* + * 'unsigned long' cast discard upper word when + * phys_addr_t is 64 bit, and makes sure that inline + * assembler expression receives 32 bit argument + * in place where 'r' 32 bit operand is expected. + */ + __pv_stub((unsigned long) x, t, "sub", __PV_BITS_31_24); return t; } -- cgit v1.2.3-70-g09d2 From d9a790df8e984b143e71ca429316064adaecf65c Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Thu, 7 Nov 2013 08:42:42 +0100 Subject: ARM: 7883/1: fix mov to mvn conversion in case of 64 bit phys_addr_t and BE Fix patching code to convert mov instruction into mvn instruction in case of CONFIG_ARCH_PHYS_ADDR_T_64BIT and CONFIG_ARM_PATCH_PHYS_VIRT. In BE case store into r0 proper bits so byte swapped instruction could be modified correctly. Signed-off-by: Victor Kamensky Reviewed-by: R Sricharan Acked-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/kernel/head.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index cd788d5b668..11d59b32fb8 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -644,8 +644,12 @@ ARM_BE8(rev16 ip, ip) ldrcc r7, [r4], #4 @ use branch for delay slot bcc 1b bx lr +#else +#ifdef CONFIG_CPU_ENDIAN_BE8 + moveq r0, #0x00004000 @ set bit 22, mov to mvn instruction #else moveq r0, #0x400000 @ set bit 22, mov to mvn instruction +#endif b 2f 1: ldr ip, [r7, r3] #ifdef CONFIG_CPU_ENDIAN_BE8 @@ -654,7 +658,7 @@ ARM_BE8(rev16 ip, ip) tst ip, #0x000f0000 @ check the rotation field orrne ip, ip, r6, lsl #24 @ mask in offset bits 31-24 biceq ip, ip, #0x00004000 @ clear bit 22 - orreq ip, ip, r0, lsl #24 @ mask in offset bits 7-0 + orreq ip, ip, r0 @ mask in offset bits 7-0 #else bic ip, ip, #0x000000ff tst ip, #0xf00 @ check the rotation field -- cgit v1.2.3-70-g09d2 From 905b57972149f205aa73b0a3b6935b0e5470ab24 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Nov 2013 12:49:53 +0100 Subject: ARM: 7884/1: mm: Fix ECC mem policy printk ECC policy can be applied to the whole system when this bit is implemented by SoC vendor (IMP - bit 9 - in L1 page table entry format). When this bit is not implemented by SoC vendor it doesn't mean that system has no other way how to do ECC. This patch ensures to show this message only when ECC is requested via cmd line ecc=on and runs on appropriate ARM core. Signed-off-by: Michal Simek Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 78eeeca78f5..580ef2de82d 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -558,8 +558,8 @@ static void __init build_mem_type_table(void) mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; break; } - printk("Memory policy: ECC %sabled, Data cache %s\n", - ecc_mask ? "en" : "dis", cp->policy); + pr_info("Memory policy: %sData cache %s\n", + ecc_mask ? "ECC enabled, " : "", cp->policy); for (i = 0; i < ARRAY_SIZE(mem_types); i++) { struct mem_type *t = &mem_types[i]; -- cgit v1.2.3-70-g09d2 From f3db3f4389dbd9a8c2b4477f37a6ebddfd670ad8 Mon Sep 17 00:00:00 2001 From: Mahesh Sivasubramanian Date: Fri, 8 Nov 2013 23:25:20 +0100 Subject: ARM: 7885/1: Save/Restore 64-bit TTBR registers on LPAE suspend/resume LPAE enabled kernels use the 64-bit version of TTBR0 and TTBR1 registers. If we're running an LPAE kernel, fill the upper half of TTBR0 with 0 because we're setting it to the idmap here (the idmap is guaranteed to be < 4Gb) and fully restore TTBR1 instead of just restoring the lower 32 bits. Failure to do so can cause failures on resume from suspend when these registers are only half restored. Signed-off-by: Mahesh Sivasubramanian Signed-off-by: Stephen Boyd Acked-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/mm/proc-v7.S | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 60920f62fdf..bd1781979a3 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -92,7 +92,7 @@ ENDPROC(cpu_v7_dcache_clean_area) /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ .globl cpu_v7_suspend_size -.equ cpu_v7_suspend_size, 4 * 8 +.equ cpu_v7_suspend_size, 4 * 9 #ifdef CONFIG_ARM_CPU_SUSPEND ENTRY(cpu_v7_do_suspend) stmfd sp!, {r4 - r10, lr} @@ -101,13 +101,17 @@ ENTRY(cpu_v7_do_suspend) stmia r0!, {r4 - r5} #ifdef CONFIG_MMU mrc p15, 0, r6, c3, c0, 0 @ Domain ID +#ifdef CONFIG_ARM_LPAE + mrrc p15, 1, r5, r7, c2 @ TTB 1 +#else mrc p15, 0, r7, c2, c0, 1 @ TTB 1 +#endif mrc p15, 0, r11, c2, c0, 2 @ TTB control register #endif mrc p15, 0, r8, c1, c0, 0 @ Control register mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control - stmia r0, {r6 - r11} + stmia r0, {r5 - r11} ldmfd sp!, {r4 - r10, pc} ENDPROC(cpu_v7_do_suspend) @@ -118,16 +122,19 @@ ENTRY(cpu_v7_do_resume) ldmia r0!, {r4 - r5} mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID - ldmia r0, {r6 - r11} + ldmia r0, {r5 - r11} #ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs mcr p15, 0, r6, c3, c0, 0 @ Domain ID -#ifndef CONFIG_ARM_LPAE +#ifdef CONFIG_ARM_LPAE + mcrr p15, 0, r1, ip, c2 @ TTB 0 + mcrr p15, 1, r5, r7, c2 @ TTB 1 +#else ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) ALT_UP(orr r1, r1, #TTB_FLAGS_UP) -#endif mcr p15, 0, r1, c2, c0, 0 @ TTB 0 mcr p15, 0, r7, c2, c0, 1 @ TTB 1 +#endif mcr p15, 0, r11, c2, c0, 2 @ TTB control register ldr r4, =PRRR @ PRRR ldr r5, =NMRR @ NMRR -- cgit v1.2.3-70-g09d2 From b02f84671cd0c69400daf1595e7c321ea8e6c657 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 9 Nov 2013 00:31:11 +0100 Subject: ARM: 7886/1: make OABI default to off Given recent discussions about the lack of OABI in the wild, switch CONFIG_OABI_COMPAT to off-by-default to encourage more system builders to avoid it. Signed-off-by: Kees Cook Acked-by: Nicolas Pitre Acked-by: Olof Johansson Signed-off-by: Russell King --- arch/arm/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 603d661b445..fa5c6003e30 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1719,7 +1719,6 @@ config AEABI config OABI_COMPAT bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" depends on AEABI && !THUMB2_KERNEL - default y help This option preserves the old syscall interface along with the new (ARM EABI) one. It also provides a compatibility layer to @@ -1731,7 +1730,7 @@ config OABI_COMPAT can say N here. If this option is not selected and you attempt to execute a legacy ABI binary then the result will be UNPREDICTABLE (in fact it can be predicted that it won't work - at all). If in doubt say Y. + at all). If in doubt say N. config ARCH_HAS_HOLES_MEMORYMODEL bool -- cgit v1.2.3-70-g09d2 From 9170217510cd280c704966738e7c1660c8fa5cbd Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 9 Nov 2013 00:51:56 +0100 Subject: ARM: 7888/1: seccomp: not compatible with ARM OABI Make sure that seccomp filter won't be built when ARM OABI is in use, since there is work needed to distinguish calling conventions. Until that is done (which is likely never since OABI is deprecated), make sure seccomp filter is unavailable in the OABI world. Signed-off-by: Kees Cook Reviewed-by: Will Drewry Signed-off-by: Russell King --- arch/arm/Kconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fa5c6003e30..085b31ba287 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -24,7 +24,7 @@ config ARM select HARDIRQS_SW_RESEND select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB - select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) select HAVE_ARCH_TRACEHOOK select HAVE_BPF_JIT select HAVE_CONTEXT_TRACKING @@ -1726,6 +1726,11 @@ config OABI_COMPAT in memory differs between the legacy ABI and the new ARM EABI (only for non "thumb" binaries). This option adds a tiny overhead to all syscalls and produces a slightly larger kernel. + + The seccomp filter system will not be available when this is + selected, since there is no way yet to sensibly distinguish + between calling conventions during filtering. + If you know you'll be using only pure EABI user space then you can say N here. If this option is not selected and you attempt to execute a legacy ABI binary then the result will be -- cgit v1.2.3-70-g09d2 From 54f8d501e842879143e867e70996574a54d1e130 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 18 Oct 2013 19:35:32 +0200 Subject: dmaengine: remove DMA unmap from drivers Remove support for DMA unmapping from drivers as it is no longer needed (DMA core code is now handling it). Cc: Vinod Koul Cc: Tomasz Figa Cc: Dave Jiang Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park [djbw: fix up chan2parent() unused warning in drivers/dma/dw/core.c] Signed-off-by: Dan Williams --- arch/arm/include/asm/hardware/iop3xx-adma.h | 30 ---- arch/arm/include/asm/hardware/iop_adma.h | 4 - arch/arm/mach-iop13xx/include/mach/adma.h | 26 --- drivers/dma/amba-pl08x.c | 31 ---- drivers/dma/at_hdmac.c | 25 --- drivers/dma/dw/core.c | 24 --- drivers/dma/ep93xx_dma.c | 29 --- drivers/dma/fsldma.c | 16 -- drivers/dma/ioat/dma.c | 16 -- drivers/dma/ioat/dma.h | 12 -- drivers/dma/ioat/dma_v2.c | 1 - drivers/dma/ioat/dma_v3.c | 166 ----------------- drivers/dma/iop-adma.c | 96 +--------- drivers/dma/mv_xor.c | 44 +---- drivers/dma/ppc4xx/adma.c | 269 ---------------------------- drivers/dma/timb_dma.c | 36 ---- drivers/dma/txx9dmac.c | 24 --- 17 files changed, 3 insertions(+), 846 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/hardware/iop3xx-adma.h b/arch/arm/include/asm/hardware/iop3xx-adma.h index 9b28f1243bd..240b29ef17d 100644 --- a/arch/arm/include/asm/hardware/iop3xx-adma.h +++ b/arch/arm/include/asm/hardware/iop3xx-adma.h @@ -393,36 +393,6 @@ static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt, return slot_cnt; } -static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc) -{ - return 0; -} - -static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc, - struct iop_adma_chan *chan) -{ - union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; - - switch (chan->device->id) { - case DMA0_ID: - case DMA1_ID: - return hw_desc.dma->dest_addr; - case AAU_ID: - return hw_desc.aau->dest_addr; - default: - BUG(); - } - return 0; -} - - -static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc, - struct iop_adma_chan *chan) -{ - BUG(); - return 0; -} - static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc, struct iop_adma_chan *chan) { diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h index 122f86d8c99..250760e0810 100644 --- a/arch/arm/include/asm/hardware/iop_adma.h +++ b/arch/arm/include/asm/hardware/iop_adma.h @@ -82,8 +82,6 @@ struct iop_adma_chan { * @slot_cnt: total slots used in an transaction (group of operations) * @slots_per_op: number of slots per operation * @idx: pool index - * @unmap_src_cnt: number of xor sources - * @unmap_len: transaction bytecount * @tx_list: list of descriptors that are associated with one operation * @async_tx: support for the async_tx api * @group_list: list of slots that make up a multi-descriptor transaction @@ -99,8 +97,6 @@ struct iop_adma_desc_slot { u16 slot_cnt; u16 slots_per_op; u16 idx; - u16 unmap_src_cnt; - size_t unmap_len; struct list_head tx_list; struct dma_async_tx_descriptor async_tx; union { diff --git a/arch/arm/mach-iop13xx/include/mach/adma.h b/arch/arm/mach-iop13xx/include/mach/adma.h index 6d3782d85a9..a86fd0ed775 100644 --- a/arch/arm/mach-iop13xx/include/mach/adma.h +++ b/arch/arm/mach-iop13xx/include/mach/adma.h @@ -218,20 +218,6 @@ iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op) #define iop_chan_pq_slot_count iop_chan_xor_slot_count #define iop_chan_pq_zero_sum_slot_count iop_chan_xor_slot_count -static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc, - struct iop_adma_chan *chan) -{ - struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; - return hw_desc->dest_addr; -} - -static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc, - struct iop_adma_chan *chan) -{ - struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; - return hw_desc->q_dest_addr; -} - static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc, struct iop_adma_chan *chan) { @@ -350,18 +336,6 @@ iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt, hw_desc->desc_ctrl = u_desc_ctrl.value; } -static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc) -{ - struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; - union { - u32 value; - struct iop13xx_adma_desc_ctrl field; - } u_desc_ctrl; - - u_desc_ctrl.value = hw_desc->desc_ctrl; - return u_desc_ctrl.field.pq_xfer_en; -} - static inline void iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, unsigned long flags) diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 7f9846464b7..6a5f782ec7e 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -1164,43 +1164,12 @@ static void pl08x_free_txd(struct pl08x_driver_data *pl08x, kfree(txd); } -static void pl08x_unmap_buffers(struct pl08x_txd *txd) -{ - struct device *dev = txd->vd.tx.chan->device->dev; - struct pl08x_sg *dsg; - - if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - if (txd->vd.tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE) - list_for_each_entry(dsg, &txd->dsg_list, node) - dma_unmap_single(dev, dsg->src_addr, dsg->len, - DMA_TO_DEVICE); - else { - list_for_each_entry(dsg, &txd->dsg_list, node) - dma_unmap_page(dev, dsg->src_addr, dsg->len, - DMA_TO_DEVICE); - } - } - if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (txd->vd.tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE) - list_for_each_entry(dsg, &txd->dsg_list, node) - dma_unmap_single(dev, dsg->dst_addr, dsg->len, - DMA_FROM_DEVICE); - else - list_for_each_entry(dsg, &txd->dsg_list, node) - dma_unmap_page(dev, dsg->dst_addr, dsg->len, - DMA_FROM_DEVICE); - } -} - static void pl08x_desc_free(struct virt_dma_desc *vd) { struct pl08x_txd *txd = to_pl08x_txd(&vd->tx); struct pl08x_dma_chan *plchan = to_pl08x_chan(vd->tx.chan); dma_descriptor_unmap(txd); - if (!plchan->slave) - pl08x_unmap_buffers(txd); - if (!txd->done) pl08x_release_mux(plchan); diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index cc7098ddf9d..6deaefbec0b 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -344,32 +344,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) /* move myself to free_list */ list_move(&desc->desc_node, &atchan->free_list); - /* unmap dma addresses (not on slave channels) */ dma_descriptor_unmap(txd); - if (!atchan->chan_common.private) { - struct device *parent = chan2parent(&atchan->chan_common); - if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) - dma_unmap_single(parent, - desc->lli.daddr, - desc->len, DMA_FROM_DEVICE); - else - dma_unmap_page(parent, - desc->lli.daddr, - desc->len, DMA_FROM_DEVICE); - } - if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) - dma_unmap_single(parent, - desc->lli.saddr, - desc->len, DMA_TO_DEVICE); - else - dma_unmap_page(parent, - desc->lli.saddr, - desc->len, DMA_TO_DEVICE); - } - } - /* for cyclic transfers, * no need to replay callback function while stopping */ if (!atc_chan_is_cyclic(atchan)) { diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index e3fe1b1a73b..1f39ccce272 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -85,10 +85,6 @@ static struct device *chan2dev(struct dma_chan *chan) { return &chan->dev->device; } -static struct device *chan2parent(struct dma_chan *chan) -{ - return chan->dev->device.parent; -} static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc) { @@ -312,26 +308,6 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc, list_move(&desc->desc_node, &dwc->free_list); dma_descriptor_unmap(txd); - if (!is_slave_direction(dwc->direction)) { - struct device *parent = chan2parent(&dwc->chan); - if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) - dma_unmap_single(parent, desc->lli.dar, - desc->total_len, DMA_FROM_DEVICE); - else - dma_unmap_page(parent, desc->lli.dar, - desc->total_len, DMA_FROM_DEVICE); - } - if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) - dma_unmap_single(parent, desc->lli.sar, - desc->total_len, DMA_TO_DEVICE); - else - dma_unmap_page(parent, desc->lli.sar, - desc->total_len, DMA_TO_DEVICE); - } - } - spin_unlock_irqrestore(&dwc->lock, flags); if (callback) diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index dcd6bf5d309..cb4bf682a70 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -733,28 +733,6 @@ static void ep93xx_dma_advance_work(struct ep93xx_dma_chan *edmac) spin_unlock_irqrestore(&edmac->lock, flags); } -static void ep93xx_dma_unmap_buffers(struct ep93xx_dma_desc *desc) -{ - struct device *dev = desc->txd.chan->device->dev; - - if (!(desc->txd.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - if (desc->txd.flags & DMA_COMPL_SRC_UNMAP_SINGLE) - dma_unmap_single(dev, desc->src_addr, desc->size, - DMA_TO_DEVICE); - else - dma_unmap_page(dev, desc->src_addr, desc->size, - DMA_TO_DEVICE); - } - if (!(desc->txd.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (desc->txd.flags & DMA_COMPL_DEST_UNMAP_SINGLE) - dma_unmap_single(dev, desc->dst_addr, desc->size, - DMA_FROM_DEVICE); - else - dma_unmap_page(dev, desc->dst_addr, desc->size, - DMA_FROM_DEVICE); - } -} - static void ep93xx_dma_tasklet(unsigned long data) { struct ep93xx_dma_chan *edmac = (struct ep93xx_dma_chan *)data; @@ -787,14 +765,7 @@ static void ep93xx_dma_tasklet(unsigned long data) /* Now we can release all the chained descriptors */ list_for_each_entry_safe(desc, d, &list, node) { - /* - * For the memcpy channels the API requires us to unmap the - * buffers unless requested otherwise. - */ dma_descriptor_unmap(&desc->txd); - if (!edmac->chan.private) - ep93xx_dma_unmap_buffers(desc); - ep93xx_dma_desc_put(edmac, desc); } diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 66c4052a1f3..d9e6381b2b1 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -869,22 +869,6 @@ static void fsldma_cleanup_descriptor(struct fsldma_chan *chan, dma_run_dependencies(txd); dma_descriptor_unmap(txd); - /* Unmap the dst buffer, if requested */ - if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) - dma_unmap_single(dev, dst, len, DMA_FROM_DEVICE); - else - dma_unmap_page(dev, dst, len, DMA_FROM_DEVICE); - } - - /* Unmap the src buffer, if requested */ - if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) - dma_unmap_single(dev, src, len, DMA_TO_DEVICE); - else - dma_unmap_page(dev, src, len, DMA_TO_DEVICE); - } - #ifdef FSL_DMA_LD_DEBUG chan_dbg(chan, "LD %p free\n", desc); #endif diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 26f8cfd6bc3..c123e32dbbb 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -531,21 +531,6 @@ static void ioat1_cleanup_event(unsigned long data) writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); } -void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, - size_t len, struct ioat_dma_descriptor *hw) -{ - struct pci_dev *pdev = chan->device->pdev; - size_t offset = len - hw->size; - - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) - ioat_unmap(pdev, hw->dst_addr - offset, len, - PCI_DMA_FROMDEVICE, flags, 1); - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) - ioat_unmap(pdev, hw->src_addr - offset, len, - PCI_DMA_TODEVICE, flags, 0); -} - dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan) { dma_addr_t phys_complete; @@ -603,7 +588,6 @@ static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete) if (tx->cookie) { dma_cookie_complete(tx); dma_descriptor_unmap(tx); - ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw); ioat->active -= desc->hw->tx_cnt; if (tx->callback) { tx->callback(tx->callback_param); diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 54fb7b9ff9a..4300d5af188 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -342,16 +342,6 @@ static inline bool is_ioat_bug(unsigned long err) return !!err; } -static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len, - int direction, enum dma_ctrl_flags flags, bool dst) -{ - if ((dst && (flags & DMA_COMPL_DEST_UNMAP_SINGLE)) || - (!dst && (flags & DMA_COMPL_SRC_UNMAP_SINGLE))) - pci_unmap_single(pdev, addr, len, direction); - else - pci_unmap_page(pdev, addr, len, direction); -} - int ioat_probe(struct ioatdma_device *device); int ioat_register(struct ioatdma_device *device); int ioat1_dma_probe(struct ioatdma_device *dev, int dca); @@ -363,8 +353,6 @@ void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx); enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, struct dma_tx_state *txstate); -void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, - size_t len, struct ioat_dma_descriptor *hw); bool ioat_cleanup_preamble(struct ioat_chan_common *chan, dma_addr_t *phys_complete); void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index fc7b50a813c..5d3affe7e97 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -149,7 +149,6 @@ static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) dump_desc_dbg(ioat, desc); if (tx->cookie) { dma_descriptor_unmap(tx); - ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw); dma_cookie_complete(tx); if (tx->callback) { tx->callback(tx->callback_param); diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 57a2901b917..43386c171bb 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -96,13 +96,6 @@ static const u8 pq16_idx_to_sed[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, static void ioat3_eh(struct ioat2_dma_chan *ioat); -static dma_addr_t xor_get_src(struct ioat_raw_descriptor *descs[2], int idx) -{ - struct ioat_raw_descriptor *raw = descs[xor_idx_to_desc >> idx & 1]; - - return raw->field[xor_idx_to_field[idx]]; -} - static void xor_set_src(struct ioat_raw_descriptor *descs[2], dma_addr_t addr, u32 offset, int idx) { @@ -296,164 +289,6 @@ static void ioat3_free_sed(struct ioatdma_device *device, struct ioat_sed_ent *s kmem_cache_free(device->sed_pool, sed); } -static void ioat3_dma_unmap(struct ioat2_dma_chan *ioat, - struct ioat_ring_ent *desc, int idx) -{ - struct ioat_chan_common *chan = &ioat->base; - struct pci_dev *pdev = chan->device->pdev; - size_t len = desc->len; - size_t offset = len - desc->hw->size; - struct dma_async_tx_descriptor *tx = &desc->txd; - enum dma_ctrl_flags flags = tx->flags; - - switch (desc->hw->ctl_f.op) { - case IOAT_OP_COPY: - if (!desc->hw->ctl_f.null) /* skip 'interrupt' ops */ - ioat_dma_unmap(chan, flags, len, desc->hw); - break; - case IOAT_OP_XOR_VAL: - case IOAT_OP_XOR: { - struct ioat_xor_descriptor *xor = desc->xor; - struct ioat_ring_ent *ext; - struct ioat_xor_ext_descriptor *xor_ex = NULL; - int src_cnt = src_cnt_to_sw(xor->ctl_f.src_cnt); - struct ioat_raw_descriptor *descs[2]; - int i; - - if (src_cnt > 5) { - ext = ioat2_get_ring_ent(ioat, idx + 1); - xor_ex = ext->xor_ex; - } - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - descs[0] = (struct ioat_raw_descriptor *) xor; - descs[1] = (struct ioat_raw_descriptor *) xor_ex; - for (i = 0; i < src_cnt; i++) { - dma_addr_t src = xor_get_src(descs, i); - - ioat_unmap(pdev, src - offset, len, - PCI_DMA_TODEVICE, flags, 0); - } - - /* dest is a source in xor validate operations */ - if (xor->ctl_f.op == IOAT_OP_XOR_VAL) { - ioat_unmap(pdev, xor->dst_addr - offset, len, - PCI_DMA_TODEVICE, flags, 1); - break; - } - } - - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) - ioat_unmap(pdev, xor->dst_addr - offset, len, - PCI_DMA_FROMDEVICE, flags, 1); - break; - } - case IOAT_OP_PQ_VAL: - case IOAT_OP_PQ: { - struct ioat_pq_descriptor *pq = desc->pq; - struct ioat_ring_ent *ext; - struct ioat_pq_ext_descriptor *pq_ex = NULL; - int src_cnt = src_cnt_to_sw(pq->ctl_f.src_cnt); - struct ioat_raw_descriptor *descs[2]; - int i; - - if (src_cnt > 3) { - ext = ioat2_get_ring_ent(ioat, idx + 1); - pq_ex = ext->pq_ex; - } - - /* in the 'continue' case don't unmap the dests as sources */ - if (dmaf_p_disabled_continue(flags)) - src_cnt--; - else if (dmaf_continue(flags)) - src_cnt -= 3; - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - descs[0] = (struct ioat_raw_descriptor *) pq; - descs[1] = (struct ioat_raw_descriptor *) pq_ex; - for (i = 0; i < src_cnt; i++) { - dma_addr_t src = pq_get_src(descs, i); - - ioat_unmap(pdev, src - offset, len, - PCI_DMA_TODEVICE, flags, 0); - } - - /* the dests are sources in pq validate operations */ - if (pq->ctl_f.op == IOAT_OP_XOR_VAL) { - if (!(flags & DMA_PREP_PQ_DISABLE_P)) - ioat_unmap(pdev, pq->p_addr - offset, - len, PCI_DMA_TODEVICE, flags, 0); - if (!(flags & DMA_PREP_PQ_DISABLE_Q)) - ioat_unmap(pdev, pq->q_addr - offset, - len, PCI_DMA_TODEVICE, flags, 0); - break; - } - } - - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (!(flags & DMA_PREP_PQ_DISABLE_P)) - ioat_unmap(pdev, pq->p_addr - offset, len, - PCI_DMA_BIDIRECTIONAL, flags, 1); - if (!(flags & DMA_PREP_PQ_DISABLE_Q)) - ioat_unmap(pdev, pq->q_addr - offset, len, - PCI_DMA_BIDIRECTIONAL, flags, 1); - } - break; - } - case IOAT_OP_PQ_16S: - case IOAT_OP_PQ_VAL_16S: { - struct ioat_pq_descriptor *pq = desc->pq; - int src_cnt = src16_cnt_to_sw(pq->ctl_f.src_cnt); - struct ioat_raw_descriptor *descs[4]; - int i; - - /* in the 'continue' case don't unmap the dests as sources */ - if (dmaf_p_disabled_continue(flags)) - src_cnt--; - else if (dmaf_continue(flags)) - src_cnt -= 3; - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - descs[0] = (struct ioat_raw_descriptor *)pq; - descs[1] = (struct ioat_raw_descriptor *)(desc->sed->hw); - descs[2] = (struct ioat_raw_descriptor *)(&desc->sed->hw->b[0]); - for (i = 0; i < src_cnt; i++) { - dma_addr_t src = pq16_get_src(descs, i); - - ioat_unmap(pdev, src - offset, len, - PCI_DMA_TODEVICE, flags, 0); - } - - /* the dests are sources in pq validate operations */ - if (pq->ctl_f.op == IOAT_OP_XOR_VAL) { - if (!(flags & DMA_PREP_PQ_DISABLE_P)) - ioat_unmap(pdev, pq->p_addr - offset, - len, PCI_DMA_TODEVICE, - flags, 0); - if (!(flags & DMA_PREP_PQ_DISABLE_Q)) - ioat_unmap(pdev, pq->q_addr - offset, - len, PCI_DMA_TODEVICE, - flags, 0); - break; - } - } - - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - if (!(flags & DMA_PREP_PQ_DISABLE_P)) - ioat_unmap(pdev, pq->p_addr - offset, len, - PCI_DMA_BIDIRECTIONAL, flags, 1); - if (!(flags & DMA_PREP_PQ_DISABLE_Q)) - ioat_unmap(pdev, pq->q_addr - offset, len, - PCI_DMA_BIDIRECTIONAL, flags, 1); - } - break; - } - default: - dev_err(&pdev->dev, "%s: unknown op type: %#x\n", - __func__, desc->hw->ctl_f.op); - } -} - static bool desc_has_ext(struct ioat_ring_ent *desc) { struct ioat_dma_descriptor *hw = desc->hw; @@ -578,7 +413,6 @@ static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) if (tx->cookie) { dma_cookie_complete(tx); dma_descriptor_unmap(tx); - ioat3_dma_unmap(ioat, desc, idx + i); if (tx->callback) { tx->callback(tx->callback_param); tx->callback = NULL; diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 8f6e426590e..173e26ff18f 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -61,80 +61,6 @@ static void iop_adma_free_slots(struct iop_adma_desc_slot *slot) } } -static void -iop_desc_unmap(struct iop_adma_chan *iop_chan, struct iop_adma_desc_slot *desc) -{ - struct dma_async_tx_descriptor *tx = &desc->async_tx; - struct iop_adma_desc_slot *unmap = desc->group_head; - struct device *dev = &iop_chan->device->pdev->dev; - u32 len = unmap->unmap_len; - enum dma_ctrl_flags flags = tx->flags; - u32 src_cnt; - dma_addr_t addr; - dma_addr_t dest; - - src_cnt = unmap->unmap_src_cnt; - dest = iop_desc_get_dest_addr(unmap, iop_chan); - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - enum dma_data_direction dir; - - if (src_cnt > 1) /* is xor? */ - dir = DMA_BIDIRECTIONAL; - else - dir = DMA_FROM_DEVICE; - - dma_unmap_page(dev, dest, len, dir); - } - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - while (src_cnt--) { - addr = iop_desc_get_src_addr(unmap, iop_chan, src_cnt); - if (addr == dest) - continue; - dma_unmap_page(dev, addr, len, DMA_TO_DEVICE); - } - } - desc->group_head = NULL; -} - -static void -iop_desc_unmap_pq(struct iop_adma_chan *iop_chan, struct iop_adma_desc_slot *desc) -{ - struct dma_async_tx_descriptor *tx = &desc->async_tx; - struct iop_adma_desc_slot *unmap = desc->group_head; - struct device *dev = &iop_chan->device->pdev->dev; - u32 len = unmap->unmap_len; - enum dma_ctrl_flags flags = tx->flags; - u32 src_cnt = unmap->unmap_src_cnt; - dma_addr_t pdest = iop_desc_get_dest_addr(unmap, iop_chan); - dma_addr_t qdest = iop_desc_get_qdest_addr(unmap, iop_chan); - int i; - - if (tx->flags & DMA_PREP_CONTINUE) - src_cnt -= 3; - - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP) && !desc->pq_check_result) { - dma_unmap_page(dev, pdest, len, DMA_BIDIRECTIONAL); - dma_unmap_page(dev, qdest, len, DMA_BIDIRECTIONAL); - } - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - dma_addr_t addr; - - for (i = 0; i < src_cnt; i++) { - addr = iop_desc_get_src_addr(unmap, iop_chan, i); - dma_unmap_page(dev, addr, len, DMA_TO_DEVICE); - } - if (desc->pq_check_result) { - dma_unmap_page(dev, pdest, len, DMA_TO_DEVICE); - dma_unmap_page(dev, qdest, len, DMA_TO_DEVICE); - } - } - - desc->group_head = NULL; -} - - static dma_cookie_t iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, struct iop_adma_chan *iop_chan, dma_cookie_t cookie) @@ -153,15 +79,8 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, tx->callback(tx->callback_param); dma_descriptor_unmap(tx); - /* unmap dma addresses - * (unmap_single vs unmap_page?) - */ - if (desc->group_head && desc->unmap_len) { - if (iop_desc_is_pq(desc)) - iop_desc_unmap_pq(iop_chan, desc); - else - iop_desc_unmap(iop_chan, desc); - } + if (desc->group_head) + desc->group_head = NULL; } /* run dependent operations */ @@ -592,7 +511,6 @@ iop_adma_prep_dma_interrupt(struct dma_chan *chan, unsigned long flags) if (sw_desc) { grp_start = sw_desc->group_head; iop_desc_init_interrupt(grp_start, iop_chan); - grp_start->unmap_len = 0; sw_desc->async_tx.flags = flags; } spin_unlock_bh(&iop_chan->lock); @@ -624,8 +542,6 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, iop_desc_set_byte_count(grp_start, iop_chan, len); iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); iop_desc_set_memcpy_src_addr(grp_start, dma_src); - sw_desc->unmap_src_cnt = 1; - sw_desc->unmap_len = len; sw_desc->async_tx.flags = flags; } spin_unlock_bh(&iop_chan->lock); @@ -658,8 +574,6 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest, iop_desc_init_xor(grp_start, src_cnt, flags); iop_desc_set_byte_count(grp_start, iop_chan, len); iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); - sw_desc->unmap_src_cnt = src_cnt; - sw_desc->unmap_len = len; sw_desc->async_tx.flags = flags; while (src_cnt--) iop_desc_set_xor_src_addr(grp_start, src_cnt, @@ -695,8 +609,6 @@ iop_adma_prep_dma_xor_val(struct dma_chan *chan, dma_addr_t *dma_src, grp_start->xor_check_result = result; pr_debug("\t%s: grp_start->xor_check_result: %p\n", __func__, grp_start->xor_check_result); - sw_desc->unmap_src_cnt = src_cnt; - sw_desc->unmap_len = len; sw_desc->async_tx.flags = flags; while (src_cnt--) iop_desc_set_zero_sum_src_addr(grp_start, src_cnt, @@ -749,8 +661,6 @@ iop_adma_prep_dma_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, dst[0] = dst[1] & 0x7; iop_desc_set_pq_addr(g, dst); - sw_desc->unmap_src_cnt = src_cnt; - sw_desc->unmap_len = len; sw_desc->async_tx.flags = flags; for (i = 0; i < src_cnt; i++) iop_desc_set_pq_src_addr(g, i, src[i], scf[i]); @@ -805,8 +715,6 @@ iop_adma_prep_dma_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, g->pq_check_result = pqres; pr_debug("\t%s: g->pq_check_result: %p\n", __func__, g->pq_check_result); - sw_desc->unmap_src_cnt = src_cnt+2; - sw_desc->unmap_len = len; sw_desc->async_tx.flags = flags; while (src_cnt--) iop_desc_set_pq_zero_sum_src_addr(g, src_cnt, diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index ed1ab1d0875..17326e780e2 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -60,14 +60,6 @@ static u32 mv_desc_get_dest_addr(struct mv_xor_desc_slot *desc) return hw_desc->phy_dest_addr; } -static u32 mv_desc_get_src_addr(struct mv_xor_desc_slot *desc, - int src_idx) -{ - struct mv_xor_desc *hw_desc = desc->hw_desc; - return hw_desc->phy_src_addr[mv_phy_src_idx(src_idx)]; -} - - static void mv_desc_set_byte_count(struct mv_xor_desc_slot *desc, u32 byte_count) { @@ -279,42 +271,8 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc, desc->async_tx.callback_param); dma_descriptor_unmap(&desc->async_tx); - /* unmap dma addresses - * (unmap_single vs unmap_page?) - */ - if (desc->group_head && desc->unmap_len) { - struct mv_xor_desc_slot *unmap = desc->group_head; - struct device *dev = mv_chan_to_devp(mv_chan); - u32 len = unmap->unmap_len; - enum dma_ctrl_flags flags = desc->async_tx.flags; - u32 src_cnt; - dma_addr_t addr; - dma_addr_t dest; - - src_cnt = unmap->unmap_src_cnt; - dest = mv_desc_get_dest_addr(unmap); - if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - enum dma_data_direction dir; - - if (src_cnt > 1) /* is xor ? */ - dir = DMA_BIDIRECTIONAL; - else - dir = DMA_FROM_DEVICE; - dma_unmap_page(dev, dest, len, dir); - } - - if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - while (src_cnt--) { - addr = mv_desc_get_src_addr(unmap, - src_cnt); - if (addr == dest) - continue; - dma_unmap_page(dev, addr, len, - DMA_TO_DEVICE); - } - } + if (desc->group_head) desc->group_head = NULL; - } } /* run dependent operations */ diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 442492da741..429be432ab7 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -801,218 +801,6 @@ static void ppc440spe_desc_set_link(struct ppc440spe_adma_chan *chan, local_irq_restore(flags); } -/** - * ppc440spe_desc_get_src_addr - extract the source address from the descriptor - */ -static u32 ppc440spe_desc_get_src_addr(struct ppc440spe_adma_desc_slot *desc, - struct ppc440spe_adma_chan *chan, int src_idx) -{ - struct dma_cdb *dma_hw_desc; - struct xor_cb *xor_hw_desc; - - switch (chan->device->id) { - case PPC440SPE_DMA0_ID: - case PPC440SPE_DMA1_ID: - dma_hw_desc = desc->hw_desc; - /* May have 0, 1, 2, or 3 sources */ - switch (dma_hw_desc->opc) { - case DMA_CDB_OPC_NO_OP: - case DMA_CDB_OPC_DFILL128: - return 0; - case DMA_CDB_OPC_DCHECK128: - if (unlikely(src_idx)) { - printk(KERN_ERR "%s: try to get %d source for" - " DCHECK128\n", __func__, src_idx); - BUG(); - } - return le32_to_cpu(dma_hw_desc->sg1l); - case DMA_CDB_OPC_MULTICAST: - case DMA_CDB_OPC_MV_SG1_SG2: - if (unlikely(src_idx > 2)) { - printk(KERN_ERR "%s: try to get %d source from" - " DMA descr\n", __func__, src_idx); - BUG(); - } - if (src_idx) { - if (le32_to_cpu(dma_hw_desc->sg1u) & - DMA_CUED_XOR_WIN_MSK) { - u8 region; - - if (src_idx == 1) - return le32_to_cpu( - dma_hw_desc->sg1l) + - desc->unmap_len; - - region = (le32_to_cpu( - dma_hw_desc->sg1u)) >> - DMA_CUED_REGION_OFF; - - region &= DMA_CUED_REGION_MSK; - switch (region) { - case DMA_RXOR123: - return le32_to_cpu( - dma_hw_desc->sg1l) + - (desc->unmap_len << 1); - case DMA_RXOR124: - return le32_to_cpu( - dma_hw_desc->sg1l) + - (desc->unmap_len * 3); - case DMA_RXOR125: - return le32_to_cpu( - dma_hw_desc->sg1l) + - (desc->unmap_len << 2); - default: - printk(KERN_ERR - "%s: try to" - " get src3 for region %02x" - "PPC440SPE_DESC_RXOR12?\n", - __func__, region); - BUG(); - } - } else { - printk(KERN_ERR - "%s: try to get %d" - " source for non-cued descr\n", - __func__, src_idx); - BUG(); - } - } - return le32_to_cpu(dma_hw_desc->sg1l); - default: - printk(KERN_ERR "%s: unknown OPC 0x%02x\n", - __func__, dma_hw_desc->opc); - BUG(); - } - return le32_to_cpu(dma_hw_desc->sg1l); - case PPC440SPE_XOR_ID: - /* May have up to 16 sources */ - xor_hw_desc = desc->hw_desc; - return xor_hw_desc->ops[src_idx].l; - } - return 0; -} - -/** - * ppc440spe_desc_get_dest_addr - extract the destination address from the - * descriptor - */ -static u32 ppc440spe_desc_get_dest_addr(struct ppc440spe_adma_desc_slot *desc, - struct ppc440spe_adma_chan *chan, int idx) -{ - struct dma_cdb *dma_hw_desc; - struct xor_cb *xor_hw_desc; - - switch (chan->device->id) { - case PPC440SPE_DMA0_ID: - case PPC440SPE_DMA1_ID: - dma_hw_desc = desc->hw_desc; - - if (likely(!idx)) - return le32_to_cpu(dma_hw_desc->sg2l); - return le32_to_cpu(dma_hw_desc->sg3l); - case PPC440SPE_XOR_ID: - xor_hw_desc = desc->hw_desc; - return xor_hw_desc->cbtal; - } - return 0; -} - -/** - * ppc440spe_desc_get_src_num - extract the number of source addresses from - * the descriptor - */ -static u32 ppc440spe_desc_get_src_num(struct ppc440spe_adma_desc_slot *desc, - struct ppc440spe_adma_chan *chan) -{ - struct dma_cdb *dma_hw_desc; - struct xor_cb *xor_hw_desc; - - switch (chan->device->id) { - case PPC440SPE_DMA0_ID: - case PPC440SPE_DMA1_ID: - dma_hw_desc = desc->hw_desc; - - switch (dma_hw_desc->opc) { - case DMA_CDB_OPC_NO_OP: - case DMA_CDB_OPC_DFILL128: - return 0; - case DMA_CDB_OPC_DCHECK128: - return 1; - case DMA_CDB_OPC_MV_SG1_SG2: - case DMA_CDB_OPC_MULTICAST: - /* - * Only for RXOR operations we have more than - * one source - */ - if (le32_to_cpu(dma_hw_desc->sg1u) & - DMA_CUED_XOR_WIN_MSK) { - /* RXOR op, there are 2 or 3 sources */ - if (((le32_to_cpu(dma_hw_desc->sg1u) >> - DMA_CUED_REGION_OFF) & - DMA_CUED_REGION_MSK) == DMA_RXOR12) { - /* RXOR 1-2 */ - return 2; - } else { - /* RXOR 1-2-3/1-2-4/1-2-5 */ - return 3; - } - } - return 1; - default: - printk(KERN_ERR "%s: unknown OPC 0x%02x\n", - __func__, dma_hw_desc->opc); - BUG(); - } - case PPC440SPE_XOR_ID: - /* up to 16 sources */ - xor_hw_desc = desc->hw_desc; - return xor_hw_desc->cbc & XOR_CDCR_OAC_MSK; - default: - BUG(); - } - return 0; -} - -/** - * ppc440spe_desc_get_dst_num - get the number of destination addresses in - * this descriptor - */ -static u32 ppc440spe_desc_get_dst_num(struct ppc440spe_adma_desc_slot *desc, - struct ppc440spe_adma_chan *chan) -{ - struct dma_cdb *dma_hw_desc; - - switch (chan->device->id) { - case PPC440SPE_DMA0_ID: - case PPC440SPE_DMA1_ID: - /* May be 1 or 2 destinations */ - dma_hw_desc = desc->hw_desc; - switch (dma_hw_desc->opc) { - case DMA_CDB_OPC_NO_OP: - case DMA_CDB_OPC_DCHECK128: - return 0; - case DMA_CDB_OPC_MV_SG1_SG2: - case DMA_CDB_OPC_DFILL128: - return 1; - case DMA_CDB_OPC_MULTICAST: - if (desc->dst_cnt == 2) - return 2; - else - return 1; - default: - printk(KERN_ERR "%s: unknown OPC 0x%02x\n", - __func__, dma_hw_desc->opc); - BUG(); - } - case PPC440SPE_XOR_ID: - /* Always only 1 destination */ - return 1; - default: - BUG(); - } - return 0; -} - /** * ppc440spe_desc_get_link - get the address of the descriptor that * follows this one @@ -1705,43 +1493,6 @@ static void ppc440spe_adma_free_slots(struct ppc440spe_adma_desc_slot *slot, } } -static void ppc440spe_adma_unmap(struct ppc440spe_adma_chan *chan, - struct ppc440spe_adma_desc_slot *desc) -{ - u32 src_cnt, dst_cnt; - dma_addr_t addr; - - /* - * get the number of sources & destination - * included in this descriptor and unmap - * them all - */ - src_cnt = ppc440spe_desc_get_src_num(desc, chan); - dst_cnt = ppc440spe_desc_get_dst_num(desc, chan); - - /* unmap destinations */ - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - while (dst_cnt--) { - addr = ppc440spe_desc_get_dest_addr( - desc, chan, dst_cnt); - dma_unmap_page(chan->device->dev, - addr, desc->unmap_len, - DMA_FROM_DEVICE); - } - } - - /* unmap sources */ - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - while (src_cnt--) { - addr = ppc440spe_desc_get_src_addr( - desc, chan, src_cnt); - dma_unmap_page(chan->device->dev, - addr, desc->unmap_len, - DMA_TO_DEVICE); - } - } -} - /** * ppc440spe_adma_run_tx_complete_actions - call functions to be called * upon completion @@ -1766,26 +1517,6 @@ static dma_cookie_t ppc440spe_adma_run_tx_complete_actions( desc->async_tx.callback_param); dma_descriptor_unmap(&desc->async_tx); - /* unmap dma addresses - * (unmap_single vs unmap_page?) - * - * actually, ppc's dma_unmap_page() functions are empty, so - * the following code is just for the sake of completeness - */ - if (chan && chan->needs_unmap && desc->group_head && - desc->unmap_len) { - struct ppc440spe_adma_desc_slot *unmap = - desc->group_head; - /* assume 1 slot per op always */ - u32 slot_count = unmap->slot_cnt; - - /* Run through the group list and unmap addresses */ - for (i = 0; i < slot_count; i++) { - BUG_ON(!unmap); - ppc440spe_adma_unmap(chan, unmap); - unmap = unmap->hw_next; - } - } } /* run dependent operations */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 1d0c9883908..4506a7b4f97 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -154,38 +154,6 @@ static bool __td_dma_done_ack(struct timb_dma_chan *td_chan) return done; } -static void __td_unmap_desc(struct timb_dma_chan *td_chan, const u8 *dma_desc, - bool single) -{ - dma_addr_t addr; - int len; - - addr = (dma_desc[7] << 24) | (dma_desc[6] << 16) | (dma_desc[5] << 8) | - dma_desc[4]; - - len = (dma_desc[3] << 8) | dma_desc[2]; - - if (single) - dma_unmap_single(chan2dev(&td_chan->chan), addr, len, - DMA_TO_DEVICE); - else - dma_unmap_page(chan2dev(&td_chan->chan), addr, len, - DMA_TO_DEVICE); -} - -static void __td_unmap_descs(struct timb_dma_desc *td_desc, bool single) -{ - struct timb_dma_chan *td_chan = container_of(td_desc->txd.chan, - struct timb_dma_chan, chan); - u8 *descs; - - for (descs = td_desc->desc_list; ; descs += TIMB_DMA_DESC_SIZE) { - __td_unmap_desc(td_chan, descs, single); - if (descs[0] & 0x02) - break; - } -} - static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, struct scatterlist *sg, bool last) { @@ -294,10 +262,6 @@ static void __td_finish(struct timb_dma_chan *td_chan) list_move(&td_desc->desc_node, &td_chan->free_list); dma_descriptor_unmap(txd); - if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) - __td_unmap_descs(td_desc, - txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE); - /* * The API requires that no submissions are done from a * callback, so we don't need to drop the lock here diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 22a0b6c78c7..6f272987401 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -420,30 +420,6 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc, list_move(&desc->desc_node, &dc->free_list); dma_descriptor_unmap(txd); - if (!ds) { - dma_addr_t dmaaddr; - if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { - dmaaddr = is_dmac64(dc) ? - desc->hwdesc.DAR : desc->hwdesc32.DAR; - if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) - dma_unmap_single(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_FROM_DEVICE); - else - dma_unmap_page(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_FROM_DEVICE); - } - if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { - dmaaddr = is_dmac64(dc) ? - desc->hwdesc.SAR : desc->hwdesc32.SAR; - if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) - dma_unmap_single(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_TO_DEVICE); - else - dma_unmap_page(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_TO_DEVICE); - } - } - /* * The API requires that no submissions are done from a * callback, so we don't need to drop the lock here -- cgit v1.2.3-70-g09d2 From 7b1998116bbb2f3e5dd6cb9a8ee6db479b0b50a9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 11 Nov 2013 22:41:56 +0100 Subject: ACPI / driver core: Store an ACPI device pointer in struct acpi_dev_node Modify struct acpi_dev_node to contain a pointer to struct acpi_device associated with the given device object (that is, its ACPI companion device) instead of an ACPI handle corresponding to it. Introduce two new macros for manipulating that pointer in a CONFIG_ACPI-safe way, ACPI_COMPANION() and ACPI_COMPANION_SET(), and rework the ACPI_HANDLE() macro to take the above changes into account. Drop the ACPI_HANDLE_SET() macro entirely and rework its users to use ACPI_COMPANION_SET() instead. For some of them who used to pass the result of acpi_get_child() directly to ACPI_HANDLE_SET() introduce a helper routine acpi_preset_companion() doing an equivalent thing. The main motivation for doing this is that there are things represented by struct acpi_device objects that don't have valid ACPI handles (so called fixed ACPI hardware features, such as power and sleep buttons) and we would like to create platform device objects for them and "glue" them to their ACPI companions in the usual way (which currently is impossible due to the lack of valid ACPI handles). However, there are more reasons why it may be useful. First, struct acpi_device pointers allow of much better type checking than void pointers which are ACPI handles, so it should be more difficult to write buggy code using modified struct acpi_dev_node and the new macros. Second, the change should help to reduce (over time) the number of places in which the result of ACPI_HANDLE() is passed to acpi_bus_get_device() in order to obtain a pointer to the struct acpi_device associated with the given "physical" device, because now that pointer is returned by ACPI_COMPANION() directly. Finally, the change should make it easier to write generic code that will build both for CONFIG_ACPI set and unset without adding explicit compiler directives to it. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Tested-by: Mika Westerberg # on Haswell Reviewed-by: Mika Westerberg Reviewed-by: Aaron Lu # for ATA and SDIO part --- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/ia64/include/asm/pci.h | 2 +- arch/ia64/pci/pci.c | 6 ++-- arch/ia64/sn/kernel/io_acpi_init.c | 4 +-- arch/x86/include/asm/pci.h | 2 +- arch/x86/pci/acpi.c | 4 +-- drivers/acpi/acpi_platform.c | 2 +- drivers/acpi/device_pm.c | 6 +--- drivers/acpi/glue.c | 47 ++++++++++++++-------------- drivers/ata/libata-acpi.c | 4 +-- drivers/base/platform.c | 4 +-- drivers/gpio/gpiolib.c | 1 + drivers/gpu/drm/radeon/radeon_atpx_handler.c | 3 +- drivers/hid/i2c-hid/i2c-hid.c | 2 +- drivers/i2c/i2c-core.c | 4 +-- drivers/ide/ide-acpi.c | 3 +- drivers/mmc/core/sdio_bus.c | 3 +- drivers/pci/hotplug/sgi_hotplug.c | 8 ++--- drivers/spi/spi.c | 2 +- include/acpi/acpi_bus.h | 2 +- include/linux/acpi.h | 15 +++++++++ include/linux/device.h | 12 ++----- 22 files changed, 70 insertions(+), 68 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index d43daf192b2..4c530a82fc4 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1992,7 +1992,7 @@ sba_connect_bus(struct pci_bus *bus) if (PCI_CONTROLLER(bus)->iommu) return; - handle = PCI_CONTROLLER(bus)->acpi_handle; + handle = acpi_device_handle(PCI_CONTROLLER(bus)->companion); if (!handle) return; diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 80775f55f03..71fbaaa495c 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -95,7 +95,7 @@ struct iospace_resource { }; struct pci_controller { - void *acpi_handle; + struct acpi_device *companion; void *iommu; int segment; int node; /* nearest node with memory or -1 for global allocation */ diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 2326790b7d8..9e4938d8ca4 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -436,9 +436,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) if (!controller) return NULL; - controller->acpi_handle = device->handle; + controller->companion = device; - pxm = acpi_get_pxm(controller->acpi_handle); + pxm = acpi_get_pxm(device->handle); #ifdef CONFIG_NUMA if (pxm >= 0) controller->node = pxm_to_node(pxm); @@ -489,7 +489,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) { struct pci_controller *controller = bridge->bus->sysdata; - ACPI_HANDLE_SET(&bridge->dev, controller->acpi_handle); + ACPI_COMPANION_SET(&bridge->dev, controller->companion); return 0; } diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index b1725398b5a..0640739cc20 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -132,7 +132,7 @@ sn_get_bussoft_ptr(struct pci_bus *bus) struct acpi_resource_vendor_typed *vendor; - handle = PCI_CONTROLLER(bus)->acpi_handle; + handle = acpi_device_handle(PCI_CONTROLLER(bus)->companion); status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { @@ -360,7 +360,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, acpi_status status; struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - rootbus_handle = PCI_CONTROLLER(dev)->acpi_handle; + rootbus_handle = acpi_device_handle(PCI_CONTROLLER(dev)->companion); status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL, &segment); if (ACPI_SUCCESS(status)) { diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 7d7443283a9..947b5c417e8 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -15,7 +15,7 @@ struct pci_sysdata { int domain; /* PCI domain */ int node; /* NUMA node */ #ifdef CONFIG_ACPI - void *acpi; /* ACPI-specific data */ + struct acpi_device *companion; /* ACPI companion device */ #endif #ifdef CONFIG_X86_64 void *iommu; /* IOMMU private data */ diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 7fb24e53d4c..4f25ec07755 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -518,7 +518,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) sd = &info->sd; sd->domain = domain; sd->node = node; - sd->acpi = device->handle; + sd->companion = device; /* * Maybe the desired pci bus has been already scanned. In such case * it is unnecessary to scan the pci bus with the given domain,busnum. @@ -589,7 +589,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) { struct pci_sysdata *sd = bridge->bus->sysdata; - ACPI_HANDLE_SET(&bridge->dev, sd->acpi); + ACPI_COMPANION_SET(&bridge->dev, sd->companion); return 0; } diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 8a4cfc7e71f..dbfe49e5fd6 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -111,7 +111,7 @@ int acpi_create_platform_device(struct acpi_device *adev, pdevinfo.id = -1; pdevinfo.res = resources; pdevinfo.num_res = count; - pdevinfo.acpi_node.handle = adev->handle; + pdevinfo.acpi_node.companion = adev; pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) { dev_err(&adev->dev, "platform device creation failed: %ld\n", diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index d42b2fb5a7e..119afda0968 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -22,16 +22,12 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#include +#include #include #include #include #include -#include -#include -#include - #include "internal.h" #define _COMPONENT ACPI_POWER_COMPONENT diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f0f40587b..782071fd3df 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -197,30 +197,27 @@ static void acpi_physnode_link_name(char *buf, unsigned int node_id) int acpi_bind_one(struct device *dev, acpi_handle handle) { - struct acpi_device *acpi_dev; - acpi_status status; + struct acpi_device *acpi_dev = NULL; struct acpi_device_physical_node *physical_node, *pn; char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; struct list_head *physnode_list; unsigned int node_id; int retval = -EINVAL; - if (ACPI_HANDLE(dev)) { + if (ACPI_COMPANION(dev)) { if (handle) { - dev_warn(dev, "ACPI handle is already set\n"); + dev_warn(dev, "ACPI companion already set\n"); return -EINVAL; } else { - handle = ACPI_HANDLE(dev); + acpi_dev = ACPI_COMPANION(dev); } + } else { + acpi_bus_get_device(handle, &acpi_dev); } - if (!handle) + if (!acpi_dev) return -EINVAL; get_device(dev); - status = acpi_bus_get_device(handle, &acpi_dev); - if (ACPI_FAILURE(status)) - goto err; - physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); if (!physical_node) { retval = -ENOMEM; @@ -242,7 +239,7 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) dev_warn(dev, "Already associated with ACPI node\n"); kfree(physical_node); - if (ACPI_HANDLE(dev) != handle) + if (ACPI_COMPANION(dev) != acpi_dev) goto err; put_device(dev); @@ -259,8 +256,8 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) list_add(&physical_node->node, physnode_list); acpi_dev->physical_node_count++; - if (!ACPI_HANDLE(dev)) - ACPI_HANDLE_SET(dev, acpi_dev->handle); + if (!ACPI_COMPANION(dev)) + ACPI_COMPANION_SET(dev, acpi_dev); acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, @@ -283,7 +280,7 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) return 0; err: - ACPI_HANDLE_SET(dev, NULL); + ACPI_COMPANION_SET(dev, NULL); put_device(dev); return retval; } @@ -291,19 +288,12 @@ EXPORT_SYMBOL_GPL(acpi_bind_one); int acpi_unbind_one(struct device *dev) { + struct acpi_device *acpi_dev = ACPI_COMPANION(dev); struct acpi_device_physical_node *entry; - struct acpi_device *acpi_dev; - acpi_status status; - if (!ACPI_HANDLE(dev)) + if (!acpi_dev) return 0; - status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); - if (ACPI_FAILURE(status)) { - dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__); - return -EINVAL; - } - mutex_lock(&acpi_dev->physical_node_lock); list_for_each_entry(entry, &acpi_dev->physical_node_list, node) @@ -316,7 +306,7 @@ int acpi_unbind_one(struct device *dev) acpi_physnode_link_name(physnode_name, entry->node_id); sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); sysfs_remove_link(&dev->kobj, "firmware_node"); - ACPI_HANDLE_SET(dev, NULL); + ACPI_COMPANION_SET(dev, NULL); /* acpi_bind_one() increase refcnt by one. */ put_device(dev); kfree(entry); @@ -328,6 +318,15 @@ int acpi_unbind_one(struct device *dev) } EXPORT_SYMBOL_GPL(acpi_unbind_one); +void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr) +{ + struct acpi_device *adev; + + if (!acpi_bus_get_device(acpi_get_child(parent, addr), &adev)) + ACPI_COMPANION_SET(dev, adev); +} +EXPORT_SYMBOL_GPL(acpi_preset_companion); + static int acpi_platform_notify(struct device *dev) { struct acpi_bus_type *type = acpi_get_bus_type(dev); diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index ab714d2ad97..4372cfa883c 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -185,7 +185,7 @@ void ata_acpi_bind_port(struct ata_port *ap) if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle) return; - ACPI_HANDLE_SET(&ap->tdev, acpi_get_child(host_handle, ap->port_no)); + acpi_preset_companion(&ap->tdev, host_handle, ap->port_no); if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; @@ -222,7 +222,7 @@ void ata_acpi_bind_dev(struct ata_device *dev) parent_handle = port_handle; } - ACPI_HANDLE_SET(&dev->tdev, acpi_get_child(parent_handle, adr)); + acpi_preset_companion(&dev->tdev, parent_handle, adr); register_hotplug_dock_device(ata_dev_acpi_handle(dev), &ata_acpi_dev_dock_ops, dev, NULL, NULL); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 47051cd2511..3a94b799f16 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -432,7 +432,7 @@ struct platform_device *platform_device_register_full( goto err_alloc; pdev->dev.parent = pdevinfo->parent; - ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle); + ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); if (pdevinfo->dma_mask) { /* @@ -463,7 +463,7 @@ struct platform_device *platform_device_register_full( ret = platform_device_add(pdev); if (ret) { err: - ACPI_HANDLE_SET(&pdev->dev, NULL); + ACPI_COMPANION_SET(&pdev->dev, NULL); kfree(pdev->dev.dma_mask); err_alloc: diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7dd44615029..4e10b10d3dd 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -13,6 +13,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index d96070bf838..27a6e9dbd0c 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -8,8 +8,7 @@ */ #include #include -#include -#include +#include #include #include "radeon_acpi.h" diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index fd7ce374f81..b7ecc3623a4 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1012,7 +1012,7 @@ static int i2c_hid_probe(struct i2c_client *client, hid->hid_get_raw_report = i2c_hid_get_raw_report; hid->hid_output_raw_report = i2c_hid_output_raw_report; hid->dev.parent = &client->dev; - ACPI_HANDLE_SET(&hid->dev, ACPI_HANDLE(&client->dev)); + ACPI_COMPANION_SET(&hid->dev, ACPI_COMPANION(&client->dev)); hid->bus = BUS_I2C; hid->version = le16_to_cpu(ihid->hdesc.bcdVersion); hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 75ba8608383..f74af33f5dd 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -674,7 +674,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.bus = &i2c_bus_type; client->dev.type = &i2c_client_type; client->dev.of_node = info->of_node; - ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle); + ACPI_COMPANION_SET(&client->dev, info->acpi_node.companion); /* For 10-bit clients, add an arbitrary offset to avoid collisions */ dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), @@ -1103,7 +1103,7 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, return AE_OK; memset(&info, 0, sizeof(info)); - info.acpi_node.handle = handle; + info.acpi_node.companion = adev; info.irq = -1; INIT_LIST_HEAD(&resource_list); diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 140c8ef5052..3662c4c536d 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -7,6 +7,7 @@ * Copyright (C) 2006 Hannes Reinecke */ +#include #include #include #include @@ -19,8 +20,6 @@ #include #include -#include - #define REGS_PER_GTF 7 struct GTM_buffer { diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index ef8956568c3..157b570ba34 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -308,8 +308,7 @@ static void sdio_acpi_set_handle(struct sdio_func *func) struct mmc_host *host = func->card->host; u64 addr = (host->slotno << 16) | func->num; - ACPI_HANDLE_SET(&func->dev, - acpi_get_child(ACPI_HANDLE(host->parent), addr)); + acpi_preset_companion(&func->dev, ACPI_HANDLE(host->parent), addr); } #else static inline void sdio_acpi_set_handle(struct sdio_func *func) {} diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index b2781dfe60e..5b05a68cca6 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -9,6 +9,7 @@ * Work to add BIOS PROM support was completed by Mike Habeck. */ +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include "../pci.h" @@ -414,7 +414,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) acpi_handle rethandle; acpi_status ret; - phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; + phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion); if (acpi_bus_get_device(phandle, &pdevice)) { dev_dbg(&slot->pci_bus->self->dev, @@ -495,7 +495,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) /* free the ACPI resources for the slot */ if (SN_ACPI_BASE_SUPPORT() && - PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { + PCI_CONTROLLER(slot->pci_bus)->companion) { unsigned long long adr; struct acpi_device *device; acpi_handle phandle; @@ -504,7 +504,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) acpi_status ret; /* Get the rootbus node pointer */ - phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; + phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion); acpi_scan_lock_acquire(); /* diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 927998aa5e7..a968d8549ee 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1144,7 +1144,7 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, return AE_NO_MEMORY; } - ACPI_HANDLE_SET(&spi->dev, handle); + ACPI_COMPANION_SET(&spi->dev, adev); spi->irq = -1; INIT_LIST_HEAD(&resource_list); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 89c60b0f640..7b2de026a4f 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -431,9 +431,9 @@ static inline acpi_handle acpi_get_child(acpi_handle handle, u64 addr) { return acpi_find_child(handle, addr, false); } +void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr); int acpi_is_root_bridge(acpi_handle); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); -#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b0972c4ce81..47369aadb1d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -44,6 +44,15 @@ #include #include +static inline acpi_handle acpi_device_handle(struct acpi_device *adev) +{ + return adev ? adev->handle : NULL; +} + +#define ACPI_COMPANION(dev) ((dev)->acpi_node.companion) +#define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) +#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) + enum acpi_irq_model_id { ACPI_IRQ_MODEL_PIC = 0, ACPI_IRQ_MODEL_IOAPIC, @@ -401,6 +410,10 @@ static inline bool acpi_driver_match_device(struct device *dev, #define acpi_disabled 1 +#define ACPI_COMPANION(dev) (NULL) +#define ACPI_COMPANION_SET(dev, adev) do { } while (0) +#define ACPI_HANDLE(dev) (NULL) + static inline void acpi_early_init(void) { } static inline int early_acpi_boot_init(void) @@ -469,6 +482,8 @@ static inline bool acpi_driver_match_device(struct device *dev, #endif /* !CONFIG_ACPI */ +#define DEVICE_ACPI_HANDLE(dev) ACPI_HANDLE(dev) + #ifdef CONFIG_ACPI void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, u32 pm1a_ctrl, u32 pm1b_ctrl)); diff --git a/include/linux/device.h b/include/linux/device.h index b025925df7f..952b01033c3 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -644,9 +644,11 @@ struct device_dma_parameters { unsigned long segment_boundary_mask; }; +struct acpi_device; + struct acpi_dev_node { #ifdef CONFIG_ACPI - void *handle; + struct acpi_device *companion; #endif }; @@ -790,14 +792,6 @@ static inline struct device *kobj_to_dev(struct kobject *kobj) return container_of(kobj, struct device, kobj); } -#ifdef CONFIG_ACPI -#define ACPI_HANDLE(dev) ((dev)->acpi_node.handle) -#define ACPI_HANDLE_SET(dev, _handle_) (dev)->acpi_node.handle = (_handle_) -#else -#define ACPI_HANDLE(dev) (NULL) -#define ACPI_HANDLE_SET(dev, _handle_) do { } while (0) -#endif - /* Get the wakeup routines, which depend on struct device */ #include -- cgit v1.2.3-70-g09d2 From fd4446f25e402fb186a6b7ec7a374aa8925ed708 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 14 Nov 2013 15:25:09 -0800 Subject: ARM: OMAP2+: Fix GPMC and simplify bootloader timings for 8250 and smc91x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit f2bf0e72d000 (ARM: OMAP2+: Add minimal 8250 support for GPMC) added support for using bootloader timings for some devices. Turns out we can do the same by looking at the compatible flags of the child without adding a new function as smc91x has a similar issue as 8250 with the bootloader timings. And let's fix the 8250 naming, we should use the device type as the name like uart instead of 8250 for zoom dts file. Cc: "Benoît Cousson" Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap-zoom-common.dtsi | 2 +- arch/arm/mach-omap2/gpmc.c | 58 +++++++++++---------------------- 2 files changed, 20 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi index b0ee342598f..68221fab978 100644 --- a/arch/arm/boot/dts/omap-zoom-common.dtsi +++ b/arch/arm/boot/dts/omap-zoom-common.dtsi @@ -13,7 +13,7 @@ * they probably share the same GPIO IRQ * REVISIT: Add timing support from slls644g.pdf */ - 8250@3,0 { + uart@3,0 { compatible = "ns16550a"; reg = <3 0 0x100>; bank-width = <2>; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 51525faa0ae..e09e5ba76a8 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1481,6 +1481,22 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, return ret; } + /* + * For some GPMC devices we still need to rely on the bootloader + * timings because the devices can be connected via FPGA. So far + * the list is smc91x on the omap2 SDP boards, and 8250 on zooms. + * REVISIT: Add timing support from slls644g.pdf and from the + * lan91c96 manual. + */ + if (of_device_is_compatible(child, "ns16550a") || + of_device_is_compatible(child, "smsc,lan91c94") || + of_device_is_compatible(child, "smsc,lan91c111")) { + dev_warn(&pdev->dev, + "%s using bootloader timings on CS%d\n", + child->name, cs); + goto no_timings; + } + /* * FIXME: gpmc_cs_request() will map the CS to an arbitary * location in the gpmc address space. When booting with @@ -1509,6 +1525,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, gpmc_read_timings_dt(child, &gpmc_t); gpmc_cs_set_timings(cs, &gpmc_t); +no_timings: if (of_platform_device_create(child, NULL, &pdev->dev)) return 0; @@ -1521,42 +1538,6 @@ err: return ret; } -/* - * REVISIT: Add timing support from slls644g.pdf - */ -static int gpmc_probe_8250(struct platform_device *pdev, - struct device_node *child) -{ - struct resource res; - unsigned long base; - int ret, cs; - - if (of_property_read_u32(child, "reg", &cs) < 0) { - dev_err(&pdev->dev, "%s has no 'reg' property\n", - child->full_name); - return -ENODEV; - } - - if (of_address_to_resource(child, 0, &res) < 0) { - dev_err(&pdev->dev, "%s has malformed 'reg' property\n", - child->full_name); - return -ENODEV; - } - - ret = gpmc_cs_request(cs, resource_size(&res), &base); - if (ret < 0) { - dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); - return ret; - } - - if (of_platform_device_create(child, NULL, &pdev->dev)) - return 0; - - dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); - - return -ENODEV; -} - static int gpmc_probe_dt(struct platform_device *pdev) { int ret; @@ -1598,10 +1579,9 @@ static int gpmc_probe_dt(struct platform_device *pdev) else if (of_node_cmp(child->name, "onenand") == 0) ret = gpmc_probe_onenand_child(pdev, child); else if (of_node_cmp(child->name, "ethernet") == 0 || - of_node_cmp(child->name, "nor") == 0) + of_node_cmp(child->name, "nor") == 0 || + of_node_cmp(child->name, "uart") == 0) ret = gpmc_probe_generic_child(pdev, child); - else if (of_node_cmp(child->name, "8250") == 0) - ret = gpmc_probe_8250(pdev, child); if (WARN(ret < 0, "%s: probing gpmc child %s failed\n", __func__, child->full_name)) -- cgit v1.2.3-70-g09d2 From 467f4bd2606d3ba7930cdcb489e7cb84d8589a39 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 14 Nov 2013 15:25:09 -0800 Subject: ARM: dts: Fix omap2 specific dtsi files by adding the missing entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like we're missing few entries for omap2 and the drivers have only worked because of the omap hwmod building the devices for the missing entries. Let's fix the missing entries so we don't need to rely on hwmod for the basic data and can then later on remove the duplicate data from hwmod. Otherwise device tree only drivers will not work properly. Cc: "Benoît Cousson" Cc: devicetree@vger.kernel.org Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap2.dtsi | 96 +++++++++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/omap2420.dtsi | 23 ++++++++++ arch/arm/boot/dts/omap2430.dtsi | 49 +++++++++++++++++++++ 3 files changed, 168 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index a2bfcde858a..d0c5b37e248 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -9,6 +9,7 @@ */ #include +#include #include #include "skeleton.dtsi" @@ -21,6 +22,8 @@ serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; + i2c0 = &i2c1; + i2c1 = &i2c2; }; cpus { @@ -53,6 +56,28 @@ ranges; ti,hwmods = "l3_main"; + aes: aes@480a6000 { + compatible = "ti,omap2-aes"; + ti,hwmods = "aes"; + reg = <0x480a6000 0x50>; + dmas = <&sdma 9 &sdma 10>; + dma-names = "tx", "rx"; + }; + + hdq1w: 1w@480b2000 { + compatible = "ti,omap2420-1w"; + ti,hwmods = "hdq1w"; + reg = <0x480b2000 0x1000>; + interrupts = <58>; + }; + + mailbox: mailbox@48094000 { + compatible = "ti,omap2-mailbox"; + ti,hwmods = "mailbox"; + reg = <0x48094000 0x200>; + interrupts = <26>; + }; + intc: interrupt-controller@1 { compatible = "ti,omap2-intc"; interrupt-controller; @@ -63,6 +88,7 @@ sdma: dma-controller@48056000 { compatible = "ti,omap2430-sdma", "ti,omap2420-sdma"; + ti,hwmods = "dma"; reg = <0x48056000 0x1000>; interrupts = <12>, <13>, @@ -73,21 +99,91 @@ #dma-requests = <64>; }; + i2c1: i2c@48070000 { + compatible = "ti,omap2-i2c"; + ti,hwmods = "i2c1"; + reg = <0x48070000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <56>; + dmas = <&sdma 27 &sdma 28>; + dma-names = "tx", "rx"; + }; + + i2c2: i2c@48072000 { + compatible = "ti,omap2-i2c"; + ti,hwmods = "i2c2"; + reg = <0x48072000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <57>; + dmas = <&sdma 29 &sdma 30>; + dma-names = "tx", "rx"; + }; + + mcspi1: mcspi@48098000 { + compatible = "ti,omap2-mcspi"; + ti,hwmods = "mcspi1"; + reg = <0x48098000 0x100>; + interrupts = <65>; + dmas = <&sdma 35 &sdma 36 &sdma 37 &sdma 38 + &sdma 39 &sdma 40 &sdma 41 &sdma 42>; + dma-names = "tx0", "rx0", "tx1", "rx1", + "tx2", "rx2", "tx3", "rx3"; + }; + + mcspi2: mcspi@4809a000 { + compatible = "ti,omap2-mcspi"; + ti,hwmods = "mcspi2"; + reg = <0x4809a000 0x100>; + interrupts = <66>; + dmas = <&sdma 43 &sdma 44 &sdma 45 &sdma 46>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + }; + + rng: rng@480a0000 { + compatible = "ti,omap2-rng"; + ti,hwmods = "rng"; + reg = <0x480a0000 0x50>; + interrupts = <36>; + }; + + sham: sham@480a4000 { + compatible = "ti,omap2-sham"; + ti,hwmods = "sham"; + reg = <0x480a4000 0x64>; + interrupts = <51>; + dmas = <&sdma 13>; + dma-names = "rx"; + }; + uart1: serial@4806a000 { compatible = "ti,omap2-uart"; ti,hwmods = "uart1"; + reg = <0x4806a000 0x2000>; + interrupts = <72>; + dmas = <&sdma 49 &sdma 50>; + dma-names = "tx", "rx"; clock-frequency = <48000000>; }; uart2: serial@4806c000 { compatible = "ti,omap2-uart"; ti,hwmods = "uart2"; + reg = <0x4806c000 0x400>; + interrupts = <73>; + dmas = <&sdma 51 &sdma 52>; + dma-names = "tx", "rx"; clock-frequency = <48000000>; }; uart3: serial@4806e000 { compatible = "ti,omap2-uart"; ti,hwmods = "uart3"; + reg = <0x4806e000 0x400>; + interrupts = <74>; + dmas = <&sdma 53 &sdma 54>; + dma-names = "tx", "rx"; clock-frequency = <48000000>; }; diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi index c8f9c55169e..60c605de22d 100644 --- a/arch/arm/boot/dts/omap2420.dtsi +++ b/arch/arm/boot/dts/omap2420.dtsi @@ -114,6 +114,15 @@ dma-names = "tx", "rx"; }; + msdi1: mmc@4809c000 { + compatible = "ti,omap2420-mmc"; + ti,hwmods = "msdi1"; + reg = <0x4809c000 0x80>; + interrupts = <83>; + dmas = <&sdma 61 &sdma 62>; + dma-names = "tx", "rx"; + }; + timer1: timer@48028000 { compatible = "ti,omap2420-timer"; reg = <0x48028000 0x400>; @@ -121,5 +130,19 @@ ti,hwmods = "timer1"; ti,timer-alwon; }; + + wd_timer2: wdt@48022000 { + compatible = "ti,omap2-wdt"; + ti,hwmods = "wd_timer2"; + reg = <0x48022000 0x80>; + }; }; }; + +&i2c1 { + compatible = "ti,omap2420-i2c"; +}; + +&i2c2 { + compatible = "ti,omap2420-i2c"; +}; diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi index c535a5a2b27..d624345666f 100644 --- a/arch/arm/boot/dts/omap2430.dtsi +++ b/arch/arm/boot/dts/omap2430.dtsi @@ -175,6 +175,25 @@ dma-names = "tx", "rx"; }; + mmc1: mmc@4809c000 { + compatible = "ti,omap2-hsmmc"; + reg = <0x4809c000 0x200>; + interrupts = <83>; + ti,hwmods = "mmc1"; + ti,dual-volt; + dmas = <&sdma 61>, <&sdma 62>; + dma-names = "tx", "rx"; + }; + + mmc2: mmc@480b4000 { + compatible = "ti,omap2-hsmmc"; + reg = <0x480b4000 0x200>; + interrupts = <86>; + ti,hwmods = "mmc2"; + dmas = <&sdma 47>, <&sdma 48>; + dma-names = "tx", "rx"; + }; + timer1: timer@49018000 { compatible = "ti,omap2420-timer"; reg = <0x49018000 0x400>; @@ -182,5 +201,35 @@ ti,hwmods = "timer1"; ti,timer-alwon; }; + + mcspi3: mcspi@480b8000 { + compatible = "ti,omap2-mcspi"; + ti,hwmods = "mcspi3"; + reg = <0x480b8000 0x100>; + interrupts = <91>; + dmas = <&sdma 15 &sdma 16 &sdma 23 &sdma 24>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + }; + + usb_otg_hs: usb_otg_hs@480ac000 { + compatible = "ti,omap2-musb"; + ti,hwmods = "usb_otg_hs"; + reg = <0x480ac000 0x1000>; + interrupts = <93>; + }; + + wd_timer2: wdt@49016000 { + compatible = "ti,omap2-wdt"; + ti,hwmods = "wd_timer2"; + reg = <0x49016000 0x80>; + }; }; }; + +&i2c1 { + compatible = "ti,omap2430-i2c"; +}; + +&i2c2 { + compatible = "ti,omap2430-i2c"; +}; -- cgit v1.2.3-70-g09d2 From b26d4cd385fc51e8844e2cdf9ba2051f5bba11a5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 25 Oct 2013 18:47:37 -0400 Subject: consolidate simple ->d_delete() instances Rename simple_delete_dentry() to always_delete_dentry() and export it. Export simple_dentry_operations, while we are at it, and get rid of their duplicates Signed-off-by: Al Viro --- arch/ia64/kernel/perfmon.c | 8 +------- fs/9p/vfs_dentry.c | 19 +------------------ fs/configfs/dir.c | 12 +----------- fs/efivarfs/super.c | 11 +---------- fs/hostfs/hostfs_kern.c | 11 +---------- fs/libfs.c | 12 +++++++----- fs/proc/generic.c | 18 +----------------- fs/proc/namespaces.c | 8 +------- include/linux/fs.h | 2 ++ kernel/cgroup.c | 7 +------ net/sunrpc/rpc_pipe.c | 11 +---------- 11 files changed, 18 insertions(+), 101 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 5a9ff1c3c3e..cb592773c78 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2166,12 +2166,6 @@ static const struct file_operations pfm_file_ops = { .flush = pfm_flush }; -static int -pfmfs_delete_dentry(const struct dentry *dentry) -{ - return 1; -} - static char *pfmfs_dname(struct dentry *dentry, char *buffer, int buflen) { return dynamic_dname(dentry, buffer, buflen, "pfm:[%lu]", @@ -2179,7 +2173,7 @@ static char *pfmfs_dname(struct dentry *dentry, char *buffer, int buflen) } static const struct dentry_operations pfmfs_dentry_operations = { - .d_delete = pfmfs_delete_dentry, + .d_delete = always_delete_dentry, .d_dname = pfmfs_dname, }; diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index f039b104a98..b03dd23feda 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -42,23 +42,6 @@ #include "v9fs_vfs.h" #include "fid.h" -/** - * v9fs_dentry_delete - called when dentry refcount equals 0 - * @dentry: dentry in question - * - * By returning 1 here we should remove cacheing of unused - * dentry components. - * - */ - -static int v9fs_dentry_delete(const struct dentry *dentry) -{ - p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n", - dentry->d_name.name, dentry); - - return 1; -} - /** * v9fs_cached_dentry_delete - called when dentry refcount equals 0 * @dentry: dentry in question @@ -134,6 +117,6 @@ const struct dentry_operations v9fs_cached_dentry_operations = { }; const struct dentry_operations v9fs_dentry_operations = { - .d_delete = v9fs_dentry_delete, + .d_delete = always_delete_dentry, .d_release = v9fs_dentry_release, }; diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 277bd1be21f..4522e075577 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -66,19 +66,9 @@ static void configfs_d_iput(struct dentry * dentry, iput(inode); } -/* - * We _must_ delete our dentries on last dput, as the chain-to-parent - * behavior is required to clear the parents of default_groups. - */ -static int configfs_d_delete(const struct dentry *dentry) -{ - return 1; -} - const struct dentry_operations configfs_dentry_ops = { .d_iput = configfs_d_iput, - /* simple_delete_dentry() isn't exported */ - .d_delete = configfs_d_delete, + .d_delete = always_delete_dentry, }; #ifdef CONFIG_LOCKDEP diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index a8766b880c0..becc725a195 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -83,19 +83,10 @@ static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr) return 0; } -/* - * Retaining negative dentries for an in-memory filesystem just wastes - * memory and lookup time: arrange for them to be deleted immediately. - */ -static int efivarfs_delete_dentry(const struct dentry *dentry) -{ - return 1; -} - static struct dentry_operations efivarfs_d_ops = { .d_compare = efivarfs_d_compare, .d_hash = efivarfs_d_hash, - .d_delete = efivarfs_delete_dentry, + .d_delete = always_delete_dentry, }; static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 25437280a20..db23ce1bd90 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -33,15 +33,6 @@ static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) #define FILE_HOSTFS_I(file) HOSTFS_I(file_inode(file)) -static int hostfs_d_delete(const struct dentry *dentry) -{ - return 1; -} - -static const struct dentry_operations hostfs_dentry_ops = { - .d_delete = hostfs_d_delete, -}; - /* Changed in hostfs_args before the kernel starts running */ static char *root_ino = ""; static int append = 0; @@ -925,7 +916,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) sb->s_blocksize_bits = 10; sb->s_magic = HOSTFS_SUPER_MAGIC; sb->s_op = &hostfs_sbops; - sb->s_d_op = &hostfs_dentry_ops; + sb->s_d_op = &simple_dentry_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; /* NULL is printed as by sprintf: avoid that. */ diff --git a/fs/libfs.c b/fs/libfs.c index 5de06947ba5..a1844244246 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -47,10 +47,16 @@ EXPORT_SYMBOL(simple_statfs); * Retaining negative dentries for an in-memory filesystem just wastes * memory and lookup time: arrange for them to be deleted immediately. */ -static int simple_delete_dentry(const struct dentry *dentry) +int always_delete_dentry(const struct dentry *dentry) { return 1; } +EXPORT_SYMBOL(always_delete_dentry); + +const struct dentry_operations simple_dentry_operations = { + .d_delete = always_delete_dentry, +}; +EXPORT_SYMBOL(simple_dentry_operations); /* * Lookup the data. This is trivial - if the dentry didn't already @@ -58,10 +64,6 @@ static int simple_delete_dentry(const struct dentry *dentry) */ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { - static const struct dentry_operations simple_dentry_operations = { - .d_delete = simple_delete_dentry, - }; - if (dentry->d_name.len > NAME_MAX) return ERR_PTR(-ENAMETOOLONG); if (!dentry->d_sb->s_d_op) diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 737e15615b0..cca93b6fb9a 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -174,22 +174,6 @@ static const struct inode_operations proc_link_inode_operations = { .follow_link = proc_follow_link, }; -/* - * As some entries in /proc are volatile, we want to - * get rid of unused dentries. This could be made - * smarter: we could keep a "volatile" flag in the - * inode to indicate which ones to keep. - */ -static int proc_delete_dentry(const struct dentry * dentry) -{ - return 1; -} - -static const struct dentry_operations proc_dentry_operations = -{ - .d_delete = proc_delete_dentry, -}; - /* * Don't create negative dentries here, return -ENOENT by hand * instead. @@ -209,7 +193,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, inode = proc_get_inode(dir->i_sb, de); if (!inode) return ERR_PTR(-ENOMEM); - d_set_d_op(dentry, &proc_dentry_operations); + d_set_d_op(dentry, &simple_dentry_operations); d_add(dentry, inode); return NULL; } diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 49a7fff2e83..9ae46b87470 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -42,12 +42,6 @@ static const struct inode_operations ns_inode_operations = { .setattr = proc_setattr, }; -static int ns_delete_dentry(const struct dentry *dentry) -{ - /* Don't cache namespace inodes when not in use */ - return 1; -} - static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) { struct inode *inode = dentry->d_inode; @@ -59,7 +53,7 @@ static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) const struct dentry_operations ns_dentry_operations = { - .d_delete = ns_delete_dentry, + .d_delete = always_delete_dentry, .d_dname = ns_dname, }; diff --git a/include/linux/fs.h b/include/linux/fs.h index bf5d574ebdf..121f11f001c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2622,7 +2622,9 @@ extern int simple_write_begin(struct file *file, struct address_space *mapping, extern int simple_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata); +extern int always_delete_dentry(const struct dentry *); extern struct inode *alloc_anon_inode(struct super_block *); +extern const struct dentry_operations simple_dentry_operations; extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned int flags); extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *); diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e0839bcd48c..4c62513fe19 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -895,11 +895,6 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) iput(inode); } -static int cgroup_delete(const struct dentry *d) -{ - return 1; -} - static void remove_dir(struct dentry *d) { struct dentry *parent = dget(d->d_parent); @@ -1486,7 +1481,7 @@ static int cgroup_get_rootdir(struct super_block *sb) { static const struct dentry_operations cgroup_dops = { .d_iput = cgroup_diput, - .d_delete = cgroup_delete, + .d_delete = always_delete_dentry, }; struct inode *inode = diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index d0d14a04dce..bf04b30a788 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -471,15 +471,6 @@ struct rpc_filelist { umode_t mode; }; -static int rpc_delete_dentry(const struct dentry *dentry) -{ - return 1; -} - -static const struct dentry_operations rpc_dentry_operations = { - .d_delete = rpc_delete_dentry, -}; - static struct inode * rpc_get_inode(struct super_block *sb, umode_t mode) { @@ -1266,7 +1257,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = RPCAUTH_GSSMAGIC; sb->s_op = &s_ops; - sb->s_d_op = &rpc_dentry_operations; + sb->s_d_op = &simple_dentry_operations; sb->s_time_gran = 1; inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); -- cgit v1.2.3-70-g09d2 From a47e5bb5764f029f989a182b0dd2d4cce69f8b14 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 11 Jul 2013 09:47:45 -0700 Subject: alpha: Eliminate compiler warning from memset macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling with GCC 4.8 yields several instances of crypto/vmac.c: In function ‘vmac_final’: crypto/vmac.c:616:9: warning: value computed is not used [-Wunused-value] memset(&mac, 0, sizeof(vmac_t)); ^ arch/alpha/include/asm/string.h:31:25: note: in definition of macro ‘memset’ ? __builtin_memset((s),0,(n)) \ ^ Converting the macro to an inline function eliminates this problem. However, doing only that causes problems with the GCC 3.x series. The inline function cannot be named "memset", as otherwise we wind up with recursion via __builtin_memset. Solve this by adjusting the symbols such that __memset is the inline, and ___memset is the real function. Signed-off-by: Richard Henderson --- arch/alpha/include/asm/string.h | 24 ++++++++++++++++++------ arch/alpha/kernel/alpha_ksyms.c | 1 + arch/alpha/lib/ev6-memset.S | 12 +++++++----- arch/alpha/lib/memset.S | 11 +++++++---- 4 files changed, 33 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/alpha/include/asm/string.h b/arch/alpha/include/asm/string.h index b02b8a28294..c2911f59170 100644 --- a/arch/alpha/include/asm/string.h +++ b/arch/alpha/include/asm/string.h @@ -22,15 +22,27 @@ extern void * __memcpy(void *, const void *, size_t); #define __HAVE_ARCH_MEMSET extern void * __constant_c_memset(void *, unsigned long, size_t); +extern void * ___memset(void *, int, size_t); extern void * __memset(void *, int, size_t); extern void * memset(void *, int, size_t); -#define memset(s, c, n) \ -(__builtin_constant_p(c) \ - ? (__builtin_constant_p(n) && (c) == 0 \ - ? __builtin_memset((s),0,(n)) \ - : __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n))) \ - : __memset((s),(c),(n))) +/* For gcc 3.x, we cannot have the inline function named "memset" because + the __builtin_memset will attempt to resolve to the inline as well, + leading to a "sorry" about unimplemented recursive inlining. */ +extern inline void *__memset(void *s, int c, size_t n) +{ + if (__builtin_constant_p(c)) { + if (__builtin_constant_p(n)) { + return __builtin_memset(s, c, n); + } else { + unsigned long c8 = (c & 0xff) * 0x0101010101010101UL; + return __constant_c_memset(s, c8, n); + } + } + return ___memset(s, c, n); +} + +#define memset __memset #define __HAVE_ARCH_STRCPY extern char * strcpy(char *,const char *); diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 89566b346c0..f4c7ab6f43b 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -40,6 +40,7 @@ EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memset); +EXPORT_SYMBOL(___memset); EXPORT_SYMBOL(__memsetw); EXPORT_SYMBOL(__constant_c_memset); EXPORT_SYMBOL(copy_page); diff --git a/arch/alpha/lib/ev6-memset.S b/arch/alpha/lib/ev6-memset.S index d8b94e1c7fc..356bb2fdd70 100644 --- a/arch/alpha/lib/ev6-memset.S +++ b/arch/alpha/lib/ev6-memset.S @@ -30,14 +30,15 @@ .set noat .set noreorder .text + .globl memset .globl __memset + .globl ___memset .globl __memsetw .globl __constant_c_memset - .globl memset - .ent __memset + .ent ___memset .align 5 -__memset: +___memset: .frame $30,0,$26,0 .prologue 0 @@ -227,7 +228,7 @@ end_b: nop nop ret $31,($26),1 # L0 : - .end __memset + .end ___memset /* * This is the original body of code, prior to replication and @@ -594,4 +595,5 @@ end_w: .end __memsetw -memset = __memset +memset = ___memset +__memset = ___memset diff --git a/arch/alpha/lib/memset.S b/arch/alpha/lib/memset.S index 311b8cfc691..76ccc6d1f36 100644 --- a/arch/alpha/lib/memset.S +++ b/arch/alpha/lib/memset.S @@ -19,11 +19,13 @@ .text .globl memset .globl __memset + .globl ___memset .globl __memsetw .globl __constant_c_memset - .ent __memset + + .ent ___memset .align 5 -__memset: +___memset: .frame $30,0,$26,0 .prologue 0 @@ -103,7 +105,7 @@ within_one_quad: end: ret $31,($26),1 /* E1 */ - .end __memset + .end ___memset .align 5 .ent __memsetw @@ -121,4 +123,5 @@ __memsetw: .end __memsetw -memset = __memset +memset = ___memset +__memset = ___memset -- cgit v1.2.3-70-g09d2 From 994dcf7055df88623d25f3593b931a018a76b502 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 28 Apr 2011 07:29:27 -0700 Subject: alpha: Notice if we're being run under QEMU When building a generic kernel, do a run-time check on the serial number, like we do for MILO. When building a custom kernel, make this a configure-time check. Signed-off-by: Richard Henderson --- arch/alpha/Kconfig | 14 ++++++++++++++ arch/alpha/include/asm/machvec.h | 18 ++++++++++++------ arch/alpha/kernel/setup.c | 13 ++++++++++++- 3 files changed, 38 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 135c674eaf9..51cc8c35316 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -488,6 +488,20 @@ config VGA_HOSE which always have multiple hoses, and whose consoles support it. +config ALPHA_QEMU + bool "Run under QEMU emulation" + depends on !ALPHA_GENERIC + ---help--- + Assume the presence of special features supported by QEMU PALcode + that reduce the overhead of system emulation. + + Generic kernels will auto-detect QEMU. But when building a + system-specific kernel, the assumption is that we want to + elimiate as many runtime tests as possible. + + If unsure, say N. + + config ALPHA_SRM bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME depends on TTY diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h index 72dbf235927..4ac90167d34 100644 --- a/arch/alpha/include/asm/machvec.h +++ b/arch/alpha/include/asm/machvec.h @@ -126,13 +126,19 @@ extern struct alpha_machine_vector alpha_mv; #ifdef CONFIG_ALPHA_GENERIC extern int alpha_using_srm; +extern int alpha_using_qemu; #else -#ifdef CONFIG_ALPHA_SRM -#define alpha_using_srm 1 -#else -#define alpha_using_srm 0 -#endif +# ifdef CONFIG_ALPHA_SRM +# define alpha_using_srm 1 +# else +# define alpha_using_srm 0 +# endif +# ifdef CONFIG_ALPHA_QEMU +# define alpha_using_qemu 1 +# else +# define alpha_using_qemu 0 +# endif #endif /* GENERIC */ -#endif +#endif /* __KERNEL__ */ #endif /* __ALPHA_MACHVEC_H */ diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 9e3107cc5eb..c38d6a1b906 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -115,10 +115,17 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE; #ifdef CONFIG_ALPHA_GENERIC struct alpha_machine_vector alpha_mv; +#endif + +#ifndef alpha_using_srm int alpha_using_srm; EXPORT_SYMBOL(alpha_using_srm); #endif +#ifndef alpha_using_qemu +int alpha_using_qemu; +#endif + static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long, unsigned long); static struct alpha_machine_vector *get_sysvec_byname(const char *); @@ -529,11 +536,15 @@ setup_arch(char **cmdline_p) atomic_notifier_chain_register(&panic_notifier_list, &alpha_panic_block); -#ifdef CONFIG_ALPHA_GENERIC +#ifndef alpha_using_srm /* Assume that we've booted from SRM if we haven't booted from MILO. Detect the later by looking for "MILO" in the system serial nr. */ alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0; #endif +#ifndef alpha_using_qemu + /* Similarly, look for QEMU. */ + alpha_using_qemu = strstr((const char *)hwrpb->ssn, "QEMU") != 0; +#endif /* If we are using SRM, we want to allow callbacks as early as possible, so do this NOW, and then -- cgit v1.2.3-70-g09d2 From fddd87d6e135924b92499917bace103e46c22d00 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 12 Jul 2013 16:15:56 -0700 Subject: alpha: Allow HZ to be configured With the 1024Hz default, we spend 50% of QEMU emulation processing timer interrupts. Signed-off-by: Richard Henderson --- arch/alpha/Kconfig | 36 ++++++++++++++++++++++++++++++++++-- arch/alpha/kernel/setup.c | 10 ++++++++-- arch/alpha/kernel/time.c | 24 +++++++++++++++++------- 3 files changed, 59 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 51cc8c35316..a67b971c830 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -627,9 +627,41 @@ config VERBOSE_MCHECK_ON Take the default (1) unless you want more control or more info. +choice + prompt "Timer interrupt frequency (HZ)?" + default HZ_128 if ALPHA_QEMU + default HZ_1200 if ALPHA_RAWHIDE + default HZ_1024 + ---help--- + The frequency at which timer interrupts occur. A high frequency + minimizes latency, whereas a low frequency minimizes overhead of + process accounting. The later effect is especially significant + when being run under QEMU. + + Note that some Alpha hardware cannot change the interrupt frequency + of the timer. If unsure, say 1024 (or 1200 for Rawhide). + + config HZ_32 + bool "32 Hz" + config HZ_64 + bool "64 Hz" + config HZ_128 + bool "128 Hz" + config HZ_256 + bool "256 Hz" + config HZ_1024 + bool "1024 Hz" + config HZ_1200 + bool "1200 Hz" +endchoice + config HZ - int - default 1200 if ALPHA_RAWHIDE + int + default 32 if HZ_32 + default 64 if HZ_64 + default 128 if HZ_128 + default 256 if HZ_256 + default 1200 if HZ_1200 default 1024 source "drivers/pci/Kconfig" diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index c38d6a1b906..b20af76f12c 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -1218,6 +1218,7 @@ show_cpuinfo(struct seq_file *f, void *slot) char *systype_name; char *sysvariation_name; int nr_processors; + unsigned long timer_freq; cpu_index = (unsigned) (cpu->type - 1); cpu_name = "Unknown"; @@ -1229,6 +1230,12 @@ show_cpuinfo(struct seq_file *f, void *slot) nr_processors = get_nr_processors(cpu, hwrpb->nr_processors); +#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200 + timer_freq = (100UL * hwrpb->intr_freq) / 4096; +#else + timer_freq = 100UL * CONFIG_HZ; +#endif + seq_printf(f, "cpu\t\t\t: Alpha\n" "cpu model\t\t: %s\n" "cpu variation\t\t: %ld\n" @@ -1254,8 +1261,7 @@ show_cpuinfo(struct seq_file *f, void *slot) (char*)hwrpb->ssn, est_cycle_freq ? : hwrpb->cycle_freq, est_cycle_freq ? "est." : "", - hwrpb->intr_freq / 4096, - (100 * hwrpb->intr_freq / 4096) % 100, + timer_freq / 100, timer_freq % 100, hwrpb->pagesize, hwrpb->pa_bits, hwrpb->max_asn, diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index ea339503655..a6bcb3113d8 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -201,16 +201,26 @@ irqreturn_t timer_interrupt(int irq, void *dev) void __init common_init_rtc(void) { - unsigned char x; + unsigned char x, sel = 0; /* Reset periodic interrupt frequency. */ - x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; - /* Test includes known working values on various platforms - where 0x26 is wrong; we refuse to change those. */ - if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { - printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); - CMOS_WRITE(0x26, RTC_FREQ_SELECT); +#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200 + x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; + /* Test includes known working values on various platforms + where 0x26 is wrong; we refuse to change those. */ + if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { + sel = RTC_REF_CLCK_32KHZ + 6; } +#elif CONFIG_HZ == 256 || CONFIG_HZ == 128 || CONFIG_HZ == 64 || CONFIG_HZ == 32 + sel = RTC_REF_CLCK_32KHZ + __builtin_ffs(32768 / CONFIG_HZ); +#else +# error "Unknown HZ from arch/alpha/Kconfig" +#endif + if (sel) { + printk(KERN_INFO "Setting RTC_FREQ to %d Hz (%x)\n", + CONFIG_HZ, sel); + CMOS_WRITE(sel, RTC_FREQ_SELECT); + } /* Turn on periodic interrupts. */ x = CMOS_READ(RTC_CONTROL); -- cgit v1.2.3-70-g09d2 From 7f3bbb82e0c371d6881129f776c90130ba66f051 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 12 Jul 2013 09:36:21 -0700 Subject: alpha: Primitive support for CPU power down. Use WTINT to wait for the next interrupt. Squash the WTINT call if the PALcode doesn't support it (e.g. MILO). No attempt is yet made to skip clock ticks during normal scheduling in order to stay in power down mode longer. Signed-off-by: Richard Henderson --- arch/alpha/Kconfig | 24 ++++++++++++++++++++++++ arch/alpha/include/asm/pal.h | 1 + arch/alpha/include/uapi/asm/pal.h | 1 + arch/alpha/kernel/process.c | 17 +++++++++++++++++ arch/alpha/kernel/traps.c | 15 +++++++++++++++ 5 files changed, 58 insertions(+) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index a67b971c830..f9e84da4971 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -586,6 +586,30 @@ config NUMA Access). This option is for configuring high-end multiprocessor server machines. If in doubt, say N. +config ALPHA_WTINT + bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC + default y if ALPHA_QEMU + default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA) + default n if !ALPHA_SRM && !ALPHA_GENERIC + default y if SMP + ---help--- + The Wait for Interrupt (WTINT) PALcall attempts to place the CPU + to sleep until the next interrupt. This may reduce the power + consumed, and the heat produced by the computer. However, it has + the side effect of making the cycle counter unreliable as a timing + device across the sleep. + + For emulation under QEMU, definitely say Y here, as we have other + mechanisms for measuring time than the cycle counter. + + For EV4 (but not LCA), EV5 and EV56 systems, or for systems running + MILO, sleep mode is not supported so you might as well say N here. + + For SMP systems we cannot use the cycle counter for timing anyway, + so you might as well say Y here. + + If unsure, say N. + config NODES_SHIFT int default "7" diff --git a/arch/alpha/include/asm/pal.h b/arch/alpha/include/asm/pal.h index 6fcd2b5b08f..e78ec9bcc76 100644 --- a/arch/alpha/include/asm/pal.h +++ b/arch/alpha/include/asm/pal.h @@ -89,6 +89,7 @@ __CALL_PAL_W1(wrmces, unsigned long); __CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long); __CALL_PAL_W1(wrusp, unsigned long); __CALL_PAL_W1(wrvptptr, unsigned long); +__CALL_PAL_RW1(wtint, unsigned long, unsigned long); /* * TB routines.. diff --git a/arch/alpha/include/uapi/asm/pal.h b/arch/alpha/include/uapi/asm/pal.h index 3c0ce08e5f5..dfc8140b908 100644 --- a/arch/alpha/include/uapi/asm/pal.h +++ b/arch/alpha/include/uapi/asm/pal.h @@ -46,6 +46,7 @@ #define PAL_rdusp 58 #define PAL_whami 60 #define PAL_retsys 61 +#define PAL_wtint 62 #define PAL_rti 63 diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index f2360a74e5d..1941a07b581 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -46,6 +46,23 @@ void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); +#ifdef CONFIG_ALPHA_WTINT +/* + * Sleep the CPU. + * EV6, LCA45 and QEMU know how to power down, skipping N timer interrupts. + */ +void arch_cpu_idle(void) +{ + wtint(0); + local_irq_enable(); +} + +void arch_cpu_idle_dead(void) +{ + wtint(INT_MAX); +} +#endif /* ALPHA_WTINT */ + struct halt_info { int mode; char *restart_cmd; diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index bd0665cdc84..9c4c189eb22 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -241,6 +241,21 @@ do_entIF(unsigned long type, struct pt_regs *regs) (const char *)(data[1] | (long)data[2] << 32), data[0]); } +#ifdef CONFIG_ALPHA_WTINT + if (type == 4) { + /* If CALL_PAL WTINT is totally unsupported by the + PALcode, e.g. MILO, "emulate" it by overwriting + the insn. */ + unsigned int *pinsn + = (unsigned int *) regs->pc - 1; + if (*pinsn == PAL_wtint) { + *pinsn = 0x47e01400; /* mov 0,$0 */ + imb(); + regs->r0 = 0; + return; + } + } +#endif /* ALPHA_WTINT */ die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"), regs, type, NULL); } -- cgit v1.2.3-70-g09d2 From 85d0b3a573d8b711ee0c96199ac24a0f3283ed68 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 13 Jul 2013 15:49:45 -0700 Subject: alpha: Reorganize rtc handling Discontinue use of GENERIC_CMOS_UPDATE; rely on the RTC subsystem. The marvel platform requires that the rtc only be touched from the boot cpu. This had been partially implemented with hooks for get/set_rtc_time, but read/update_persistent_clock were not handled. Move the hooks from the machine_vec to a special rtc_class_ops struct. We had read_persistent_clock managing the epoch against which the rtc hw is based, but this didn't apply to get_rtc_time or set_rtc_time. This resulted in incorrect values when hwclock(8) gets involved. Allow the epoch to be set from the kernel command-line, overriding the autodetection, which is doomed to fail in 2020. Further, by implementing the rtc ioctl function, we can expose this epoch to userland. Elide the alarm functions that RTC_DRV_CMOS implements. This was highly questionable on Alpha, since the interrupt is used by the system timer. Signed-off-by: Richard Henderson --- arch/alpha/Kconfig | 1 - arch/alpha/include/asm/machvec.h | 4 +- arch/alpha/include/asm/rtc.h | 11 -- arch/alpha/kernel/Makefile | 1 + arch/alpha/kernel/machvec_impl.h | 5 +- arch/alpha/kernel/proto.h | 2 - arch/alpha/kernel/rtc.c | 323 +++++++++++++++++++++++++++++++++++++++ arch/alpha/kernel/sys_jensen.c | 2 - arch/alpha/kernel/sys_marvel.c | 55 +------ arch/alpha/kernel/time.c | 146 +----------------- drivers/rtc/Kconfig | 10 +- 11 files changed, 337 insertions(+), 223 deletions(-) create mode 100644 arch/alpha/kernel/rtc.c (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index f9e84da4971..5d863d171b9 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -17,7 +17,6 @@ config ALPHA select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select GENERIC_SMP_IDLE_THREAD - select GENERIC_CMOS_UPDATE select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select HAVE_MOD_ARCH_SPECIFIC diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h index 4ac90167d34..75cb3641ed2 100644 --- a/arch/alpha/include/asm/machvec.h +++ b/arch/alpha/include/asm/machvec.h @@ -33,6 +33,7 @@ struct alpha_machine_vector int nr_irqs; int rtc_port; + int rtc_boot_cpu_only; unsigned int max_asn; unsigned long max_isa_dma_address; unsigned long irq_probe_mask; @@ -95,9 +96,6 @@ struct alpha_machine_vector struct _alpha_agp_info *(*agp_info)(void); - unsigned int (*rtc_get_time)(struct rtc_time *); - int (*rtc_set_time)(struct rtc_time *); - const char *vector_name; /* NUMA information */ diff --git a/arch/alpha/include/asm/rtc.h b/arch/alpha/include/asm/rtc.h index d70408d3667..f71c3b0ed36 100644 --- a/arch/alpha/include/asm/rtc.h +++ b/arch/alpha/include/asm/rtc.h @@ -1,12 +1 @@ -#ifndef _ALPHA_RTC_H -#define _ALPHA_RTC_H - -#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \ - || defined(CONFIG_ALPHA_GENERIC) -# define get_rtc_time alpha_mv.rtc_get_time -# define set_rtc_time alpha_mv.rtc_set_time -#endif - #include - -#endif diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 84ec46b38f7..0d54650e78f 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o obj-$(CONFIG_SRM_ENV) += srm_env.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o +obj-$(CONFIG_RTC_DRV_ALPHA) += rtc.o ifdef CONFIG_ALPHA_GENERIC diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index 7fa62488bd1..f54bdf658cd 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -43,10 +43,7 @@ #define CAT1(x,y) x##y #define CAT(x,y) CAT1(x,y) -#define DO_DEFAULT_RTC \ - .rtc_port = 0x70, \ - .rtc_get_time = common_get_rtc_time, \ - .rtc_set_time = common_set_rtc_time +#define DO_DEFAULT_RTC .rtc_port = 0x70 #define DO_EV4_MMU \ .max_asn = EV4_MAX_ASN, \ diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index d3e52d3fd59..3b250fa5f2c 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -144,8 +144,6 @@ extern void smp_percpu_timer_interrupt(struct pt_regs *); extern irqreturn_t timer_interrupt(int irq, void *dev); extern void common_init_rtc(void); extern unsigned long est_cycle_freq; -extern unsigned int common_get_rtc_time(struct rtc_time *time); -extern int common_set_rtc_time(struct rtc_time *time); /* smc37c93x.c */ extern void SMC93x_Init(void); diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c new file mode 100644 index 00000000000..c8d284d8521 --- /dev/null +++ b/arch/alpha/kernel/rtc.c @@ -0,0 +1,323 @@ +/* + * linux/arch/alpha/kernel/rtc.c + * + * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds + * + * This file contains date handling. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "proto.h" + + +/* + * Support for the RTC device. + * + * We don't want to use the rtc-cmos driver, because we don't want to support + * alarms, as that would be indistinguishable from timer interrupts. + * + * Further, generic code is really, really tied to a 1900 epoch. This is + * true in __get_rtc_time as well as the users of struct rtc_time e.g. + * rtc_tm_to_time. Thankfully all of the other epochs in use are later + * than 1900, and so it's easy to adjust. + */ + +static unsigned long rtc_epoch; + +static int __init +specifiy_epoch(char *str) +{ + unsigned long epoch = simple_strtoul(str, NULL, 0); + if (epoch < 1900) + printk("Ignoring invalid user specified epoch %lu\n", epoch); + else + rtc_epoch = epoch; + return 1; +} +__setup("epoch=", specifiy_epoch); + +static void __init +init_rtc_epoch(void) +{ + int epoch, year, ctrl; + + if (rtc_epoch != 0) { + /* The epoch was specified on the command-line. */ + return; + } + + /* Detect the epoch in use on this computer. */ + ctrl = CMOS_READ(RTC_CONTROL); + year = CMOS_READ(RTC_YEAR); + if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + year = bcd2bin(year); + + /* PC-like is standard; used for year >= 70 */ + epoch = 1900; + if (year < 20) { + epoch = 2000; + } else if (year >= 20 && year < 48) { + /* NT epoch */ + epoch = 1980; + } else if (year >= 48 && year < 70) { + /* Digital UNIX epoch */ + epoch = 1952; + } + rtc_epoch = epoch; + + printk(KERN_INFO "Using epoch %d for rtc year %d\n", epoch, year); +} + +static int +alpha_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + __get_rtc_time(tm); + + /* Adjust for non-default epochs. It's easier to depend on the + generic __get_rtc_time and adjust the epoch here than create + a copy of __get_rtc_time with the edits we need. */ + if (rtc_epoch != 1900) { + int year = tm->tm_year; + /* Undo the century adjustment made in __get_rtc_time. */ + if (year >= 100) + year -= 100; + year += rtc_epoch - 1900; + /* Redo the century adjustment with the epoch in place. */ + if (year <= 69) + year += 100; + tm->tm_year = year; + } + + return rtc_valid_tm(tm); +} + +static int +alpha_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct rtc_time xtm; + + if (rtc_epoch != 1900) { + xtm = *tm; + xtm.tm_year -= rtc_epoch - 1900; + tm = &xtm; + } + + return __set_rtc_time(tm); +} + +static int +alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char save_control, save_freq_select; + + /* Note: This code only updates minutes and seconds. Comments + indicate this was to avoid messing with unknown time zones, + and with the epoch nonsense described above. In order for + this to work, the existing clock cannot be off by more than + 15 minutes. + + ??? This choice is may be out of date. The x86 port does + not have problems with timezones, and the epoch processing has + now been fixed in alpha_set_rtc_time. + + In either case, one can always force a full rtc update with + the userland hwclock program, so surely 15 minute accuracy + is no real burden. */ + + /* In order to set the CMOS clock precisely, we have to be called + 500 ms after the second nowtime has started, because when + nowtime is written into the registers of the CMOS clock, it will + jump to the next second precisely 500 ms later. Check the Motorola + MC146818A or Dallas DS12887 data sheet for details. */ + + /* irq are locally disabled here */ + spin_lock(&rtc_lock); + /* Tell the clock it's being set */ + save_control = CMOS_READ(RTC_CONTROL); + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + + /* Stop and reset prescaler */ + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + cmos_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + cmos_minutes = bcd2bin(cmos_minutes); + + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) { + /* correct for half hour time zone */ + real_minutes += 30; + } + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + real_seconds = bin2bcd(real_seconds); + real_minutes = bin2bcd(real_minutes); + } + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); + } else { + printk_once(KERN_NOTICE + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + spin_unlock(&rtc_lock); + + return retval; +} + +static int +alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case RTC_EPOCH_READ: + return put_user(rtc_epoch, (unsigned long __user *)arg); + case RTC_EPOCH_SET: + if (arg < 1900) + return -EINVAL; + rtc_epoch = arg; + return 0; + default: + return -ENOIOCTLCMD; + } +} + +static const struct rtc_class_ops alpha_rtc_ops = { + .read_time = alpha_rtc_read_time, + .set_time = alpha_rtc_set_time, + .set_mmss = alpha_rtc_set_mmss, + .ioctl = alpha_rtc_ioctl, +}; + +/* + * Similarly, except do the actual CMOS access on the boot cpu only. + * This requires marshalling the data across an interprocessor call. + */ + +#if defined(CONFIG_SMP) && \ + (defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_MARVEL)) +# define HAVE_REMOTE_RTC 1 + +union remote_data { + struct rtc_time *tm; + unsigned long now; + long retval; +}; + +static void +do_remote_read(void *data) +{ + union remote_data *x = data; + x->retval = alpha_rtc_read_time(NULL, x->tm); +} + +static int +remote_read_time(struct device *dev, struct rtc_time *tm) +{ + union remote_data x; + if (smp_processor_id() != boot_cpuid) { + x.tm = tm; + smp_call_function_single(boot_cpuid, do_remote_read, &x, 1); + return x.retval; + } + return alpha_rtc_read_time(NULL, tm); +} + +static void +do_remote_set(void *data) +{ + union remote_data *x = data; + x->retval = alpha_rtc_set_time(NULL, x->tm); +} + +static int +remote_set_time(struct device *dev, struct rtc_time *tm) +{ + union remote_data x; + if (smp_processor_id() != boot_cpuid) { + x.tm = tm; + smp_call_function_single(boot_cpuid, do_remote_set, &x, 1); + return x.retval; + } + return alpha_rtc_set_time(NULL, tm); +} + +static void +do_remote_mmss(void *data) +{ + union remote_data *x = data; + x->retval = alpha_rtc_set_mmss(NULL, x->now); +} + +static int +remote_set_mmss(struct device *dev, unsigned long now) +{ + union remote_data x; + if (smp_processor_id() != boot_cpuid) { + x.now = now; + smp_call_function_single(boot_cpuid, do_remote_mmss, &x, 1); + return x.retval; + } + return alpha_rtc_set_mmss(NULL, now); +} + +static const struct rtc_class_ops remote_rtc_ops = { + .read_time = remote_read_time, + .set_time = remote_set_time, + .set_mmss = remote_set_mmss, + .ioctl = alpha_rtc_ioctl, +}; +#endif + +static int __init +alpha_rtc_init(void) +{ + const struct rtc_class_ops *ops; + struct platform_device *pdev; + struct rtc_device *rtc; + const char *name; + + init_rtc_epoch(); + name = "rtc-alpha"; + ops = &alpha_rtc_ops; + +#ifdef HAVE_REMOTE_RTC + if (alpha_mv.rtc_boot_cpu_only) + ops = &remote_rtc_ops; +#endif + + pdev = platform_device_register_simple(name, -1, NULL, 0); + rtc = devm_rtc_device_register(&pdev->dev, name, ops, THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + platform_set_drvdata(pdev, rtc); + return 0; +} +device_initcall(alpha_rtc_init); diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 5a0af11b3a6..608f2a7fa0a 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -224,8 +224,6 @@ struct alpha_machine_vector jensen_mv __initmv = { .machine_check = jensen_machine_check, .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, .rtc_port = 0x170, - .rtc_get_time = common_get_rtc_time, - .rtc_set_time = common_set_rtc_time, .nr_irqs = 16, .device_interrupt = jensen_device_interrupt, diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index c92e389ff21..f21d61fab67 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "proto.h" #include "err_impl.h" @@ -400,57 +399,6 @@ marvel_init_rtc(void) init_rtc_irq(); } -struct marvel_rtc_time { - struct rtc_time *time; - int retval; -}; - -#ifdef CONFIG_SMP -static void -smp_get_rtc_time(void *data) -{ - struct marvel_rtc_time *mrt = data; - mrt->retval = __get_rtc_time(mrt->time); -} - -static void -smp_set_rtc_time(void *data) -{ - struct marvel_rtc_time *mrt = data; - mrt->retval = __set_rtc_time(mrt->time); -} -#endif - -static unsigned int -marvel_get_rtc_time(struct rtc_time *time) -{ -#ifdef CONFIG_SMP - struct marvel_rtc_time mrt; - - if (smp_processor_id() != boot_cpuid) { - mrt.time = time; - smp_call_function_single(boot_cpuid, smp_get_rtc_time, &mrt, 1); - return mrt.retval; - } -#endif - return __get_rtc_time(time); -} - -static int -marvel_set_rtc_time(struct rtc_time *time) -{ -#ifdef CONFIG_SMP - struct marvel_rtc_time mrt; - - if (smp_processor_id() != boot_cpuid) { - mrt.time = time; - smp_call_function_single(boot_cpuid, smp_set_rtc_time, &mrt, 1); - return mrt.retval; - } -#endif - return __set_rtc_time(time); -} - static void marvel_smp_callin(void) { @@ -492,8 +440,7 @@ struct alpha_machine_vector marvel_ev7_mv __initmv = { .vector_name = "MARVEL/EV7", DO_EV7_MMU, .rtc_port = 0x70, - .rtc_get_time = marvel_get_rtc_time, - .rtc_set_time = marvel_set_rtc_time, + .rtc_boot_cpu_only = 1, DO_MARVEL_IO, .machine_check = marvel_machine_check, .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index a6bcb3113d8..4c6c0fe47a7 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -3,13 +3,7 @@ * * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds * - * This file contains the PC-specific time handling details: - * reading the RTC at bootup, etc.. - * 1994-07-02 Alan Modra - * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime - * 1995-03-26 Markus Kuhn - * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887 - * precision CMOS clock update + * This file contains the clocksource time handling. * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 * "A Kernel Model for Precision Timekeeping" by Dave Mills * 1997-01-09 Adrian Sun @@ -21,9 +15,6 @@ * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net) * fixed algorithm in do_gettimeofday() for calculating the precise time * from processor cycle counter (now taking lost_ticks into account) - * 2000-08-13 Jan-Benedict Glaw - * Fixed time_init to be aware of epoches != 1900. This prevents - * booting up in 2048 for me;) Code is stolen from rtc.c. * 2003-06-03 R. Scott Bailey * Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM */ @@ -46,7 +37,6 @@ #include #include #include -#include #include #include @@ -56,8 +46,6 @@ #include "proto.h" #include "irq_impl.h" -static int set_rtc_mmss(unsigned long); - DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -108,53 +96,6 @@ static inline __u32 rpcc(void) return __builtin_alpha_rpcc(); } -int update_persistent_clock(struct timespec now) -{ - return set_rtc_mmss(now.tv_sec); -} - -void read_persistent_clock(struct timespec *ts) -{ - unsigned int year, mon, day, hour, min, sec, epoch; - - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); - } - - /* PC-like is standard; used for year >= 70 */ - epoch = 1900; - if (year < 20) - epoch = 2000; - else if (year >= 20 && year < 48) - /* NT epoch */ - epoch = 1980; - else if (year >= 48 && year < 70) - /* Digital UNIX epoch */ - epoch = 1952; - - printk(KERN_INFO "Using epoch = %d\n", epoch); - - if ((year += epoch) < 1970) - year += 100; - - ts->tv_sec = mktime(year, mon, day, hour, min, sec); - ts->tv_nsec = 0; -} - - - /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "xtime_update()" routine every clocktick @@ -243,16 +184,6 @@ common_init_rtc(void) init_rtc_irq(); } -unsigned int common_get_rtc_time(struct rtc_time *time) -{ - return __get_rtc_time(time); -} - -int common_set_rtc_time(struct rtc_time *time) -{ - return __set_rtc_time(time); -} - /* Validate a computed cycle counter result against the known bounds for the given processor core. There's too much brokenness in the way of timing hardware for any one method to work everywhere. :-( @@ -453,78 +384,3 @@ time_init(void) /* Startup the timer source. */ alpha_mv.init_rtc(); } - -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you won't notice until after reboot! - */ - - -static int -set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - /* irq are locally disabled here */ - spin_lock(&rtc_lock); - /* Tell the clock it's being set */ - save_control = CMOS_READ(RTC_CONTROL); - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - /* Stop and reset prescaler */ - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - cmos_minutes = bcd2bin(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) { - /* correct for half hour time zone */ - real_minutes += 30; - } - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - real_seconds = bin2bcd(real_seconds); - real_minutes = bin2bcd(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else { - printk_once(KERN_NOTICE - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - spin_unlock(&rtc_lock); - - return retval; -} diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 15f166a470a..00773022211 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -626,7 +626,7 @@ comment "Platform RTC drivers" config RTC_DRV_CMOS tristate "PC-style 'CMOS'" - depends on X86 || ALPHA || ARM || M32R || ATARI || PPC || MIPS || SPARC64 + depends on X86 || ARM || M32R || ATARI || PPC || MIPS || SPARC64 default y if X86 help Say "yes" here to get direct support for the real time clock @@ -643,6 +643,14 @@ config RTC_DRV_CMOS This driver can also be built as a module. If so, the module will be called rtc-cmos. +config RTC_DRV_ALPHA + bool "Alpha PC-style CMOS" + depends on ALPHA + default y + help + Direct support for the real-time clock found on every Alpha + system, specifically MC146818 compatibles. If in doubt, say Y. + config RTC_DRV_VRTC tristate "Virtual RTC for Intel MID platforms" depends on X86_INTEL_MID -- cgit v1.2.3-70-g09d2 From db2d3260617ae8c9076ef12e6de06bd5b3d82cd3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Jul 2013 09:55:08 -0700 Subject: alpha: Enable the rpcc clocksource for single processor Don't depend on SMP, just check the number of processors online. This allows a single distribution kernel to use the clocksource when run on a single processor machine. Do depend on whether or not we're using WTINT. Signed-off-by: Richard Henderson --- arch/alpha/kernel/time.c | 67 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 4c6c0fe47a7..0d72e2df4b0 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -184,6 +184,37 @@ common_init_rtc(void) init_rtc_irq(); } + +#ifndef CONFIG_ALPHA_WTINT +/* + * The RPCC as a clocksource primitive. + * + * While we have free-running timecounters running on all CPUs, and we make + * a half-hearted attempt in init_rtc_rpcc_info to sync the timecounter + * with the wall clock, that initialization isn't kept up-to-date across + * different time counters in SMP mode. Therefore we can only use this + * method when there's only one CPU enabled. + * + * When using the WTINT PALcall, the RPCC may shift to a lower frequency, + * or stop altogether, while waiting for the interrupt. Therefore we cannot + * use this method when WTINT is in use. + */ + +static cycle_t read_rpcc(struct clocksource *cs) +{ + return rpcc(); +} + +static struct clocksource clocksource_rpcc = { + .name = "rpcc", + .rating = 300, + .read = read_rpcc, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS +}; +#endif /* ALPHA_WTINT */ + + /* Validate a computed cycle counter result against the known bounds for the given processor core. There's too much brokenness in the way of timing hardware for any one method to work everywhere. :-( @@ -294,33 +325,6 @@ rpcc_after_update_in_progress(void) return rpcc(); } -#ifndef CONFIG_SMP -/* Until and unless we figure out how to get cpu cycle counters - in sync and keep them there, we can't use the rpcc. */ -static cycle_t read_rpcc(struct clocksource *cs) -{ - cycle_t ret = (cycle_t)rpcc(); - return ret; -} - -static struct clocksource clocksource_rpcc = { - .name = "rpcc", - .rating = 300, - .read = read_rpcc, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS -}; - -static inline void register_rpcc_clocksource(long cycle_freq) -{ - clocksource_register_hz(&clocksource_rpcc, cycle_freq); -} -#else /* !CONFIG_SMP */ -static inline void register_rpcc_clocksource(long cycle_freq) -{ -} -#endif /* !CONFIG_SMP */ - void __init time_init(void) { @@ -362,20 +366,23 @@ time_init(void) "and unable to estimate a proper value!\n"); } + /* See above for restrictions on using clocksource_rpcc. */ +#ifndef CONFIG_ALPHA_WTINT + if (hwrpb->nr_processors == 1) + clocksource_register_hz(&clocksource_rpcc, cycle_freq); +#endif + /* From John Bowman : allow the values to settle, as the Update-In-Progress bit going low isn't good enough on some hardware. 2ms is our guess; we haven't found bogomips yet, but this is close on a 500Mhz box. */ __delay(1000000); - if (HZ > (1<<16)) { extern void __you_loose (void); __you_loose(); } - register_rpcc_clocksource(cycle_freq); - state.last_time = cc1; state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; -- cgit v1.2.3-70-g09d2 From a1659d6d128a7e0c2985bce7c957b66af1f71181 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Jul 2013 10:57:34 -0700 Subject: alpha: Switch to GENERIC_CLOCKEVENTS This allows us to get rid of some hacky code for SMP. Get rid of some cycle counter hackery that's now handled by generic code via clocksource + clock_event_device objects. Signed-off-by: Richard Henderson --- arch/alpha/Kconfig | 1 + arch/alpha/kernel/irq_alpha.c | 14 ------ arch/alpha/kernel/proto.h | 2 +- arch/alpha/kernel/smp.c | 33 ++----------- arch/alpha/kernel/time.c | 112 ++++++++++++++++++------------------------ 5 files changed, 53 insertions(+), 109 deletions(-) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 5d863d171b9..d39dc9b95a2 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -16,6 +16,7 @@ config ALPHA select ARCH_WANT_IPC_PARSE_VERSION select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select GENERIC_CLOCKEVENTS select GENERIC_SMP_IDLE_THREAD select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 28e4429596f..6990ddc0fba 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -66,21 +66,7 @@ do_entInt(unsigned long type, unsigned long vector, break; case 1: old_regs = set_irq_regs(regs); -#ifdef CONFIG_SMP - { - long cpu; - - smp_percpu_timer_interrupt(regs); - cpu = smp_processor_id(); - if (cpu != boot_cpuid) { - kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ)); - } else { - handle_irq(RTC_IRQ); - } - } -#else handle_irq(RTC_IRQ); -#endif set_irq_regs(old_regs); return; case 2: diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 3b250fa5f2c..bc806893afe 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -135,13 +135,13 @@ extern void unregister_srm_console(void); /* smp.c */ extern void setup_smp(void); extern void handle_ipi(struct pt_regs *); -extern void smp_percpu_timer_interrupt(struct pt_regs *); /* bios32.c */ /* extern void reset_for_srm(void); */ /* time.c */ extern irqreturn_t timer_interrupt(int irq, void *dev); +extern void init_clockevent(void); extern void common_init_rtc(void); extern unsigned long est_cycle_freq; diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 9dbbcb3b914..99ac36d5de4 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -138,9 +138,11 @@ smp_callin(void) /* Get our local ticker going. */ smp_setup_percpu_timer(cpuid); + init_clockevent(); /* Call platform-specific callin, if specified */ - if (alpha_mv.smp_callin) alpha_mv.smp_callin(); + if (alpha_mv.smp_callin) + alpha_mv.smp_callin(); /* All kernel threads share the same mm context. */ atomic_inc(&init_mm.mm_count); @@ -498,35 +500,6 @@ smp_cpus_done(unsigned int max_cpus) ((bogosum + 2500) / (5000/HZ)) % 100); } - -void -smp_percpu_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs; - int cpu = smp_processor_id(); - unsigned long user = user_mode(regs); - struct cpuinfo_alpha *data = &cpu_data[cpu]; - - old_regs = set_irq_regs(regs); - - /* Record kernel PC. */ - profile_tick(CPU_PROFILING); - - if (!--data->prof_counter) { - /* We need to make like a normal interrupt -- otherwise - timer interrupts ignore the global interrupt lock, - which would be a Bad Thing. */ - irq_enter(); - - update_process_times(user); - - data->prof_counter = data->prof_multiplier; - - irq_exit(); - } - set_irq_regs(old_regs); -} - int setup_profiling_timer(unsigned int multiplier) { diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 0d72e2df4b0..08ff3f502a7 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "proto.h" #include "irq_impl.h" @@ -49,25 +50,6 @@ DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); -#define TICK_SIZE (tick_nsec / 1000) - -/* - * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting - * by 48 gives us 16 bits for HZ while keeping the accuracy good even - * for large CPU clock rates. - */ -#define FIX_SHIFT 48 - -/* lump static variables together for more efficient access: */ -static struct { - /* cycle counter last time it got invoked */ - __u32 last_time; - /* ticks/cycle * 2^48 */ - unsigned long scaled_ticks_per_cycle; - /* partial unused tick */ - unsigned long partial_tick; -} state; - unsigned long est_cycle_freq; #ifdef CONFIG_IRQ_WORK @@ -96,49 +78,64 @@ static inline __u32 rpcc(void) return __builtin_alpha_rpcc(); } + + /* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "xtime_update()" routine every clocktick + * The RTC as a clock_event_device primitive. */ -irqreturn_t timer_interrupt(int irq, void *dev) -{ - unsigned long delta; - __u32 now; - long nticks; -#ifndef CONFIG_SMP - /* Not SMP, do kernel PC profiling here. */ - profile_tick(CPU_PROFILING); -#endif +static DEFINE_PER_CPU(struct clock_event_device, cpu_ce); - /* - * Calculate how many ticks have passed since the last update, - * including any previous partial leftover. Save any resulting - * fraction for the next pass. - */ - now = rpcc(); - delta = now - state.last_time; - state.last_time = now; - delta = delta * state.scaled_ticks_per_cycle + state.partial_tick; - state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); - nticks = delta >> FIX_SHIFT; +irqreturn_t +timer_interrupt(int irq, void *dev) +{ + int cpu = smp_processor_id(); + struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); - if (nticks) - xtime_update(nticks); + /* Don't run the hook for UNUSED or SHUTDOWN. */ + if (likely(ce->mode == CLOCK_EVT_MODE_PERIODIC)) + ce->event_handler(ce); if (test_irq_work_pending()) { clear_irq_work_pending(); irq_work_run(); } -#ifndef CONFIG_SMP - while (nticks--) - update_process_times(user_mode(get_irq_regs())); -#endif - return IRQ_HANDLED; } +static void +rtc_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce) +{ + /* The mode member of CE is updated in generic code. + Since we only support periodic events, nothing to do. */ +} + +static int +rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce) +{ + /* This hook is for oneshot mode, which we don't support. */ + return -EINVAL; +} + +void __init +init_clockevent(void) +{ + int cpu = smp_processor_id(); + struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); + + *ce = (struct clock_event_device){ + .name = "rtc", + .features = CLOCK_EVT_FEAT_PERIODIC, + .rating = 100, + .cpumask = cpumask_of(cpu), + .set_mode = rtc_ce_set_mode, + .set_next_event = rtc_ce_set_next_event, + }; + + clockevents_config_and_register(ce, CONFIG_HZ, 0, 0); +} + void __init common_init_rtc(void) { @@ -372,22 +369,9 @@ time_init(void) clocksource_register_hz(&clocksource_rpcc, cycle_freq); #endif - /* From John Bowman : allow the values - to settle, as the Update-In-Progress bit going low isn't good - enough on some hardware. 2ms is our guess; we haven't found - bogomips yet, but this is close on a 500Mhz box. */ - __delay(1000000); - - if (HZ > (1<<16)) { - extern void __you_loose (void); - __you_loose(); - } - - state.last_time = cc1; - state.scaled_ticks_per_cycle - = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; - state.partial_tick = 0L; - /* Startup the timer source. */ alpha_mv.init_rtc(); + + /* Start up the clock event device. */ + init_clockevent(); } -- cgit v1.2.3-70-g09d2 From 4914d7b458e35a7db2f9c7dc6eb014620254bbbf Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Jul 2013 14:50:21 -0700 Subject: alpha: Use qemu+cserve provided high-res clock and alarm. QEMU provides a high-resolution timer and alarm; use this for a clock source and clock event source when available. Signed-off-by: Richard Henderson --- arch/alpha/include/asm/pal.h | 70 +++++++++++++++++++++++++++++++ arch/alpha/kernel/irq_alpha.c | 2 +- arch/alpha/kernel/proto.h | 2 +- arch/alpha/kernel/time.c | 98 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 165 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/alpha/include/asm/pal.h b/arch/alpha/include/asm/pal.h index e78ec9bcc76..5422a47646f 100644 --- a/arch/alpha/include/asm/pal.h +++ b/arch/alpha/include/asm/pal.h @@ -112,5 +112,75 @@ __CALL_PAL_RW1(wtint, unsigned long, unsigned long); #define tbiap() __tbi(-1, /* no second argument */) #define tbia() __tbi(-2, /* no second argument */) +/* + * QEMU Cserv routines.. + */ + +static inline unsigned long +qemu_get_walltime(void) +{ + register unsigned long v0 __asm__("$0"); + register unsigned long a0 __asm__("$16") = 3; + + asm("call_pal %2 # cserve get_time" + : "=r"(v0), "+r"(a0) + : "i"(PAL_cserve) + : "$17", "$18", "$19", "$20", "$21"); + + return v0; +} + +static inline unsigned long +qemu_get_alarm(void) +{ + register unsigned long v0 __asm__("$0"); + register unsigned long a0 __asm__("$16") = 4; + + asm("call_pal %2 # cserve get_alarm" + : "=r"(v0), "+r"(a0) + : "i"(PAL_cserve) + : "$17", "$18", "$19", "$20", "$21"); + + return v0; +} + +static inline void +qemu_set_alarm_rel(unsigned long expire) +{ + register unsigned long a0 __asm__("$16") = 5; + register unsigned long a1 __asm__("$17") = expire; + + asm volatile("call_pal %2 # cserve set_alarm_rel" + : "+r"(a0), "+r"(a1) + : "i"(PAL_cserve) + : "$0", "$18", "$19", "$20", "$21"); +} + +static inline void +qemu_set_alarm_abs(unsigned long expire) +{ + register unsigned long a0 __asm__("$16") = 6; + register unsigned long a1 __asm__("$17") = expire; + + asm volatile("call_pal %2 # cserve set_alarm_abs" + : "+r"(a0), "+r"(a1) + : "i"(PAL_cserve) + : "$0", "$18", "$19", "$20", "$21"); +} + +static inline unsigned long +qemu_get_vmtime(void) +{ + register unsigned long v0 __asm__("$0"); + register unsigned long a0 __asm__("$16") = 7; + + asm("call_pal %2 # cserve get_time" + : "=r"(v0), "+r"(a0) + : "i"(PAL_cserve) + : "$17", "$18", "$19", "$20", "$21"); + + return v0; +} + #endif /* !__ASSEMBLY__ */ #endif /* __ALPHA_PAL_H */ diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 6990ddc0fba..1c8625cb0e2 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -214,7 +214,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr, */ struct irqaction timer_irqaction = { - .handler = timer_interrupt, + .handler = rtc_timer_interrupt, .name = "timer", }; diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index bc806893afe..da2d6ec9c37 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -140,7 +140,7 @@ extern void handle_ipi(struct pt_regs *); /* extern void reset_for_srm(void); */ /* time.c */ -extern irqreturn_t timer_interrupt(int irq, void *dev); +extern irqreturn_t rtc_timer_interrupt(int irq, void *dev); extern void init_clockevent(void); extern void common_init_rtc(void); extern unsigned long est_cycle_freq; diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 08ff3f502a7..ee39cee8064 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -87,7 +87,7 @@ static inline __u32 rpcc(void) static DEFINE_PER_CPU(struct clock_event_device, cpu_ce); irqreturn_t -timer_interrupt(int irq, void *dev) +rtc_timer_interrupt(int irq, void *dev) { int cpu = smp_processor_id(); struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); @@ -118,8 +118,8 @@ rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce) return -EINVAL; } -void __init -init_clockevent(void) +static void __init +init_rtc_clockevent(void) { int cpu = smp_processor_id(); struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); @@ -136,6 +136,75 @@ init_clockevent(void) clockevents_config_and_register(ce, CONFIG_HZ, 0, 0); } + +/* + * The QEMU clock as a clocksource primitive. + */ + +static cycle_t +qemu_cs_read(struct clocksource *cs) +{ + return qemu_get_vmtime(); +} + +static struct clocksource qemu_cs = { + .name = "qemu", + .rating = 400, + .read = qemu_cs_read, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .max_idle_ns = LONG_MAX +}; + + +/* + * The QEMU alarm as a clock_event_device primitive. + */ + +static void +qemu_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce) +{ + /* The mode member of CE is updated for us in generic code. + Just make sure that the event is disabled. */ + qemu_set_alarm_abs(0); +} + +static int +qemu_ce_set_next_event(unsigned long evt, struct clock_event_device *ce) +{ + qemu_set_alarm_rel(evt); + return 0; +} + +static irqreturn_t +qemu_timer_interrupt(int irq, void *dev) +{ + int cpu = smp_processor_id(); + struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); + + ce->event_handler(ce); + return IRQ_HANDLED; +} + +static void __init +init_qemu_clockevent(void) +{ + int cpu = smp_processor_id(); + struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); + + *ce = (struct clock_event_device){ + .name = "qemu", + .features = CLOCK_EVT_FEAT_ONESHOT, + .rating = 400, + .cpumask = cpumask_of(cpu), + .set_mode = qemu_ce_set_mode, + .set_next_event = qemu_ce_set_next_event, + }; + + clockevents_config_and_register(ce, NSEC_PER_SEC, 1000, LONG_MAX); +} + + void __init common_init_rtc(void) { @@ -329,6 +398,15 @@ time_init(void) unsigned long cycle_freq, tolerance; long diff; + if (alpha_using_qemu) { + clocksource_register_hz(&qemu_cs, NSEC_PER_SEC); + init_qemu_clockevent(); + + timer_irqaction.handler = qemu_timer_interrupt; + init_rtc_irq(); + return; + } + /* Calibrate CPU clock -- attempt #1. */ if (!est_cycle_freq) est_cycle_freq = validate_cc_value(calibrate_cc_with_pit()); @@ -371,7 +449,17 @@ time_init(void) /* Startup the timer source. */ alpha_mv.init_rtc(); + init_rtc_clockevent(); +} - /* Start up the clock event device. */ - init_clockevent(); +/* Initialize the clock_event_device for secondary cpus. */ +#ifdef CONFIG_SMP +void __init +init_clockevent(void) +{ + if (alpha_using_qemu) + init_qemu_clockevent(); + else + init_rtc_clockevent(); } +#endif -- cgit v1.2.3-70-g09d2 From 6e22f8f2e8d81dcab4c40bc229d53388fda63dbc Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 10 Sep 2013 10:58:12 +0100 Subject: alpha: perf: fix out-of-bounds array access triggered from raw event Vince's perf fuzzer uncovered the following issue on Alpha: Unable to handle kernel paging request at virtual address fffffbfe4e46a0e8 CPU 0 perf_fuzzer(1278): Oops 0 pc = [] ra = [] ps = 0007 Not tainted pc is at alpha_perf_event_set_period+0x60/0xf0 ra is at alpha_pmu_enable+0x1a4/0x1c0 v0 = 0000000000000000 t0 = 00000000000fffff t1 = fffffc007b3f5800 t2 = fffffbff275faa94 t3 = ffffffffc9b9bd89 t4 = fffffbfe4e46a098 t5 = 0000000000000020 t6 = fffffbfe4e46a0b8 t7 = fffffc007f4c8000 s0 = 0000000000000000 s1 = fffffc0001b0c018 s2 = fffffc0001b0c020 s3 = fffffc007b3f5800 s4 = 0000000000000001 s5 = ffffffffc9b9bd85 s6 = 0000000000000001 a0 = 0000000000000006 a1 = fffffc007b3f5908 a2 = fffffbfe4e46a098 a3 = 00000005000108c0 a4 = 0000000000000000 a5 = 0000000000000000 t8 = 0000000000000001 t9 = 0000000000000001 t10= 0000000027829f6f t11= 0000000000000020 pv = fffffc000031fb60 at = fffffc0000950900 gp = fffffc0000940900 sp = fffffc007f4cbca8 Disabling lock debugging due to kernel taint Trace: [] alpha_pmu_enable+0x1a4/0x1c0 [] perf_pmu_enable+0x48/0x60 [] __perf_install_in_context+0x15c/0x230 [] remote_function+0x80/0xa0 [] __perf_install_in_context+0x0/0x230 [] smp_call_function_single+0x1b4/0x1d0 [] task_function_call+0x60/0x80 [] __perf_install_in_context+0x0/0x230 [] task_function_call+0x34/0x80 [] perf_install_in_context+0x9c/0x150 [] __perf_install_in_context+0x0/0x230 [] SYSC_perf_event_open+0x360/0xac0 [] entSys+0xa4/0xc0 This is due to the raw event encoding being used as an index directly into the ev67_mapping array, rather than being validated against the ev67_pmc_event_type enumeration instead. Unlike other architectures, which allow raw events to propagate into the hardware counters with little interference, the limited number of events on Alpha and the strict event <-> counter relationships mean that raw events actually correspond to the Linux-specific Alpha events, rather than anything defined by the architecture. This patch adds a new callback to alpha_pmu_t for validating the raw event encoding with the Linux event types for the PMU, preventing the out-of-bounds array access. Cc: Peter Zijlstra Acked-by: Michael Cree Acked-by: Matt Turner Signed-off-by: Will Deacon --- arch/alpha/kernel/perf_event.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index d821b17047e..c52e7f0ee5f 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c @@ -83,6 +83,8 @@ struct alpha_pmu_t { long pmc_left[3]; /* Subroutine for allocation of PMCs. Enforces constraints. */ int (*check_constraints)(struct perf_event **, unsigned long *, int); + /* Subroutine for checking validity of a raw event for this PMU. */ + int (*raw_event_valid)(u64 config); }; /* @@ -203,6 +205,12 @@ success: } +static int ev67_raw_event_valid(u64 config) +{ + return config >= EV67_CYCLES && config < EV67_LAST_ET; +}; + + static const struct alpha_pmu_t ev67_pmu = { .event_map = ev67_perfmon_event_map, .max_events = ARRAY_SIZE(ev67_perfmon_event_map), @@ -211,7 +219,8 @@ static const struct alpha_pmu_t ev67_pmu = { .pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0}, .pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0}, .pmc_left = {16, 4, 0}, - .check_constraints = ev67_check_constraints + .check_constraints = ev67_check_constraints, + .raw_event_valid = ev67_raw_event_valid, }; @@ -609,7 +618,9 @@ static int __hw_perf_event_init(struct perf_event *event) } else if (attr->type == PERF_TYPE_HW_CACHE) { return -EOPNOTSUPP; } else if (attr->type == PERF_TYPE_RAW) { - ev = attr->config & 0xff; + if (!alpha_pmu->raw_event_valid(attr->config)) + return -EINVAL; + ev = attr->config; } else { return -EOPNOTSUPP; } -- cgit v1.2.3-70-g09d2 From 5cfe8f1ba5eebe6f4b6e5858cdb1a5be4f3272a6 Mon Sep 17 00:00:00 2001 From: Jay Estabrook Date: Sat, 16 Nov 2013 16:45:31 -0800 Subject: alpha: Prevent a NULL ptr dereference in csum_partial_copy. Introduced by 3ddc5b46a8e90f3c92 ("kernel-wide: fix missing validations on __get/__put/__copy_to/__copy_from_user()"). Also fix some other places which could be problematic in a similar way, although they hadn't been proved so, as far as I can tell. Cc: Michael Cree Signed-off-by: Matt Turner --- arch/alpha/lib/csum_partial_copy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c index ffb19b7da99..ff3c10721ca 100644 --- a/arch/alpha/lib/csum_partial_copy.c +++ b/arch/alpha/lib/csum_partial_copy.c @@ -130,7 +130,7 @@ csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst, *dst = word | tmp; checksum += carry; } - if (err) *errp = err; + if (err && errp) *errp = err; return checksum; } @@ -185,7 +185,7 @@ csum_partial_cfu_dest_aligned(const unsigned long __user *src, *dst = word | tmp; checksum += carry; } - if (err) *errp = err; + if (err && errp) *errp = err; return checksum; } @@ -242,7 +242,7 @@ csum_partial_cfu_src_aligned(const unsigned long __user *src, stq_u(partial_dest | second_dest, dst); out: checksum += carry; - if (err) *errp = err; + if (err && errp) *errp = err; return checksum; } @@ -325,7 +325,7 @@ csum_partial_cfu_unaligned(const unsigned long __user * src, stq_u(partial_dest | word | second_dest, dst); checksum += carry; } - if (err) *errp = err; + if (err && errp) *errp = err; return checksum; } @@ -339,7 +339,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst, int len, if (len) { if (!access_ok(VERIFY_READ, src, len)) { - *errp = -EFAULT; + if (errp) *errp = -EFAULT; memset(dst, 0, len); return sum; } -- cgit v1.2.3-70-g09d2 From 40c2729bab48e2832b17c1fa8af9db60e776131b Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Fri, 15 Nov 2013 13:14:12 -0800 Subject: arm/arm64: KVM: Fix hyp mappings of vmalloc regions Using virt_to_phys on percpu mappings is horribly wrong as it may be backed by vmalloc. Introduce kvm_kaddr_to_phys which translates both types of valid kernel addresses to the corresponding physical address. At the same time resolves a typing issue where we were storing the physical address as a 32 bit unsigned long (on arm), truncating the physical address for addresses above the 4GB limit. This caused breakage on Keystone. Cc: [3.10+] Reported-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm/kvm/mmu.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index b0de86b56c1..cb79a5dd6d9 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -307,6 +307,17 @@ out: return err; } +static phys_addr_t kvm_kaddr_to_phys(void *kaddr) +{ + if (!is_vmalloc_addr(kaddr)) { + BUG_ON(!virt_addr_valid(kaddr)); + return __pa(kaddr); + } else { + return page_to_phys(vmalloc_to_page(kaddr)) + + offset_in_page(kaddr); + } +} + /** * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode * @from: The virtual kernel start address of the range @@ -318,16 +329,27 @@ out: */ int create_hyp_mappings(void *from, void *to) { - unsigned long phys_addr = virt_to_phys(from); + phys_addr_t phys_addr; + unsigned long virt_addr; unsigned long start = KERN_TO_HYP((unsigned long)from); unsigned long end = KERN_TO_HYP((unsigned long)to); - /* Check for a valid kernel memory mapping */ - if (!virt_addr_valid(from) || !virt_addr_valid(to - 1)) - return -EINVAL; + start = start & PAGE_MASK; + end = PAGE_ALIGN(end); - return __create_hyp_mappings(hyp_pgd, start, end, - __phys_to_pfn(phys_addr), PAGE_HYP); + for (virt_addr = start; virt_addr < end; virt_addr += PAGE_SIZE) { + int err; + + phys_addr = kvm_kaddr_to_phys(from + virt_addr - start); + err = __create_hyp_mappings(hyp_pgd, virt_addr, + virt_addr + PAGE_SIZE, + __phys_to_pfn(phys_addr), + PAGE_HYP); + if (err) + return err; + } + + return 0; } /** -- cgit v1.2.3-70-g09d2 From 793b4b10720174b6b27beaf915425248858d7fc5 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 16 Nov 2013 22:38:29 +0800 Subject: ARM: dts: imx6qdl: disable spdif "rxtx5" clock option The spdif "rxtx5" clock option is being set to ipg clk (62) by mistake. This causes an incorrect time keeping when spdif driver is running, because ipg is ancestor clock for clocksource while spdif driver will change the rate of this clock in certain circumstance. Before the correct clock for "rxtx5" option can be supplied, let's disable this option for now by filling a dummy clock for it. Reported-by: Russell King Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 59154dc15fe..fb28b2ecb1d 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -161,7 +161,7 @@ clocks = <&clks 197>, <&clks 3>, <&clks 197>, <&clks 107>, <&clks 0>, <&clks 118>, - <&clks 62>, <&clks 139>, + <&clks 0>, <&clks 139>, <&clks 0>; clock-names = "core", "rxtx0", "rxtx1", "rxtx2", -- cgit v1.2.3-70-g09d2 From c8999a889f466bd4e4db45337a43b8544b91c550 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 18 Nov 2013 08:48:07 -0500 Subject: arm/xen: Export phys_to_mach to fix Xen module link errors Various xen drivers fail to link when built as modules with the following error: ERROR: "phys_to_mach" [drivers/xen/xen-gntalloc.ko] undefined! ERROR: "phys_to_mach" [drivers/net/xen-netfront.ko] undefined! ERROR: "phys_to_mach" [drivers/net/xen-netback/xen-netback.ko] undefined! ERROR: "phys_to_mach" [drivers/block/xen-blkfront.ko] undefined! The mfn_to_pfn and pfn_to_mfn functions get inlined in these modules and those functions require phys_to_mach. Export the symbol to fix the link errors. Signed-off-by: Josh Boyer Signed-off-by: Stefano Stabellini --- arch/arm/xen/p2m.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c index 23732cdff55..0f842e85879 100644 --- a/arch/arm/xen/p2m.c +++ b/arch/arm/xen/p2m.c @@ -27,6 +27,7 @@ struct xen_p2m_entry { rwlock_t p2m_lock; struct rb_root phys_to_mach = RB_ROOT; +EXPORT_SYMBOL_GPL(phys_to_mach); static struct rb_root mach_to_phys = RB_ROOT; static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new) -- cgit v1.2.3-70-g09d2 From f9c7ec1649607d68a47ab99e2ebb3379a2016157 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Sun, 17 Nov 2013 16:31:34 +0000 Subject: xen/arm: p2m_init and p2m_lock should be static Signed-off-by: Stefano Stabellini --- arch/arm/xen/p2m.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c index 0f842e85879..b31ee1b275b 100644 --- a/arch/arm/xen/p2m.c +++ b/arch/arm/xen/p2m.c @@ -25,7 +25,7 @@ struct xen_p2m_entry { struct rb_node rbnode_phys; }; -rwlock_t p2m_lock; +static rwlock_t p2m_lock; struct rb_root phys_to_mach = RB_ROOT; EXPORT_SYMBOL_GPL(phys_to_mach); static struct rb_root mach_to_phys = RB_ROOT; @@ -201,7 +201,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) } EXPORT_SYMBOL_GPL(__set_phys_to_machine); -int p2m_init(void) +static int p2m_init(void) { rwlock_init(&p2m_lock); return 0; -- cgit v1.2.3-70-g09d2 From cae26f31138a7f5850294e3bc4500e4283890f9f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sat, 16 Nov 2013 07:15:25 -0800 Subject: ARM: OMAP2+: More randconfig fixes for reconfigure_io_chain Commit 26273e02a0cf (ARM: OMAP2+: Fix build for dra7xx without omap4 and 5) attempted to fix randconfig found errors for redefinition of omap44xx_prm_reconfigure_io_chain, but was not enough. We need to check for AM43XX without any omap4 or 5 related SoCs as well. And looks like we have prm44xx.o built always anyways with omap-4-5-prcm-common because of the calls to omap4_prm_vp_clear_txdone, so we can remove the duplicate entries in the Makefile. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 6 +++--- arch/arm/mach-omap2/prm44xx_54xx.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 1f25f3e99c0..adcef406ff0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -19,11 +19,11 @@ secure-common = omap-smc.o omap-secure.o obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) -obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common) +obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common) obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common) -obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common) obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common) -obj-$(CONFIG_SOC_DRA7XX) += prm44xx.o $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common) ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) obj-y += mcbsp.o diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h index 7a976065e13..8d95aa543ef 100644 --- a/arch/arm/mach-omap2/prm44xx_54xx.h +++ b/arch/arm/mach-omap2/prm44xx_54xx.h @@ -43,7 +43,7 @@ extern void omap4_prm_vcvp_write(u32 val, u8 offset); extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ - defined(CONFIG_SOC_DRA7XX) + defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX) void omap44xx_prm_reconfigure_io_chain(void); #else static inline void omap44xx_prm_reconfigure_io_chain(void) -- cgit v1.2.3-70-g09d2 From 39cec6222924dfbb5d7f5d2b2f718af34e872add Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 18 Nov 2013 13:56:48 -0800 Subject: ARM: OMAP2+: Fix undefined reference to set_cntfreq If CONFIG_SOC_HAS_REALTIME_COUNTER is not selected for omap5 or dra7xx, we can get the following error: arch/arm/mach-omap2/built-in.o: In function `omap4_secondary_init': :(.text+0x7ab0): undefined reference to `set_cntfreq' Fix the issue by not trying to initalize the realtime counter unles CONFIG_SOC_HAS_REALTIME_COUNTER is selected. Acked-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap-secure.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index 8cc7d331437..3e97c6c8ecf 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -76,6 +76,13 @@ static inline void omap_barrier_reserve_memblock(void) { } #endif +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER void set_cntfreq(void); +#else +static inline void set_cntfreq(void) +{ +} +#endif + #endif /* __ASSEMBLER__ */ #endif /* OMAP_ARCH_OMAP_SECURE_H */ -- cgit v1.2.3-70-g09d2 From e30b06f4d5f000c31a7747a7e7ada78a5fd419a1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 18 Nov 2013 16:24:57 -0800 Subject: ARM: OMAP2+: Remove legacy mux code for display.c This is all omap4 specific, which is device tree based nowadays and should use pinctrl-single instead. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/display.c | 78 ------------------------------------------- 1 file changed, 78 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index a4e536b11ec..58347bb874a 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -32,7 +32,6 @@ #include "soc.h" #include "iomap.h" -#include "mux.h" #include "control.h" #include "display.h" #include "prm.h" @@ -102,90 +101,13 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = { { "dss_hdmi", "omapdss_hdmi", -1 }, }; -static void __init omap4_tpd12s015_mux_pads(void) -{ - omap_mux_init_signal("hdmi_cec", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("hdmi_ddc_scl", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("hdmi_ddc_sda", - OMAP_PIN_INPUT_PULLUP); -} - -static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) -{ - u32 reg; - u16 control_i2c_1; - - /* - * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and - * HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable - * internal pull up resistor. - */ - if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) { - control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1; - reg = omap4_ctrl_pad_readl(control_i2c_1); - reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK | - OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK); - omap4_ctrl_pad_writel(reg, control_i2c_1); - } -} - -static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) -{ - u32 enable_mask, enable_shift; - u32 pipd_mask, pipd_shift; - u32 reg; - - if (dsi_id == 0) { - enable_mask = OMAP4_DSI1_LANEENABLE_MASK; - enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT; - pipd_mask = OMAP4_DSI1_PIPD_MASK; - pipd_shift = OMAP4_DSI1_PIPD_SHIFT; - } else if (dsi_id == 1) { - enable_mask = OMAP4_DSI2_LANEENABLE_MASK; - enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT; - pipd_mask = OMAP4_DSI2_PIPD_MASK; - pipd_shift = OMAP4_DSI2_PIPD_SHIFT; - } else { - return -ENODEV; - } - - reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY); - - reg &= ~enable_mask; - reg &= ~pipd_mask; - - reg |= (lanes << enable_shift) & enable_mask; - reg |= (lanes << pipd_shift) & pipd_mask; - - omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY); - - return 0; -} - -int __init omap_hdmi_init(enum omap_hdmi_flags flags) -{ - if (cpu_is_omap44xx()) { - omap4_hdmi_mux_pads(flags); - omap4_tpd12s015_mux_pads(); - } - - return 0; -} - static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask) { - if (cpu_is_omap44xx()) - return omap4_dsi_mux_pads(dsi_id, lane_mask); - return 0; } static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask) { - if (cpu_is_omap44xx()) - omap4_dsi_mux_pads(dsi_id, 0); } static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput) -- cgit v1.2.3-70-g09d2 From b2ff4790612bbfa3433cc92e56445c2a40098e2c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 18 Nov 2013 16:24:58 -0800 Subject: ARM: OMAP2+: Remove legacy omap4_twl6030_hsmmc_init This is no longer used, omap4 is device tree based now. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/common.h | 1 - arch/arm/mach-omap2/omap4-common.c | 57 -------------------------------------- 2 files changed, 58 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index f7644febee8..e30ef6797c6 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -299,7 +299,6 @@ struct omap_sdrc_params; extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1); struct omap2_hsmmc_info; -extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers); extern void omap_reserve(void); struct omap_hwmod; diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 57911430324..b39efd46abf 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -35,7 +35,6 @@ #include "iomap.h" #include "common.h" #include "mmc.h" -#include "hsmmc.h" #include "prminst44xx.h" #include "prcm_mpu44xx.h" #include "omap4-sar-layout.h" @@ -284,59 +283,3 @@ skip_errata_init: omap_wakeupgen_init(); irqchip_init(); } - -#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) -static int omap4_twl6030_hsmmc_late_init(struct device *dev) -{ - int irq = 0; - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); - struct omap_mmc_platform_data *pdata = dev->platform_data; - - /* Setting MMC1 Card detect Irq */ - if (pdev->id == 0) { - irq = twl6030_mmc_card_detect_config(); - if (irq < 0) { - dev_err(dev, "%s: Error card detect config(%d)\n", - __func__, irq); - return irq; - } - pdata->slots[0].card_detect_irq = irq; - pdata->slots[0].card_detect = twl6030_mmc_card_detect; - } - return 0; -} - -static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) -{ - struct omap_mmc_platform_data *pdata; - - /* dev can be null if CONFIG_MMC_OMAP_HS is not set */ - if (!dev) { - pr_err("Failed %s\n", __func__); - return; - } - pdata = dev->platform_data; - pdata->init = omap4_twl6030_hsmmc_late_init; -} - -int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) -{ - struct omap2_hsmmc_info *c; - - omap_hsmmc_init(controllers); - for (c = controllers; c->mmc; c++) { - /* pdev can be null if CONFIG_MMC_OMAP_HS is not set */ - if (!c->pdev) - continue; - omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev); - } - - return 0; -} -#else -int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) -{ - return 0; -} -#endif -- cgit v1.2.3-70-g09d2 From 5761704a41c63ebe756295a13d2e236280dd8a86 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 18 Nov 2013 06:01:38 +0100 Subject: ARM: 7892/1: Fix warning for V7M builds Fixes a harmless warning when building for V7M (!MMU): arch/arm/kernel/traps.c:859:123: warning: 'kuser_init' defined but not used [-Wunused-function] By making the stub static inline instead of just static. Fixes: f6f91b0d9fd9 ('ARM: allow kuser helpers to be removed from the vector page') Signed-off-by: Olof Johansson Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 6125f259b7b..dbf0923e8d7 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -856,7 +856,7 @@ static void __init kuser_init(void *vectors) memcpy(vectors + 0xfe0, vectors + 0xfe8, 4); } #else -static void __init kuser_init(void *vectors) +static inline void __init kuser_init(void *vectors) { } #endif -- cgit v1.2.3-70-g09d2 From d5b5f391d434c5cc8bcb1ab2d759738797b85f52 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 14 Nov 2013 16:23:04 +0100 Subject: ftrace, perf: Avoid infinite event generation loop Vince's perf-trinity fuzzer found yet another 'interesting' problem. When we sample the irq_work_exit tracepoint with period==1 (or PERF_SAMPLE_PERIOD) and we add an fasync SIGNAL handler we create an infinite event generation loop: ,-> | irq_work_exit() -> | trace_irq_work_exit() -> | ... | __perf_event_overflow() -> (due to fasync) | irq_work_queue() -> (irq_work_list must be empty) '--------- arch_irq_work_raise() Similar things can happen due to regular poll() wakeups if we exceed the ring-buffer wakeup watermark, or have an event_limit. To avoid this, dis-allow sampling this particular tracepoint. In order to achieve this, create a special perf_perm function pointer for each event and call this (when set) on trying to create a tracepoint perf event. [ roasted: use expr... to allow for ',' in your expression ] Reported-by: Vince Weaver Tested-by: Vince Weaver Signed-off-by: Peter Zijlstra Cc: Steven Rostedt Cc: Dave Jones Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/20131114152304.GC5364@laptop.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/trace/irq_vectors.h | 11 +++++++++++ include/linux/ftrace_event.h | 16 ++++++++++++++++ include/linux/tracepoint.h | 4 ++++ include/trace/ftrace.h | 7 +++++++ kernel/trace/trace_event_perf.c | 6 ++++++ 5 files changed, 44 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h index 2874df24e7a..4cab890007a 100644 --- a/arch/x86/include/asm/trace/irq_vectors.h +++ b/arch/x86/include/asm/trace/irq_vectors.h @@ -71,6 +71,17 @@ DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi); */ DEFINE_IRQ_VECTOR_EVENT(irq_work); +/* + * We must dis-allow sampling irq_work_exit() because perf event sampling + * itself can cause irq_work, which would lead to an infinite loop; + * + * 1) irq_work_exit happens + * 2) generates perf sample + * 3) generates irq_work + * 4) goto 1 + */ +TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0); + /* * call_function - called when entering/exiting a call function interrupt * vector handler diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 9abbe630c45..8c9b7a1c413 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -248,6 +248,9 @@ struct ftrace_event_call { #ifdef CONFIG_PERF_EVENTS int perf_refcount; struct hlist_head __percpu *perf_events; + + int (*perf_perm)(struct ftrace_event_call *, + struct perf_event *); #endif }; @@ -317,6 +320,19 @@ struct ftrace_event_file { } \ early_initcall(trace_init_flags_##name); +#define __TRACE_EVENT_PERF_PERM(name, expr...) \ + static int perf_perm_##name(struct ftrace_event_call *tp_event, \ + struct perf_event *p_event) \ + { \ + return ({ expr; }); \ + } \ + static int __init trace_init_perf_perm_##name(void) \ + { \ + event_##name.perf_perm = &perf_perm_##name; \ + return 0; \ + } \ + early_initcall(trace_init_perf_perm_##name); + #define PERF_MAX_TRACE_SIZE 2048 #define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index ebeab360d85..f16dc0a4004 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -267,6 +267,8 @@ static inline void tracepoint_synchronize_unregister(void) #define TRACE_EVENT_FLAGS(event, flag) +#define TRACE_EVENT_PERF_PERM(event, expr...) + #endif /* DECLARE_TRACE */ #ifndef TRACE_EVENT @@ -399,4 +401,6 @@ static inline void tracepoint_synchronize_unregister(void) #define TRACE_EVENT_FLAGS(event, flag) +#define TRACE_EVENT_PERF_PERM(event, expr...) + #endif /* ifdef TRACE_EVENT (see note above) */ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 52594b20179..6b852f60f8a 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -90,6 +90,10 @@ #define TRACE_EVENT_FLAGS(name, value) \ __TRACE_EVENT_FLAGS(name, value) +#undef TRACE_EVENT_PERF_PERM +#define TRACE_EVENT_PERF_PERM(name, expr...) \ + __TRACE_EVENT_PERF_PERM(name, expr) + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) @@ -140,6 +144,9 @@ #undef TRACE_EVENT_FLAGS #define TRACE_EVENT_FLAGS(event, flag) +#undef TRACE_EVENT_PERF_PERM +#define TRACE_EVENT_PERF_PERM(event, expr...) + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 78e27e3b52a..630889f68b1 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -24,6 +24,12 @@ static int total_ref_count; static int perf_trace_event_perm(struct ftrace_event_call *tp_event, struct perf_event *p_event) { + if (tp_event->perf_perm) { + int ret = tp_event->perf_perm(tp_event, p_event); + if (ret) + return ret; + } + /* The ftrace function trace is allowed only for root. */ if (ftrace_event_is_function(tp_event) && perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN)) -- cgit v1.2.3-70-g09d2 From a0ffa8f06f77a6197405521324501614d281bee1 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 19 Nov 2013 23:31:35 +0100 Subject: Revert "parisc: implement full version of access_ok()" This reverts commit 63379c135331c724d40a87b98eb62d2122981341. It broke userspace and adding more checking is not needed. Even checking if a syscall would access memory in page zero doesn't makes sense since it may lead to some syscalls returning -EFAULT where we would return other error codes on other platforms. In summary, just drop this change and return to always return 1. Signed-off-by: Helge Deller --- arch/parisc/include/asm/uaccess.h | 46 ++++----------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 63f4dd0b49c..4006964d8e1 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -4,14 +4,11 @@ /* * User space memory access functions */ -#include #include #include #include #include -#include - #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -36,43 +33,12 @@ extern int __get_user_bad(void); extern int __put_kernel_bad(void); extern int __put_user_bad(void); - -/* - * Test whether a block of memory is a valid user space address. - * Returns 0 if the range is valid, nonzero otherwise. - */ -static inline int __range_not_ok(unsigned long addr, unsigned long size, - unsigned long limit) +static inline long access_ok(int type, const void __user * addr, + unsigned long size) { - unsigned long __newaddr = addr + size; - return (__newaddr < addr || __newaddr > limit || size > limit); + return 1; } -/** - * access_ok: - Checks if a user space pointer is valid - * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that - * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe - * to write to a block, it is always safe to read from it. - * @addr: User space pointer to start of block to check - * @size: Size of block to check - * - * Context: User context only. This function may sleep. - * - * Checks if a pointer to a block of memory in user space is valid. - * - * Returns true (nonzero) if the memory block may be valid, false (zero) - * if it is definitely invalid. - * - * Note that, depending on architecture, this function probably just - * checks that the pointer is in the user space range - after calling - * this function, memory access functions may still return -EFAULT. - */ -#define access_ok(type, addr, size) \ -( __chk_user_ptr(addr), \ - !__range_not_ok((unsigned long) (__force void *) (addr), \ - size, user_addr_max()) \ -) - #define put_user __put_user #define get_user __get_user @@ -253,11 +219,7 @@ extern long lstrnlen_user(const char __user *,long); /* * Complex access routines -- macros */ -#ifdef CONFIG_COMPAT -#define user_addr_max() (TASK_SIZE) -#else -#define user_addr_max() (DEFAULT_TASK_SIZE) -#endif +#define user_addr_max() (~0UL) #define strnlen_user lstrnlen_user #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL) -- cgit v1.2.3-70-g09d2 From 9af63aedb84c4281cde1610280246f7749c27799 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 17 Nov 2013 22:03:11 +0100 Subject: parisc: do not inline pa_memcpy() internal functions gcc (4.8.x) creates wrong code when the pa_memcpy() functions are inlined. Especially in 32bit builds it calculates wrong return values if we encounter a fault during execution of the memcpy. Signed-off-by: Helge Deller --- arch/parisc/lib/memcpy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index b5507ec06b8..6c5b5d35bfc 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -161,7 +161,7 @@ static inline void prefetch_dst(const void *addr) /* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words * per loop. This code is derived from glibc. */ -static inline unsigned long copy_dstaligned(unsigned long dst, +static noinline unsigned long copy_dstaligned(unsigned long dst, unsigned long src, unsigned long len) { /* gcc complains that a2 and a3 may be uninitialized, but actually @@ -276,7 +276,7 @@ handle_store_error: /* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR. * In case of an access fault the faulty address can be read from the per_cpu * exception data struct. */ -static unsigned long pa_memcpy_internal(void *dstp, const void *srcp, +static noinline unsigned long pa_memcpy_internal(void *dstp, const void *srcp, unsigned long len) { register unsigned long src, dst, t1, t2, t3; -- cgit v1.2.3-70-g09d2 From 38c7937379276a5ea8c54481205003af2f2b5694 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 14 Oct 2013 21:04:13 +0200 Subject: parisc: break out SOCK_NONBLOCK define to own asm header file Break SOCK_NONBLOCK out to its own asm-file as other arches do. This fixes build errors with auditd and probably other packages. Signed-off-by: Helge Deller --- arch/parisc/include/asm/socket.h | 11 +++++++++++ arch/parisc/include/uapi/asm/socket.h | 11 +++-------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 arch/parisc/include/asm/socket.h (limited to 'arch') diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h new file mode 100644 index 00000000000..748016cb122 --- /dev/null +++ b/arch/parisc/include/asm/socket.h @@ -0,0 +1,11 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include + +/* O_NONBLOCK clashes with the bits used for socket types. Therefore we + * have to define SOCK_NONBLOCK to a different value here. + */ +#define SOCK_NONBLOCK 0x40000000 + +#endif /* _ASM_SOCKET_H */ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 7c614d01f1f..f33113a6141 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -1,5 +1,5 @@ -#ifndef _ASM_SOCKET_H -#define _ASM_SOCKET_H +#ifndef _UAPI_ASM_SOCKET_H +#define _UAPI_ASM_SOCKET_H #include @@ -77,9 +77,4 @@ #define SO_MAX_PACING_RATE 0x4048 -/* O_NONBLOCK clashes with the bits used for socket types. Therefore we - * have to define SOCK_NONBLOCK to a different value here. - */ -#define SOCK_NONBLOCK 0x40000000 - -#endif /* _ASM_SOCKET_H */ +#endif /* _UAPI_ASM_SOCKET_H */ -- cgit v1.2.3-70-g09d2 From 49d1cb2bcadfc5cea4b700a0ec6b957567889714 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 18 Nov 2013 22:12:11 +0100 Subject: parisc: improve SIGBUS/SIGSEGV error reporting This patch fixes most of the Linux Test Project testcases, e.g. fstat05. Signed-off-by: Helge Deller --- arch/parisc/mm/fault.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 7584a5df0fa..9d08c71a967 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -282,16 +282,34 @@ bad_area: #endif switch (code) { case 15: /* Data TLB miss fault/Data page fault */ + /* send SIGSEGV when outside of vma */ + if (!vma || + address < vma->vm_start || address > vma->vm_end) { + si.si_signo = SIGSEGV; + si.si_code = SEGV_MAPERR; + break; + } + + /* send SIGSEGV for wrong permissions */ + if ((vma->vm_flags & acc_type) != acc_type) { + si.si_signo = SIGSEGV; + si.si_code = SEGV_ACCERR; + break; + } + + /* probably address is outside of mapped file */ + /* fall through */ case 17: /* NA data TLB miss / page fault */ case 18: /* Unaligned access - PCXS only */ si.si_signo = SIGBUS; - si.si_code = BUS_ADRERR; + si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR; break; case 16: /* Non-access instruction TLB miss fault */ case 26: /* PCXL: Data memory access rights trap */ default: si.si_signo = SIGSEGV; - si.si_code = SEGV_MAPERR; + si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; + break; } si.si_errno = 0; si.si_addr = (void __user *) address; -- cgit v1.2.3-70-g09d2 From 964f413323e8306ac0acb5e08ccdb5f12418835b Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 12 Nov 2013 21:01:24 +0100 Subject: parisc: size_t is unsigned, so comparison size < 0 doesn't make sense. Signed-off-by: Helge Deller CC: Mikulas Patocka --- arch/parisc/lib/memcpy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index 6c5b5d35bfc..413dc176929 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -529,7 +529,7 @@ long probe_kernel_read(void *dst, const void *src, size_t size) { unsigned long addr = (unsigned long)src; - if (size < 0 || addr < PAGE_SIZE) + if (addr < PAGE_SIZE) return -EFAULT; /* check for I/O space F_EXTEND(0xfff00000) access as well? */ -- cgit v1.2.3-70-g09d2 From aa7e04b3808614980d474735cdb0bf35ac5cdf26 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 19 Nov 2013 12:26:09 +0100 Subject: s390/signal: always restore saved runtime instrumentation psw bit Commit "s390: fix handling of runtime instrumentation psw bit" (5ebf250dab) changed the behavior of setting the runtime instrumentation psw bit. This commit restores the original logic: 1. When returning from the signal handler, the runtime instrumentation psw bit is restored to its saved state. 2. If the runtime instrumentation psw bit is enabled during the signal handler, it is always turned off when leaving the signal handler. The saved state is restored as described in 1. That also implies that turning on runtime instrumentation in the signal handler is only effective while running in the signal context. Signed-off-by: Hendrik Brueckner --- arch/s390/kernel/compat_signal.c | 2 +- arch/s390/kernel/signal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 6e244297840..95e7ba0fbb7 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -194,7 +194,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) return -EINVAL; /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ - regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | + regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 | (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 | (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index fb535874a24..d8fd508ccd1 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -94,7 +94,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) return -EINVAL; /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ - regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | + regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI)); /* Check for invalid user address space control. */ if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) -- cgit v1.2.3-70-g09d2 From dba6bb60043ed73abca8990f237db63a8cea6c50 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Nov 2013 14:25:17 +0100 Subject: s390/mm: optimize copy_page Always use the mvcl instruction to copy a page instead of mvpg or a couple of mvc instructions. Copying a huge page is 25% faster this way. Also bypass caches when copying pages since only parts of a page will be used afterwards. Especially when copying a huge page this would kick everything out of the L1 and L2 data caches on a zEC12 machine. Signed-off-by: Heiko Carstens --- arch/s390/include/asm/page.h | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 316c8503a3b..114258eeaac 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -48,33 +48,21 @@ static inline void clear_page(void *page) : "memory", "cc"); } +/* + * copy_page uses the mvcl instruction with 0xb0 padding byte in order to + * bypass caches when copying a page. Especially when copying huge pages + * this keeps L1 and L2 data caches alive. + */ static inline void copy_page(void *to, void *from) { - if (MACHINE_HAS_MVPG) { - register unsigned long reg0 asm ("0") = 0; - asm volatile( - " mvpg %0,%1" - : : "a" (to), "a" (from), "d" (reg0) - : "memory", "cc"); - } else - asm volatile( - " mvc 0(256,%0),0(%1)\n" - " mvc 256(256,%0),256(%1)\n" - " mvc 512(256,%0),512(%1)\n" - " mvc 768(256,%0),768(%1)\n" - " mvc 1024(256,%0),1024(%1)\n" - " mvc 1280(256,%0),1280(%1)\n" - " mvc 1536(256,%0),1536(%1)\n" - " mvc 1792(256,%0),1792(%1)\n" - " mvc 2048(256,%0),2048(%1)\n" - " mvc 2304(256,%0),2304(%1)\n" - " mvc 2560(256,%0),2560(%1)\n" - " mvc 2816(256,%0),2816(%1)\n" - " mvc 3072(256,%0),3072(%1)\n" - " mvc 3328(256,%0),3328(%1)\n" - " mvc 3584(256,%0),3584(%1)\n" - " mvc 3840(256,%0),3840(%1)\n" - : : "a" (to), "a" (from) : "memory"); + register void *reg2 asm ("2") = to; + register unsigned long reg3 asm ("3") = 0x1000; + register void *reg4 asm ("4") = from; + register unsigned long reg5 asm ("5") = 0xb0001000; + asm volatile( + " mvcl 2,4" + : "+d" (reg2), "+d" (reg3), "+d" (reg4), "+d" (reg5) + : : "memory", "cc"); } #define clear_user_page(page, vaddr, pg) clear_page(page) -- cgit v1.2.3-70-g09d2 From 7a2a74f4b856993218aa7cdeeb6c3103101340db Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Thu, 24 Oct 2013 12:31:03 +0200 Subject: avr32: setup crt for early panic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before the CRT was (fully) set up in kernel_entry (bss cleared before in _start, but also not before jump to panic() in no_tag_table case). This patch fixes this up to have a fully working CRT when branching to panic() in no_tag_table. Signed-off-by: Andreas Bießmann Acked-by: Hans-Christian Egtvedt Cc: Haavard Skinnemoen Cc: stable@vger.kernel.org --- arch/avr32/boot/u-boot/head.S | 30 +++++++++++++++++++++++++----- arch/avr32/kernel/head.S | 20 -------------------- 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/avr32/boot/u-boot/head.S b/arch/avr32/boot/u-boot/head.S index 4488fa27fe9..d36d865308d 100644 --- a/arch/avr32/boot/u-boot/head.S +++ b/arch/avr32/boot/u-boot/head.S @@ -8,6 +8,8 @@ * published by the Free Software Foundation. */ #include +#include +#include /* * The kernel is loaded where we want it to be and all caches @@ -20,11 +22,6 @@ .section .init.text,"ax" .global _start _start: - /* Check if the boot loader actually provided a tag table */ - lddpc r0, magic_number - cp.w r12, r0 - brne no_tag_table - /* Initialize .bss */ lddpc r2, bss_start_addr lddpc r3, end_addr @@ -34,6 +31,25 @@ _start: cp r2, r3 brlo 1b + /* Initialize status register */ + lddpc r0, init_sr + mtsr SYSREG_SR, r0 + + /* Set initial stack pointer */ + lddpc sp, stack_addr + sub sp, -THREAD_SIZE + +#ifdef CONFIG_FRAME_POINTER + /* Mark last stack frame */ + mov lr, 0 + mov r7, 0 +#endif + + /* Check if the boot loader actually provided a tag table */ + lddpc r0, magic_number + cp.w r12, r0 + brne no_tag_table + /* * Save the tag table address for later use. This must be done * _after_ .bss has been initialized... @@ -53,6 +69,10 @@ bss_start_addr: .long __bss_start end_addr: .long _end +init_sr: + .long 0x007f0000 /* Supervisor mode, everything masked */ +stack_addr: + .long init_thread_union no_tag_table: sub r12, pc, (. - 2f) diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S index 6163bd0acb9..59eae6dfbed 100644 --- a/arch/avr32/kernel/head.S +++ b/arch/avr32/kernel/head.S @@ -10,33 +10,13 @@ #include #include -#include -#include .section .init.text,"ax" .global kernel_entry kernel_entry: - /* Initialize status register */ - lddpc r0, init_sr - mtsr SYSREG_SR, r0 - - /* Set initial stack pointer */ - lddpc sp, stack_addr - sub sp, -THREAD_SIZE - -#ifdef CONFIG_FRAME_POINTER - /* Mark last stack frame */ - mov lr, 0 - mov r7, 0 -#endif - /* Start the show */ lddpc pc, kernel_start_addr .align 2 -init_sr: - .long 0x007f0000 /* Supervisor mode, everything masked */ -stack_addr: - .long init_thread_union kernel_start_addr: .long start_kernel -- cgit v1.2.3-70-g09d2 From d617b338bbfdd77e9cbd8e7dc949cee3dd73d575 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Thu, 24 Oct 2013 12:31:04 +0200 Subject: avr32: fix out-of-range jump in large kernels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes following error (for big kernels): ---8<--- arch/avr32/boot/u-boot/head.o: In function `no_tag_table': (.init.text+0x44): relocation truncated to fit: R_AVR32_22H_PCREL against symbol `panic' defined in .text.unlikely section in kernel/built-in.o arch/avr32/kernel/built-in.o: In function `bad_return': (.ex.text+0x236): relocation truncated to fit: R_AVR32_22H_PCREL against symbol `panic' defined in .text.unlikely section in kernel/built-in.o --->8--- It comes up when the kernel increases and 'panic()' is too far away to fit in the +/- 2MiB range. Which in turn issues from the 21-bit displacement in 'br{cond4}' mnemonic which is one of the two ways to do jumps (rjmp has just 10-bit displacement and therefore a way smaller range). This fact was stated before in 8d29b7b9f81d6b83d869ff054e6c189d6da73f1f. One solution to solve this is to add a local storage for the symbol address and just load the $pc with that value. Signed-off-by: Andreas Bießmann Acked-by: Hans-Christian Egtvedt Cc: Haavard Skinnemoen Cc: stable@vger.kernel.org --- arch/avr32/boot/u-boot/head.S | 5 ++++- arch/avr32/kernel/entry-avr32b.S | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/avr32/boot/u-boot/head.S b/arch/avr32/boot/u-boot/head.S index d36d865308d..2ffc298f061 100644 --- a/arch/avr32/boot/u-boot/head.S +++ b/arch/avr32/boot/u-boot/head.S @@ -73,8 +73,11 @@ init_sr: .long 0x007f0000 /* Supervisor mode, everything masked */ stack_addr: .long init_thread_union +panic_addr: + .long panic no_tag_table: sub r12, pc, (. - 2f) - bral panic + /* branch to panic() which can be far away with that construct */ + lddpc pc, panic_addr 2: .asciz "Boot loader didn't provide correct magic number\n" diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 9899d3cc6f0..7301f4806bb 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S @@ -401,9 +401,10 @@ handle_critical: /* We should never get here... */ bad_return: sub r12, pc, (. - 1f) - bral panic + lddpc pc, 2f .align 2 1: .asciz "Return from critical exception!" +2: .long panic .align 1 do_bus_error_write: -- cgit v1.2.3-70-g09d2 From dbc0d691a4dd7787efd94aa26fe7682a457e53d8 Mon Sep 17 00:00:00 2001 From: Eirik Aanonsen Date: Wed, 6 Nov 2013 22:00:33 +0100 Subject: avr32: add kprobe_ctlblk memory struct This re-enables kprobes on AVR32 architecture. Signed-off-by: Eirik Aanonsen Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/include/asm/kprobes.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/avr32/include/asm/kprobes.h b/arch/avr32/include/asm/kprobes.h index 996cb656474..45f563ed73f 100644 --- a/arch/avr32/include/asm/kprobes.h +++ b/arch/avr32/include/asm/kprobes.h @@ -16,6 +16,7 @@ typedef u16 kprobe_opcode_t; #define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */ #define MAX_INSN_SIZE 2 +#define MAX_STACK_SIZE 64 /* 32 would probably be OK */ #define kretprobe_blacklist_size 0 @@ -26,6 +27,19 @@ struct arch_specific_insn { kprobe_opcode_t insn[MAX_INSN_SIZE]; }; +struct prev_kprobe { + struct kprobe *kp; + unsigned int status; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned int kprobe_status; + struct prev_kprobe prev_kprobe; + struct pt_regs jprobe_saved_regs; + char jprobes_stack[MAX_STACK_SIZE]; +}; + extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); -- cgit v1.2.3-70-g09d2 From e7f2c8c1f0e5b062c23001dac229e570228940e8 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Tue, 12 Nov 2013 16:38:47 +0800 Subject: avr32: uapi: be sure of "_UAPI" prefix for all guard macros For all uapi headers, need use "_UAPI" prefix for its guard macro (which will be stripped by "scripts/headers_installer.sh"). Also remove redundant files (bitsperlong.h, errno.h, fcntl.h, ioctl.h, ioctls.h, ipcbuf.h, kvm_para.h, mman.h, poll.h, resource.h, siginfo.h, statfs.h, and unistd.h) which are already in Kbuild. Also be sure that all "#endif" only have one empty line above, and each file has guard macro. Signed-off-by: Chen Gang Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/include/uapi/asm/Kbuild | 24 ++++++++++++------------ arch/avr32/include/uapi/asm/auxvec.h | 6 +++--- arch/avr32/include/uapi/asm/bitsperlong.h | 1 - arch/avr32/include/uapi/asm/byteorder.h | 6 +++--- arch/avr32/include/uapi/asm/cachectl.h | 6 +++--- arch/avr32/include/uapi/asm/errno.h | 6 ------ arch/avr32/include/uapi/asm/fcntl.h | 6 ------ arch/avr32/include/uapi/asm/ioctl.h | 6 ------ arch/avr32/include/uapi/asm/ioctls.h | 6 ------ arch/avr32/include/uapi/asm/ipcbuf.h | 1 - arch/avr32/include/uapi/asm/kvm_para.h | 1 - arch/avr32/include/uapi/asm/mman.h | 1 - arch/avr32/include/uapi/asm/msgbuf.h | 6 +++--- arch/avr32/include/uapi/asm/poll.h | 1 - arch/avr32/include/uapi/asm/posix_types.h | 6 +++--- arch/avr32/include/uapi/asm/resource.h | 6 ------ arch/avr32/include/uapi/asm/sembuf.h | 6 +++--- arch/avr32/include/uapi/asm/setup.h | 1 - arch/avr32/include/uapi/asm/shmbuf.h | 6 +++--- arch/avr32/include/uapi/asm/sigcontext.h | 6 +++--- arch/avr32/include/uapi/asm/siginfo.h | 6 ------ arch/avr32/include/uapi/asm/signal.h | 1 - arch/avr32/include/uapi/asm/socket.h | 6 +++--- arch/avr32/include/uapi/asm/sockios.h | 6 +++--- arch/avr32/include/uapi/asm/stat.h | 6 +++--- arch/avr32/include/uapi/asm/statfs.h | 6 ------ arch/avr32/include/uapi/asm/swab.h | 6 +++--- arch/avr32/include/uapi/asm/termbits.h | 6 +++--- arch/avr32/include/uapi/asm/termios.h | 1 - arch/avr32/include/uapi/asm/types.h | 5 +++++ arch/avr32/include/uapi/asm/unistd.h | 1 - 31 files changed, 56 insertions(+), 102 deletions(-) delete mode 100644 arch/avr32/include/uapi/asm/bitsperlong.h delete mode 100644 arch/avr32/include/uapi/asm/errno.h delete mode 100644 arch/avr32/include/uapi/asm/fcntl.h delete mode 100644 arch/avr32/include/uapi/asm/ioctl.h delete mode 100644 arch/avr32/include/uapi/asm/ioctls.h delete mode 100644 arch/avr32/include/uapi/asm/ipcbuf.h delete mode 100644 arch/avr32/include/uapi/asm/kvm_para.h delete mode 100644 arch/avr32/include/uapi/asm/mman.h delete mode 100644 arch/avr32/include/uapi/asm/poll.h delete mode 100644 arch/avr32/include/uapi/asm/resource.h delete mode 100644 arch/avr32/include/uapi/asm/siginfo.h delete mode 100644 arch/avr32/include/uapi/asm/statfs.h (limited to 'arch') diff --git a/arch/avr32/include/uapi/asm/Kbuild b/arch/avr32/include/uapi/asm/Kbuild index 3b85eaddf52..08d8a3d76ea 100644 --- a/arch/avr32/include/uapi/asm/Kbuild +++ b/arch/avr32/include/uapi/asm/Kbuild @@ -2,35 +2,35 @@ include include/uapi/asm-generic/Kbuild.asm header-y += auxvec.h -header-y += bitsperlong.h header-y += byteorder.h header-y += cachectl.h -header-y += errno.h -header-y += fcntl.h -header-y += ioctl.h -header-y += ioctls.h -header-y += ipcbuf.h -header-y += kvm_para.h -header-y += mman.h header-y += msgbuf.h header-y += param.h -header-y += poll.h header-y += posix_types.h header-y += ptrace.h -header-y += resource.h header-y += sembuf.h header-y += setup.h header-y += shmbuf.h header-y += sigcontext.h -header-y += siginfo.h header-y += signal.h header-y += socket.h header-y += sockios.h header-y += stat.h -header-y += statfs.h header-y += swab.h header-y += termbits.h header-y += termios.h header-y += types.h header-y += unistd.h +generic-y += bitsperlong.h +generic-y += errno.h +generic-y += fcntl.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += ipcbuf.h +generic-y += kvm_para.h +generic-y += mman.h generic-y += param.h +generic-y += poll.h +generic-y += resource.h +generic-y += siginfo.h +generic-y += statfs.h diff --git a/arch/avr32/include/uapi/asm/auxvec.h b/arch/avr32/include/uapi/asm/auxvec.h index d5dd435bf8f..4f02da3ffef 100644 --- a/arch/avr32/include/uapi/asm/auxvec.h +++ b/arch/avr32/include/uapi/asm/auxvec.h @@ -1,4 +1,4 @@ -#ifndef __ASM_AVR32_AUXVEC_H -#define __ASM_AVR32_AUXVEC_H +#ifndef _UAPI__ASM_AVR32_AUXVEC_H +#define _UAPI__ASM_AVR32_AUXVEC_H -#endif /* __ASM_AVR32_AUXVEC_H */ +#endif /* _UAPI__ASM_AVR32_AUXVEC_H */ diff --git a/arch/avr32/include/uapi/asm/bitsperlong.h b/arch/avr32/include/uapi/asm/bitsperlong.h deleted file mode 100644 index 6dc0bb0c13b..00000000000 --- a/arch/avr32/include/uapi/asm/bitsperlong.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/avr32/include/uapi/asm/byteorder.h b/arch/avr32/include/uapi/asm/byteorder.h index 50abc21619a..71242f0d39c 100644 --- a/arch/avr32/include/uapi/asm/byteorder.h +++ b/arch/avr32/include/uapi/asm/byteorder.h @@ -1,9 +1,9 @@ /* * AVR32 endian-conversion functions. */ -#ifndef __ASM_AVR32_BYTEORDER_H -#define __ASM_AVR32_BYTEORDER_H +#ifndef _UAPI__ASM_AVR32_BYTEORDER_H +#define _UAPI__ASM_AVR32_BYTEORDER_H #include -#endif /* __ASM_AVR32_BYTEORDER_H */ +#endif /* _UAPI__ASM_AVR32_BYTEORDER_H */ diff --git a/arch/avr32/include/uapi/asm/cachectl.h b/arch/avr32/include/uapi/asm/cachectl.h index 4faf1ce6006..573a9584dd5 100644 --- a/arch/avr32/include/uapi/asm/cachectl.h +++ b/arch/avr32/include/uapi/asm/cachectl.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_CACHECTL_H -#define __ASM_AVR32_CACHECTL_H +#ifndef _UAPI__ASM_AVR32_CACHECTL_H +#define _UAPI__ASM_AVR32_CACHECTL_H /* * Operations that can be performed through the cacheflush system call @@ -8,4 +8,4 @@ /* Clean the data cache, then invalidate the icache */ #define CACHE_IFLUSH 0 -#endif /* __ASM_AVR32_CACHECTL_H */ +#endif /* _UAPI__ASM_AVR32_CACHECTL_H */ diff --git a/arch/avr32/include/uapi/asm/errno.h b/arch/avr32/include/uapi/asm/errno.h deleted file mode 100644 index 558a7249f06..00000000000 --- a/arch/avr32/include/uapi/asm/errno.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_ERRNO_H -#define __ASM_AVR32_ERRNO_H - -#include - -#endif /* __ASM_AVR32_ERRNO_H */ diff --git a/arch/avr32/include/uapi/asm/fcntl.h b/arch/avr32/include/uapi/asm/fcntl.h deleted file mode 100644 index 14c0c4402b1..00000000000 --- a/arch/avr32/include/uapi/asm/fcntl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_FCNTL_H -#define __ASM_AVR32_FCNTL_H - -#include - -#endif /* __ASM_AVR32_FCNTL_H */ diff --git a/arch/avr32/include/uapi/asm/ioctl.h b/arch/avr32/include/uapi/asm/ioctl.h deleted file mode 100644 index c8472c1398e..00000000000 --- a/arch/avr32/include/uapi/asm/ioctl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_IOCTL_H -#define __ASM_AVR32_IOCTL_H - -#include - -#endif /* __ASM_AVR32_IOCTL_H */ diff --git a/arch/avr32/include/uapi/asm/ioctls.h b/arch/avr32/include/uapi/asm/ioctls.h deleted file mode 100644 index 909cf66feaf..00000000000 --- a/arch/avr32/include/uapi/asm/ioctls.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_IOCTLS_H -#define __ASM_AVR32_IOCTLS_H - -#include - -#endif /* __ASM_AVR32_IOCTLS_H */ diff --git a/arch/avr32/include/uapi/asm/ipcbuf.h b/arch/avr32/include/uapi/asm/ipcbuf.h deleted file mode 100644 index 84c7e51cb6d..00000000000 --- a/arch/avr32/include/uapi/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/avr32/include/uapi/asm/kvm_para.h b/arch/avr32/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b95..00000000000 --- a/arch/avr32/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/avr32/include/uapi/asm/mman.h b/arch/avr32/include/uapi/asm/mman.h deleted file mode 100644 index 8eebf89f5ab..00000000000 --- a/arch/avr32/include/uapi/asm/mman.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/avr32/include/uapi/asm/msgbuf.h b/arch/avr32/include/uapi/asm/msgbuf.h index ac18bc4da7f..9eae6effad1 100644 --- a/arch/avr32/include/uapi/asm/msgbuf.h +++ b/arch/avr32/include/uapi/asm/msgbuf.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_MSGBUF_H -#define __ASM_AVR32_MSGBUF_H +#ifndef _UAPI__ASM_AVR32_MSGBUF_H +#define _UAPI__ASM_AVR32_MSGBUF_H /* * The msqid64_ds structure for i386 architecture. @@ -28,4 +28,4 @@ struct msqid64_ds { unsigned long __unused5; }; -#endif /* __ASM_AVR32_MSGBUF_H */ +#endif /* _UAPI__ASM_AVR32_MSGBUF_H */ diff --git a/arch/avr32/include/uapi/asm/poll.h b/arch/avr32/include/uapi/asm/poll.h deleted file mode 100644 index c98509d3149..00000000000 --- a/arch/avr32/include/uapi/asm/poll.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/avr32/include/uapi/asm/posix_types.h b/arch/avr32/include/uapi/asm/posix_types.h index 9ba9e749b3f..5b813a8abf0 100644 --- a/arch/avr32/include/uapi/asm/posix_types.h +++ b/arch/avr32/include/uapi/asm/posix_types.h @@ -5,8 +5,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef __ASM_AVR32_POSIX_TYPES_H -#define __ASM_AVR32_POSIX_TYPES_H +#ifndef _UAPI__ASM_AVR32_POSIX_TYPES_H +#define _UAPI__ASM_AVR32_POSIX_TYPES_H /* * This file is generally used by user-level software, so you need to @@ -34,4 +34,4 @@ typedef unsigned short __kernel_old_dev_t; #include -#endif /* __ASM_AVR32_POSIX_TYPES_H */ +#endif /* _UAPI__ASM_AVR32_POSIX_TYPES_H */ diff --git a/arch/avr32/include/uapi/asm/resource.h b/arch/avr32/include/uapi/asm/resource.h deleted file mode 100644 index c6dd101472b..00000000000 --- a/arch/avr32/include/uapi/asm/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_RESOURCE_H -#define __ASM_AVR32_RESOURCE_H - -#include - -#endif /* __ASM_AVR32_RESOURCE_H */ diff --git a/arch/avr32/include/uapi/asm/sembuf.h b/arch/avr32/include/uapi/asm/sembuf.h index e472216e0c9..6c6f7cf1e75 100644 --- a/arch/avr32/include/uapi/asm/sembuf.h +++ b/arch/avr32/include/uapi/asm/sembuf.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_SEMBUF_H -#define __ASM_AVR32_SEMBUF_H +#ifndef _UAPI__ASM_AVR32_SEMBUF_H +#define _UAPI__ASM_AVR32_SEMBUF_H /* * The semid64_ds structure for AVR32 architecture. @@ -22,4 +22,4 @@ struct semid64_ds { unsigned long __unused4; }; -#endif /* __ASM_AVR32_SEMBUF_H */ +#endif /* _UAPI__ASM_AVR32_SEMBUF_H */ diff --git a/arch/avr32/include/uapi/asm/setup.h b/arch/avr32/include/uapi/asm/setup.h index e58aa9356fa..a654df7dba4 100644 --- a/arch/avr32/include/uapi/asm/setup.h +++ b/arch/avr32/include/uapi/asm/setup.h @@ -13,5 +13,4 @@ #define COMMAND_LINE_SIZE 256 - #endif /* _UAPI__ASM_AVR32_SETUP_H__ */ diff --git a/arch/avr32/include/uapi/asm/shmbuf.h b/arch/avr32/include/uapi/asm/shmbuf.h index c62fba41739..b94cf8b60b7 100644 --- a/arch/avr32/include/uapi/asm/shmbuf.h +++ b/arch/avr32/include/uapi/asm/shmbuf.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_SHMBUF_H -#define __ASM_AVR32_SHMBUF_H +#ifndef _UAPI__ASM_AVR32_SHMBUF_H +#define _UAPI__ASM_AVR32_SHMBUF_H /* * The shmid64_ds structure for i386 architecture. @@ -39,4 +39,4 @@ struct shminfo64 { unsigned long __unused4; }; -#endif /* __ASM_AVR32_SHMBUF_H */ +#endif /* _UAPI__ASM_AVR32_SHMBUF_H */ diff --git a/arch/avr32/include/uapi/asm/sigcontext.h b/arch/avr32/include/uapi/asm/sigcontext.h index e04062b5f39..27e56bf6377 100644 --- a/arch/avr32/include/uapi/asm/sigcontext.h +++ b/arch/avr32/include/uapi/asm/sigcontext.h @@ -5,8 +5,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef __ASM_AVR32_SIGCONTEXT_H -#define __ASM_AVR32_SIGCONTEXT_H +#ifndef _UAPI__ASM_AVR32_SIGCONTEXT_H +#define _UAPI__ASM_AVR32_SIGCONTEXT_H struct sigcontext { unsigned long oldmask; @@ -31,4 +31,4 @@ struct sigcontext { unsigned long r0; }; -#endif /* __ASM_AVR32_SIGCONTEXT_H */ +#endif /* _UAPI__ASM_AVR32_SIGCONTEXT_H */ diff --git a/arch/avr32/include/uapi/asm/siginfo.h b/arch/avr32/include/uapi/asm/siginfo.h deleted file mode 100644 index 5ee93f40a8a..00000000000 --- a/arch/avr32/include/uapi/asm/siginfo.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _AVR32_SIGINFO_H -#define _AVR32_SIGINFO_H - -#include - -#endif diff --git a/arch/avr32/include/uapi/asm/signal.h b/arch/avr32/include/uapi/asm/signal.h index 1b77a93eff5..ffe8c770caf 100644 --- a/arch/avr32/include/uapi/asm/signal.h +++ b/arch/avr32/include/uapi/asm/signal.h @@ -118,5 +118,4 @@ typedef struct sigaltstack { size_t ss_size; } stack_t; - #endif /* _UAPI__ASM_AVR32_SIGNAL_H */ diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h index 43993642143..cbf902e4cd9 100644 --- a/arch/avr32/include/uapi/asm/socket.h +++ b/arch/avr32/include/uapi/asm/socket.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_SOCKET_H -#define __ASM_AVR32_SOCKET_H +#ifndef _UAPI__ASM_AVR32_SOCKET_H +#define _UAPI__ASM_AVR32_SOCKET_H #include @@ -78,4 +78,4 @@ #define SO_MAX_PACING_RATE 47 -#endif /* __ASM_AVR32_SOCKET_H */ +#endif /* _UAPI__ASM_AVR32_SOCKET_H */ diff --git a/arch/avr32/include/uapi/asm/sockios.h b/arch/avr32/include/uapi/asm/sockios.h index 0802d742f97..d0478545353 100644 --- a/arch/avr32/include/uapi/asm/sockios.h +++ b/arch/avr32/include/uapi/asm/sockios.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_SOCKIOS_H -#define __ASM_AVR32_SOCKIOS_H +#ifndef _UAPI__ASM_AVR32_SOCKIOS_H +#define _UAPI__ASM_AVR32_SOCKIOS_H /* Socket-level I/O control calls. */ #define FIOSETOWN 0x8901 @@ -10,4 +10,4 @@ #define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ #define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ -#endif /* __ASM_AVR32_SOCKIOS_H */ +#endif /* _UAPI__ASM_AVR32_SOCKIOS_H */ diff --git a/arch/avr32/include/uapi/asm/stat.h b/arch/avr32/include/uapi/asm/stat.h index e72881e1023..c06acef7fce 100644 --- a/arch/avr32/include/uapi/asm/stat.h +++ b/arch/avr32/include/uapi/asm/stat.h @@ -5,8 +5,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef __ASM_AVR32_STAT_H -#define __ASM_AVR32_STAT_H +#ifndef _UAPI__ASM_AVR32_STAT_H +#define _UAPI__ASM_AVR32_STAT_H struct __old_kernel_stat { unsigned short st_dev; @@ -76,4 +76,4 @@ struct stat64 { unsigned long __unused2; }; -#endif /* __ASM_AVR32_STAT_H */ +#endif /* _UAPI__ASM_AVR32_STAT_H */ diff --git a/arch/avr32/include/uapi/asm/statfs.h b/arch/avr32/include/uapi/asm/statfs.h deleted file mode 100644 index 2961bd18c50..00000000000 --- a/arch/avr32/include/uapi/asm/statfs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_STATFS_H -#define __ASM_AVR32_STATFS_H - -#include - -#endif /* __ASM_AVR32_STATFS_H */ diff --git a/arch/avr32/include/uapi/asm/swab.h b/arch/avr32/include/uapi/asm/swab.h index 14cc737bbca..1a03549e7dc 100644 --- a/arch/avr32/include/uapi/asm/swab.h +++ b/arch/avr32/include/uapi/asm/swab.h @@ -1,8 +1,8 @@ /* * AVR32 byteswapping functions. */ -#ifndef __ASM_AVR32_SWAB_H -#define __ASM_AVR32_SWAB_H +#ifndef _UAPI__ASM_AVR32_SWAB_H +#define _UAPI__ASM_AVR32_SWAB_H #include #include @@ -32,4 +32,4 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 val) #define __arch_swab32 __arch_swab32 #endif -#endif /* __ASM_AVR32_SWAB_H */ +#endif /* _UAPI__ASM_AVR32_SWAB_H */ diff --git a/arch/avr32/include/uapi/asm/termbits.h b/arch/avr32/include/uapi/asm/termbits.h index 366adc5ebb1..32789ccb38f 100644 --- a/arch/avr32/include/uapi/asm/termbits.h +++ b/arch/avr32/include/uapi/asm/termbits.h @@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_TERMBITS_H -#define __ASM_AVR32_TERMBITS_H +#ifndef _UAPI__ASM_AVR32_TERMBITS_H +#define _UAPI__ASM_AVR32_TERMBITS_H #include @@ -193,4 +193,4 @@ struct ktermios { #define TCSADRAIN 1 #define TCSAFLUSH 2 -#endif /* __ASM_AVR32_TERMBITS_H */ +#endif /* _UAPI__ASM_AVR32_TERMBITS_H */ diff --git a/arch/avr32/include/uapi/asm/termios.h b/arch/avr32/include/uapi/asm/termios.h index b8ef8ea6335..c8a0081556c 100644 --- a/arch/avr32/include/uapi/asm/termios.h +++ b/arch/avr32/include/uapi/asm/termios.h @@ -46,5 +46,4 @@ struct termio { /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - #endif /* _UAPI__ASM_AVR32_TERMIOS_H */ diff --git a/arch/avr32/include/uapi/asm/types.h b/arch/avr32/include/uapi/asm/types.h index bb34ad349df..7c986c4e99b 100644 --- a/arch/avr32/include/uapi/asm/types.h +++ b/arch/avr32/include/uapi/asm/types.h @@ -5,4 +5,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#ifndef _UAPI__ASM_AVR32_TYPES_H +#define _UAPI__ASM_AVR32_TYPES_H + #include + +#endif /* _UAPI__ASM_AVR32_TYPES_H */ diff --git a/arch/avr32/include/uapi/asm/unistd.h b/arch/avr32/include/uapi/asm/unistd.h index 3eaa68753ad..8822bf46ddc 100644 --- a/arch/avr32/include/uapi/asm/unistd.h +++ b/arch/avr32/include/uapi/asm/unistd.h @@ -301,5 +301,4 @@ #define __NR_eventfd 281 #define __NR_setns 283 - #endif /* _UAPI__ASM_AVR32_UNISTD_H */ -- cgit v1.2.3-70-g09d2 From 521ee0cfb876dd31ce4e0878e1163fe0817a7acc Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 19 Nov 2013 15:22:47 -0500 Subject: kvm: mmu: delay mmu audit activation We should not be using jump labels before they were initialized. Push back the callback to until after jump label initialization. Signed-off-by: Sasha Levin Signed-off-by: Gleb Natapov --- arch/x86/kvm/mmu_audit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c index daff69e2115..1185fe7a7f4 100644 --- a/arch/x86/kvm/mmu_audit.c +++ b/arch/x86/kvm/mmu_audit.c @@ -296,4 +296,4 @@ static struct kernel_param_ops audit_param_ops = { .get = param_get_bool, }; -module_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644); +arch_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644); -- cgit v1.2.3-70-g09d2 From 1c283531115bda77a9b559271311c1983fbcffaa Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 8 Oct 2013 16:38:53 +0200 Subject: ARM: at91: rm9200: switch back to clockevents_config_and_register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timer code for at91rm9200 was already converted some time ago by Shawn Guo in commit 838a2ae (ARM: use clockevents_config_and_register() where possible) but because of a rounding issue in the timer core this resulted in an easily reproducible oops. So it was reverted (commit b7a8ca5 (ARM: at91: rm9200 fix time support)) which stopped the oops from happening because min_delta_ns is increased by one in arch code which stopped from problem from happening. Now that the timer core problem is fixed (commit a4578ea (clockevents: Sanitize ticks to nsec conversion)), we can switch back to the clockevents_config_and_register helper. Tested-by: Nicolas Ferre Signed-off-by: Uwe Kleine-König Signed-off-by: Daniel Lezcano --- arch/arm/mach-at91/at91rm9200_time.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index f607deb40f4..bc7b363a308 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -174,7 +174,6 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) static struct clock_event_device clkevt = { .name = "at91_tick", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, .rating = 150, .set_next_event = clkevt32k_next_event, .set_mode = clkevt32k_mode, @@ -265,11 +264,9 @@ void __init at91rm9200_timer_init(void) at91_st_write(AT91_ST_RTMR, 1); /* Setup timer clockevent, with minimum of two ticks (important!!) */ - clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); - clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt); - clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1; clkevt.cpumask = cpumask_of(0); - clockevents_register_device(&clkevt); + clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK, + 2, AT91_ST_ALMV); /* register clocksource */ clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); -- cgit v1.2.3-70-g09d2 From b91da2d4ce896c324bdbf1a078dbbe2db9a35ef1 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 20 Nov 2013 22:14:58 +1100 Subject: powerpc/pseries: Fix endian issues in pseries EEH code Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/eeh_pseries.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 7fbc25b1813..ccb633e077b 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -189,8 +189,9 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) struct eeh_dev *edev; struct eeh_pe pe; struct pci_dn *pdn = PCI_DN(dn); - const u32 *class_code, *vendor_id, *device_id; - const u32 *regs; + const __be32 *classp, *vendorp, *devicep; + u32 class_code; + const __be32 *regs; u32 pcie_flags; int enable = 0; int ret; @@ -201,22 +202,24 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) return NULL; /* Retrieve class/vendor/device IDs */ - class_code = of_get_property(dn, "class-code", NULL); - vendor_id = of_get_property(dn, "vendor-id", NULL); - device_id = of_get_property(dn, "device-id", NULL); + classp = of_get_property(dn, "class-code", NULL); + vendorp = of_get_property(dn, "vendor-id", NULL); + devicep = of_get_property(dn, "device-id", NULL); /* Skip for bad OF node or PCI-ISA bridge */ - if (!class_code || !vendor_id || !device_id) + if (!classp || !vendorp || !devicep) return NULL; if (dn->type && !strcmp(dn->type, "isa")) return NULL; + class_code = of_read_number(classp, 1); + /* * Update class code and mode of eeh device. We need * correctly reflects that current device is root port * or PCIe switch downstream port. */ - edev->class_code = *class_code; + edev->class_code = class_code; edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); edev->mode &= 0xFFFFFF00; if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { @@ -243,12 +246,12 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) /* Initialize the fake PE */ memset(&pe, 0, sizeof(struct eeh_pe)); pe.phb = edev->phb; - pe.config_addr = regs[0]; + pe.config_addr = of_read_number(regs, 1); /* Enable EEH on the device */ ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); if (!ret) { - edev->config_addr = regs[0]; + edev->config_addr = of_read_number(regs, 1); /* Retrieve PE address */ edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); pe.addr = edev->pe_config_addr; -- cgit v1.2.3-70-g09d2 From e844b1eeae42dc93bf13e67812a95ee7b58be8c7 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 20 Nov 2013 22:14:59 +1100 Subject: pseries: Add H_SET_MODE to change exception endianness On little endian builds call H_SET_MODE so exceptions have the correct endianness. We need to reset the endian during kexec so do that in the MMU hashtable clear callback. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hvcall.h | 2 ++ arch/powerpc/include/asm/plpar_wrappers.h | 26 +++++++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 17 +++++++++++++ arch/powerpc/platforms/pseries/setup.c | 42 +++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 0c7f2bfcf13..d8b600b3f05 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -403,6 +403,8 @@ static inline unsigned long cmo_get_page_size(void) extern long pSeries_enable_reloc_on_exc(void); extern long pSeries_disable_reloc_on_exc(void); +extern long pseries_big_endian_exceptions(void); + #else #define pSeries_enable_reloc_on_exc() do {} while (0) diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h index a63b045e707..12c32c5f533 100644 --- a/arch/powerpc/include/asm/plpar_wrappers.h +++ b/arch/powerpc/include/asm/plpar_wrappers.h @@ -287,6 +287,32 @@ static inline long disable_reloc_on_exceptions(void) { return plpar_set_mode(0, 3, 0, 0); } +/* + * Take exceptions in big endian mode on this partition + * + * Note: this call has a partition wide scope and can take a while to complete. + * If it returns H_LONG_BUSY_* it should be retried periodically until it + * returns H_SUCCESS. + */ +static inline long enable_big_endian_exceptions(void) +{ + /* mflags = 0: big endian exceptions */ + return plpar_set_mode(0, 4, 0, 0); +} + +/* + * Take exceptions in little endian mode on this partition + * + * Note: this call has a partition wide scope and can take a while to complete. + * If it returns H_LONG_BUSY_* it should be retried periodically until it + * returns H_SUCCESS. + */ +static inline long enable_little_endian_exceptions(void) +{ + /* mflags = 1: little endian exceptions */ + return plpar_set_mode(1, 4, 0, 0); +} + static inline long plapr_set_ciabr(unsigned long ciabr) { return plpar_set_mode(0, 1, ciabr, 0); diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 356bc75ca74..4fca3def9db 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -245,6 +245,23 @@ static void pSeries_lpar_hptab_clear(void) &(ptes[j].pteh), &(ptes[j].ptel)); } } + +#ifdef __LITTLE_ENDIAN__ + /* Reset exceptions to big endian */ + if (firmware_has_feature(FW_FEATURE_SET_MODE)) { + long rc; + + rc = pseries_big_endian_exceptions(); + /* + * At this point it is unlikely panic() will get anything + * out to the user, but at least this will stop us from + * continuing on further and creating an even more + * difficult to debug situation. + */ + if (rc) + panic("Could not enable big endian exceptions"); + } +#endif } /* diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 1f97e2b87a6..c1f19085870 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -442,6 +442,32 @@ static void pSeries_machine_kexec(struct kimage *image) } #endif +#ifdef __LITTLE_ENDIAN__ +long pseries_big_endian_exceptions(void) +{ + long rc; + + while (1) { + rc = enable_big_endian_exceptions(); + if (!H_IS_LONG_BUSY(rc)) + return rc; + mdelay(get_longbusy_msecs(rc)); + } +} + +static long pseries_little_endian_exceptions(void) +{ + long rc; + + while (1) { + rc = enable_little_endian_exceptions(); + if (!H_IS_LONG_BUSY(rc)) + return rc; + mdelay(get_longbusy_msecs(rc)); + } +} +#endif + static void __init pSeries_setup_arch(void) { panic_timeout = 10; @@ -698,6 +724,22 @@ static int __init pSeries_probe(void) /* Now try to figure out if we are running on LPAR */ of_scan_flat_dt(pseries_probe_fw_features, NULL); +#ifdef __LITTLE_ENDIAN__ + if (firmware_has_feature(FW_FEATURE_SET_MODE)) { + long rc; + /* + * Tell the hypervisor that we want our exceptions to + * be taken in little endian mode. If this fails we don't + * want to use BUG() because it will trigger an exception. + */ + rc = pseries_little_endian_exceptions(); + if (rc) { + ppc_md.progress("H_SET_MODE LE exception fail", 0); + panic("Could not enable little endian exceptions"); + } + } +#endif + if (firmware_has_feature(FW_FEATURE_LPAR)) hpte_init_lpar(); else -- cgit v1.2.3-70-g09d2 From 373c76d62240cd3c1a3af42440b0a73cb7296bda Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Nov 2013 22:15:00 +1100 Subject: powerpc: Add TIF_ELF2ABI flag. Little endian ppc64 is getting an exciting new ABI. This is reflected by the bottom two bits of e_flags in the ELF header: 0 == legacy binaries (v1 ABI) 1 == binaries using the old ABI (compiled with a new toolchain) 2 == binaries using the new ABI. We store this in a thread flag, because we need to set it in core dumps and for signal delivery. Our chief concern is that it doesn't use function descriptors. Signed-off-by: Rusty Russell Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/elf.h | 2 ++ arch/powerpc/include/asm/thread_info.h | 9 +++++++++ 2 files changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index cc0655a702a..6d0e2369fe8 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h @@ -86,6 +86,8 @@ typedef elf_vrregset_t elf_fpxregset_t; #ifdef __powerpc64__ # define SET_PERSONALITY(ex) \ do { \ + if (((ex).e_flags & 0x3) == 2) \ + set_thread_flag(TIF_ELF2ABI); \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ set_thread_flag(TIF_32BIT); \ else \ diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index ba7b1973866..05a3030b458 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -107,6 +107,9 @@ static inline struct thread_info *current_thread_info(void) #define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation for stack store? */ #define TIF_MEMDIE 17 /* is terminating due to OOM killer */ +#if defined(CONFIG_PPC64) +#define TIF_ELF2ABI 18 /* function descriptors must die! */ +#endif /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< Date: Wed, 20 Nov 2013 22:15:01 +1100 Subject: powerpc: Set eflags correctly for ELF ABIv2 core dumps. We leave it at zero (though it could be 1) for old tasks. Signed-off-by: Rusty Russell Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/elf.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 6d0e2369fe8..935b5e7a143 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h @@ -31,6 +31,8 @@ extern unsigned long randomize_et_dyn(unsigned long base); #define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000)) +#define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0) + /* * Our registers are always unsigned longs, whether we're a 32 bit * process or 64 bit, on either a 64 bit or 32 bit kernel. -- cgit v1.2.3-70-g09d2 From 94af3abf995b17f6a008b00152c94841242ec6c7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Nov 2013 22:15:02 +1100 Subject: powerpc: ELF2 binaries launched directly. No function descriptor, but we set r12 up and set TIF_RESTOREALL as it normally isn't restored on return from syscall. Signed-off-by: Rusty Russell Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 50 ++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 75c2d100998..0650e18169f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1086,25 +1086,45 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->msr = MSR_USER; #else if (!is_32bit_task()) { - unsigned long entry, toc; + unsigned long entry; - /* start is a relocated pointer to the function descriptor for - * the elf _start routine. The first entry in the function - * descriptor is the entry address of _start and the second - * entry is the TOC value we need to use. - */ - __get_user(entry, (unsigned long __user *)start); - __get_user(toc, (unsigned long __user *)start+1); + if (is_elf2_task()) { + /* Look ma, no function descriptors! */ + entry = start; - /* Check whether the e_entry function descriptor entries - * need to be relocated before we can use them. - */ - if (load_addr != 0) { - entry += load_addr; - toc += load_addr; + /* + * Ulrich says: + * The latest iteration of the ABI requires that when + * calling a function (at its global entry point), + * the caller must ensure r12 holds the entry point + * address (so that the function can quickly + * establish addressability). + */ + regs->gpr[12] = start; + /* Make sure that's restored on entry to userspace. */ + set_thread_flag(TIF_RESTOREALL); + } else { + unsigned long toc; + + /* start is a relocated pointer to the function + * descriptor for the elf _start routine. The first + * entry in the function descriptor is the entry + * address of _start and the second entry is the TOC + * value we need to use. + */ + __get_user(entry, (unsigned long __user *)start); + __get_user(toc, (unsigned long __user *)start+1); + + /* Check whether the e_entry function descriptor entries + * need to be relocated before we can use them. + */ + if (load_addr != 0) { + entry += load_addr; + toc += load_addr; + } + regs->gpr[2] = toc; } regs->nip = entry; - regs->gpr[2] = toc; regs->msr = MSR_USER64; } else { regs->nip = start; -- cgit v1.2.3-70-g09d2 From d606b92aedb0542e60965e9058ab37efcebfaec6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Nov 2013 22:15:03 +1100 Subject: powerpc: ELF2 binaries signal handling For the ELFv2 ABI, the hander is the entry point, not a function descriptor. We also need to set up r12, and fortunately the fast_exception_return exit path restores r12 for us so nothing else is required. Signed-off-by: Rusty Russell Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/signal_64.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index b3c615764c9..e66f67b8b9e 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -701,12 +701,6 @@ badframe: int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { - /* Handler is *really* a pointer to the function descriptor for - * the signal routine. The first entry in the function - * descriptor is the entry address of signal and the second - * entry is the TOC value we need to use. - */ - func_descr_t __user *funct_desc_ptr; struct rt_sigframe __user *frame; unsigned long newsp = 0; long err = 0; @@ -766,19 +760,32 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, goto badframe; regs->link = (unsigned long) &frame->tramp[0]; } - funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler; /* Allocate a dummy caller frame for the signal handler. */ newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); /* Set up "regs" so we "return" to the signal handler. */ - err |= get_user(regs->nip, &funct_desc_ptr->entry); + if (is_elf2_task()) { + regs->nip = (unsigned long) ka->sa.sa_handler; + regs->gpr[12] = regs->nip; + } else { + /* Handler is *really* a pointer to the function descriptor for + * the signal routine. The first entry in the function + * descriptor is the entry address of signal and the second + * entry is the TOC value we need to use. + */ + func_descr_t __user *funct_desc_ptr = + (func_descr_t __user *) ka->sa.sa_handler; + + err |= get_user(regs->nip, &funct_desc_ptr->entry); + err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); + } + /* enter the signal handler in native-endian mode */ regs->msr &= ~MSR_LE; regs->msr |= (MSR_KERNEL & MSR_LE); regs->gpr[1] = newsp; - err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); regs->gpr[3] = signr; regs->result = 0; if (ka->sa.sa_flags & SA_SIGINFO) { -- cgit v1.2.3-70-g09d2 From b2ca8c895e711b10d6f28b26248358bfa2f354ad Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Wed, 20 Nov 2013 22:15:04 +1100 Subject: powerpc: Don't use ELFv2 ABI to build the kernel The kernel doesn't build correctly using the ELFv2 ABI. This patch ensures that the ELFv1 ABI is used when building a kernel with an ELFv2 enabled compiler. Signed-off-by: Alistair Popple Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 607acf54a42..8a2463670a5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -111,6 +111,7 @@ endif endif CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc +CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1) CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc) CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD) -- cgit v1.2.3-70-g09d2 From 7c105b63bd9887f10ec281b0020492e7c774d0fc Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 20 Nov 2013 22:15:05 +1100 Subject: powerpc: Add CONFIG_CPU_LITTLE_ENDIAN kernel config option. With the little endian support merged, we can add the CONFIG_CPU_LITTLE_ENDIAN kernel config option. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/Kconfig.cputype | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index c2a566fb8bb..132f8726a25 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -403,3 +403,14 @@ config PPC_DOORBELL default n endmenu + +config CPU_LITTLE_ENDIAN + bool "Build little endian kernel" + default n + help + This option selects whether a big endian or little endian kernel will + be built. + + Note that if cross compiling a little endian kernel, + CROSS_COMPILE must point to a toolchain capable of targeting + little endian powerpc. -- cgit v1.2.3-70-g09d2 From f53e462e907cbaed29c49c0f10f5b8f614e1bf1d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 20 Nov 2013 22:15:06 +1100 Subject: powerpc: Add pseries_le_defconfig Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/configs/pseries_le_defconfig | 352 ++++++++++++++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 arch/powerpc/configs/pseries_le_defconfig (limited to 'arch') diff --git a/arch/powerpc/configs/pseries_le_defconfig b/arch/powerpc/configs/pseries_le_defconfig new file mode 100644 index 00000000000..62771e0adb7 --- /dev/null +++ b/arch/powerpc/configs/pseries_le_defconfig @@ -0,0 +1,352 @@ +CONFIG_PPC64=y +CONFIG_ALTIVEC=y +CONFIG_VSX=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2048 +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_PPC_SPLPAR=y +CONFIG_SCANLOG=m +CONFIG_PPC_SMLPAR=y +CONFIG_DTL=y +# CONFIG_PPC_PMAC is not set +CONFIG_RTAS_FLASH=m +CONFIG_IBMEBUS=y +CONFIG_HZ_100=y +CONFIG_BINFMT_MISC=m +CONFIG_PPC_TRANSACTIONAL_MEM=y +CONFIG_KEXEC=y +CONFIG_IRQ_ALL_CPUS=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_CMA=y +CONFIG_PPC_64K_PAGES=y +CONFIG_PPC_SUBPAGE_PROT=y +CONFIG_SCHED_SMT=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_RPA=m +CONFIG_HOTPLUG_PCI_RPA_DLPAR=m +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_NET_IPIP=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_BLK_DEV_FD=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_VIRTIO_BLK=m +CONFIG_IDE=y +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_FC_ATTRS=y +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_BE2ISCSI=m +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_IBMVSCSI=y +CONFIG_SCSI_IBMVFC=m +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_IPR=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_ATA=y +# CONFIG_ATA_SFF is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_UEVENT=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL_TRAP=y +CONFIG_TUN=m +CONFIG_VIRTIO_NET=m +CONFIG_VORTEX=y +CONFIG_ACENIC=m +CONFIG_ACENIC_OMIT_TIGON_I=y +CONFIG_PCNET32=y +CONFIG_TIGON3=y +CONFIG_CHELSIO_T1=m +CONFIG_BE2NET=m +CONFIG_S2IO=m +CONFIG_IBMVETH=y +CONFIG_EHEA=y +CONFIG_E100=y +CONFIG_E1000=y +CONFIG_E1000E=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_MLX4_EN=m +CONFIG_MYRI10GE=m +CONFIG_QLGE=m +CONFIG_NETXEN_NIC=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_ICOM=m +CONFIG_SERIAL_JSM=m +CONFIG_HVC_CONSOLE=y +CONFIG_HVC_RTAS=y +CONFIG_HVCS=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_IBM_BSR=m +CONFIG_GEN_RTC=y +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=1024 +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_OF=y +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_RADEON=y +CONFIG_FB_IBM_GXT4500=y +CONFIG_LCD_PLATFORM=m +# CONFIG_VGA_CONSOLE is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +CONFIG_HID_GYRATION=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SUNPLUS=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_MON=m +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_HCD_PPC_OF is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_STORAGE=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_EHCA=m +CONFIG_INFINIBAND_CXGB3=m +CONFIG_INFINIBAND_CXGB4=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_ISER=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_REISERFS_FS=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_ISO9660_FS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_PSTORE=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_CRC_T10DIF=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_LATENCYTOP=y +CONFIG_SCHED_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_CODE_PATCHING_SELFTEST=y +CONFIG_FTR_FIXUP_SELFTEST=y +CONFIG_MSI_BITMAP_SELFTEST=y +CONFIG_XMON=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DEV_NX=y +CONFIG_CRYPTO_DEV_NX_ENCRYPT=m -- cgit v1.2.3-70-g09d2 From 280270828f108be56f0c486def58acabb070244f Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 21 Nov 2013 07:38:05 +1100 Subject: powerpc: Wrong DWARF CFI in the kernel vdso for little-endian / ELFv2 I've finally tracked down why my CR signal-unwind test case still fails on little-endian. The problem turned to be that the kernel installs a signal trampoline in the vDSO, and provides a DWARF CFI record for that trampoline. This CFI describes the save location for CR: rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) which is correct for big-endian, but points to the wrong word on little-endian. This is wrong no matter which ABI. In addition, for the ELFv2 ABI, we should not only provide a CFI record for register 70 (cr2), but for all CR fields separately. Strictly speaking, I guess this would mean providing two separate vDSO images, one for ELFv1 processes and one for ELFv2 processes (or maybe playing some tricks with conditional DWARF expressions). However, having CFI records for the other CR fields in ELFv1 is not actually wrong, they just will be ignored. So it seems the simplest fix would be just to always provide CFI for all the fields. Signed-off-by: Ulrich Weigand Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vdso64/sigtramp.S | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S index 45ea281e9a2..542c6f422e4 100644 --- a/arch/powerpc/kernel/vdso64/sigtramp.S +++ b/arch/powerpc/kernel/vdso64/sigtramp.S @@ -142,6 +142,13 @@ V_FUNCTION_END(__kernel_sigtramp_rt64) /* Size of CR reg in DWARF unwind info. */ #define CRSIZE 4 +/* Offset of CR reg within a full word. */ +#ifdef __LITTLE_ENDIAN__ +#define CROFF 0 +#else +#define CROFF (RSIZE - CRSIZE) +#endif + /* This is the offset of the VMX reg pointer. */ #define VREGS 48*RSIZE+33*8 @@ -181,7 +188,14 @@ V_FUNCTION_END(__kernel_sigtramp_rt64) rsave (31, 31*RSIZE); \ rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \ rsave (65, 36*RSIZE); /* lr */ \ - rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */ + rsave (68, 38*RSIZE + CROFF); /* cr fields */ \ + rsave (69, 38*RSIZE + CROFF); \ + rsave (70, 38*RSIZE + CROFF); \ + rsave (71, 38*RSIZE + CROFF); \ + rsave (72, 38*RSIZE + CROFF); \ + rsave (73, 38*RSIZE + CROFF); \ + rsave (74, 38*RSIZE + CROFF); \ + rsave (75, 38*RSIZE + CROFF) /* Describe where the FP regs are saved. */ #define EH_FRAME_FP \ -- cgit v1.2.3-70-g09d2 From 2a46eed54a28c1e3de701ca4237ce4f8bebf14c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 20 Nov 2013 22:16:36 +0000 Subject: Wrong page freed on preallocate_pmds() failure exit Note that pmds[i] is simply uninitialized at that point... Granted, it's very hard to hit (you need split page locks *and* kmalloc(sizeof(spinlock_t), GFP_KERNEL) failing), but the code is obviously bogus. Introduced by commit 09ef4939850a ("x86: add missed pgtable_pmd_page_ctor/dtor calls for preallocated pmds") Signed-off-by: Al Viro Cc: Kirill A. Shutemov Cc: Ingo Molnar Cc: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/mm/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index a7cccb6d7fe..36aa999b263 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -209,7 +209,7 @@ static int preallocate_pmds(pmd_t *pmds[]) if (!pmd) failed = true; if (pmd && !pgtable_pmd_page_ctor(virt_to_page(pmd))) { - free_page((unsigned long)pmds[i]); + free_page((unsigned long)pmd); pmd = NULL; failed = true; } -- cgit v1.2.3-70-g09d2 From b7ec699405f55667caeb46d96229d75bf33a83ad Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 19 Nov 2013 15:46:11 +0100 Subject: ARM: 7893/1: bitops: only emit .arch_extension mp if CONFIG_SMP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uwe reported a build failure when targetting a NOMMU platform with my recent prefetch changes: arch/arm/lib/changebit.S: Assembler messages: arch/arm/lib/changebit.S:15: Error: architectural extension `mp' is not allowed for the current base architecture This is due to use of the .arch_extension mp directive immediately prior to an ALT_SMP(...) instruction. Whilst the ALT_SMP macro will expand to nothing if !CONFIG_SMP, gas will still choke on the directive. This patch fixes the issue by only emitting the sequence (including the directive) if CONFIG_SMP=y. Tested-by: Uwe Kleine-König Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/lib/bitops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index e0c68d5bb7d..52886b89706 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -10,7 +10,7 @@ UNWIND( .fnstart ) and r3, r0, #31 @ Get bit offset mov r0, r0, lsr #5 add r1, r1, r0, lsl #2 @ Get word offset -#if __LINUX_ARM_ARCH__ >= 7 +#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) .arch_extension mp ALT_SMP(W(pldw) [r1]) ALT_UP(W(nop)) -- cgit v1.2.3-70-g09d2 From 0c403462d6822227ea37fb0293a3e9f511e6929f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 19 Nov 2013 15:46:17 +0100 Subject: ARM: 7894/1: kconfig: select GENERIC_CLOCKEVENTS if HAVE_ARM_ARCH_TIMER The ARM architected timer driver doesn't compile without GENERIC_CLOCKEVENTS selected, so ensure that we select it when building for a platform that has the timer. Without this patch, mach-virt fails to build without something like mach-vexpress also selected. Acked-by: Marc Zyngier Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 085b31ba287..c2a372a6994 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1496,6 +1496,7 @@ config HAVE_ARM_ARCH_TIMER bool "Architected timer support" depends on CPU_V7 select ARM_ARCH_TIMER + select GENERIC_CLOCKEVENTS help This option enables support for the ARM architected timer -- cgit v1.2.3-70-g09d2 From bf898ec5cbd33be11147743bee27b66b10cb2f85 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 12 Nov 2013 14:49:21 +0800 Subject: powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges On PHB3, we will fail to fetch IODA tables without PCI_COMMAND_MASTER on PCI bridges. According to one experiment I had, the MSIx interrupts didn't raise from the adapter without the bit applied to all upstream PCI bridges including root port of the adapter. The patch forces to have that bit enabled accordingly. Signed-off-by: Gavin Shan CC: Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/eeh.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 67130206534..4bd687d5e7a 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -686,6 +686,15 @@ void eeh_save_bars(struct eeh_dev *edev) for (i = 0; i < 16; i++) eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]); + + /* + * For PCI bridges including root port, we need enable bus + * master explicitly. Otherwise, it can't fetch IODA table + * entries correctly. So we cache the bit in advance so that + * we can restore it after reset, either PHB range or PE range. + */ + if (edev->mode & EEH_DEV_BRIDGE) + edev->config_space[1] |= PCI_COMMAND_MASTER; } /** -- cgit v1.2.3-70-g09d2 From 0b5381a61821d1c074c76e01b27bf5f69cf2dd01 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 12 Nov 2013 14:49:22 +0800 Subject: powerpc/eeh: More accurate log This clarifies in the log whether the error is a global PHB error or an individual PE being frozen. Signed-off-by: Gavin Shan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/eeh_event.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/eeh_event.c b/arch/powerpc/kernel/eeh_event.c index d27c5afc90a..72d748b56c8 100644 --- a/arch/powerpc/kernel/eeh_event.c +++ b/arch/powerpc/kernel/eeh_event.c @@ -74,8 +74,13 @@ static int eeh_event_handler(void * dummy) pe = event->pe; if (pe) { eeh_pe_state_mark(pe, EEH_PE_RECOVERING); - pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n", - pe->phb->global_number, pe->addr); + if (pe->type & EEH_PE_PHB) + pr_info("EEH: Detected error on PHB#%d\n", + pe->phb->global_number); + else + pr_info("EEH: Detected PCI bus error on " + "PHB#%d-PE#%x\n", + pe->phb->global_number, pe->addr); eeh_handle_event(pe); eeh_pe_state_clear(pe, EEH_PE_RECOVERING); } else { -- cgit v1.2.3-70-g09d2 From 95f715b08fa4a953771398d20cbe35a6803ea41d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 14 Nov 2013 15:01:43 +1100 Subject: powerpc: Fix __get_user_pages_fast() irq handling __get_user_pages_fast() may be called with interrupts disabled (see e.g. get_futex_key() in kernel/futex.c) and therefore should use local_irq_save() and local_irq_restore() instead of local_irq_disable()/enable(). Signed-off-by: Heiko Carstens CC: [v3.12] Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/gup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c index 6936547018b..c5f734e20b0 100644 --- a/arch/powerpc/mm/gup.c +++ b/arch/powerpc/mm/gup.c @@ -123,6 +123,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, struct mm_struct *mm = current->mm; unsigned long addr, len, end; unsigned long next; + unsigned long flags; pgd_t *pgdp; int nr = 0; @@ -156,7 +157,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, * So long as we atomically load page table pointers versus teardown, * we can follow the address down to the the page and take a ref on it. */ - local_irq_disable(); + local_irq_save(flags); pgdp = pgd_offset(mm, addr); do { @@ -179,7 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, break; } while (pgdp++, addr = next, addr != end); - local_irq_enable(); + local_irq_restore(flags); return nr; } -- cgit v1.2.3-70-g09d2 From c54006491dde7d1b8050c5542716b751be92ed80 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 15 Nov 2013 15:41:19 +1100 Subject: powerpc: Print DAR and DSISR on machine check oopses Machine check exceptions set DAR and DSISR, so print them in our oops output. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 75c2d100998..37c4103a8cf 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -864,7 +864,7 @@ void show_regs(struct pt_regs * regs) trap = TRAP(regs); if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) printk("CFAR: "REG"\n", regs->orig_gpr3); - if (trap == 0x300 || trap == 0x600) + if (trap == 0x200 || trap == 0x300 || trap == 0x600) #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); #else -- cgit v1.2.3-70-g09d2 From 9db8bcfd73d4a18c0b3428c30557ccce1171d0af Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 15 Nov 2013 15:48:38 +1100 Subject: powerpc: Remove a few lines of oops output We waste quite a few lines in our oops output: ... MSR: 8000000000009032 CR: 28044024 XER: 00000000 SOFTE: 0 CFAR: 0000000000009088 DAR: 000000000000001c, DSISR: 40000000 GPR00: c0000000000c74f0 c00000037cc1b010 c000000000d2bb30 0000000000000000 ... We can do a better job here and remove 3 lines: MSR: 8000000000009032 CR: 28044024 XER: 00000000 CFAR: 0000000000009088 DAR: 0000000000000010, DSISR: 40000000 SOFTE: 1 GPR00: c0000000000e3d10 c00000037cc2fda0 c000000000d2c3a8 0000000000000001 Also move PACATMSCRATCH up, it doesn't really belong in the stack trace section. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 37c4103a8cf..373980ae52a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -858,17 +858,20 @@ void show_regs(struct pt_regs * regs) printk("MSR: "REG" ", regs->msr); printbits(regs->msr, msr_bits); printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); -#ifdef CONFIG_PPC64 - printk("SOFTE: %ld\n", regs->softe); -#endif trap = TRAP(regs); if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) - printk("CFAR: "REG"\n", regs->orig_gpr3); + printk("CFAR: "REG" ", regs->orig_gpr3); if (trap == 0x200 || trap == 0x300 || trap == 0x600) #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); + printk("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); #else - printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr); + printk("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr); +#endif +#ifdef CONFIG_PPC64 + printk("SOFTE: %ld ", regs->softe); +#endif +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch); #endif for (i = 0; i < 32; i++) { @@ -886,9 +889,6 @@ void show_regs(struct pt_regs * regs) */ printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); -#endif -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch); #endif show_stack(current, (unsigned long *) regs->gpr[1]); if (!user_mode(regs)) -- cgit v1.2.3-70-g09d2 From 84b073868b9d9e754ae48b828337633d1b386482 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 17 Nov 2013 11:39:05 +1100 Subject: powerpc/pseries: Duplicate dtl entries sometimes sent to userspace When reading from the dispatch trace log (dtl) userspace interface, I sometimes see duplicate entries. One example: # hexdump -C dtl.out 00000000 07 04 00 0c 00 00 48 44 00 00 00 00 00 00 00 00 00000010 00 0c a0 b4 16 83 6d 68 00 00 00 00 00 00 00 00 00000020 00 00 00 00 10 00 13 50 80 00 00 00 00 00 d0 32 00000030 07 04 00 0c 00 00 48 44 00 00 00 00 00 00 00 00 00000040 00 0c a0 b4 16 83 6d 68 00 00 00 00 00 00 00 00 00000050 00 00 00 00 10 00 13 50 80 00 00 00 00 00 d0 32 The problem is in scan_dispatch_log() where we call dtl_consumer() but bail out before incrementing the index. To fix this I moved dtl_consumer() after the timebase comparison. Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 192b051df97..b3b144121cc 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -213,8 +213,6 @@ static u64 scan_dispatch_log(u64 stop_tb) if (i == be64_to_cpu(vpa->dtl_idx)) return 0; while (i < be64_to_cpu(vpa->dtl_idx)) { - if (dtl_consumer) - dtl_consumer(dtl, i); dtb = be64_to_cpu(dtl->timebase); tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + be32_to_cpu(dtl->ready_to_enqueue_time); @@ -227,6 +225,8 @@ static u64 scan_dispatch_log(u64 stop_tb) } if (dtb > stop_tb) break; + if (dtl_consumer) + dtl_consumer(dtl, i); stolen += tb_delta; ++i; ++dtl; -- cgit v1.2.3-70-g09d2 From 6d888d1ab0000dff8ea2901bcdf5d213f2a54e8b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 18 Nov 2013 13:19:17 +1100 Subject: powerpc: Only print PACATMSCRATCH in oops when TM is active If TM is not active there is no need to print PACATMSCRATCH so we can save ourselves a line. Signed-off-by: Anton Blanchard Acked-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 373980ae52a..6cd50ac1221 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -871,7 +871,8 @@ void show_regs(struct pt_regs * regs) printk("SOFTE: %ld ", regs->softe); #endif #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch); + if (MSR_TM_ACTIVE(regs->msr)) + printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch); #endif for (i = 0; i < 32; i++) { -- cgit v1.2.3-70-g09d2 From 5a049f14902982c26538250bdc8d54156d357252 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 18 Nov 2013 14:55:28 +1100 Subject: powerpc: ppc64 address space capped at 32TB, mmap randomisation disabled Commit fba2369e6ceb (mm: use vm_unmapped_area() on powerpc architecture) has a bug in slice_scan_available() where we compare an unsigned long (high_slices) against a shifted int. As a result, comparisons against the top 32 bits of high_slices (representing the top 32TB) always returns 0 and the top of our mmap region is clamped at 32TB This also breaks mmap randomisation since the randomised address is always up near the top of the address space and it gets clamped down to 32TB. Cc: stable@vger.kernel.org # v3.10+ Signed-off-by: Anton Blanchard Acked-by: Michel Lespinasse Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/slice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 3e99c149271..7ce9cf3b698 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -258,7 +258,7 @@ static bool slice_scan_available(unsigned long addr, slice = GET_HIGH_SLICE_INDEX(addr); *boundary_addr = (slice + end) ? ((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP; - return !!(available.high_slices & (1u << slice)); + return !!(available.high_slices & (1ul << slice)); } } -- cgit v1.2.3-70-g09d2 From dc7a9bd3d0583bdc6ac291b4e1bf540dea398ea2 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 18 Nov 2013 14:50:18 +0530 Subject: powerpc: booke: Fix build failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/powerpc/platforms/wsp/wsp.c: In function ‘wsp_probe_devices’: arch/powerpc/platforms/wsp/wsp.c:76:3: error: implicit declaration of function ‘of_address_to_resource’ [-Werror=implicit-function-declaration] Signed-off-by: Aneesh Kumar K.V Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/wsp/chroma.c | 1 + arch/powerpc/platforms/wsp/h8.c | 1 + arch/powerpc/platforms/wsp/ics.c | 2 ++ arch/powerpc/platforms/wsp/opb_pic.c | 2 ++ arch/powerpc/platforms/wsp/psr2.c | 1 + arch/powerpc/platforms/wsp/scom_wsp.c | 1 + arch/powerpc/platforms/wsp/wsp.c | 1 + 7 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/wsp/chroma.c b/arch/powerpc/platforms/wsp/chroma.c index 8ef53bc2e70..aaa46b35371 100644 --- a/arch/powerpc/platforms/wsp/chroma.c +++ b/arch/powerpc/platforms/wsp/chroma.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/wsp/h8.c b/arch/powerpc/platforms/wsp/h8.c index d18e6cc19df..a3c87f39575 100644 --- a/arch/powerpc/platforms/wsp/h8.c +++ b/arch/powerpc/platforms/wsp/h8.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "wsp.h" diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c index 2d3b1dd9571..9cd92e64502 100644 --- a/arch/powerpc/platforms/wsp/ics.c +++ b/arch/powerpc/platforms/wsp/ics.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c index cb565bf9365..3f672980793 100644 --- a/arch/powerpc/platforms/wsp/opb_pic.c +++ b/arch/powerpc/platforms/wsp/opb_pic.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c index 508ec8282b9..a87b414c766 100644 --- a/arch/powerpc/platforms/wsp/psr2.c +++ b/arch/powerpc/platforms/wsp/psr2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/wsp/scom_wsp.c b/arch/powerpc/platforms/wsp/scom_wsp.c index 8928507affe..6538b4de34f 100644 --- a/arch/powerpc/platforms/wsp/scom_wsp.c +++ b/arch/powerpc/platforms/wsp/scom_wsp.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c index ddb6efe8891..58cd1f00e1e 100644 --- a/arch/powerpc/platforms/wsp/wsp.c +++ b/arch/powerpc/platforms/wsp/wsp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include -- cgit v1.2.3-70-g09d2 From c6102609289de268bcc6093e606483ea8bb35c84 Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Tue, 19 Nov 2013 16:11:37 +0800 Subject: powerpc/vio: Fix a dma_mask issue of vio I encountered following issue: [ 0.283035] ibmvscsi 30000015: couldn't initialize event pool [ 5.688822] ibmvscsi: probe of 30000015 failed with error -1 which prevents the storage from being recognized, and the machine from booting. After some digging, it seems that it is caused by commit 4886c399da as dma_mask pointer in viodev->dev is not set, so in dma_set_mask_and_coherent(), dma_set_coherent_mask() is not called because dma_set_mask(), which is dma_set_mask_pSeriesLP() returned EIO. While before the commit, dma_set_coherent_mask() is always called. I tried to replace dma_set_mask_and_coherent() with dma_coerce_mask_and_coherent(), and the machine could boot again. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index e7d0c88f621..76a64821f4a 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1419,7 +1419,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) /* needed to ensure proper operation of coherent allocations * later, in case driver doesn't set it explicitly */ - dma_set_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64)); + dma_coerce_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64)); } /* register with generic device framework */ -- cgit v1.2.3-70-g09d2 From 3eb906c6b6c123513718e7742a96a4189f900382 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 20 Nov 2013 11:05:01 +1100 Subject: powerpc: Make cpu_to_chip_id() available when SMP=n Up until now we have only used cpu_to_chip_id() in the topology code, which is only used on SMP builds. However my recent commit a4da0d5 "Implement arch_get_random_long/int() for powernv" added a usage when SMP=n, breaking the build. Move cpu_to_chip_id() into prom.c so it is available for SMP=n builds. We would move the extern to prom.h, but that breaks the include in topology.h. Instead we leave it in smp.h, but move it out of the CONFIG_SMP #ifdef. We also need to include asm/smp.h in rng.c, because the linux version skips asm/smp.h on UP. What a mess. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/smp.h | 2 +- arch/powerpc/kernel/prom.c | 20 ++++++++++++++++++++ arch/powerpc/kernel/smp.c | 16 ---------------- arch/powerpc/platforms/powernv/rng.c | 1 + 4 files changed, 22 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 98da78e0c2c..084e0807db9 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -33,6 +33,7 @@ extern int boot_cpuid; extern int spinning_secondaries; extern void cpu_die(void); +extern int cpu_to_chip_id(int cpu); #ifdef CONFIG_SMP @@ -112,7 +113,6 @@ static inline struct cpumask *cpu_core_mask(int cpu) } extern int cpu_to_core_id(int cpu); -extern int cpu_to_chip_id(int cpu); /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. * diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f3a47098fb8..fa0ad8aafbc 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -777,6 +777,26 @@ int of_get_ibm_chip_id(struct device_node *np) return -1; } +/** + * cpu_to_chip_id - Return the cpus chip-id + * @cpu: The logical cpu number. + * + * Return the value of the ibm,chip-id property corresponding to the given + * logical cpu number. If the chip-id can not be found, returns -1. + */ +int cpu_to_chip_id(int cpu) +{ + struct device_node *np; + + np = of_get_cpu_node(cpu, NULL); + if (!np) + return -1; + + of_node_put(np); + return of_get_ibm_chip_id(np); +} +EXPORT_SYMBOL(cpu_to_chip_id); + #ifdef CONFIG_PPC_PSERIES /* * Fix up the uninitialized fields in a new device node: diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 930cd8af350..a3b64f3bf9a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -597,22 +597,6 @@ out: return id; } -/* Return the value of the chip-id property corresponding - * to the given logical cpu. - */ -int cpu_to_chip_id(int cpu) -{ - struct device_node *np; - - np = of_get_cpu_node(cpu, NULL); - if (!np) - return -1; - - of_node_put(np); - return of_get_ibm_chip_id(np); -} -EXPORT_SYMBOL(cpu_to_chip_id); - /* Helper routines for cpu to core mapping */ int cpu_core_index_of_thread(int cpu) { diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 8844628915d..1cb160dc160 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -19,6 +19,7 @@ #include #include #include +#include struct powernv_rng { -- cgit v1.2.3-70-g09d2 From 148924f7a282b3acb1f8868ae03c3f76be301d8d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 20 Nov 2013 11:05:02 +1100 Subject: powerpc/pseries: Fix SMP=n build of rng.c In commit a489043 "Implement arch_get_random_long() based on H_RANDOM" I broke the SMP=n build. We were getting plpar_wrappers.h via spinlock.h which breaks when SMP=n. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/rng.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c index a702f1c0824..72a102758d4 100644 --- a/arch/powerpc/platforms/pseries/rng.c +++ b/arch/powerpc/platforms/pseries/rng.c @@ -13,6 +13,7 @@ #include #include #include +#include static int pseries_get_random_long(unsigned long *v) -- cgit v1.2.3-70-g09d2 From c13f20ac48328b05cd3b8c19e31ed6c132b44b42 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 20 Nov 2013 16:18:54 +1100 Subject: powerpc/signals: Mark VSX not saved with small contexts The VSX MSR bit in the user context indicates if the context contains VSX state. Currently we set this when the process has touched VSX at any stage. Unfortunately, if the user has not provided enough space to save the VSX state, we can't save it but we currently still set the MSR VSX bit. This patch changes this to clear the MSR VSX bit when the user doesn't provide enough space. This indicates that there is no valid VSX state in the user context. This is needed to support get/set/make/swapcontext for applications that use VSX but only provide a small context. For example, getcontext in glibc provides a smaller context since the VSX registers don't need to be saved over the glibc function call. But since the program calling getcontext may have used VSX, the kernel currently says the VSX state is valid when it's not. If the returned context is then used in setcontext (ie. a small context without VSX but with MSR VSX set), the kernel will refuse the context. This situation has been reported by the glibc community. Based on patch from Carlos O'Donell. Tested-by: Haren Myneni Signed-off-by: Michael Neuling Cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/signal_32.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 749778e0a69..1844298f5ea 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; msr |= MSR_VSX; - } + } else if (!ctx_has_vsx_region) + /* + * With a small context structure we can't hold the VSX + * registers, hence clear the MSR value to indicate the state + * was not saved. + */ + msr &= ~MSR_VSX; + + #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* save spe registers */ -- cgit v1.2.3-70-g09d2 From e462f1f5174893f3f5efd03a31ca014b02120f9a Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Fri, 8 Nov 2013 12:15:56 +0530 Subject: ARM: davinci: fix number of resources passed to davinci_gpio_register() The davinci_gpio_register() function expects the number of resources as the second parameter, but sizeof() resources was passed to it due to which it was causing unexpected behaviour. This patch fixes the same by passing the ARRAY_SIZE() of resources. Reported-by: Grygorii Strashko Signed-off-by: Lad, Prabhakar Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index ef9ff1fb6f5..536ce52d51c 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -906,7 +906,7 @@ static struct davinci_gpio_platform_data dm355_gpio_platform_data = { int __init dm355_gpio_register(void) { return davinci_gpio_register(dm355_gpio_resources, - sizeof(dm355_gpio_resources), + ARRAY_SIZE(dm355_gpio_resources), &dm355_gpio_platform_data); } /*----------------------------------------------------------------------*/ diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 1511a0680f9..9c965204488 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -720,7 +720,7 @@ static struct davinci_gpio_platform_data dm365_gpio_platform_data = { int __init dm365_gpio_register(void) { return davinci_gpio_register(dm365_gpio_resources, - sizeof(dm365_gpio_resources), + ARRAY_SIZE(dm365_gpio_resources), &dm365_gpio_platform_data); } diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 143a3217e8e..72a3aa71910 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -792,7 +792,7 @@ static struct davinci_gpio_platform_data dm644_gpio_platform_data = { int __init dm644x_gpio_register(void) { return davinci_gpio_register(dm644_gpio_resources, - sizeof(dm644_gpio_resources), + ARRAY_SIZE(dm644_gpio_resources), &dm644_gpio_platform_data); } /*----------------------------------------------------------------------*/ diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 2a73f299c1d..d1b646c099f 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -769,7 +769,7 @@ static struct davinci_gpio_platform_data dm646x_gpio_platform_data = { int __init dm646x_gpio_register(void) { return davinci_gpio_register(dm646x_gpio_resources, - sizeof(dm646x_gpio_resources), + ARRAY_SIZE(dm646x_gpio_resources), &dm646x_gpio_platform_data); } /*----------------------------------------------------------------------*/ -- cgit v1.2.3-70-g09d2 From c283610e44ec4ccc412dde8b71cf297ed9515f2f Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 21 Nov 2013 14:32:09 -0800 Subject: x86, mm: do not leak page->ptl for pmd page tables There are two code paths how page with pmd page table can be freed: pmd_free() and pmd_free_tlb(). I've missed the second one and didn't add page table destructor call there. It leads to leak of page->ptl for pmd page tables, if dynamically allocated page->ptl is in use. The patch adds the missed destructor and modifies documentation accordingly. Signed-off-by: Kirill A. Shutemov Reported-by: Andrey Vagin Tested-by: Andrey Vagin Cc: Ingo Molnar Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/vm/split_page_table_lock | 6 +++--- arch/x86/mm/pgtable.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/Documentation/vm/split_page_table_lock b/Documentation/vm/split_page_table_lock index 7521d367f21..6dea4fd5c96 100644 --- a/Documentation/vm/split_page_table_lock +++ b/Documentation/vm/split_page_table_lock @@ -63,9 +63,9 @@ levels. PMD split lock enabling requires pgtable_pmd_page_ctor() call on PMD table allocation and pgtable_pmd_page_dtor() on freeing. -Allocation usually happens in pmd_alloc_one(), freeing in pmd_free(), but -make sure you cover all PMD table allocation / freeing paths: i.e X86_PAE -preallocate few PMDs on pgd_alloc(). +Allocation usually happens in pmd_alloc_one(), freeing in pmd_free() and +pmd_free_tlb(), but make sure you cover all PMD table allocation / freeing +paths: i.e X86_PAE preallocate few PMDs on pgd_alloc(). With everything in place you can set CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK. diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 36aa999b263..c96314abd14 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -61,6 +61,7 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) #if PAGETABLE_LEVELS > 2 void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { + struct page *page = virt_to_page(pmd); paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); /* * NOTE! For PAE, any changes to the top page-directory-pointer-table @@ -69,7 +70,8 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) #ifdef CONFIG_X86_PAE tlb->need_flush_all = 1; #endif - tlb_remove_page(tlb, virt_to_page(pmd)); + pgtable_pmd_page_dtor(page); + tlb_remove_page(tlb, page); } #if PAGETABLE_LEVELS > 3 -- cgit v1.2.3-70-g09d2 From cbf8a358be27ceecea5bd44cf82ab01683fcc90c Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Fri, 22 Nov 2013 10:49:00 +0800 Subject: powerpc/corenet64: compile with CONFIG_E{5,6}500_CPU well If CONFIG_ALTIVEC is enabled for CoreNet64, and if we also select CONFIG_E{5,6}500_CPU this may introduce -mcpu=e500mc64 into $CFLAGS. But Altivec option not allowed with e500mc64, then some compiling errors occur like this: CC arch/powerpc/lib/xor_vmx.o arch/powerpc/lib/xor_vmx.c:1:0: error: AltiVec not supported in this target make[1]: *** [arch/powerpc/lib/xor_vmx.o] Error 1 make: *** [arch/powerpc/lib] Error 2 So we should restrict e500mc64 in altivec scenario. Signed-off-by: Tiejun Chen Signed-off-by: Scott Wood --- arch/powerpc/Makefile | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 8a2463670a5..a284d7fbc97 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -128,7 +128,12 @@ CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5) CFLAGS-$(CONFIG_POWER6_CPU) += $(call cc-option,-mcpu=power6) CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7) +# Altivec option not allowed with e500mc64 in GCC. +ifeq ($(CONFIG_ALTIVEC),y) +E5500_CPU := -mcpu=powerpc64 +else E5500_CPU := $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64) +endif CFLAGS-$(CONFIG_E5500_CPU) += $(E5500_CPU) CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU)) -- cgit v1.2.3-70-g09d2 From ae2163be10ac6090e7aeed72591e2d7fabb1cdda Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 22 Nov 2013 17:57:31 +0100 Subject: powerpc/8xx: mfspr SPRN_TBRx in lieu of mftb/mftbu is not supported Commit beb2dc0a7a84be003ce54e98b95d65cc66e6e536 breaks the MPC8xx which seems to not support using mfspr SPRN_TBRx instead of mftb/mftbu despite what is written in the reference manual. This patch reverts to the use of mftb/mftbu when CONFIG_8xx is selected. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/boot/util.S | 14 ++++++++++++++ arch/powerpc/include/asm/ppc_asm.h | 2 ++ arch/powerpc/include/asm/reg.h | 7 +++++++ arch/powerpc/include/asm/timex.h | 8 ++++++++ arch/powerpc/kernel/vdso32/gettimeofday.S | 6 ++++++ 5 files changed, 37 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index 5143228e3e5..6636b1d7821 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S @@ -71,18 +71,32 @@ udelay: add r4,r4,r5 addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ +#ifdef CONFIG_8xx +1: mftbu r5 + mftb r6 + mftbu r7 +#else 1: mfspr r5, SPRN_TBRU mfspr r6, SPRN_TBRL mfspr r7, SPRN_TBRU +#endif cmpw 0,r5,r7 bne 1b /* Get [synced] base time */ addc r9,r6,r4 /* Compute end time */ addze r8,r5 +#ifdef CONFIG_8xx +2: mftbu r5 +#else 2: mfspr r5, SPRN_TBRU +#endif cmpw 0,r5,r8 blt 2b bgt 3f +#ifdef CONFIG_8xx + mftb r6 +#else mfspr r6, SPRN_TBRL +#endif cmpw 0,r6,r9 blt 2b 3: blr diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 3c1acc31a09..f595b98079e 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -366,6 +366,8 @@ BEGIN_FTR_SECTION_NESTED(96); \ cmpwi dest,0; \ beq- 90b; \ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) +#elif defined(CONFIG_8xx) +#define MFTB(dest) mftb dest #else #define MFTB(dest) mfspr dest, SPRN_TBRL #endif diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 5c45787d551..fa8388ed94c 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1174,12 +1174,19 @@ #else /* __powerpc64__ */ +#if defined(CONFIG_8xx) +#define mftbl() ({unsigned long rval; \ + asm volatile("mftbl %0" : "=r" (rval)); rval;}) +#define mftbu() ({unsigned long rval; \ + asm volatile("mftbu %0" : "=r" (rval)); rval;}) +#else #define mftbl() ({unsigned long rval; \ asm volatile("mfspr %0, %1" : "=r" (rval) : \ "i" (SPRN_TBRL)); rval;}) #define mftbu() ({unsigned long rval; \ asm volatile("mfspr %0, %1" : "=r" (rval) : \ "i" (SPRN_TBRU)); rval;}) +#endif #endif /* !__powerpc64__ */ #define mttbl(v) asm volatile("mttbl %0":: "r"(v)) diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h index 18908caa1f3..2cf846edb3f 100644 --- a/arch/powerpc/include/asm/timex.h +++ b/arch/powerpc/include/asm/timex.h @@ -29,7 +29,11 @@ static inline cycles_t get_cycles(void) ret = 0; __asm__ __volatile__( +#ifdef CONFIG_8xx + "97: mftb %0\n" +#else "97: mfspr %0, %2\n" +#endif "99:\n" ".section __ftr_fixup,\"a\"\n" ".align 2\n" @@ -41,7 +45,11 @@ static inline cycles_t get_cycles(void) " .long 0\n" " .long 0\n" ".previous" +#ifdef CONFIG_8xx + : "=r" (ret) : "i" (CPU_FTR_601)); +#else : "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL)); +#endif return ret; #endif } diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 6b1f2a6d551..6b2b69616e7 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -232,9 +232,15 @@ __do_get_tspec: lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) /* Get a stable TB value */ +#ifdef CONFIG_8xx +2: mftbu r3 + mftbl r4 + mftbu r0 +#else 2: mfspr r3, SPRN_TBRU mfspr r4, SPRN_TBRL mfspr r0, SPRN_TBRU +#endif cmplw cr0,r3,r0 bne- 2b -- cgit v1.2.3-70-g09d2 From 53567cf3c28d11f58927e5d4946a744ec2fbf06e Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Tue, 12 Nov 2013 17:56:51 +0100 Subject: powerpc/85xx: typo in dts: "interupt" (four devices) These lines were inoperative for four years, which puts some doubt into their importance, and it's possible the fixed version will regress, but at the very least they should be removed instead. Signed-off-by: Adam Borowski Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/xcalibur1501.dts | 4 ++-- arch/powerpc/boot/dts/xpedite5301.dts | 4 ++-- arch/powerpc/boot/dts/xpedite5330.dts | 4 ++-- arch/powerpc/boot/dts/xpedite5370.dts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/xcalibur1501.dts b/arch/powerpc/boot/dts/xcalibur1501.dts index cc00f4ddd9a..c409cbafb12 100644 --- a/arch/powerpc/boot/dts/xcalibur1501.dts +++ b/arch/powerpc/boot/dts/xcalibur1501.dts @@ -637,14 +637,14 @@ tlu@2f000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x2f000 0x1000>; - interupts = <61 2 >; + interrupts = <61 2>; interrupt-parent = <&mpic>; }; tlu@15000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x15000 0x1000>; - interupts = <75 2>; + interrupts = <75 2>; interrupt-parent = <&mpic>; }; }; diff --git a/arch/powerpc/boot/dts/xpedite5301.dts b/arch/powerpc/boot/dts/xpedite5301.dts index 53c1c6a9752..04cb410da48 100644 --- a/arch/powerpc/boot/dts/xpedite5301.dts +++ b/arch/powerpc/boot/dts/xpedite5301.dts @@ -547,14 +547,14 @@ tlu@2f000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x2f000 0x1000>; - interupts = <61 2 >; + interrupts = <61 2>; interrupt-parent = <&mpic>; }; tlu@15000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x15000 0x1000>; - interupts = <75 2>; + interrupts = <75 2>; interrupt-parent = <&mpic>; }; }; diff --git a/arch/powerpc/boot/dts/xpedite5330.dts b/arch/powerpc/boot/dts/xpedite5330.dts index 21522598315..73f8620f1ce 100644 --- a/arch/powerpc/boot/dts/xpedite5330.dts +++ b/arch/powerpc/boot/dts/xpedite5330.dts @@ -583,14 +583,14 @@ tlu@2f000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x2f000 0x1000>; - interupts = <61 2 >; + interrupts = <61 2>; interrupt-parent = <&mpic>; }; tlu@15000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x15000 0x1000>; - interupts = <75 2>; + interrupts = <75 2>; interrupt-parent = <&mpic>; }; }; diff --git a/arch/powerpc/boot/dts/xpedite5370.dts b/arch/powerpc/boot/dts/xpedite5370.dts index 11dbda10d75..cd0ea2b9936 100644 --- a/arch/powerpc/boot/dts/xpedite5370.dts +++ b/arch/powerpc/boot/dts/xpedite5370.dts @@ -545,14 +545,14 @@ tlu@2f000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x2f000 0x1000>; - interupts = <61 2 >; + interrupts = <61 2>; interrupt-parent = <&mpic>; }; tlu@15000 { compatible = "fsl,mpc8572-tlu", "fsl_tlu"; reg = <0x15000 0x1000>; - interupts = <75 2>; + interrupts = <75 2>; interrupt-parent = <&mpic>; }; }; -- cgit v1.2.3-70-g09d2 From d742aa152f27448d39ce65fb829e396d10cd63a9 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 21 Nov 2013 18:26:42 -0600 Subject: powerpc/booke: Only check for hugetlb in flush if vma != NULL And in flush_hugetlb_page(), don't check whether vma is NULL after we've already dereferenced it. This was found by Dan using static analysis as described here: https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-November/113161.html We currently get away with this because the callers that currently pass NULL for vma seem to be 32-bit-only (e.g. highmem, and CONFIG_DEBUG_PGALLOC in pgtable_32.c) Hugetlb is currently 64-bit only, so we never saw a NULL vma here. Signed-off-by: Scott Wood Reported-by: Dan Carpenter --- arch/powerpc/mm/hugetlbpage-book3e.c | 3 +-- arch/powerpc/mm/tlb_nohash.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index 3bc700655fc..74551b5e41e 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -117,6 +117,5 @@ void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr) struct hstate *hstate = hstate_file(vma->vm_file); unsigned long tsize = huge_page_shift(hstate) - 10; - __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0); - + __flush_tlb_page(vma->vm_mm, vmaddr, tsize, 0); } diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index 41cd68dee68..358d7430313 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c @@ -305,7 +305,7 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { #ifdef CONFIG_HUGETLB_PAGE - if (is_vm_hugetlb_page(vma)) + if (vma && is_vm_hugetlb_page(vma)) flush_hugetlb_page(vma, vmaddr); #endif -- cgit v1.2.3-70-g09d2 From 12b69a599745fc9e203f61fbb7160b2cc5f479dd Mon Sep 17 00:00:00 2001 From: Arnaud Ebalard Date: Tue, 5 Nov 2013 21:45:48 +0100 Subject: ARM: mvebu: second PCIe unit of Armada XP mv78230 is only x1 capable Various Marvell datasheets advertise second PCIe unit of mv78230 flavour of Armada XP as x4/quad x1 capable. This second unit is in fact only x1 capable. This patch fixes current mv78230 .dtsi to reflect that, i.e. makes 1.0 the second interface (instead of 2.0 at the moment). This was successfully tested on a mv78230-based ReadyNAS 2120 platform with a x1 device (FL1009 XHCI controller) connected to this second interface. Signed-off-by: Arnaud Ebalard Acked-by: Thomas Petazzoni Cc: # v3.10.x Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-xp-mv78230.dtsi | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi index 3f5e6121c73..98335fb34b7 100644 --- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -47,7 +47,7 @@ /* * MV78230 has 2 PCIe units Gen2.0: One unit can be * configured as x4 or quad x1 lanes. One unit is - * x4/x1. + * x1 only. */ pcie-controller { compatible = "marvell,armada-xp-pcie"; @@ -62,10 +62,10 @@ ranges = <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */ - 0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */ 0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */ + 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */ @@ -74,8 +74,8 @@ 0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */ 0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */ 0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */ - 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */ - 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>; + 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */ + 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>; pcie@1,0 { device_type = "pci"; @@ -145,20 +145,20 @@ status = "disabled"; }; - pcie@9,0 { + pcie@5,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; - reg = <0x4800 0 0 0 0>; + assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; - ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 - 0x81000000 0 0 0x81000000 0x9 0 1 0>; + ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 + 0x81000000 0 0 0x81000000 0x5 0 1 0>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 99>; - marvell,pcie-port = <2>; + interrupt-map = <0 0 0 0 &mpic 62>; + marvell,pcie-port = <1>; marvell,pcie-lane = <0>; - clocks = <&gateclk 26>; + clocks = <&gateclk 9>; status = "disabled"; }; }; -- cgit v1.2.3-70-g09d2 From 2163e61c92d9337e721a0d067d88ae62b52e0d3e Mon Sep 17 00:00:00 2001 From: Arnaud Ebalard Date: Tue, 5 Nov 2013 21:46:02 +0100 Subject: ARM: mvebu: fix second and third PCIe unit of Armada XP mv78260 mv78260 flavour of Marvell Armada XP SoC has 3 PCIe units. The two first units are both x4 and quad x1 capable. The third unit is only x4 capable. This patch fixes mv78260 .dtsi to reflect those capabilities. Signed-off-by: Arnaud Ebalard Acked-by: Thomas Petazzoni Cc: # v3.10.x Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-xp-mv78260.dtsi | 109 ++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 3e9fd1353f8..66609684d41 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -48,7 +48,7 @@ /* * MV78260 has 3 PCIe units Gen2.0: Two units can be * configured as x4 or quad x1 lanes. One unit is - * x4/x1. + * x4 only. */ pcie-controller { compatible = "marvell,armada-xp-pcie"; @@ -68,7 +68,9 @@ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */ 0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */ - 0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000 /* Port 3.0 registers */ + 0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */ + 0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */ + 0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */ @@ -77,10 +79,18 @@ 0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */ 0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */ 0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */ - 0x82000000 0x9 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */ - 0x81000000 0x9 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */ - 0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */ - 0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>; + + 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */ + 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */ + 0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */ + 0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */ + 0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */ + 0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */ + 0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */ + 0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */ + + 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */ + 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>; pcie@1,0 { device_type = "pci"; @@ -106,8 +116,8 @@ #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; - ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 - 0x81000000 0 0 0x81000000 0x2 0 1 0>; + ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 + 0x81000000 0 0 0x81000000 0x2 0 1 0>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -150,37 +160,88 @@ status = "disabled"; }; - pcie@9,0 { + pcie@5,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; - reg = <0x4800 0 0 0 0>; + assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; - ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 - 0x81000000 0 0 0x81000000 0x9 0 1 0>; + ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 + 0x81000000 0 0 0x81000000 0x5 0 1 0>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 99>; - marvell,pcie-port = <2>; + interrupt-map = <0 0 0 0 &mpic 62>; + marvell,pcie-port = <1>; marvell,pcie-lane = <0>; - clocks = <&gateclk 26>; + clocks = <&gateclk 9>; status = "disabled"; }; - pcie@10,0 { + pcie@6,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x82000 0 0x2000>; - reg = <0x5000 0 0 0 0>; + assigned-addresses = <0x82000800 0 0x84000 0 0x2000>; + reg = <0x3000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; - ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0 - 0x81000000 0 0 0x81000000 0xa 0 1 0>; + ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 + 0x81000000 0 0 0x81000000 0x6 0 1 0>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 103>; - marvell,pcie-port = <3>; + interrupt-map = <0 0 0 0 &mpic 63>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <1>; + clocks = <&gateclk 10>; + status = "disabled"; + }; + + pcie@7,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x88000 0 0x2000>; + reg = <0x3800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 + 0x81000000 0 0 0x81000000 0x7 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 64>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <2>; + clocks = <&gateclk 11>; + status = "disabled"; + }; + + pcie@8,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>; + reg = <0x4000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 + 0x81000000 0 0 0x81000000 0x8 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 65>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <3>; + clocks = <&gateclk 12>; + status = "disabled"; + }; + + pcie@9,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; + reg = <0x4800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 + 0x81000000 0 0 0x81000000 0x9 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 99>; + marvell,pcie-port = <2>; marvell,pcie-lane = <0>; - clocks = <&gateclk 27>; + clocks = <&gateclk 26>; status = "disabled"; }; }; -- cgit v1.2.3-70-g09d2 From 924dd50bc4ad26612efbc75f7e60492c5faaa868 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 21 Nov 2013 14:59:07 +1100 Subject: powerpc: Fix error when cross building TAGS & cscope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently if I cross build TAGS or cscope from x86 I get this: % make ARCH=powerpc TAGS gcc-4.8.real: error: unrecognized command line option ‘-mbig-endian’ GEN TAGS % I'm not setting CROSS_COMPILE= as logically I shouldn't need to and I haven't needed to in the past when building TAGS or cscope. Also, the above completess correct as the error is not fatal to the build. This was caused by: commit d72b08017161ab385d4ae080ea415c9eb7ceef83 Author: Ian Munsie powerpc: Add ability to build little endian kernels The below fixes this by testing for the -mbig-endian option before adding it. I've not done the same thing in the little endian case as if -mlittle-endian doesn't exist, we probably want to fail quickly as you probably have an old big endian compiler. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index a284d7fbc97..0f4344e6fbc 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -75,8 +75,10 @@ LDEMULATION := lppc GNUTARGET := powerpcle MULTIPLEWORD := -mno-multiple else +ifeq ($(call cc-option-yn,-mbig-endian),y) override CC += -mbig-endian override AS += -mbig-endian +endif override LD += -EB LDEMULATION := ppc GNUTARGET := powerpc -- cgit v1.2.3-70-g09d2 From 962bc221c3b1d63a461f8065bfb37122ce660119 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 21 Nov 2013 16:33:55 +1100 Subject: powerpc: allyesconfig should not select CONFIG_CPU_LITTLE_ENDIAN Stephen reported a failure in an allyesconfig build. CONFIG_CPU_LITTLE_ENDIAN=y gets set but his toolchain is not new enough to support little endian. We really want to default to a big endian build; Ben suggested using a choice which defaults to CPU_BIG_ENDIAN. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/Kconfig.cputype | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 132f8726a25..bca2465a9c3 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -404,13 +404,27 @@ config PPC_DOORBELL endmenu -config CPU_LITTLE_ENDIAN - bool "Build little endian kernel" - default n +choice + prompt "Endianness selection" + default CPU_BIG_ENDIAN help This option selects whether a big endian or little endian kernel will be built. +config CPU_BIG_ENDIAN + bool "Build big endian kernel" + help + Build a big endian kernel. + + If unsure, select this option. + +config CPU_LITTLE_ENDIAN + bool "Build little endian kernel" + help + Build a little endian kernel. + Note that if cross compiling a little endian kernel, CROSS_COMPILE must point to a toolchain capable of targeting little endian powerpc. + +endchoice -- cgit v1.2.3-70-g09d2 From 8ff812719ac73ef9428b788e210221c8d87b2a8c Mon Sep 17 00:00:00 2001 From: Hari Bathini Date: Fri, 15 Nov 2013 23:01:32 +0530 Subject: powerpc/kdump: Adding symbols in vmcoreinfo to facilitate dump filtering When CONFIG_SPARSEMEM_VMEMMAP option is used in kernel, makedumpfile fails to filter vmcore dump as it fails to do vmemmap translations. So far dump filtering on ppc64 never had to deal with vmemmap addresses seperately as vmemmap regions where mapped in zone normal. But with the inclusion of CONFIG_SPARSEMEM_VMEMMAP config option in kernel, this vmemmap address translation support becomes necessary for dump filtering. For vmemmap adress translation, few kernel symbols are needed by dump filtering tool. This patch adds those symbols to vmcoreinfo, which a dump filtering tool can use for filtering the kernel dump. Tested this changes successfully with makedumpfile tool that supports vmemmap to physical address translation outside zone normal. [ Removed unneeded #ifdef as suggested by Michael Ellerman --BenH ] Signed-off-by: Hari Bathini Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/pgalloc-64.h | 1 + arch/powerpc/kernel/machine_kexec.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 16cb92d215d..694012877bf 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -16,6 +16,7 @@ struct vmemmap_backing { unsigned long phys; unsigned long virt_addr; }; +extern struct vmemmap_backing *vmemmap_list; /* * Functions that deal with pagetables that could be at any level of diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index e1ec57e87b3..88a7fb458df 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -75,6 +76,17 @@ void arch_crash_save_vmcoreinfo(void) #ifndef CONFIG_NEED_MULTIPLE_NODES VMCOREINFO_SYMBOL(contig_page_data); #endif +#if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP) + VMCOREINFO_SYMBOL(vmemmap_list); + VMCOREINFO_SYMBOL(mmu_vmemmap_psize); + VMCOREINFO_SYMBOL(mmu_psize_defs); + VMCOREINFO_STRUCT_SIZE(vmemmap_backing); + VMCOREINFO_OFFSET(vmemmap_backing, list); + VMCOREINFO_OFFSET(vmemmap_backing, phys); + VMCOREINFO_OFFSET(vmemmap_backing, virt_addr); + VMCOREINFO_STRUCT_SIZE(mmu_psize_def); + VMCOREINFO_OFFSET(mmu_psize_def, shift); +#endif } /* -- cgit v1.2.3-70-g09d2 From ec67ad82814bee92251fd963bf01c7a173856555 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 25 Nov 2013 11:12:20 +1100 Subject: powerpc/signals: Improved mark VSX not saved with small contexts fix In a recent patch: commit c13f20ac48328b05cd3b8c19e31ed6c132b44b42 Author: Michael Neuling powerpc/signals: Mark VSX not saved with small contexts We fixed an issue but an improved solution was later discussed after the patch was merged. Firstly, this patch doesn't handle the 64bit signals case, which could also hit this issue (but has never been reported). Secondly, the original patch isn't clear what MSR VSX should be set to. The new approach below always clears the MSR VSX bit (to indicate no VSX is in the context) and sets it only in the specific case where VSX is available (ie. when VSX has been used and the signal context passed has space to provide the state). This reverts the original patch and replaces it with the improved solution. It also adds a 64 bit version. Signed-off-by: Michael Neuling Cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/signal_32.c | 16 +++++++--------- arch/powerpc/kernel/signal_64.c | 6 ++++++ 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 1844298f5ea..68027bfa5f8 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -445,6 +445,12 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, #endif /* CONFIG_ALTIVEC */ if (copy_fpr_to_user(&frame->mc_fregs, current)) return 1; + + /* + * Clear the MSR VSX bit to indicate there is no valid state attached + * to this context, except in the specific case below where we set it. + */ + msr &= ~MSR_VSX; #ifdef CONFIG_VSX /* * Copy VSR 0-31 upper half from thread_struct to local @@ -457,15 +463,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; msr |= MSR_VSX; - } else if (!ctx_has_vsx_region) - /* - * With a small context structure we can't hold the VSX - * registers, hence clear the MSR value to indicate the state - * was not saved. - */ - msr &= ~MSR_VSX; - - + } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* save spe registers */ diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index e66f67b8b9e..42991045349 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -122,6 +122,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, flush_fp_to_thread(current); /* copy fpr regs and fpscr */ err |= copy_fpr_to_user(&sc->fp_regs, current); + + /* + * Clear the MSR VSX bit to indicate there is no valid state attached + * to this context, except in the specific case below where we set it. + */ + msr &= ~MSR_VSX; #ifdef CONFIG_VSX /* * Copy VSX low doubleword to local buffer for formatting, -- cgit v1.2.3-70-g09d2 From e0513d9ea8dd2a7b21b699ada8d59d8afbb8b5b7 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 24 Jan 2013 12:14:52 +0800 Subject: arch/powerpc/kernel: Use %12.12s instead of %12s to avoid memory overflow for tmp_part->header.name: it is "Terminating null required only for names < 12 chars". so need to limit the %.12s for it in printk additional info: %12s limit the width, not for the original string output length if name length is more than 12, it still can be fully displayed. if name length is less than 12, the ' ' will be filled before name. %.12s truly limit the original string output length (precision) Signed-off-by: Chen Gang Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index fd82c289ab1..28b898e6818 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -210,7 +210,7 @@ static void __init nvram_print_partitions(char * label) printk(KERN_WARNING "--------%s---------\n", label); printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); list_for_each_entry(tmp_part, &nvram_partitions, partition) { - printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12s\n", + printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12.12s\n", tmp_part->index, tmp_part->header.signature, tmp_part->header.checksum, tmp_part->header.length, tmp_part->header.name); -- cgit v1.2.3-70-g09d2 From f06d19e460cdd326eff955ca614cb8064bd0a5f2 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 15 Nov 2013 12:08:05 +0530 Subject: ARC: extable: Enable sorting at build time Avoids wasting cycles at boot specially on slower simulators Signed-off-by: Vineet Gupta Cc: Michal Marek Cc: Francois Bedard Cc: linux-kernel@vger.kernel.org Acked-by: David Daney --- arch/arc/Kconfig | 1 + scripts/sortextable.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 2ee0c9bfd03..9063ae6553c 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -8,6 +8,7 @@ config ARC def_bool y + select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS # ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev select DEVTMPFS if !INITRAMFS_SOURCE="" diff --git a/scripts/sortextable.c b/scripts/sortextable.c index 5f7a8b663cb..7941fbdfb05 100644 --- a/scripts/sortextable.c +++ b/scripts/sortextable.c @@ -31,6 +31,10 @@ #include #include +#ifndef EM_ARCOMPACT +#define EM_ARCOMPACT 93 +#endif + #ifndef EM_AARCH64 #define EM_AARCH64 183 #endif @@ -268,6 +272,7 @@ do_file(char const *const fname) case EM_S390: custom_sort = sort_relative_table; break; + case EM_ARCOMPACT: case EM_ARM: case EM_AARCH64: case EM_MIPS: -- cgit v1.2.3-70-g09d2 From 97bc386fc12deeb41d5bff33548e3002b258d4e0 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 21 Nov 2013 15:34:16 +0530 Subject: ARC: Add guard macro to uapi/asm/unistd.h Chen originally proposed this as "right thing to do" however I actually ran into this when building perf tools. Some of the utils include unistd.h as well as linux/unistd.h. Since -I includes kernel headers too, we end up including the ARC unistd.h twice, leading to redefinition nwarnings. ------------------>8------------------- CC bench/sched-pipe.o In file included from ~/kernel/arch/arc/include/uapi/asm/unistd.h:21:0, from ~/kernel/include/uapi/linux/unistd.h:7, from bench/sched-pipe.c:24: ~/kernel/include/uapi/asm-generic/unistd.h:889:0: error: "__NR_fcntl64" redefined [-Werror] #define __NR_fcntl64 __NR3264_fcntl ^ In file included from ~/gnu/arc-linux-uclibc/sys-include/sys/syscall.h:24:0, from bench/../perf.h:112, from bench/sched-pipe.c:13: ~/gnu/arc-linux-uclibc/include/bits/sysnum.h:761:0: note: this is the location of the previous definition ------------------>8------------------- Verified that make headers_install works fine with this. Suggested-by: Chen Gang Signed-off-by: Vineet Gupta Cc: David Howells --- arch/arc/include/uapi/asm/unistd.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arc/include/uapi/asm/unistd.h b/arch/arc/include/uapi/asm/unistd.h index 6f30484f34b..68125dd766c 100644 --- a/arch/arc/include/uapi/asm/unistd.h +++ b/arch/arc/include/uapi/asm/unistd.h @@ -8,6 +8,9 @@ /******** no-legacy-syscalls-ABI *******/ +#ifndef _UAPI_ASM_ARC_UNISTD_H +#define _UAPI_ASM_ARC_UNISTD_H + #define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_CLONE #define __ARCH_WANT_SYS_VFORK @@ -32,3 +35,5 @@ __SYSCALL(__NR_arc_gettls, sys_arc_gettls) /* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */ #define __NR_sysfs (__NR_arch_specific_syscall + 3) __SYSCALL(__NR_sysfs, sys_sysfs) + +#endif -- cgit v1.2.3-70-g09d2 From 71a86ef055f569b93bc6901f007bdf447dbf515f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 21 Nov 2013 16:22:17 +0100 Subject: s390/uaccess: add missing page table walk range check When translating a user space address, the address must be checked against the ASCE limit of the process. If the address is larger than the maximum address that is reachable with the ASCE, an ASCE type exception must be generated. The current code simply ignored the higher order bits. This resulted in an address wrap around in user space instead of an exception in user space. Cc: stable@vger.kernel.org # v3.9+ Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_pt.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 97e03caf782..dbdab3e7a1a 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -78,11 +78,14 @@ static size_t copy_in_kernel(size_t count, void __user *to, * contains the (negative) exception code. */ #ifdef CONFIG_64BIT + static unsigned long follow_table(struct mm_struct *mm, unsigned long address, int write) { unsigned long *table = (unsigned long *)__pa(mm->pgd); + if (unlikely(address > mm->context.asce_limit - 1)) + return -0x38UL; switch (mm->context.asce_bits & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: table = table + ((address >> 53) & 0x7ff); -- cgit v1.2.3-70-g09d2 From 79c74ecbebf76732f91b82a62ce7fc8a88326962 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 22 Nov 2013 10:04:53 +0100 Subject: s390/time,vdso: convert to the new update_vsyscall interface Switch to the improved update_vsyscall interface that provides sub-nanosecond precision for gettimeofday and clock_gettime. Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 2 +- arch/s390/include/asm/vdso.h | 5 +++-- arch/s390/kernel/asm-offsets.c | 3 ++- arch/s390/kernel/time.c | 27 ++++++++++++++++++--------- arch/s390/kernel/vdso32/clock_gettime.S | 30 ++++++++++++++++-------------- arch/s390/kernel/vdso32/gettimeofday.S | 9 +++++---- arch/s390/kernel/vdso64/clock_gettime.S | 22 ++++++++++++---------- arch/s390/kernel/vdso64/gettimeofday.S | 9 +++++---- 8 files changed, 62 insertions(+), 45 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 314fced4fc1..5877e71901b 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -101,7 +101,7 @@ config S390 select GENERIC_CPU_DEVICES if !SMP select GENERIC_FIND_FIRST_BIT select GENERIC_SMP_IDLE_THREAD - select GENERIC_TIME_VSYSCALL_OLD + select GENERIC_TIME_VSYSCALL select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 select HAVE_ARCH_SECCOMP_FILTER diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index a73eb2e1e91..bc9746a7d47 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -26,8 +26,9 @@ struct vdso_data { __u64 wtom_clock_nsec; /* 0x28 */ __u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */ __u32 tz_dsttime; /* Type of dst correction 0x34 */ - __u32 ectg_available; - __u32 ntp_mult; /* NTP adjusted multiplier 0x3C */ + __u32 ectg_available; /* ECTG instruction present 0x38 */ + __u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */ + __u32 tk_shift; /* Shift used for xtime_nsec 0x40 */ }; struct vdso_per_cpu_data { diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 2416138ebd3..496116cd65e 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -65,7 +65,8 @@ int main(void) DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available)); - DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult)); + DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult)); + DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift)); DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base)); DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time)); /* constants used by the vdso */ diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 064c3082ab3..60a508a9b98 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -221,21 +221,30 @@ struct clocksource * __init clocksource_default_clock(void) return &clocksource_tod; } -void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm, - struct clocksource *clock, u32 mult) +void update_vsyscall(struct timekeeper *tk) { - if (clock != &clocksource_tod) + u64 nsecps; + + if (tk->clock != &clocksource_tod) return; /* Make userspace gettimeofday spin until we're done. */ ++vdso_data->tb_update_count; smp_wmb(); - vdso_data->xtime_tod_stamp = clock->cycle_last; - vdso_data->xtime_clock_sec = wall_time->tv_sec; - vdso_data->xtime_clock_nsec = wall_time->tv_nsec; - vdso_data->wtom_clock_sec = wtm->tv_sec; - vdso_data->wtom_clock_nsec = wtm->tv_nsec; - vdso_data->ntp_mult = mult; + vdso_data->xtime_tod_stamp = tk->clock->cycle_last; + vdso_data->xtime_clock_sec = tk->xtime_sec; + vdso_data->xtime_clock_nsec = tk->xtime_nsec; + vdso_data->wtom_clock_sec = + tk->xtime_sec + tk->wall_to_monotonic.tv_sec; + vdso_data->wtom_clock_nsec = tk->xtime_nsec + + + (tk->wall_to_monotonic.tv_nsec << tk->shift); + nsecps = (u64) NSEC_PER_SEC << tk->shift; + while (vdso_data->wtom_clock_nsec >= nsecps) { + vdso_data->wtom_clock_nsec -= nsecps; + vdso_data->wtom_clock_sec++; + } + vdso_data->tk_mult = tk->mult; + vdso_data->tk_shift = tk->shift; smp_wmb(); ++vdso_data->tb_update_count; } diff --git a/arch/s390/kernel/vdso32/clock_gettime.S b/arch/s390/kernel/vdso32/clock_gettime.S index b2224e0b974..5be8e472f57 100644 --- a/arch/s390/kernel/vdso32/clock_gettime.S +++ b/arch/s390/kernel/vdso32/clock_gettime.S @@ -38,25 +38,26 @@ __kernel_clock_gettime: sl %r1,__VDSO_XTIME_STAMP+4(%r5) brc 3,2f ahi %r0,-1 -2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */ +2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ lr %r2,%r0 - l %r0,__VDSO_NTP_MULT(%r5) + l %r0,__VDSO_TK_MULT(%r5) ltr %r1,%r1 mr %r0,%r0 jnm 3f - a %r0,__VDSO_NTP_MULT(%r5) + a %r0,__VDSO_TK_MULT(%r5) 3: alr %r0,%r2 - srdl %r0,12 - al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ + al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ al %r1,__VDSO_XTIME_NSEC+4(%r5) brc 12,4f ahi %r0,1 -4: l %r2,__VDSO_XTIME_SEC+4(%r5) - al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */ +4: al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */ al %r1,__VDSO_WTOM_NSEC+4(%r5) brc 12,5f ahi %r0,1 -5: al %r2,__VDSO_WTOM_SEC+4(%r5) +5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ + srdl %r0,0(%r2) /* >> tk->shift */ + l %r2,__VDSO_XTIME_SEC+4(%r5) + al %r2,__VDSO_WTOM_SEC+4(%r5) cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ jne 1b basr %r5,0 @@ -86,20 +87,21 @@ __kernel_clock_gettime: sl %r1,__VDSO_XTIME_STAMP+4(%r5) brc 3,12f ahi %r0,-1 -12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */ +12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ lr %r2,%r0 - l %r0,__VDSO_NTP_MULT(%r5) + l %r0,__VDSO_TK_MULT(%r5) ltr %r1,%r1 mr %r0,%r0 jnm 13f - a %r0,__VDSO_NTP_MULT(%r5) + a %r0,__VDSO_TK_MULT(%r5) 13: alr %r0,%r2 - srdl %r0,12 - al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ + al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ al %r1,__VDSO_XTIME_NSEC+4(%r5) brc 12,14f ahi %r0,1 -14: l %r2,__VDSO_XTIME_SEC+4(%r5) +14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ + srdl %r0,0(%r2) /* >> tk->shift */ + l %r2,__VDSO_XTIME_SEC+4(%r5) cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ jne 11b basr %r5,0 diff --git a/arch/s390/kernel/vdso32/gettimeofday.S b/arch/s390/kernel/vdso32/gettimeofday.S index 2d3633175e3..fd621a950f7 100644 --- a/arch/s390/kernel/vdso32/gettimeofday.S +++ b/arch/s390/kernel/vdso32/gettimeofday.S @@ -35,15 +35,14 @@ __kernel_gettimeofday: sl %r1,__VDSO_XTIME_STAMP+4(%r5) brc 3,3f ahi %r0,-1 -3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */ +3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ st %r0,24(%r15) - l %r0,__VDSO_NTP_MULT(%r5) + l %r0,__VDSO_TK_MULT(%r5) ltr %r1,%r1 mr %r0,%r0 jnm 4f - a %r0,__VDSO_NTP_MULT(%r5) + a %r0,__VDSO_TK_MULT(%r5) 4: al %r0,24(%r15) - srdl %r0,12 al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ al %r1,__VDSO_XTIME_NSEC+4(%r5) brc 12,5f @@ -51,6 +50,8 @@ __kernel_gettimeofday: 5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5) cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ jne 1b + l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ + srdl %r0,0(%r4) /* >> tk->shift */ l %r4,24(%r15) /* get tv_sec from stack */ basr %r5,0 6: ltr %r0,%r0 diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index d46c95ed5f1..0add1072ba3 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S @@ -34,14 +34,15 @@ __kernel_clock_gettime: tmll %r4,0x0001 /* pending update ? loop */ jnz 0b stck 48(%r15) /* Store TOD clock */ + lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ + lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ + alg %r0,__VDSO_WTOM_SEC(%r5) /* + wall_to_monotonic.sec */ lg %r1,48(%r15) sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ - msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ - srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ - alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ - lg %r0,__VDSO_XTIME_SEC(%r5) - alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */ - alg %r0,__VDSO_WTOM_SEC(%r5) + msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ + alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ + alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */ + srlg %r1,%r1,0(%r2) /* >> tk->shift */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ jne 0b larl %r5,13f @@ -62,12 +63,13 @@ __kernel_clock_gettime: tmll %r4,0x0001 /* pending update ? loop */ jnz 5b stck 48(%r15) /* Store TOD clock */ + lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ lg %r1,48(%r15) sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ - msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ - srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ - alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ - lg %r0,__VDSO_XTIME_SEC(%r5) + msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ + alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ + srlg %r1,%r1,0(%r2) /* >> tk->shift */ + lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ jne 5b larl %r5,13f diff --git a/arch/s390/kernel/vdso64/gettimeofday.S b/arch/s390/kernel/vdso64/gettimeofday.S index 36ee674722e..d0860d1d0cc 100644 --- a/arch/s390/kernel/vdso64/gettimeofday.S +++ b/arch/s390/kernel/vdso64/gettimeofday.S @@ -31,12 +31,13 @@ __kernel_gettimeofday: stck 48(%r15) /* Store TOD clock */ lg %r1,48(%r15) sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ - msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ - srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ - alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */ - lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */ + msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ + alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ + lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ jne 0b + lgf %r5,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ + srlg %r1,%r1,0(%r5) /* >> tk->shift */ larl %r5,5f 2: clg %r1,0(%r5) jl 3f -- cgit v1.2.3-70-g09d2 From 8adbf78ec4839c1dc4ff20c9a1f332a7bc99e6e6 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 22 Nov 2013 12:04:18 +0100 Subject: s390,time: revert direct ktime path for s390 clockevent device Git commit 4f37a68cdaf6dea833cfdded2a3e0c47c0f006da "s390: Use direct ktime path for s390 clockevent device" makes use of the CLOCK_EVT_FEAT_KTIME clockevent option to avoid the delta calculation with ktime_get() in clockevents_program_event and the get_tod_clock() in s390_next_event. This is based on the assumption that the difference between the internal ktime and the hardware clock is reflected in the wall_to_monotonic delta. But this is not true, the ntp corrections are applied via changes to the tk->mult multiplier and this is not reflected in wall_to_monotonic. In theory this could be solved by using the raw monotonic clock but it is simpler to switch back to the standard clock delta calculation. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/time.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 60a508a9b98..dd95f163162 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -108,20 +108,10 @@ static void fixup_clock_comparator(unsigned long long delta) set_clock_comparator(S390_lowcore.clock_comparator); } -static int s390_next_ktime(ktime_t expires, +static int s390_next_event(unsigned long delta, struct clock_event_device *evt) { - struct timespec ts; - u64 nsecs; - - ts.tv_sec = ts.tv_nsec = 0; - monotonic_to_bootbased(&ts); - nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires)); - do_div(nsecs, 125); - S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9); - /* Program the maximum value if we have an overflow (== year 2042) */ - if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc)) - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = get_tod_clock() + delta; set_clock_comparator(S390_lowcore.clock_comparator); return 0; } @@ -146,15 +136,14 @@ void init_cpu_timer(void) cpu = smp_processor_id(); cd = &per_cpu(comparators, cpu); cd->name = "comparator"; - cd->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_KTIME; + cd->features = CLOCK_EVT_FEAT_ONESHOT; cd->mult = 16777; cd->shift = 12; cd->min_delta_ns = 1; cd->max_delta_ns = LONG_MAX; cd->rating = 400; cd->cpumask = cpumask_of(cpu); - cd->set_next_ktime = s390_next_ktime; + cd->set_next_event = s390_next_event; cd->set_mode = s390_set_mode; clockevents_register_device(cd); -- cgit v1.2.3-70-g09d2 From 127581b64b432804948535d49847b36366b9ff64 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 22 Nov 2013 15:14:23 +0100 Subject: s390/mm: handle asce-type exceptions as normal page fault Git commit 9e34f2686bb088b211b6cac8772e1f644c6180f8 "s390/mm,tlb: tlb flush on page table upgrade fixup" removed the exception handler for the asce-type exception. This is incorrect as the user-copy with MVCOS can cause asce-type exceptions in the kernel if a user pointer is too large. Those need to be handled with do_no_context to branch to the fixup in the user-copy code. The simplest fix for this problem is to call do_dat_exception for asce-type excpetions, as there is no vma for the address the code will handle the exception correctly. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/pgm_check.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/pgm_check.S b/arch/s390/kernel/pgm_check.S index 4a460c44e17..813ec726087 100644 --- a/arch/s390/kernel/pgm_check.S +++ b/arch/s390/kernel/pgm_check.S @@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT /* 34 */ PGM_CHECK_DEFAULT /* 35 */ PGM_CHECK_DEFAULT /* 36 */ PGM_CHECK_DEFAULT /* 37 */ -PGM_CHECK_DEFAULT /* 38 */ +PGM_CHECK_64BIT(do_dat_exception) /* 38 */ PGM_CHECK_64BIT(do_dat_exception) /* 39 */ PGM_CHECK_64BIT(do_dat_exception) /* 3a */ PGM_CHECK_64BIT(do_dat_exception) /* 3b */ -- cgit v1.2.3-70-g09d2 From 6468178767c4c7e600fdbf50aaca03f4a8a82ca4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 12 Nov 2013 17:11:53 +0000 Subject: arm64: let the core code deal with preempt_count Commit f27dde8deef3 (sched: Add NEED_RESCHED to the preempt_count) introduced the use of bit 31 in preempt_count for obscure scheduling purposes. This causes interrupts taken from EL0 to hit the (open coded) BUG when this flag is flipped while handling the interrupt (we compare the values before and after, and kill the kernel if they are different). The fix is to stop messing with the preempt count entirely, as this is already being dealt with in the generic code (irq_enter/irq_exit). Tested on a dual A53 FPGA running cyclictest. Signed-off-by: Marc Zyngier Signed-off-by: Catalin Marinas --- arch/arm64/kernel/entry.S | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index e1166145ca2..4d2c6f3f0c4 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -309,15 +309,12 @@ el1_irq: #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_off #endif -#ifdef CONFIG_PREEMPT - get_thread_info tsk - ldr w24, [tsk, #TI_PREEMPT] // get preempt count - add w0, w24, #1 // increment it - str w0, [tsk, #TI_PREEMPT] -#endif + irq_handler + #ifdef CONFIG_PREEMPT - str w24, [tsk, #TI_PREEMPT] // restore preempt count + get_thread_info tsk + ldr w24, [tsk, #TI_PREEMPT] // restore preempt count cbnz w24, 1f // preempt count != 0 ldr x0, [tsk, #TI_FLAGS] // get flags tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? @@ -507,22 +504,10 @@ el0_irq_naked: #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_off #endif - get_thread_info tsk -#ifdef CONFIG_PREEMPT - ldr w24, [tsk, #TI_PREEMPT] // get preempt count - add w23, w24, #1 // increment it - str w23, [tsk, #TI_PREEMPT] -#endif + irq_handler -#ifdef CONFIG_PREEMPT - ldr w0, [tsk, #TI_PREEMPT] - str w24, [tsk, #TI_PREEMPT] - cmp w0, w23 - b.eq 1f - mov x1, #0 - str x1, [x1] // BUG -1: -#endif + get_thread_info tsk + #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_on #endif -- cgit v1.2.3-70-g09d2 From df503ba7f653c590b475ab80bde788edf5af70d5 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 14 Nov 2013 15:15:37 +0000 Subject: arm64: dts: Reserve the memory used for secondary CPU release address With the spin-table SMP booting method, secondary CPUs poll a location passed in the DT. The foundation-v8.dts file doesn't have this memory reserved and there is a risk of Linux using it before secondary CPUs are started. Signed-off-by: Catalin Marinas --- arch/arm64/boot/dts/foundation-v8.dts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm64/boot/dts/foundation-v8.dts b/arch/arm64/boot/dts/foundation-v8.dts index 84fcc501828..519c4b2c068 100644 --- a/arch/arm64/boot/dts/foundation-v8.dts +++ b/arch/arm64/boot/dts/foundation-v8.dts @@ -6,6 +6,8 @@ /dts-v1/; +/memreserve/ 0x80000000 0x00010000; + / { model = "Foundation-v8A"; compatible = "arm,foundation-aarch64", "arm,vexpress"; -- cgit v1.2.3-70-g09d2 From b3bf6aa7e79117419f7eddccf0b7af4382d823c3 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 21 Nov 2013 14:46:17 +0000 Subject: arm64: Unmask asynchronous aborts when in kernel mode The asynchronous aborts are generally fatal for the kernel but they can be masked via the pstate A bit. If a system error happens while in kernel mode, it won't be visible until returning to user space. This patch enables this kind of abort early to help identifying the cause. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/irqflags.h | 3 +++ arch/arm64/kernel/setup.c | 5 +++++ arch/arm64/kernel/smp.c | 1 + 3 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h index aa11943b850..b2fcfbc51ec 100644 --- a/arch/arm64/include/asm/irqflags.h +++ b/arch/arm64/include/asm/irqflags.h @@ -56,6 +56,9 @@ static inline void arch_local_irq_disable(void) #define local_fiq_enable() asm("msr daifclr, #1" : : : "memory") #define local_fiq_disable() asm("msr daifset, #1" : : : "memory") +#define local_async_enable() asm("msr daifclr, #4" : : : "memory") +#define local_async_disable() asm("msr daifset, #4" : : : "memory") + /* * Save the current interrupt enable state. */ diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 0bc5e4cbc01..bd9bbd0e44e 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -205,6 +205,11 @@ u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; void __init setup_arch(char **cmdline_p) { + /* + * Unmask asynchronous aborts early to catch possible system errors. + */ + local_async_enable(); + setup_processor(); setup_machine_fdt(__fdt_pointer); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index a5aeefab03c..a0c2ca602cf 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -160,6 +160,7 @@ asmlinkage void secondary_start_kernel(void) local_irq_enable(); local_fiq_enable(); + local_async_enable(); /* * OK, it's off to the idle thread for us -- cgit v1.2.3-70-g09d2 From b6dda00cddcc71d2030668bc0cc0fed758c411c2 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 25 Nov 2013 17:26:46 +0100 Subject: ARM: mvebu: use the virtual CPU registers to access coherency registers The Armada XP provides a mechanism called "virtual CPU registers" or "per-CPU register banking", to access the per-CPU registers of the current CPU, without having to worry about finding on which CPU we're running. CPU0 has its registers at 0x21800, CPU1 at 0x21900, CPU2 at 0x21A00 and CPU3 at 0x21B00. The virtual registers accessing the current CPU registers are at 0x21000. However, in the Device Tree node that provides the register addresses for the coherency unit (which is responsible for ensuring coherency between processors, and I/O coherency between processors and the DMA-capable devices), a mistake was made: the CPU0-specific registers were specified instead of the virtual CPU registers. This means that the coherency barrier needed for I/O coherency was not behaving properly when executed from a CPU different from CPU0. This patch fixes that by using the virtual CPU registers. Signed-off-by: Gregory CLEMENT Signed-off-by: Thomas Petazzoni Cc: # v3.8+ Fixes: e60304f8cb7bb5 "arm: mvebu: Add hardware I/O Coherency support" Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-xp.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 00d6a798c70..7f10f627ae5 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -118,7 +118,7 @@ coherency-fabric@20200 { compatible = "marvell,coherency-fabric"; - reg = <0x20200 0xb0>, <0x21810 0x1c>; + reg = <0x20200 0xb0>, <0x21010 0x1c>; }; serial@12000 { -- cgit v1.2.3-70-g09d2 From 96039f735e290281d0c8a08fc467de2cd610543d Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 25 Nov 2013 17:26:47 +0100 Subject: ARM: mvebu: re-enable PCIe on Armada 370 DB Commit 14fd8ed0a7fd19913 ("ARM: mvebu: Relocate Armada 370/XP PCIe device tree nodes") relocated the PCIe controller DT nodes one level up in the Device Tree, to reflect a more correct representation of the hardware introduced by the mvebu-mbus Device Tree binding. However, while most of the boards were properly adjusted accordingly, the Armada 370 DB board was left unchanged, and therefore, PCIe is seen as not enabled on this board. This patch fixes that by moving the PCIe controller node one level-up in armada-370-db.dts. Signed-off-by: Thomas Petazzoni Cc: # v3.12+ Fixes: 14fd8ed0a7fd19913 "ARM: mvebu: Relocate Armada 370/XP PCIe device tree nodes" Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-db.dts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts index 90ce29dbe11..08a56bcfc72 100644 --- a/arch/arm/boot/dts/armada-370-db.dts +++ b/arch/arm/boot/dts/armada-370-db.dts @@ -99,22 +99,22 @@ spi-max-frequency = <50000000>; }; }; + }; - pcie-controller { + pcie-controller { + status = "okay"; + /* + * The two PCIe units are accessible through + * both standard PCIe slots and mini-PCIe + * slots on the board. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + pcie@2,0 { + /* Port 1, Lane 0 */ status = "okay"; - /* - * The two PCIe units are accessible through - * both standard PCIe slots and mini-PCIe - * slots on the board. - */ - pcie@1,0 { - /* Port 0, Lane 0 */ - status = "okay"; - }; - pcie@2,0 { - /* Port 1, Lane 0 */ - status = "okay"; - }; }; }; }; -- cgit v1.2.3-70-g09d2 From 6dd1e357372c21ec37b6902380bd47b278d168f1 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 12 Nov 2013 22:51:28 -0800 Subject: ARM: omap: fix warning with LPAE build Some omap3 code is throwing a warning: arch/arm/mach-omap2/pm34xx.c: In function 'omap3_save_secure_ram_context': arch/arm/mach-omap2/pm34xx.c:123:32: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] In reality this code will never actually execute with LPAE=y, since Cortex-A8 doesn't support it. So downcasting the __pa() is safe in this case. Signed-off-by: Olof Johansson Acked-by: Tony Lindgren --- arch/arm/mach-omap2/pm34xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 93b80e5da8d..1f3770a8a72 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -120,7 +120,7 @@ static void omap3_save_secure_ram_context(void) * will hang the system. */ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); - ret = _omap_save_secure_sram((u32 *) + ret = _omap_save_secure_sram((u32 *)(unsigned long) __pa(omap3_secure_ram_storage)); pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); /* Following is for error tracking, it should not happen */ -- cgit v1.2.3-70-g09d2 From 33cb667a00f841fa036ad79f1aaaf7d6380c971d Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 25 Nov 2013 16:16:25 +0000 Subject: ARM: vexpress/TC2: Implement MCPM power_down_finish() This patch implements the power_down_finish() method for TC2, to enable the kernel to confirm when CPUs are safely powered down. The information required for determining when a CPU is parked cannot be obtained from any single place, so a few sources of information must be combined: * mcpm_cpu_power_down() must be pending for the CPU, so that we don't get confused by false STANDBYWFI positives arising from CPUidle. This is detected by waiting for the tc2_pm use count for the target CPU to reach 0. * Either the SPC must report that the CPU has asserted STANDBYWFI, or the TC2 tile's reset control logic must be holding the CPU in reset. Just checking for STANDBYWFI is not sufficient, because this signal is not latched when the the cluster is clamped off and powered down: the relevant status bits just drop to zero. This means that STANDBYWFI status cannot be used for reliable detection of the last CPU in a cluster reaching WFI. This patch is required in order for kexec to work with MCPM on TC2. MCPM code was changed in commit 0de0d6467525 ('ARM: 7848/1: mcpm: Implement cpu_kill() to synchronise on powerdown'), and since then it will hit a WARN_ON_ONCE() due to power_down_finish not being implemented on the TC2 platform. Signed-off-by: Dave Martin Acked-by: Pawel Moll Reviewed-by: Nicolas Pitre Signed-off-by: Olof Johansson --- arch/arm/mach-vexpress/spc.c | 40 +++++++++++++++++++++++++ arch/arm/mach-vexpress/spc.h | 1 + arch/arm/mach-vexpress/tc2_pm.c | 66 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 102 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c index 033d34dcbd3..c26ef5b92ca 100644 --- a/arch/arm/mach-vexpress/spc.c +++ b/arch/arm/mach-vexpress/spc.c @@ -53,6 +53,11 @@ #define A15_BX_ADDR0 0x68 #define A7_BX_ADDR0 0x78 +/* SPC CPU/cluster reset statue */ +#define STANDBYWFI_STAT 0x3c +#define STANDBYWFI_STAT_A15_CPU_MASK(cpu) (1 << (cpu)) +#define STANDBYWFI_STAT_A7_CPU_MASK(cpu) (1 << (3 + (cpu))) + /* SPC system config interface registers */ #define SYSCFG_WDATA 0x70 #define SYSCFG_RDATA 0x74 @@ -213,6 +218,41 @@ void ve_spc_powerdown(u32 cluster, bool enable) writel_relaxed(enable, info->baseaddr + pwdrn_reg); } +static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster) +{ + return cluster_is_a15(cluster) ? + STANDBYWFI_STAT_A15_CPU_MASK(cpu) + : STANDBYWFI_STAT_A7_CPU_MASK(cpu); +} + +/** + * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster) + * + * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster + * @cluster: mpidr[15:8] bitfield describing cluster affinity level + * + * @return: non-zero if and only if the specified CPU is in WFI + * + * Take care when interpreting the result of this function: a CPU might + * be in WFI temporarily due to idle, and is not necessarily safely + * parked. + */ +int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster) +{ + int ret; + u32 mask = standbywfi_cpu_mask(cpu, cluster); + + if (cluster >= MAX_CLUSTERS) + return 1; + + ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT); + + pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n", + __func__, STANDBYWFI_STAT, ret, mask); + + return ret & mask; +} + static int ve_spc_get_performance(int cluster, u32 *freq) { struct ve_spc_opp *opps = info->opps[cluster]; diff --git a/arch/arm/mach-vexpress/spc.h b/arch/arm/mach-vexpress/spc.h index dbd44c3720f..793d065243b 100644 --- a/arch/arm/mach-vexpress/spc.h +++ b/arch/arm/mach-vexpress/spc.h @@ -20,5 +20,6 @@ void ve_spc_global_wakeup_irq(bool set); void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set); void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr); void ve_spc_powerdown(u32 cluster, bool enable); +int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster); #endif diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c index 05a364c5077..29e7785a54b 100644 --- a/arch/arm/mach-vexpress/tc2_pm.c +++ b/arch/arm/mach-vexpress/tc2_pm.c @@ -12,6 +12,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -32,11 +33,17 @@ #include "spc.h" /* SCC conf registers */ +#define RESET_CTRL 0x018 +#define RESET_A15_NCORERESET(cpu) (1 << (2 + (cpu))) +#define RESET_A7_NCORERESET(cpu) (1 << (16 + (cpu))) + #define A15_CONF 0x400 #define A7_CONF 0x500 #define SYS_INFO 0x700 #define SPC_BASE 0xb00 +static void __iomem *scc; + /* * We can't use regular spinlocks. In the switcher case, it is possible * for an outbound CPU to call power_down() after its inbound counterpart @@ -190,6 +197,55 @@ static void tc2_pm_power_down(void) tc2_pm_down(0); } +static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster) +{ + u32 mask = cluster ? + RESET_A7_NCORERESET(cpu) + : RESET_A15_NCORERESET(cpu); + + return !(readl_relaxed(scc + RESET_CTRL) & mask); +} + +#define POLL_MSEC 10 +#define TIMEOUT_MSEC 1000 + +static int tc2_pm_power_down_finish(unsigned int cpu, unsigned int cluster) +{ + unsigned tries; + + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); + BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER); + + for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) { + /* + * Only examine the hardware state if the target CPU has + * caught up at least as far as tc2_pm_down(): + */ + if (ACCESS_ONCE(tc2_pm_use_count[cpu][cluster]) == 0) { + pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n", + __func__, cpu, cluster, + readl_relaxed(scc + RESET_CTRL)); + + /* + * We need the CPU to reach WFI, but the power + * controller may put the cluster in reset and + * power it off as soon as that happens, before + * we have a chance to see STANDBYWFI. + * + * So we need to check for both conditions: + */ + if (tc2_core_in_reset(cpu, cluster) || + ve_spc_cpu_in_wfi(cpu, cluster)) + return 0; /* success: the CPU is halted */ + } + + /* Otherwise, wait and retry: */ + msleep(POLL_MSEC); + } + + return -ETIMEDOUT; /* timeout */ +} + static void tc2_pm_suspend(u64 residency) { unsigned int mpidr, cpu, cluster; @@ -232,10 +288,11 @@ static void tc2_pm_powered_up(void) } static const struct mcpm_platform_ops tc2_pm_power_ops = { - .power_up = tc2_pm_power_up, - .power_down = tc2_pm_power_down, - .suspend = tc2_pm_suspend, - .powered_up = tc2_pm_powered_up, + .power_up = tc2_pm_power_up, + .power_down = tc2_pm_power_down, + .power_down_finish = tc2_pm_power_down_finish, + .suspend = tc2_pm_suspend, + .powered_up = tc2_pm_powered_up, }; static bool __init tc2_pm_usage_count_init(void) @@ -269,7 +326,6 @@ static void __naked tc2_pm_power_up_setup(unsigned int affinity_level) static int __init tc2_pm_init(void) { int ret, irq; - void __iomem *scc; u32 a15_cluster_id, a7_cluster_id, sys_info; struct device_node *np; -- cgit v1.2.3-70-g09d2 From 7ce93f3186119754ec7a646bcbeb1f80e4214767 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 25 Nov 2013 14:23:45 -0800 Subject: ARM: OMAP2+: Fix more missing data for omap3.dtsi file After dropping the duplicate data in hwmod that now should come from the .dts files, I noticed few more entries missing. Let's add these as otherwise devices relying on these won't work. Looks like the side tone entries are bundled into the mcbsp1 to 3, so that may needs some special handling in the hwmod code as it's currently trying to look up mcbsp2_sidetone and mcbsp3_sidetone entries. Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3.dtsi | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index f3a0c26ed0c..daabf99d402 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -82,6 +82,13 @@ ranges; ti,hwmods = "l3_main"; + aes: aes@480c5000 { + compatible = "ti,omap3-aes"; + ti,hwmods = "aes"; + reg = <0x480c5000 0x50>; + interrupts = <0>; + }; + counter32k: counter@48320000 { compatible = "ti,omap-counter32k"; reg = <0x48320000 0x20>; @@ -260,6 +267,13 @@ ti,hwmods = "i2c3"; }; + mailbox: mailbox@48094000 { + compatible = "ti,omap3-mailbox"; + ti,hwmods = "mailbox"; + reg = <0x48094000 0x200>; + interrupts = <26>; + }; + mcspi1: spi@48098000 { compatible = "ti,omap2-mcspi"; reg = <0x48098000 0x100>; @@ -357,6 +371,13 @@ dma-names = "tx", "rx"; }; + mmu_isp: mmu@480bd400 { + compatible = "ti,omap3-mmu-isp"; + ti,hwmods = "mmu_isp"; + reg = <0x480bd400 0x80>; + interrupts = <8>; + }; + wdt2: wdt@48314000 { compatible = "ti,omap3-wdt"; reg = <0x48314000 0x80>; @@ -442,6 +463,27 @@ dma-names = "tx", "rx"; }; + sham: sham@480c3000 { + compatible = "ti,omap3-sham"; + ti,hwmods = "sham"; + reg = <0x480c3000 0x64>; + interrupts = <49>; + }; + + smartreflex_core: smartreflex@480cb000 { + compatible = "ti,omap3-smartreflex-core"; + ti,hwmods = "smartreflex_core"; + reg = <0x480cb000 0x400>; + interrupts = <19>; + }; + + smartreflex_mpu_iva: smartreflex@480c9000 { + compatible = "ti,omap3-smartreflex-iva"; + ti,hwmods = "smartreflex_mpu_iva"; + reg = <0x480c9000 0x400>; + interrupts = <18>; + }; + timer1: timer@48318000 { compatible = "ti,omap3430-timer"; reg = <0x48318000 0x400>; -- cgit v1.2.3-70-g09d2 From 26f67a31265d459aa6f93b0a1ecbd64e7435519d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 25 Nov 2013 14:23:45 -0800 Subject: ARM: OMAP2+: Add fixed regulator to omap2plus_defconfig We do not have REGULATOR_FIXED selected if no boards are selected and we boot with device tree. This can cause various devices to fail. Signed-off-by: Tony Lindgren --- arch/arm/configs/omap2plus_defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 98a50c309b9..bfa80a11e8c 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -173,6 +173,7 @@ CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65217=y CONFIG_MFD_TPS65910=y CONFIG_TWL6040_CORE=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y -- cgit v1.2.3-70-g09d2 From edd5eb4e99e4153ea7be05390fda542d986bf28d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 25 Nov 2013 14:23:45 -0800 Subject: ARM: OMAP2+: Fix eMMC on n900 with device tree Looks like we need to configure the regulators and use the pdata quirk to make eMMC work with device tree. It seems that mostly vaux3 is used, and only some earlier revisions used vmmc2. This has been tested to work on devices where the system_rev passed by the bootloader has versions 0x0010, 0x2101 and 0x2204. Cc: devicetree@vger.kernel.org Cc: Pavel Machek Cc: Aaro Koskinen Signed-off-by: Sebastian Reichel [tony@atomide.com: updated with pinctrl changes and comments from Sebastian] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-n900.dts | 23 ++++++++++++++++++++++- arch/arm/mach-omap2/pdata-quirks.c | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index c4f20bfe4cc..c2c306d13b8 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -125,6 +125,21 @@ >; }; + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */ + 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */ + 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */ + 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */ + 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */ + 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */ + 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat4 */ + 0x136 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat5 */ + 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat6 */ + 0x13a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat7 */ + >; + }; + display_pins: pinmux_display_pins { pinctrl-single,pins = < 0x0d4 (PIN_OUTPUT | MUX_MODE4) /* RX51_LCD_RESET_GPIO */ @@ -358,8 +373,14 @@ cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */ }; +/* most boards use vaux3, only some old versions use vmmc2 instead */ &mmc2 { - status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <&vaux3>; + vmmc_aux-supply = <&vsim>; + bus-width = <8>; + non-removable; }; &mmc3 { diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 10c71450cf6..39f020c982e 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -139,6 +139,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { static struct pdata_init pdata_quirks[] __initdata = { #ifdef CONFIG_ARCH_OMAP3 + { "nokia,omap3-n900", hsmmc2_internal_input_clk, }, { "nokia,omap3-n9", hsmmc2_internal_input_clk, }, { "nokia,omap3-n950", hsmmc2_internal_input_clk, }, { "isee,omap3-igep0020", omap3_igep0020_legacy_init, }, -- cgit v1.2.3-70-g09d2 From c61248afa8190ae3f47ee67f46e3c9b584a73d31 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Wed, 23 Oct 2013 06:11:01 -0700 Subject: ARM: dts: Add max77686 RTC interrupt to cros5250-common Without the interrupt you'll get problems if you enable CONFIG_RTC_DRV_MAX77686. Setup the interrupt properly in the device tree. Signed-off-by: Doug Anderson Tested-by: Marc Zyngier Signed-off-by: Olof Johansson Cc: stable@vger.kernel.org --- arch/arm/boot/dts/cros5250-common.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/cros5250-common.dtsi b/arch/arm/boot/dts/cros5250-common.dtsi index dc259e8b8a7..9b186ac06c8 100644 --- a/arch/arm/boot/dts/cros5250-common.dtsi +++ b/arch/arm/boot/dts/cros5250-common.dtsi @@ -27,6 +27,13 @@ i2c2_bus: i2c2-bus { samsung,pin-pud = <0>; }; + + max77686_irq: max77686-irq { + samsung,pins = "gpx3-2"; + samsung,pin-function = <0>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; }; i2c@12C60000 { @@ -35,6 +42,11 @@ max77686@09 { compatible = "maxim,max77686"; + interrupt-parent = <&gpx3>; + interrupts = <2 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max77686_irq>; + wakeup-source; reg = <0x09>; voltage-regulators { -- cgit v1.2.3-70-g09d2 From a31ab44ef5d07c6707df4a9ad2c8affd2d62ff4b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 25 Nov 2013 20:35:42 -0700 Subject: ARM: bcm2835: add missing #xxx-cells to I2C nodes The I2C controller node needs #address-cells and #size-cells properties, but these are currently missing. Add them. This allows child nodes to be parsed correctly. Cc: stable@vger.kernel.org Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/boot/dts/bcm2835.dtsi | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi index 1e12aeff403..aa537ed13f0 100644 --- a/arch/arm/boot/dts/bcm2835.dtsi +++ b/arch/arm/boot/dts/bcm2835.dtsi @@ -85,6 +85,8 @@ reg = <0x7e205000 0x1000>; interrupts = <2 21>; clocks = <&clk_i2c>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -93,6 +95,8 @@ reg = <0x7e804000 0x1000>; interrupts = <2 21>; clocks = <&clk_i2c>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; -- cgit v1.2.3-70-g09d2 From a09b5add6f2458486df42a4431a0599f18fa8f52 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Thu, 18 Jul 2013 21:35:30 +0200 Subject: u8500_defconfig: allow creation and mounting of devtmpfs This patch enables CONFIG_DETTMPFS and CONFIG_DEVTMPFS_MOUNT flags for u8500 based devices. In this way it's possible to create a tmpfs/ramfs already in the early stages of the boot, allowing programs like udev/mdev to populate the /dev directory. Signed-off-by: Andi Shyti Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index ac632cc38f2..3738cd69513 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -109,6 +109,8 @@ CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_VFAT_FS=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_MISC_FILESYSTEMS is not set -- cgit v1.2.3-70-g09d2 From 59b023e9bf62933f7078dec339b110d5785f63f6 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 30 Sep 2013 13:36:36 +0200 Subject: ARM: ux500: u8500_defconfig: add missing cpuidle option With the commit d3f2950f2adeea3da0317e952914b59adaa4cdb3, the option ARM_U8500_CPUIDLE was added to the Kconfig but not reflected in the default config file, hence the cpuidle driver is no longer enabled since this commit. Enable it again by adding the missing option in the default config file. Signed-off-by: Daniel Lezcano Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 3738cd69513..c6ebc184bf6 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -22,6 +22,7 @@ CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_IDLE=y +CONFIG_ARM_U8500_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_PM_RUNTIME=y -- cgit v1.2.3-70-g09d2 From 1f202dea74713589f2af29f1dba3ac6de043618a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 13 Nov 2013 09:28:53 +0100 Subject: Revert "ARM: ux500: Remove AUXDATA relating to SDI (MMC) clock-name bindings" This reverts commit ce16feb8510cbbcd090c2320c35db2fbbffde210. This commit stopped tying down the name of the MMC/SD devices, but these names are used in the pin control table, so the MMC/SD cards stopped working. Cc: Lee Jones Reviewed-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 2e85c1e7253..8e7e60d2a42 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -140,6 +140,10 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires call-back bindings. */ OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), /* Requires DMA bindings. */ + OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", NULL), + OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", NULL), + OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2", NULL), + OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4", NULL), OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, "ux500-msp-i2s.0", &msp0_platform_data), OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000, -- cgit v1.2.3-70-g09d2 From 5281973012bdcfd93a8f6e0f5b4e04af0038ea99 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 13 Nov 2013 09:33:36 +0100 Subject: Revert "ARM: ux500: Stop passing MMC's platform data for Device Tree boots" This reverts commit 49c129519a7a8840767321c38d2eaf84a263529b. The special settings for the SD/MMC card parameters that are not yet fully agreed upon how to encode into the device tree went missing with this commit. We need to first put it into the device tree, and then remove the platform data. Cc: Lee Jones Reviewed-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 8e7e60d2a42..12c7e5c03ea 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -140,10 +140,10 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires call-back bindings. */ OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), /* Requires DMA bindings. */ - OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", NULL), - OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", NULL), - OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2", NULL), - OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4", NULL), + OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", &mop500_sdi0_data), + OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", &mop500_sdi1_data), + OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2", &mop500_sdi2_data), + OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4", &mop500_sdi4_data), OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, "ux500-msp-i2s.0", &msp0_platform_data), OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000, -- cgit v1.2.3-70-g09d2 From 912e663127c5f700da6805ce21635dce703cb2cc Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Tue, 26 Nov 2013 15:03:36 -0800 Subject: ARM: OMAP2+: Disable POSTED mode for errata i103 and i767 Enabling of Posted mode is seen to cause problems on dmtimer modules on AM33xx (much like other OMAPs). Reference discussions on forums [1] [2]. Earlier patch solving this on other OMAPs [3]. For OMAP SoCs with this errata, the fix has been to not enable Posted mode. However, on some SoCs (atleast AM33xx) which carry this errata, Posted mode is enabled on reset. So we not only need to ignore enabling of the POSTED bit when the timer is requested, but also disable Posted mode if errata is present. [1] http://e2e.ti.com/support/arm/sitara_arm/f/791/t/285744.aspx [2] http://e2e.ti.com/support/arm/sitara_arm/f/791/t/270632.aspx [3] http://www.spinics.net/lists/linux-omap/msg81770.html Cc: stable@vgerk.kernel.org Reported-by: Russ Dill Cc: Santosh Shilimkar Signed-off-by: Joel Fernandes Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/dmtimer.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index fb92abb9162..2861b155485 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -336,8 +336,11 @@ static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer) if (timer->posted) return; - if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) + if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) { + timer->posted = OMAP_TIMER_NONPOSTED; + __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0); return; + } __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, OMAP_TIMER_CTRL_POSTED, 0); -- cgit v1.2.3-70-g09d2 From 11d3a7d6d4c1df43240cc8b8aaa2dcff4e3fe072 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 Nov 2013 15:03:36 -0800 Subject: ARM: OMAP2+: dss-common: change IGEP's DVI DDC i2c bus IGEP's DVI connector's DDC pins are connected to OMAP's third i2c bus. When booting with Device Trees the requested bus number is set to -1 which means that the bus number should be dynamically assigned. So the third i2c bus has 2 has a bus number. Since now only DT booting is supported for IGEP boards after commit 06ff74fd ("ARM: OMAP2+: remove legacy support for IGEP boards"), the i2c bus number has to be changed. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/dss-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c index 365bfd3d9c6..dadccc91488 100644 --- a/arch/arm/mach-omap2/dss-common.c +++ b/arch/arm/mach-omap2/dss-common.c @@ -223,7 +223,7 @@ void __init omap_4430sdp_display_init_of(void) static struct connector_dvi_platform_data omap3_igep2_dvi_connector_pdata = { .name = "dvi", .source = "tfp410.0", - .i2c_bus_num = 3, + .i2c_bus_num = 2, }; static struct platform_device omap3_igep2_dvi_connector_device = { -- cgit v1.2.3-70-g09d2 From 8559133d82560a8b1f5d32419c6c829d81b89fb1 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:36 -0800 Subject: ARM: dts: omap3-igep: Fix bus-width for mmc1 Both, IGEPv2 and IGEP COM MODULE have a bus-width of 4 not 8, so fix this and do not mux data pins from mmc1_data4 to mmc1_data7. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep.dtsi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index ba1e58b7b7e..d4fecce9106 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -65,10 +65,6 @@ 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */ 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */ 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */ - 0x120 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat4.sdmmc1_dat4 */ - 0x122 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat5.sdmmc1_dat5 */ - 0x124 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat6.sdmmc1_dat6 */ - 0x126 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat7.sdmmc1_dat7 */ >; }; @@ -114,7 +110,7 @@ pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; vmmc_aux-supply = <&vsim>; - bus-width = <8>; + bus-width = <4>; }; &mmc2 { -- cgit v1.2.3-70-g09d2 From 0e9fd77771d0a0c3318905d33f29eec7680dfe5e Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:37 -0800 Subject: ARM: dts: omap3-igep: Add support for LBEE1USJYC WiFi connected to SDIO The LBEE1USJYC is a WiFi/BT combo module used on OMAP3-based IGEP boards. In both cases, IGEPv2 Rev. C and IGEP COM MODULE, the module is connected using the same MMC interface and uses the same GPIOs. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep.dtsi | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index d4fecce9106..b3517b2910a 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -24,6 +24,25 @@ ti,mcbsp = <&mcbsp2>; ti,codec = <&twl_audio>; }; + + vdd33: regulator-vdd33 { + compatible = "regulator-fixed"; + regulator-name = "vdd33"; + regulator-always-on; + }; + + lbee1usjyc_vmmc: lbee1usjyc_vmmc { + pinctrl-names = "default"; + pinctrl-0 = <&lbee1usjyc_pins>; + compatible = "regulator-fixed"; + regulator-name = "regulator-lbee1usjyc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>; /* gpio_138 WIFI_PDN */ + startup-delay-us = <10000>; + enable-active-high; + vin-supply = <&vdd33>; + }; }; &omap3_pmx_core { @@ -48,6 +67,15 @@ >; }; + /* WiFi/BT combo */ + lbee1usjyc_pins: pinmux_lbee1usjyc_pins { + pinctrl-single,pins = < + 0x136 (PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 */ + 0x138 (PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 */ + 0x13a (PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 */ + >; + }; + mcbsp2_pins: pinmux_mcbsp2_pins { pinctrl-single,pins = < 0x10c (PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx.mcbsp2_fsx */ @@ -68,6 +96,17 @@ >; }; + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */ + 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */ + 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */ + 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */ + 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */ + 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */ + >; + }; + smsc911x_pins: pinmux_smsc911x_pins { pinctrl-single,pins = < 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */ @@ -114,7 +153,11 @@ }; &mmc2 { - status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <&lbee1usjyc_vmmc>; + bus-width = <4>; + non-removable; }; &mmc3 { -- cgit v1.2.3-70-g09d2 From 9aa36dfd3d9a1c9e305e53f5c0915036c3941a3f Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:37 -0800 Subject: ARM: dts: omap3-igep: Update to use the TI AM/DM37x processor Most of the boards are using the TI AM/DM37x processor, there is only a small quantity of IGEP Processor Boards based on TI OMAP3530. So it's better use the omap36xx.dtsi include instead of omap34xx.dtsi include. We can add support for the 34xx based variant later on as needed. To avoid confusion we have added to the model the (TI AM/DM37x) comment. Signed-off-by: Enric Balletbo i Serra [tony@atomide.com: updated comments for the 34xx to 36xx include change] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep.dtsi | 4 ++-- arch/arm/boot/dts/omap3-igep0020.dts | 4 ++-- arch/arm/boot/dts/omap3-igep0030.dts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index b3517b2910a..e4c87693b10 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -1,5 +1,5 @@ /* - * Device Tree Source for IGEP Technology devices + * Common device tree for IGEP boards based on AM/DM37x * * Copyright (C) 2012 Javier Martinez Canillas * Copyright (C) 2012 Enric Balletbo i Serra @@ -10,7 +10,7 @@ */ /dts-v1/; -#include "omap34xx.dtsi" +#include "omap36xx.dtsi" / { memory { diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index d5cc7926725..33ce1236e96 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts @@ -1,5 +1,5 @@ /* - * Device Tree Source for IGEPv2 board + * Device Tree Source for IGEPv2 Rev. (TI OMAP AM/DM37x) * * Copyright (C) 2012 Javier Martinez Canillas * Copyright (C) 2012 Enric Balletbo i Serra @@ -13,7 +13,7 @@ #include "omap-gpmc-smsc911x.dtsi" / { - model = "IGEPv2"; + model = "IGEPv2 (TI OMAP AM/DM37x)"; compatible = "isee,omap3-igep0020", "ti,omap3"; leds { diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts index 525e6d9b097..02a23f8a338 100644 --- a/arch/arm/boot/dts/omap3-igep0030.dts +++ b/arch/arm/boot/dts/omap3-igep0030.dts @@ -1,5 +1,5 @@ /* - * Device Tree Source for IGEP COM Module + * Device Tree Source for IGEP COM MODULE (TI OMAP AM/DM37x) * * Copyright (C) 2012 Javier Martinez Canillas * Copyright (C) 2012 Enric Balletbo i Serra @@ -12,7 +12,7 @@ #include "omap3-igep.dtsi" / { - model = "IGEP COM Module"; + model = "IGEP COM MODULE (TI OMAP AM/DM37x)"; compatible = "isee,omap3-igep0030", "ti,omap3"; leds { -- cgit v1.2.3-70-g09d2 From d526daebfd88706b52573325920dac33d14a5f6c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 Nov 2013 15:03:37 -0800 Subject: ARM: dts: omap3-igep0020: Add pinmux setup for i2c devices Add pin muxing support for IGEP boards i2c controllers. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep.dtsi | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index e4c87693b10..165aaf7591b 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -113,10 +113,33 @@ >; }; + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0x18a (PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */ + 0x18c (PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0x18e (PIN_INPUT | MUX_MODE0) /* i2c2_scl.i2c2_scl */ + 0x190 (PIN_INPUT | MUX_MODE0) /* i2c2_sda.i2c2_sda */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + 0x192 (PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */ + 0x194 (PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */ + >; + }; + leds_pins: pinmux_leds_pins { }; }; &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; clock-frequency = <2600000>; twl: twl@48 { @@ -136,9 +159,16 @@ #include "twl4030_omap3.dtsi" &i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; clock-frequency = <400000>; }; +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; +}; + &mcbsp2 { pinctrl-names = "default"; pinctrl-0 = <&mcbsp2_pins>; -- cgit v1.2.3-70-g09d2 From 50592dc30ca3617b7b66abd7071930e2489bff26 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 Nov 2013 15:03:38 -0800 Subject: ARM: dts: omap3-igep0020: Add pinmuxing for DVI output The IGEPv2 has a TFP410 DPI-to-DVI encoder attached to OMAP's Display SubSystem (DSS). Add mux setup for DSS pins and also for the GPIO 170 pin that is used to ensure that the DVI-D is powered down on power up. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep0020.dts | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index 33ce1236e96..b9a9e17acb5 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts @@ -67,6 +67,8 @@ pinctrl-names = "default"; pinctrl-0 = < &hsusbb1_pins + &tfp410_pins + &dss_pins >; hsusbb1_pins: pinmux_hsusbb1_pins { @@ -85,6 +87,45 @@ 0x5ba (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */ >; }; + + tfp410_pins: tfp410_dvi_pins { + pinctrl-single,pins = < + 0x196 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */ + >; + }; + + dss_pins: pinmux_dss_dvi_pins { + pinctrl-single,pins = < + 0x0a4 (PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */ + 0x0a6 (PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */ + 0x0a8 (PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */ + 0x0aa (PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */ + 0x0ac (PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */ + 0x0ae (PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */ + 0x0b0 (PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */ + 0x0b2 (PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */ + 0x0b4 (PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */ + 0x0b6 (PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */ + 0x0b8 (PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */ + 0x0ba (PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */ + 0x0bc (PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */ + 0x0be (PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */ + 0x0c0 (PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */ + 0x0c2 (PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */ + 0x0c4 (PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */ + 0x0c6 (PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */ + 0x0c8 (PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */ + 0x0ca (PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */ + 0x0cc (PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */ + 0x0ce (PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */ + 0x0d0 (PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */ + 0x0d2 (PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */ + 0x0d4 (PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */ + 0x0d6 (PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */ + 0x0d8 (PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */ + 0x0da (PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */ + >; + }; }; &leds_pins { -- cgit v1.2.3-70-g09d2 From 0710b679862dc730eb9900592649929da3ec824e Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:38 -0800 Subject: ARM: dts: AM33XX BASE0033: add pinmux and hdmi node to enable display Enable the hdmi output and the LCD Controller on IGEP AQUILA. Also configure the correct pinmux for output of video data from the SoC to the HDMI encoder. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-base0033.dts | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts index b4f95c2bbf7..620970c0c99 100644 --- a/arch/arm/boot/dts/am335x-base0033.dts +++ b/arch/arm/boot/dts/am335x-base0033.dts @@ -13,4 +13,50 @@ / { model = "IGEP COM AM335x on AQUILA Expansion"; compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx"; + + hdmi { + compatible = "ti,tilcdc,slave"; + i2c = <&i2c0>; + pinctrl-names = "default", "off"; + pinctrl-0 = <&nxp_hdmi_pins>; + pinctrl-1 = <&nxp_hdmi_off_pins>; + status = "okay"; + }; +}; + +&am33xx_pinmux { + nxp_hdmi_pins: pinmux_nxp_hdmi_pins { + pinctrl-single,pins = < + 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */ + 0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0 */ + 0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1 */ + 0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2 */ + 0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3 */ + 0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4 */ + 0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5 */ + 0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6 */ + 0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7 */ + 0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8 */ + 0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9 */ + 0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10 */ + 0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11 */ + 0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12 */ + 0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13 */ + 0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14 */ + 0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15 */ + 0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync */ + 0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync */ + 0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk */ + 0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en */ + >; + }; + nxp_hdmi_off_pins: pinmux_nxp_hdmi_off_pins { + pinctrl-single,pins = < + 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */ + >; + }; +}; + +&lcdc { + status = "okay"; }; -- cgit v1.2.3-70-g09d2 From f3689fd6dd30974d5b5ccf1daea964440ca5955f Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:38 -0800 Subject: ARM: dts: AM33XX BASE0033: add pinmux and user led support Enable the user leds on the IGEP AQUILA EXPANSION. The has two leds, one green and one red, that are controllable by software. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-base0033.dts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts index 620970c0c99..ffae1482d95 100644 --- a/arch/arm/boot/dts/am335x-base0033.dts +++ b/arch/arm/boot/dts/am335x-base0033.dts @@ -22,6 +22,25 @@ pinctrl-1 = <&nxp_hdmi_off_pins>; status = "okay"; }; + + leds_base { + pinctrl-names = "default"; + pinctrl-0 = <&leds_base_pins>; + + compatible = "gpio-leds"; + + led@0 { + label = "base:red:user"; + gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; /* gpio1_21 */ + default-state = "off"; + }; + + led@1 { + label = "base:green:user"; + gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; /* gpio2_0 */ + default-state = "off"; + }; + }; }; &am33xx_pinmux { @@ -55,6 +74,13 @@ 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */ >; }; + + leds_base_pins: pinmux_leds_base_pins { + pinctrl-single,pins = < + 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ + 0x88 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.gpio2_0 */ + >; + }; }; &lcdc { -- cgit v1.2.3-70-g09d2 From d8e5b2bdd3674a65f3f50fb54061516d4b6c999f Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:38 -0800 Subject: ARM: dts: AM33XX BASE0033: add 32KBit EEPROM support The IGEP AQUILA EXPANSION has a 32KBit EEPROM for user data storage. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-base0033.dts | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts index ffae1482d95..72a9b3fc425 100644 --- a/arch/arm/boot/dts/am335x-base0033.dts +++ b/arch/arm/boot/dts/am335x-base0033.dts @@ -86,3 +86,10 @@ &lcdc { status = "okay"; }; + +&i2c0 { + eeprom: eeprom@50 { + compatible = "at,24c256"; + reg = <0x50>; + }; +}; -- cgit v1.2.3-70-g09d2 From caa73370ead3160ed6cdabbfeecc5fbbda06d903 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 26 Nov 2013 15:03:39 -0800 Subject: ARM: dts: AM33XX IGEP0033: add USB support Add node to support the USB Host and the USB OTG on the IGEP AQUILA Processor Board. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-igep0033.dtsi | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index 61962447931..7063311a58d 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -199,6 +199,35 @@ pinctrl-0 = <&uart0_pins>; }; +&usb { + status = "okay"; + + control@44e10000 { + status = "okay"; + }; + + usb-phy@47401300 { + status = "okay"; + }; + + usb-phy@47401b00 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; + + usb@47401800 { + status = "okay"; + dr_mode = "host"; + }; + + dma-controller@07402000 { + status = "okay"; + }; +}; + #include "tps65910.dtsi" &tps { -- cgit v1.2.3-70-g09d2 From 2f2befd820252d05be7b1f5528a57af85338f59c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 Nov 2013 15:03:39 -0800 Subject: ARM: dts: omap3-igep0020: name twl4030 VPLL2 regulator as vdds_dsi On Device Tree boot the VDDS_DSI regulator is not linked to the DPI device so omapfb driver probing fails with: [ 3.186035] OMAPFB: omapfb_probe [ 3.190704] omapdss DPI error: can't get VDDS_DSI regulator [ 3.196594] omapfb omapfb: failed to connect default display [ 3.202667] omapfb omapfb: failed to init overlay connections [ 3.208892] OMAPFB: free_resources [ 3.212493] OMAPFB: free all fbmem [ 3.216735] omapfb omapfb: failed to setup omapfb As a workaround name the VPLL2 regulator from twl4030 as vdds_dsi so getting the VDDS_DSI regulator will succeed on dpi_init_regulator(). Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep0020.dts | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index b9a9e17acb5..1c7e74d2d2b 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts @@ -215,3 +215,8 @@ &usbhsehci { phys = <&hsusb1_phy>; }; + +&vpll2 { + /* Needed for DSS */ + regulator-name = "vdds_dsi"; +}; -- cgit v1.2.3-70-g09d2 From 30023a7e4fef11c596fd7f3c323035c49dfaed85 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 26 Nov 2013 15:03:39 -0800 Subject: ARM: dts: omap3-beagle: Fix USB host on beagle boards (for 3.13) Beagle (rev. C4) and Beagle-XM (all revs) need VAUX2 1.8V supply for the USB PHY. As the generic PHY driver can't handle more than one supply at the moment, we configure this supply to be always on. This will cause a very small power impact if the USB host subsystem is not in use, about 76.86 micro-W + LDO power. Older Beagle boards (prior to C4) don't have VAUX2 connected anywhere, so there won't be any functional impact on those boards other than some additional LDO power consumption. Reported-by: Nishanth Menon Tested-by: Nishanth Menon Signed-off-by: Roger Quadros Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-beagle-xm.dts | 7 +++++++ arch/arm/boot/dts/omap3-beagle.dts | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 31a632f7eff..df33a50bc07 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -215,3 +215,10 @@ &usbhsehci { phys = <0 &hsusb2_phy>; }; + +&vaux2 { + regulator-name = "usb_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index fa532aaacc6..4e384fcc6ad 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -178,3 +178,10 @@ mode = <3>; power = <50>; }; + +&vaux2 { + regulator-name = "vdd_ehci"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; -- cgit v1.2.3-70-g09d2 From da990a4f2d5a321911026c26c7eeec3bbc6fb7b7 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 28 Nov 2013 15:49:59 +0530 Subject: ARC: [perf] Fix a few thinkos Signed-off-by: Vineet Gupta --- arch/arc/kernel/perf_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index e46d81f7097..63177e4cb66 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -79,9 +79,9 @@ static int arc_pmu_cache_event(u64 config) cache_result = (config >> 16) & 0xff; if (cache_type >= PERF_COUNT_HW_CACHE_MAX) return -EINVAL; - if (cache_type >= PERF_COUNT_HW_CACHE_OP_MAX) + if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) return -EINVAL; - if (cache_type >= PERF_COUNT_HW_CACHE_RESULT_MAX) + if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) return -EINVAL; ret = arc_pmu_cache_map[cache_type][cache_op][cache_result]; -- cgit v1.2.3-70-g09d2 From 9dda2769af4f3f3093434648c409bb351120d9e8 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Tue, 19 Nov 2013 17:12:47 +0100 Subject: crypto: s390 - Fix aes-xts parameter corruption Some s390 crypto algorithms incorrectly use the crypto_tfm structure to store private data. As the tfm can be shared among multiple threads, this can result in data corruption. This patch fixes aes-xts by moving the xts and pcc parameter blocks from the tfm onto the stack (48 + 96 bytes). Cc: stable@vger.kernel.org Signed-off-by: Gerald Schaefer Signed-off-by: Herbert Xu --- arch/s390/crypto/aes_s390.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 4363528dc8f..b3feabd39f3 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -55,8 +55,7 @@ struct pcc_param { struct s390_xts_ctx { u8 key[32]; - u8 xts_param[16]; - struct pcc_param pcc; + u8 pcc_key[32]; long enc; long dec; int key_len; @@ -591,7 +590,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, xts_ctx->enc = KM_XTS_128_ENCRYPT; xts_ctx->dec = KM_XTS_128_DECRYPT; memcpy(xts_ctx->key + 16, in_key, 16); - memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16); + memcpy(xts_ctx->pcc_key + 16, in_key + 16, 16); break; case 48: xts_ctx->enc = 0; @@ -602,7 +601,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, xts_ctx->enc = KM_XTS_256_ENCRYPT; xts_ctx->dec = KM_XTS_256_DECRYPT; memcpy(xts_ctx->key, in_key, 32); - memcpy(xts_ctx->pcc.key, in_key + 32, 32); + memcpy(xts_ctx->pcc_key, in_key + 32, 32); break; default: *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; @@ -621,29 +620,33 @@ static int xts_aes_crypt(struct blkcipher_desc *desc, long func, unsigned int nbytes = walk->nbytes; unsigned int n; u8 *in, *out; - void *param; + struct pcc_param pcc_param; + struct { + u8 key[32]; + u8 init[16]; + } xts_param; if (!nbytes) goto out; - memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block)); - memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit)); - memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts)); - memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak)); - param = xts_ctx->pcc.key + offset; - ret = crypt_s390_pcc(func, param); + memset(pcc_param.block, 0, sizeof(pcc_param.block)); + memset(pcc_param.bit, 0, sizeof(pcc_param.bit)); + memset(pcc_param.xts, 0, sizeof(pcc_param.xts)); + memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak)); + memcpy(pcc_param.key, xts_ctx->pcc_key, 32); + ret = crypt_s390_pcc(func, &pcc_param.key[offset]); if (ret < 0) return -EIO; - memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16); - param = xts_ctx->key + offset; + memcpy(xts_param.key, xts_ctx->key, 32); + memcpy(xts_param.init, pcc_param.xts, 16); do { /* only use complete blocks */ n = nbytes & ~(AES_BLOCK_SIZE - 1); out = walk->dst.virt.addr; in = walk->src.virt.addr; - ret = crypt_s390_km(func, param, out, in, n); + ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n); if (ret < 0 || ret != n) return -EIO; -- cgit v1.2.3-70-g09d2 From 6a2e5e521c333a0b56cb60dc5587e3f90859c5e7 Mon Sep 17 00:00:00 2001 From: Matthew Leach Date: Thu, 28 Nov 2013 12:07:22 +0000 Subject: arm64: ptrace: fix compat registes get/set to be endian clean On a BE system the wrong half of the X registers is retrieved/written when attempting to get/set the value of aarch32 registers through ptrace. Ensure that types are the correct width so that the relevant casting occurs. Signed-off-by: Matthew Leach Reviewed-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/ptrace.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index fecdbf7de82..6777a2192b8 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target, for (i = 0; i < num_regs; ++i) { unsigned int idx = start + i; - void *reg; + compat_ulong_t reg; switch (idx) { case 15: - reg = (void *)&task_pt_regs(target)->pc; + reg = task_pt_regs(target)->pc; break; case 16: - reg = (void *)&task_pt_regs(target)->pstate; + reg = task_pt_regs(target)->pstate; break; case 17: - reg = (void *)&task_pt_regs(target)->orig_x0; + reg = task_pt_regs(target)->orig_x0; break; default: - reg = (void *)&task_pt_regs(target)->regs[idx]; + reg = task_pt_regs(target)->regs[idx]; } - ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t)); - + ret = copy_to_user(ubuf, ®, sizeof(reg)); if (ret) break; - else - ubuf += sizeof(compat_ulong_t); + + ubuf += sizeof(reg); } return ret; @@ -685,28 +684,28 @@ static int compat_gpr_set(struct task_struct *target, for (i = 0; i < num_regs; ++i) { unsigned int idx = start + i; - void *reg; + compat_ulong_t reg; + + ret = copy_from_user(®, ubuf, sizeof(reg)); + if (ret) + return ret; + + ubuf += sizeof(reg); switch (idx) { case 15: - reg = (void *)&newregs.pc; + newregs.pc = reg; break; case 16: - reg = (void *)&newregs.pstate; + newregs.pstate = reg; break; case 17: - reg = (void *)&newregs.orig_x0; + newregs.orig_x0 = reg; break; default: - reg = (void *)&newregs.regs[idx]; + newregs.regs[idx] = reg; } - ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t)); - - if (ret) - goto out; - else - ubuf += sizeof(compat_ulong_t); } if (valid_user_regs(&newregs.user_regs)) @@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target, else ret = -EINVAL; -out: return ret; } -- cgit v1.2.3-70-g09d2 From 2dacab73dc9f86ad12eb41bc3355d7f492696bca Mon Sep 17 00:00:00 2001 From: Matthew Leach Date: Thu, 28 Nov 2013 12:07:23 +0000 Subject: arm64: debug: make aarch32 bkpt checking endian clean The current breakpoint instruction checking code for A32 is not endian clean. Fix this with appropriate byte-swapping when retrieving instructions. Signed-off-by: Matthew Leach Reviewed-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/debug-monitors.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 6a0a9b132d7..4ae68579031 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -248,7 +248,8 @@ static int brk_handler(unsigned long addr, unsigned int esr, int aarch32_break_handler(struct pt_regs *regs) { siginfo_t info; - unsigned int instr; + u32 arm_instr; + u16 thumb_instr; bool bp = false; void __user *pc = (void __user *)instruction_pointer(regs); @@ -257,18 +258,21 @@ int aarch32_break_handler(struct pt_regs *regs) if (compat_thumb_mode(regs)) { /* get 16-bit Thumb instruction */ - get_user(instr, (u16 __user *)pc); - if (instr == AARCH32_BREAK_THUMB2_LO) { + get_user(thumb_instr, (u16 __user *)pc); + thumb_instr = le16_to_cpu(thumb_instr); + if (thumb_instr == AARCH32_BREAK_THUMB2_LO) { /* get second half of 32-bit Thumb-2 instruction */ - get_user(instr, (u16 __user *)(pc + 2)); - bp = instr == AARCH32_BREAK_THUMB2_HI; + get_user(thumb_instr, (u16 __user *)(pc + 2)); + thumb_instr = le16_to_cpu(thumb_instr); + bp = thumb_instr == AARCH32_BREAK_THUMB2_HI; } else { - bp = instr == AARCH32_BREAK_THUMB; + bp = thumb_instr == AARCH32_BREAK_THUMB; } } else { /* 32-bit ARM instruction */ - get_user(instr, (u32 __user *)pc); - bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM; + get_user(arm_instr, (u32 __user *)pc); + arm_instr = le32_to_cpu(arm_instr); + bp = (arm_instr & ~0xf0000000) == AARCH32_BREAK_ARM; } if (!bp) -- cgit v1.2.3-70-g09d2 From 1f3a8bae21a22808f242ccfb22aca37a635e261e Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 11 Nov 2013 16:18:59 +0000 Subject: x86/efi: Fix earlyprintk off-by-one bug Dave reported seeing the following incorrect output on his Thinkpad T420 when using earlyprintk=efi, [ 0.000000] efi: EFI v2.00 by Lenovo ACPI=0xdabfe000 ACPI 2.0=0xdabfe014 SMBIOS=0xdaa9e000 The output should be on one line, not split over two. The cause is an off-by-one error when checking that the efi_y coordinate hasn't been incremented out of bounds. Reported-by: Dave Young Signed-off-by: Matt Fleming --- arch/x86/platform/efi/early_printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/early_printk.c b/arch/x86/platform/efi/early_printk.c index 6599a0027b7..81b506d5bef 100644 --- a/arch/x86/platform/efi/early_printk.c +++ b/arch/x86/platform/efi/early_printk.c @@ -142,7 +142,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) efi_y += font->height; } - if (efi_y + font->height >= si->lfb_height) { + if (efi_y + font->height > si->lfb_height) { u32 i; efi_y -= font->height; -- cgit v1.2.3-70-g09d2 From 4f00130b70e5eee813cc7bc298e0f3fdf79673cc Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 29 Nov 2013 10:56:14 +0000 Subject: arm64: Use Normal NonCacheable memory for writecombine This provides better performance compared to Device GRE and also allows unaligned accesses. Such memory is intended to be used with standard RAM (e.g. framebuffers) and not I/O. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 17bd3af0a11..5347b39fdb3 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -254,7 +254,7 @@ static inline int has_transparent_hugepage(void) #define pgprot_noncached(prot) \ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE)) #define pgprot_writecombine(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_GRE)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)) #define pgprot_dmacoherent(prot) \ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)) #define __HAVE_PHYS_MEM_ACCESS_PROT -- cgit v1.2.3-70-g09d2 From 3676f9ef5481d614f8c5c857f5319755be248268 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 27 Nov 2013 16:59:27 +0000 Subject: arm64: Move PTE_PROT_NONE higher up PTE_PROT_NONE means that a pte is present but does not have any read/write attributes. However, setting the memory type like pgprot_writecombine() is allowed and such bits overlap with PTE_PROT_NONE. This causes mmap/munmap issues in drivers that change the vma->vm_pg_prot on PROT_NONE mappings. This patch reverts the PTE_FILE/PTE_PROT_NONE shift in commit 59911ca4325d (ARM64: mm: Move PTE_PROT_NONE bit) and moves PTE_PROT_NONE together with the other software bits. Signed-off-by: Steve Capper Signed-off-by: Catalin Marinas Tested-by: Steve Capper Cc: # 3.11+ --- arch/arm64/include/asm/pgtable.h | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 5347b39fdb3..7f2b60affbb 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -25,10 +25,11 @@ * Software defined PTE bits definition. */ #define PTE_VALID (_AT(pteval_t, 1) << 0) -#define PTE_PROT_NONE (_AT(pteval_t, 1) << 2) /* only when !PTE_VALID */ -#define PTE_FILE (_AT(pteval_t, 1) << 3) /* only when !pte_present() */ +#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ #define PTE_DIRTY (_AT(pteval_t, 1) << 55) #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) + /* bit 57 for PMD_SECT_SPLITTING */ +#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ /* * VMALLOC and SPARSEMEM_VMEMMAP ranges. @@ -357,18 +358,20 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; /* * Encode and decode a swap entry: - * bits 0, 2: present (must both be zero) - * bit 3: PTE_FILE - * bits 4-8: swap type - * bits 9-63: swap offset + * bits 0-1: present (must be zero) + * bit 2: PTE_FILE + * bits 3-8: swap type + * bits 9-57: swap offset */ -#define __SWP_TYPE_SHIFT 4 +#define __SWP_TYPE_SHIFT 3 #define __SWP_TYPE_BITS 6 +#define __SWP_OFFSET_BITS 49 #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) +#define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1) #define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) -#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT) +#define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK) #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) @@ -382,15 +385,15 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; /* * Encode and decode a file entry: - * bits 0, 2: present (must both be zero) - * bit 3: PTE_FILE - * bits 4-63: file offset / PAGE_SIZE + * bits 0-1: present (must be zero) + * bit 2: PTE_FILE + * bits 3-57: file offset / PAGE_SIZE */ #define pte_file(pte) (pte_val(pte) & PTE_FILE) -#define pte_to_pgoff(x) (pte_val(x) >> 4) -#define pgoff_to_pte(x) __pte(((x) << 4) | PTE_FILE) +#define pte_to_pgoff(x) (pte_val(x) >> 3) +#define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE) -#define PTE_FILE_MAX_BITS 60 +#define PTE_FILE_MAX_BITS 55 extern int kern_addr_valid(unsigned long addr); -- cgit v1.2.3-70-g09d2 From 11a5aa32562e1e90ab2d0278748fe0fbecda1cbe Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 25 Nov 2013 21:52:25 +0000 Subject: ARM: dma-mapping: check DMA mask against available memory Some buses have negative offsets, which causes the DMA mask checks to falsely fail. Fix this by using the actual amount of memory fitted in the system. Signed-off-by: Russell King --- arch/arm/mm/dma-mapping.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 79f8b39801a..f6b6bfa88ec 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -9,6 +9,7 @@ * * DMA uncached mapping support. */ +#include #include #include #include @@ -162,6 +163,8 @@ static u64 get_coherent_dma_mask(struct device *dev) u64 mask = (u64)DMA_BIT_MASK(32); if (dev) { + unsigned long max_dma_pfn; + mask = dev->coherent_dma_mask; /* @@ -173,6 +176,8 @@ static u64 get_coherent_dma_mask(struct device *dev) return 0; } + max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); + /* * If the mask allows for more memory than we can address, * and we actually have that much memory, then fail the @@ -180,7 +185,7 @@ static u64 get_coherent_dma_mask(struct device *dev) */ if (sizeof(mask) != sizeof(dma_addr_t) && mask > (dma_addr_t)~0 && - dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) { + dma_to_pfn(dev, ~0) > max_dma_pfn) { dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", mask); dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); @@ -192,7 +197,7 @@ static u64 get_coherent_dma_mask(struct device *dev) * fits within the allowable addresses which we can * allocate. */ - if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) { + if (dma_to_pfn(dev, mask) < max_dma_pfn) { dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", mask, dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, -- cgit v1.2.3-70-g09d2 From d8aa712c30148ba26fd89a5dc14de95d4c375184 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 28 Nov 2013 21:43:40 +0000 Subject: ARM: fix booting low-vectors machines Commit f6f91b0d9fd9 (ARM: allow kuser helpers to be removed from the vector page) required two pages for the vectors code. Although the code setting up the initial page tables was updated, the code which allocates page tables for new processes wasn't, neither was the code which tears down the mappings. Fix this. Fixes: f6f91b0d9fd9 ("ARM: allow kuser helpers to be removed from the vector page") Signed-off-by: Russell King Cc: --- arch/arm/include/asm/pgtable.h | 2 +- arch/arm/mm/mmap.c | 2 +- arch/arm/mm/pgd.c | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index be956dbf6ba..1571d126e9d 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -61,7 +61,7 @@ extern void __pgd_error(const char *file, int line, pgd_t); * mapping to be mapped at. This is particularly important for * non-high vector CPUs. */ -#define FIRST_USER_ADDRESS PAGE_SIZE +#define FIRST_USER_ADDRESS (PAGE_SIZE * 2) /* * Use TASK_SIZE as the ceiling argument for free_pgtables() and diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index d27158c38eb..5e85ed37136 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -146,7 +146,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.flags = VM_UNMAPPED_AREA_TOPDOWN; info.length = len; - info.low_limit = PAGE_SIZE; + info.low_limit = FIRST_USER_ADDRESS; info.high_limit = mm->mmap_base; info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; info.align_offset = pgoff << PAGE_SHIFT; diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 0acb089d0f7..1046b373d1a 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -87,7 +87,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) init_pud = pud_offset(init_pgd, 0); init_pmd = pmd_offset(init_pud, 0); init_pte = pte_offset_map(init_pmd, 0); - set_pte_ext(new_pte, *init_pte, 0); + set_pte_ext(new_pte + 0, init_pte[0], 0); + set_pte_ext(new_pte + 1, init_pte[1], 0); pte_unmap(init_pte); pte_unmap(new_pte); } -- cgit v1.2.3-70-g09d2 From 43659222e7a0113912ed02f6b2231550b3e471ac Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 28 Nov 2013 21:55:41 +0000 Subject: ARM: footbridge: fix VGA initialisation It's no good setting vga_base after the VGA console has been initialised, because if we do that we get this: Unable to handle kernel paging request at virtual address 000b8000 pgd = c0004000 [000b8000] *pgd=07ffc831, *pte=00000000, *ppte=00000000 0Internal error: Oops: 5017 [#1] ARM Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.0+ #49 task: c03e2974 ti: c03d8000 task.ti: c03d8000 PC is at vgacon_startup+0x258/0x39c LR is at request_resource+0x10/0x1c pc : [] lr : [] psr: 60000053 sp : c03d9f68 ip : 000b8000 fp : c03d9f8c r10: 000055aa r9 : 4401a103 r8 : ffffaa55 r7 : c03e357c r6 : c051b460 r5 : 000000ff r4 : 000c0000 r3 : 000b8000 r2 : c03e0514 r1 : 00000000 r0 : c0304971 Flags: nZCv IRQs on FIQs off Mode SVC_32 ISA ARM Segment kernel which is an access to the 0xb8000 without the PCI offset required to make it work. Fixes: cc22b4c18540 ("ARM: set vga memory base at run-time") Signed-off-by: Russell King Cc: --- arch/arm/mach-footbridge/common.c | 3 +++ arch/arm/mach-footbridge/dc21285.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index 2739ca2c133..e0091685fd4 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -15,6 +15,7 @@ #include #include #include +#include