diff options
Diffstat (limited to 'arch/arm')
93 files changed, 1322 insertions, 484 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 91be74d8df65..2196aac0e45c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -19,6 +19,7 @@ config ARM select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_NO_SG_CHAIN if !ARM_HAS_SG_CHAIN select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7 select ARCH_SUPPORTS_ATOMIC_RMW @@ -29,7 +30,7 @@ config ARM select CLONE_BACKWARDS select CPU_PM if (SUSPEND || CPU_IDLE) select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS - select DMA_DIRECT_OPS if !MMU + select DMA_REMAP if MMU select EDAC_SUPPORT select EDAC_ATOMIC_SCRUB select GENERIC_ALLOCATOR @@ -118,7 +119,6 @@ config ARM <http://www.arm.linux.org.uk/>. config ARM_HAS_SG_CHAIN - select ARCH_HAS_SG_CHAIN bool config ARM_DMA_USE_IOMMU @@ -1810,6 +1810,21 @@ config XEN help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. +config STACKPROTECTOR_PER_TASK + bool "Use a unique stack canary value for each task" + depends on GCC_PLUGINS && STACKPROTECTOR && SMP && !XIP_DEFLATED_DATA + select GCC_PLUGIN_ARM_SSP_PER_TASK + default y + help + Due to the fact that GCC uses an ordinary symbol reference from + which to load the value of the stack canary, this value can only + change at reboot time on SMP systems, and all tasks running in the + kernel's address space are forced to use the same canary value for + the entire duration that the system is up. + + Enable this option to switch to a different method that uses a + different canary value for each task. + endmenu menu "Boot options" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 05a91d8b89f3..0436002d5091 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -303,6 +303,18 @@ else KBUILD_IMAGE := $(boot)/zImage endif +ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) +prepare: stack_protector_prepare +stack_protector_prepare: prepare0 + $(eval KBUILD_CFLAGS += \ + -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ + awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ + include/generated/asm-offsets.h) \ + -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ + awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ + include/generated/asm-offsets.h)) +endif + all: $(notdir $(KBUILD_IMAGE)) diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 1f5a5ffe7fcf..01bf2585a0fa 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -101,6 +101,7 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ $(libfdt) $(libfdt_hdrs) hyp-stub.S KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) diff --git a/arch/arm/boot/dts/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm-realview-pb1176.dts index f2a1d25eb6cf..83e0fbc4a1a1 100644 --- a/arch/arm/boot/dts/arm-realview-pb1176.dts +++ b/arch/arm/boot/dts/arm-realview-pb1176.dts @@ -45,7 +45,7 @@ }; /* The voltage to the MMC card is hardwired at 3.3V */ - vmmc: fixedregulator@0 { + vmmc: regulator-vmmc { compatible = "regulator-fixed"; regulator-name = "vmmc"; regulator-min-microvolt = <3300000>; @@ -53,7 +53,7 @@ regulator-boot-on; }; - veth: fixedregulator@0 { + veth: regulator-veth { compatible = "regulator-fixed"; regulator-name = "veth"; regulator-min-microvolt = <3300000>; diff --git a/arch/arm/boot/dts/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm-realview-pb11mp.dts index 7f9cbdf33a51..2f6aa24a0b67 100644 --- a/arch/arm/boot/dts/arm-realview-pb11mp.dts +++ b/arch/arm/boot/dts/arm-realview-pb11mp.dts @@ -145,7 +145,7 @@ }; /* The voltage to the MMC card is hardwired at 3.3V */ - vmmc: fixedregulator@0 { + vmmc: regulator-vmmc { compatible = "regulator-fixed"; regulator-name = "vmmc"; regulator-min-microvolt = <3300000>; @@ -153,7 +153,7 @@ regulator-boot-on; }; - veth: fixedregulator@0 { + veth: regulator-veth { compatible = "regulator-fixed"; regulator-name = "veth"; regulator-min-microvolt = <3300000>; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts index 4adb85e66be3..93762244be7f 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts @@ -31,7 +31,7 @@ wifi_pwrseq: wifi-pwrseq { compatible = "mmc-pwrseq-simple"; - reset-gpios = <&expgpio 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts index c318bcbc6ba7..89e6fd547c75 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -26,7 +26,7 @@ wifi_pwrseq: wifi-pwrseq { compatible = "mmc-pwrseq-simple"; - reset-gpios = <&expgpio 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts index d8aac4a2d02a..177d21fdeb28 100644 --- a/arch/arm/boot/dts/imx7d-nitrogen7.dts +++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts @@ -86,13 +86,17 @@ compatible = "regulator-fixed"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - clocks = <&clks IMX7D_CLKO2_ROOT_DIV>; - clock-names = "slow"; regulator-name = "reg_wlan"; startup-delay-us = <70000>; gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + usdhc2_pwrseq: usdhc2_pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&clks IMX7D_CLKO2_ROOT_DIV>; + clock-names = "ext_clock"; + }; }; &adc1 { @@ -375,6 +379,7 @@ bus-width = <4>; non-removable; vmmc-supply = <®_wlan>; + mmc-pwrseq = <&usdhc2_pwrseq>; cap-power-off-card; keep-power-in-suspend; status = "okay"; diff --git a/arch/arm/boot/dts/imx7d-pico.dtsi b/arch/arm/boot/dts/imx7d-pico.dtsi index 21973eb55671..f27b3849d3ff 100644 --- a/arch/arm/boot/dts/imx7d-pico.dtsi +++ b/arch/arm/boot/dts/imx7d-pico.dtsi @@ -100,6 +100,19 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + + usdhc2_pwrseq: usdhc2_pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&clks IMX7D_CLKO2_ROOT_DIV>; + clock-names = "ext_clock"; + }; +}; + +&clks { + assigned-clocks = <&clks IMX7D_CLKO2_ROOT_SRC>, + <&clks IMX7D_CLKO2_ROOT_DIV>; + assigned-clock-parents = <&clks IMX7D_CKIL>; + assigned-clock-rates = <0>, <32768>; }; &i2c4 { @@ -199,12 +212,13 @@ &usdhc2 { /* Wifi SDIO */ pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_wifi_clk>; no-1-8-v; non-removable; keep-power-in-suspend; wakeup-source; vmmc-supply = <®_ap6212>; + mmc-pwrseq = <&usdhc2_pwrseq>; status = "okay"; }; @@ -301,6 +315,12 @@ }; &iomuxc_lpsr { + pinctrl_wifi_clk: wificlkgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO03__CCM_CLKO2 0x7d + >; + }; + pinctrl_wdog: wdoggrp { fsl,pins = < MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x74 diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts index b828677f331d..ffafe9720b35 100644 --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts @@ -245,6 +245,8 @@ regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; regulator-name = "vddio-csi0"; + regulator-soft-start; + regulator-ramp-delay = <1600>; }; ®_ldo4 { diff --git a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts index 742d2946b08b..583a5a01642f 100644 --- a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts +++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts @@ -314,8 +314,8 @@ ®_dldo3 { regulator-always-on; - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; regulator-name = "vcc-pd"; }; diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 9a92de63426f..5ba4622030ca 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -257,7 +257,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, if (buf == NULL) { dev_err(dev, "%s: unable to map unsafe buffer %p!\n", __func__, ptr); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", @@ -327,7 +327,7 @@ static dma_addr_t dmabounce_map_page(struct device *dev, struct page *page, ret = needs_bounce(dev, dma_addr, size); if (ret < 0) - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; if (ret == 0) { arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir); @@ -336,7 +336,7 @@ static dma_addr_t dmabounce_map_page(struct device *dev, struct page *page, if (PageHighMem(page)) { dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n"); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } return map_single(dev, page_address(page) + offset, size, dir, attrs); @@ -453,11 +453,6 @@ static int dmabounce_dma_supported(struct device *dev, u64 dma_mask) return arm_dma_ops.dma_supported(dev, dma_mask); } -static int dmabounce_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return arm_dma_ops.mapping_error(dev, dma_addr); -} - static const struct dma_map_ops dmabounce_ops = { .alloc = arm_dma_alloc, .free = arm_dma_free, @@ -472,7 +467,6 @@ static const struct dma_map_ops dmabounce_ops = { .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, .sync_sg_for_device = arm_dma_sync_sg_for_device, .dma_supported = dmabounce_dma_supported, - .mapping_error = dmabounce_mapping_error, }; static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index 07b2eadac3dd..207962a656a2 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -167,8 +167,9 @@ CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_USB_AUDIO=m CONFIG_SND_SOC=m -CONFIG_SND_EDMA_SOC=m -CONFIG_SND_DA850_SOC_EVM=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_DAVINCI_MCASP=m +CONFIG_SND_SOC_DAVINCI_EVM=m CONFIG_SND_SIMPLE_CARD=m CONFIG_HID=m CONFIG_HID_A4TECH=m diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 72f4bc83f467..cfc00b0961ec 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -175,8 +175,6 @@ CONFIG_SND_PCM_OSS=y # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_DUMMY=y CONFIG_SND_USB_AUDIO=y -CONFIG_SND_SOC=y -CONFIG_SND_OMAP_SOC=y # CONFIG_USB_HID is not set CONFIG_USB=y CONFIG_USB_PHY=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 6491419b1dad..2274e45623f9 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -381,13 +381,13 @@ CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_SOC=m -CONFIG_SND_EDMA_SOC=m -CONFIG_SND_AM33XX_SOC_EVM=m -CONFIG_SND_OMAP_SOC=m -CONFIG_SND_OMAP_SOC_HDMI_AUDIO=m -CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m -CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m -CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_DAVINCI_MCASP=m +CONFIG_SND_SOC_NOKIA_RX51=m +CONFIG_SND_SOC_OMAP_HDMI=m +CONFIG_SND_SOC_OMAP_ABE_TWL6040=m +CONFIG_SND_SOC_OMAP3_PANDORA=m +CONFIG_SND_SOC_OMAP3_TWL4030=m CONFIG_SND_SOC_CPCAP=m CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig index ef0c7feea6e2..a95322b59799 100644 --- a/arch/arm/crypto/Kconfig +++ b/arch/arm/crypto/Kconfig @@ -69,6 +69,15 @@ config CRYPTO_AES_ARM help Use optimized AES assembler routines for ARM platforms. + On ARM processors without the Crypto Extensions, this is the + fastest AES implementation for single blocks. For multiple + blocks, the NEON bit-sliced implementation is usually faster. + + This implementation may be vulnerable to cache timing attacks, + since it uses lookup tables. However, as countermeasures it + disables IRQs and preloads the tables; it is hoped this makes + such attacks very difficult. + config CRYPTO_AES_ARM_BS tristate "Bit sliced AES using NEON instructions" depends on KERNEL_MODE_NEON @@ -117,9 +126,14 @@ config CRYPTO_CRC32_ARM_CE select CRYPTO_HASH config CRYPTO_CHACHA20_NEON - tristate "NEON accelerated ChaCha20 symmetric cipher" + tristate "NEON accelerated ChaCha stream cipher algorithms" depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER select CRYPTO_CHACHA20 +config CRYPTO_NHPOLY1305_NEON + tristate "NEON accelerated NHPoly1305 hash function (for Adiantum)" + depends on KERNEL_MODE_NEON + select CRYPTO_NHPOLY1305 + endif diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile index bd5bceef0605..b65d6bfab8e6 100644 --- a/arch/arm/crypto/Makefile +++ b/arch/arm/crypto/Makefile @@ -9,7 +9,8 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o -obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha20-neon.o +obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o +obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o @@ -52,7 +53,8 @@ aes-arm-ce-y := aes-ce-core.o aes-ce-glue.o ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o crct10dif-arm-ce-y := crct10dif-ce-core.o crct10dif-ce-glue.o crc32-arm-ce-y:= crc32-ce-core.o crc32-ce-glue.o -chacha20-neon-y := chacha20-neon-core.o chacha20-neon-glue.o +chacha-neon-y := chacha-neon-core.o chacha-neon-glue.o +nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o ifdef REGENERATE_ARM_CRYPTO quiet_cmd_perl = PERL $@ diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c index d0a9cec73707..5affb8482379 100644 --- a/arch/arm/crypto/aes-ce-glue.c +++ b/arch/arm/crypto/aes-ce-glue.c @@ -10,7 +10,6 @@ #include <asm/hwcap.h> #include <asm/neon.h> -#include <asm/hwcap.h> #include <crypto/aes.h> #include <crypto/internal/simd.h> #include <crypto/internal/skcipher.h> diff --git a/arch/arm/crypto/aes-cipher-core.S b/arch/arm/crypto/aes-cipher-core.S index 184d6c2d15d5..f2d67c095e59 100644 --- a/arch/arm/crypto/aes-cipher-core.S +++ b/arch/arm/crypto/aes-cipher-core.S @@ -10,6 +10,7 @@ */ #include <linux/linkage.h> +#include <asm/assembler.h> #include <asm/cache.h> .text @@ -41,7 +42,7 @@ .endif .endm - .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op + .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op, oldcpsr __select \out0, \in0, 0 __select t0, \in1, 1 __load \out0, \out0, 0, \sz, \op @@ -73,6 +74,14 @@ __load t0, t0, 3, \sz, \op __load \t4, \t4, 3, \sz, \op + .ifnb \oldcpsr + /* + * This is the final round and we're done with all data-dependent table + * lookups, so we can safely re-enable interrupts. + */ + restore_irqs \oldcpsr + .endif + eor \out1, \out1, t1, ror #24 eor \out0, \out0, t2, ror #16 ldm rk!, {t1, t2} @@ -83,14 +92,14 @@ eor \out1, \out1, t2 .endm - .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op, oldcpsr __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op - __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op + __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op, \oldcpsr .endm - .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op, oldcpsr __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op - __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op + __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op, \oldcpsr .endm .macro __rev, out, in @@ -118,13 +127,14 @@ .macro do_crypt, round, ttab, ltab, bsz push {r3-r11, lr} + // Load keys first, to reduce latency in case they're not cached yet. + ldm rk!, {r8-r11} + ldr r4, [in] ldr r5, [in, #4] ldr r6, [in, #8] ldr r7, [in, #12] - ldm rk!, {r8-r11} - #ifdef CONFIG_CPU_BIG_ENDIAN __rev r4, r4 __rev r5, r5 @@ -138,6 +148,25 @@ eor r7, r7, r11 __adrl ttab, \ttab + /* + * Disable interrupts and prefetch the 1024-byte 'ft' or 'it' table into + * L1 cache, assuming cacheline size >= 32. This is a hardening measure + * intended to make cache-timing attacks more difficult. They may not + * be fully prevented, however; see the paper + * https://cr.yp.to/antiforgery/cachetiming-20050414.pdf + * ("Cache-timing attacks on AES") for a discussion of the many + * difficulties involved in writing truly constant-time AES software. + */ + save_and_disable_irqs t0 + .set i, 0 + .rept 1024 / 128 + ldr r8, [ttab, #i + 0] + ldr r9, [ttab, #i + 32] + ldr r10, [ttab, #i + 64] + ldr r11, [ttab, #i + 96] + .set i, i + 128 + .endr + push {t0} // oldcpsr tst rounds, #2 bne 1f @@ -151,8 +180,21 @@ \round r4, r5, r6, r7, r8, r9, r10, r11 b 0b -2: __adrl ttab, \ltab - \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b +2: .ifb \ltab + add ttab, ttab, #1 + .else + __adrl ttab, \ltab + // Prefetch inverse S-box for final round; see explanation above + .set i, 0 + .rept 256 / 64 + ldr t0, [ttab, #i + 0] + ldr t1, [ttab, #i + 32] + .set i, i + 64 + .endr + .endif + + pop {rounds} // oldcpsr + \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b, rounds #ifdef CONFIG_CPU_BIG_ENDIAN __rev r4, r4 @@ -175,7 +217,7 @@ .endm ENTRY(__aes_arm_encrypt) - do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 + do_crypt fround, crypto_ft_tab,, 2 ENDPROC(__aes_arm_encrypt) .align 5 diff --git a/arch/arm/crypto/chacha20-neon-core.S b/arch/arm/crypto/chacha-neon-core.S index 50e7b9896818..eb22926d4912 100644 --- a/arch/arm/crypto/chacha20-neon-core.S +++ b/arch/arm/crypto/chacha-neon-core.S @@ -1,5 +1,5 @@ /* - * ChaCha20 256-bit cipher algorithm, RFC7539, ARM NEON functions + * ChaCha/XChaCha NEON helper functions * * Copyright (C) 2016 Linaro, Ltd. <ard.biesheuvel@linaro.org> * @@ -27,9 +27,9 @@ * (d) vtbl.8 + vtbl.8 (multiple of 8 bits rotations only, * needs index vector) * - * ChaCha20 has 16, 12, 8, and 7-bit rotations. For the 12 and 7-bit - * rotations, the only choices are (a) and (b). We use (a) since it takes - * two-thirds the cycles of (b) on both Cortex-A7 and Cortex-A53. + * ChaCha has 16, 12, 8, and 7-bit rotations. For the 12 and 7-bit rotations, + * the only choices are (a) and (b). We use (a) since it takes two-thirds the + * cycles of (b) on both Cortex-A7 and Cortex-A53. * * For the 16-bit rotation, we use vrev32.16 since it's consistently fastest * and doesn't need a temporary register. @@ -52,30 +52,20 @@ .fpu neon .align 5 -ENTRY(chacha20_block_xor_neon) - // r0: Input state matrix, s - // r1: 1 data block output, o - // r2: 1 data block input, i - - // - // This function encrypts one ChaCha20 block by loading the state matrix - // in four NEON registers. It performs matrix operation on four words in - // parallel, but requireds shuffling to rearrange the words after each - // round. - // - - // x0..3 = s0..3 - add ip, r0, #0x20 - vld1.32 {q0-q1}, [r0] - vld1.32 {q2-q3}, [ip] - - vmov q8, q0 - vmov q9, q1 - vmov q10, q2 - vmov q11, q3 +/* + * chacha_permute - permute one block + * + * Permute one 64-byte block where the state matrix is stored in the four NEON + * registers q0-q3. It performs matrix operations on four words in parallel, + * but requires shuffling to rearrange the words after each round. + * + * The round count is given in r3. + * + * Clobbers: r3, ip, q4-q5 + */ +chacha_permute: adr ip, .Lrol8_table - mov r3, #10 vld1.8 {d10}, [ip, :64] .Ldoubleround: @@ -139,9 +129,31 @@ ENTRY(chacha20_block_xor_neon) // x3 = shuffle32(x3, MASK(0, 3, 2, 1)) vext.8 q3, q3, q3, #4 - subs r3, r3, #1 + subs r3, r3, #2 bne .Ldoubleround + bx lr +ENDPROC(chacha_permute) + +ENTRY(chacha_block_xor_neon) + // r0: Input state matrix, s + // r1: 1 data block output, o + // r2: 1 data block input, i + // r3: nrounds + push {lr} + + // x0..3 = s0..3 + add ip, r0, #0x20 + vld1.32 {q0-q1}, [r0] + vld1.32 {q2-q3}, [ip] + + vmov q8, q0 + vmov q9, q1 + vmov q10, q2 + vmov q11, q3 + + bl chacha_permute + add ip, r2, #0x20 vld1.8 {q4-q5}, [r2] vld1.8 {q6-q7}, [ip] @@ -166,15 +178,33 @@ ENTRY(chacha20_block_xor_neon) vst1.8 {q0-q1}, [r1] vst1.8 {q2-q3}, [ip] - bx lr -ENDPROC(chacha20_block_xor_neon) + pop {pc} +ENDPROC(chacha_block_xor_neon) + +ENTRY(hchacha_block_neon) + // r0: Input state matrix, s + // r1: output (8 32-bit words) + // r2: nrounds + push {lr} + + vld1.32 {q0-q1}, [r0]! + vld1.32 {q2-q3}, [r0] + + mov r3, r2 + bl chacha_permute + + vst1.32 {q0}, [r1]! + vst1.32 {q3}, [r1] + + pop {pc} +ENDPROC(hchacha_block_neon) .align 4 .Lctrinc: .word 0, 1, 2, 3 .Lrol8_table: .byte 3, 0, 1, 2, 7, 4, 5, 6 .align 5 -ENTRY(chacha20_4block_xor_neon) +ENTRY(chacha_4block_xor_neon) push {r4-r5} mov r4, sp // preserve the stack pointer sub ip, sp, #0x20 // allocate a 32 byte buffer @@ -184,9 +214,10 @@ ENTRY(chacha20_4block_xor_neon) // r0: Input state matrix, s // r1: 4 data blocks output, o // r2: 4 data blocks input, i + // r3: nrounds // - // This function encrypts four consecutive ChaCha20 blocks by loading + // This function encrypts four consecutive ChaCha blocks by loading // the state matrix in NEON registers four times. The algorithm performs // each operation on the corresponding word of each state matrix, hence // requires no word shuffling. The words are re-interleaved before the @@ -219,7 +250,6 @@ ENTRY(chacha20_4block_xor_neon) vdup.32 q0, d0[0] adr ip, .Lrol8_table - mov r3, #10 b 1f .Ldoubleround4: @@ -417,7 +447,7 @@ ENTRY(chacha20_4block_xor_neon) vsri.u32 q5, q8, #25 vsri.u32 q6, q9, #25 - subs r3, r3, #1 + subs r3, r3, #2 bne .Ldoubleround4 // x0..7[0-3] are in q0-q7, x10..15[0-3] are in q10-q15. @@ -527,4 +557,4 @@ ENTRY(chacha20_4block_xor_neon) pop {r4-r5} bx lr -ENDPROC(chacha20_4block_xor_neon) +ENDPROC(chacha_4block_xor_neon) diff --git a/arch/arm/crypto/chacha-neon-glue.c b/arch/arm/crypto/chacha-neon-glue.c new file mode 100644 index 000000000000..9d6fda81986d --- /dev/null +++ b/arch/arm/crypto/chacha-neon-glue.c @@ -0,0 +1,201 @@ +/* + * ARM NEON accelerated ChaCha and XChaCha stream ciphers, + * including ChaCha20 (RFC7539) + * + * Copyright (C) 2016 Linaro, Ltd. <ard.biesheuvel@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Based on: + * ChaCha20 256-bit cipher algorithm, RFC7539, SIMD glue code + * + * Copyright (C) 2015 Martin Willi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <crypto/algapi.h> +#include <crypto/chacha.h> +#include <crypto/internal/skcipher.h> +#include <linux/kernel.h> +#include <linux/module.h> + +#include <asm/hwcap.h> +#include <asm/neon.h> +#include <asm/simd.h> + +asmlinkage void chacha_block_xor_neon(const u32 *state, u8 *dst, const u8 *src, + int nrounds); +asmlinkage void chacha_4block_xor_neon(const u32 *state, u8 *dst, const u8 *src, + int nrounds); +asmlinkage void hchacha_block_neon(const u32 *state, u32 *out, int nrounds); + +static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, + unsigned int bytes, int nrounds) +{ + u8 buf[CHACHA_BLOCK_SIZE]; + + while (bytes >= CHACHA_BLOCK_SIZE * 4) { + chacha_4block_xor_neon(state, dst, src, nrounds); + bytes -= CHACHA_BLOCK_SIZE * 4; + src += CHACHA_BLOCK_SIZE * 4; + dst += CHACHA_BLOCK_SIZE * 4; + state[12] += 4; + } + while (bytes >= CHACHA_BLOCK_SIZE) { + chacha_block_xor_neon(state, dst, src, nrounds); + bytes -= CHACHA_BLOCK_SIZE; + src += CHACHA_BLOCK_SIZE; + dst += CHACHA_BLOCK_SIZE; + state[12]++; + } + if (bytes) { + memcpy(buf, src, bytes); + chacha_block_xor_neon(state, buf, buf, nrounds); + memcpy(dst, buf, bytes); + } +} + +static int chacha_neon_stream_xor(struct skcipher_request *req, + struct chacha_ctx *ctx, u8 *iv) +{ + struct skcipher_walk walk; + u32 state[16]; + int err; + + err = skcipher_walk_virt(&walk, req, false); + + crypto_chacha_init(state, ctx, iv); + + while (walk.nbytes > 0) { + unsigned int nbytes = walk.nbytes; + + if (nbytes < walk.total) + nbytes = round_down(nbytes, walk.stride); + + kernel_neon_begin(); + chacha_doneon(state, walk.dst.virt.addr, walk.src.virt.addr, + nbytes, ctx->nrounds); + kernel_neon_end(); + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static int chacha_neon(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm); + + if (req->cryptlen <= CHACHA_BLOCK_SIZE || !may_use_simd()) + return crypto_chacha_crypt(req); + + return chacha_neon_stream_xor(req, ctx, req->iv); +} + +static int xchacha_neon(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm); + struct chacha_ctx subctx; + u32 state[16]; + u8 real_iv[16]; + + if (req->cryptlen <= CHACHA_BLOCK_SIZE || !may_use_simd()) + return crypto_xchacha_crypt(req); + + crypto_chacha_init(state, ctx, req->iv); + + kernel_neon_begin(); + hchacha_block_neon(state, subctx.key, ctx->nrounds); + kernel_neon_end(); + subctx.nrounds = ctx->nrounds; + + memcpy(&real_iv[0], req->iv + 24, 8); + memcpy(&real_iv[8], req->iv + 16, 8); + return chacha_neon_stream_xor(req, &subctx, real_iv); +} + +static struct skcipher_alg algs[] = { + { + .base.cra_name = "chacha20", + .base.cra_driver_name = "chacha20-neon", + .base.cra_priority = 300, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct chacha_ctx), + .base.cra_module = THIS_MODULE, + + .min_keysize = CHACHA_KEY_SIZE, + .max_keysize = CHACHA_KEY_SIZE, + .ivsize = CHACHA_IV_SIZE, + .chunksize = CHACHA_BLOCK_SIZE, + .walksize = 4 * CHACHA_BLOCK_SIZE, + .setkey = crypto_chacha20_setkey, + .encrypt = chacha_neon, + .decrypt = chacha_neon, + }, { + .base.cra_name = "xchacha20", + .base.cra_driver_name = "xchacha20-neon", + .base.cra_priority = 300, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct chacha_ctx), + .base.cra_module = THIS_MODULE, + + .min_keysize = CHACHA_KEY_SIZE, + .max_keysize = CHACHA_KEY_SIZE, + .ivsize = XCHACHA_IV_SIZE, + .chunksize = CHACHA_BLOCK_SIZE, + .walksize = 4 * CHACHA_BLOCK_SIZE, + .setkey = crypto_chacha20_setkey, + .encrypt = xchacha_neon, + .decrypt = xchacha_neon, + }, { + .base.cra_name = "xchacha12", + .base.cra_driver_name = "xchacha12-neon", + .base.cra_priority = 300, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct chacha_ctx), + .base.cra_module = THIS_MODULE, + + .min_keysize = CHACHA_KEY_SIZE, + .max_keysize = CHACHA_KEY_SIZE, + .ivsize = XCHACHA_IV_SIZE, + .chunksize = CHACHA_BLOCK_SIZE, + .walksize = 4 * CHACHA_BLOCK_SIZE, + .setkey = crypto_chacha12_setkey, + .encrypt = xchacha_neon, + .decrypt = xchacha_neon, + } +}; + +static int __init chacha_simd_mod_init(void) +{ + if (!(elf_hwcap & HWCAP_NEON)) + return -ENODEV; + + return crypto_register_skciphers(algs, ARRAY_SIZE(algs)); +} + +static void __exit chacha_simd_mod_fini(void) +{ + crypto_unregister_skciphers(algs, ARRAY_SIZE(algs)); +} + +module_init(chacha_simd_mod_init); +module_exit(chacha_simd_mod_fini); + +MODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (NEON accelerated)"); +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("chacha20"); +MODULE_ALIAS_CRYPTO("chacha20-neon"); +MODULE_ALIAS_CRYPTO("xchacha20"); +MODULE_ALIAS_CRYPTO("xchacha20-neon"); +MODULE_ALIAS_CRYPTO("xchacha12"); +MODULE_ALIAS_CRYPTO("xchacha12-neon"); diff --git a/arch/arm/crypto/chacha20-neon-glue.c b/arch/arm/crypto/chacha20-neon-glue.c deleted file mode 100644 index 59a7be08e80c..000000000000 --- a/arch/arm/crypto/chacha20-neon-glue.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ChaCha20 256-bit cipher algorithm, RFC7539, ARM NEON functions - * - * Copyright (C) 2016 Linaro, Ltd. <ard.biesheuvel@linaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Based on: - * ChaCha20 256-bit cipher algorithm, RFC7539, SIMD glue code - * - * Copyright (C) 2015 Martin Willi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include <crypto/algapi.h> -#include <crypto/chacha20.h> -#include <crypto/internal/skcipher.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <asm/hwcap.h> -#include <asm/neon.h> -#include <asm/simd.h> - -asmlinkage void chacha20_block_xor_neon(u32 *state, u8 *dst, const u8 *src); -asmlinkage void chacha20_4block_xor_neon(u32 *state, u8 *dst, const u8 *src); - -static void chacha20_doneon(u32 *state, u8 *dst, const u8 *src, - unsigned int bytes) -{ - u8 buf[CHACHA20_BLOCK_SIZE]; - - while (bytes >= CHACHA20_BLOCK_SIZE * 4) { - chacha20_4block_xor_neon(state, dst, src); - bytes -= CHACHA20_BLOCK_SIZE * 4; - src += CHACHA20_BLOCK_SIZE * 4; - dst += CHACHA20_BLOCK_SIZE * 4; - state[12] += 4; - } - while (bytes >= CHACHA20_BLOCK_SIZE) { - chacha20_block_xor_neon(state, dst, src); - bytes -= CHACHA20_BLOCK_SIZE; - src += CHACHA20_BLOCK_SIZE; - dst += CHACHA20_BLOCK_SIZE; - state[12]++; - } - if (bytes) { - memcpy(buf, src, bytes); - chacha20_block_xor_neon(state, buf, buf); - memcpy(dst, buf, bytes); - } -} - -static int chacha20_neon(struct skcipher_request *req) -{ - struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); - struct chacha20_ctx *ctx = crypto_skcipher_ctx(tfm); - struct skcipher_walk walk; - u32 state[16]; - int err; - - if (req->cryptlen <= CHACHA20_BLOCK_SIZE || !may_use_simd()) - return crypto_chacha20_crypt(req); - - err = skcipher_walk_virt(&walk, req, true); - - crypto_chacha20_init(state, ctx, walk.iv); - - kernel_neon_begin(); - while (walk.nbytes > 0) { - unsigned int nbytes = walk.nbytes; - - if (nbytes < walk.total) - nbytes = round_down(nbytes, walk.stride); - - chacha20_doneon(state, walk.dst.virt.addr, walk.src.virt.addr, - nbytes); - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } - kernel_neon_end(); - - return err; -} - -static struct skcipher_alg alg = { - .base.cra_name = "chacha20", - .base.cra_driver_name = "chacha20-neon", - .base.cra_priority = 300, - .base.cra_blocksize = 1, - .base.cra_ctxsize = sizeof(struct chacha20_ctx), - .base.cra_module = THIS_MODULE, - - .min_keysize = CHACHA20_KEY_SIZE, - .max_keysize = CHACHA20_KEY_SIZE, - .ivsize = CHACHA20_IV_SIZE, - .chunksize = CHACHA20_BLOCK_SIZE, - .walksize = 4 * CHACHA20_BLOCK_SIZE, - .setkey = crypto_chacha20_setkey, - .encrypt = chacha20_neon, - .decrypt = chacha20_neon, -}; - -static int __init chacha20_simd_mod_init(void) -{ - if (!(elf_hwcap & HWCAP_NEON)) - return -ENODEV; - - return crypto_register_skcipher(&alg); -} - -static void __exit chacha20_simd_mod_fini(void) -{ - crypto_unregister_skcipher(&alg); -} - -module_init(chacha20_simd_mod_init); -module_exit(chacha20_simd_mod_fini); - -MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS_CRYPTO("chacha20"); diff --git a/arch/arm/crypto/nh-neon-core.S b/arch/arm/crypto/nh-neon-core.S new file mode 100644 index 000000000000..434d80ab531c --- /dev/null +++ b/arch/arm/crypto/nh-neon-core.S @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * NH - ε-almost-universal hash function, NEON accelerated version + * + * Copyright 2018 Google LLC + * + * Author: Eric Biggers <ebiggers@google.com> + */ + +#include <linux/linkage.h> + + .text + .fpu neon + + KEY .req r0 + MESSAGE .req r1 + MESSAGE_LEN .req r2 + HASH .req r3 + + PASS0_SUMS .req q0 + PASS0_SUM_A .req d0 + PASS0_SUM_B .req d1 + PASS1_SUMS .req q1 + PASS1_SUM_A .req d2 + PASS1_SUM_B .req d3 + PASS2_SUMS .req q2 + PASS2_SUM_A .req d4 + PASS2_SUM_B .req d5 + PASS3_SUMS .req q3 + PASS3_SUM_A .req d6 + PASS3_SUM_B .req d7 + K0 .req q4 + K1 .req q5 + K2 .req q6 + K3 .req q7 + T0 .req q8 + T0_L .req d16 + T0_H .req d17 + T1 .req q9 + T1_L .req d18 + T1_H .req d19 + T2 .req q10 + T2_L .req d20 + T2_H .req d21 + T3 .req q11 + T3_L .req d22 + T3_H .req d23 + +.macro _nh_stride k0, k1, k2, k3 + + // Load next message stride + vld1.8 {T3}, [MESSAGE]! + + // Load next key stride + vld1.32 {\k3}, [KEY]! + + // Add message words to key words + vadd.u32 T0, T3, \k0 + vadd.u32 T1, T3, \k1 + vadd.u32 T2, T3, \k2 + vadd.u32 T3, T3, \k3 + + // Multiply 32x32 => 64 and accumulate + vmlal.u32 PASS0_SUMS, T0_L, T0_H + vmlal.u32 PASS1_SUMS, T1_L, T1_H + vmlal.u32 PASS2_SUMS, T2_L, T2_H + vmlal.u32 PASS3_SUMS, T3_L, T3_H +.endm + +/* + * void nh_neon(const u32 *key, const u8 *message, size_t message_len, + * u8 hash[NH_HASH_BYTES]) + * + * It's guaranteed that message_len % 16 == 0. + */ +ENTRY(nh_neon) + + vld1.32 {K0,K1}, [KEY]! + vmov.u64 PASS0_SUMS, #0 + vmov.u64 PASS1_SUMS, #0 + vld1.32 {K2}, [KEY]! + vmov.u64 PASS2_SUMS, #0 + vmov.u64 PASS3_SUMS, #0 + + subs MESSAGE_LEN, MESSAGE_LEN, #64 + blt .Lloop4_done +.Lloop4: + _nh_stride K0, K1, K2, K3 + _nh_stride K1, K2, K3, K0 + _nh_stride K2, K3, K0, K1 + _nh_stride K3, K0, K1, K2 + subs MESSAGE_LEN, MESSAGE_LEN, #64 + bge .Lloop4 + +.Lloop4_done: + ands MESSAGE_LEN, MESSAGE_LEN, #63 + beq .Ldone + _nh_stride K0, K1, K2, K3 + + subs MESSAGE_LEN, MESSAGE_LEN, #16 + beq .Ldone + _nh_stride K1, K2, K3, K0 + + subs MESSAGE_LEN, MESSAGE_LEN, #16 + beq .Ldone + _nh_stride K2, K3, K0, K1 + +.Ldone: + // Sum the accumulators for each pass, then store the sums to 'hash' + vadd.u64 T0_L, PASS0_SUM_A, PASS0_SUM_B + vadd.u64 T0_H, PASS1_SUM_A, PASS1_SUM_B + vadd.u64 T1_L, PASS2_SUM_A, PASS2_SUM_B + vadd.u64 T1_H, PASS3_SUM_A, PASS3_SUM_B + vst1.8 {T0-T1}, [HASH] + bx lr +ENDPROC(nh_neon) diff --git a/arch/arm/crypto/nhpoly1305-neon-glue.c b/arch/arm/crypto/nhpoly1305-neon-glue.c new file mode 100644 index 000000000000..49aae87cb2bc --- /dev/null +++ b/arch/arm/crypto/nhpoly1305-neon-glue.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * NHPoly1305 - ε-almost-∆-universal hash function for Adiantum + * (NEON accelerated version) + * + * Copyright 2018 Google LLC + */ + +#include <asm/neon.h> +#include <asm/simd.h> +#include <crypto/internal/hash.h> +#include <crypto/nhpoly1305.h> +#include <linux/module.h> + +asmlinkage void nh_neon(const u32 *key, const u8 *message, size_t message_len, + u8 hash[NH_HASH_BYTES]); + +/* wrapper to avoid indirect call to assembly, which doesn't work with CFI */ +static void _nh_neon(const u32 *key, const u8 *message, size_t message_len, + __le64 hash[NH_NUM_PASSES]) +{ + nh_neon(key, message, message_len, (u8 *)hash); +} + +static int nhpoly1305_neon_update(struct shash_desc *desc, + const u8 *src, unsigned int srclen) +{ + if (srclen < 64 || !may_use_simd()) + return crypto_nhpoly1305_update(desc, src, srclen); + + do { + unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); + + kernel_neon_begin(); + crypto_nhpoly1305_update_helper(desc, src, n, _nh_neon); + kernel_neon_end(); + src += n; + srclen -= n; + } while (srclen); + return 0; +} + +static struct shash_alg nhpoly1305_alg = { + .base.cra_name = "nhpoly1305", + .base.cra_driver_name = "nhpoly1305-neon", + .base.cra_priority = 200, + .base.cra_ctxsize = sizeof(struct nhpoly1305_key), + .base.cra_module = THIS_MODULE, + .digestsize = POLY1305_DIGEST_SIZE, + .init = crypto_nhpoly1305_init, + .update = nhpoly1305_neon_update, + .final = crypto_nhpoly1305_final, + .setkey = crypto_nhpoly1305_setkey, + .descsize = sizeof(struct nhpoly1305_state), +}; + +static int __init nhpoly1305_mod_init(void) +{ + if (!(elf_hwcap & HWCAP_NEON)) + return -ENODEV; + + return crypto_register_shash(&nhpoly1305_alg); +} + +static void __exit nhpoly1305_mod_exit(void) +{ + crypto_unregister_shash(&nhpoly1305_alg); +} + +module_init(nhpoly1305_mod_init); +module_exit(nhpoly1305_mod_exit); + +MODULE_DESCRIPTION("NHPoly1305 ε-almost-∆-universal hash function (NEON-accelerated)"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>"); +MODULE_ALIAS_CRYPTO("nhpoly1305"); +MODULE_ALIAS_CRYPTO("nhpoly1305-neon"); diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index 6821f1249300..772f48ef84b7 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -9,8 +9,6 @@ #include <linux/dma-debug.h> #include <linux/kref.h> -#define ARM_MAPPING_ERROR (~(dma_addr_t)0x0) - struct dma_iommu_mapping { /* iommu specific data */ struct iommu_domain *domain; diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 965b7c846ecb..31d3b96f0f4b 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -18,7 +18,7 @@ extern const struct dma_map_ops arm_coherent_dma_ops; static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) { - return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_direct_ops; + return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : NULL; } #ifdef __arch_page_to_dma diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 231e87ad45d5..35491af87985 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -23,6 +23,10 @@ #define ARM_EXIT_WITH_ABORT_BIT 31 #define ARM_EXCEPTION_CODE(x) ((x) & ~(1U << ARM_EXIT_WITH_ABORT_BIT)) +#define ARM_EXCEPTION_IS_TRAP(x) \ + (ARM_EXCEPTION_CODE((x)) == ARM_EXCEPTION_PREF_ABORT || \ + ARM_EXCEPTION_CODE((x)) == ARM_EXCEPTION_DATA_ABORT || \ + ARM_EXCEPTION_CODE((x)) == ARM_EXCEPTION_HVC) #define ARM_ABORT_PENDING(x) !!((x) & (1U << ARM_EXIT_WITH_ABORT_BIT)) #define ARM_EXCEPTION_RESET 0 diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 5ca5d9af0c26..ca56537b61bc 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -225,7 +225,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu, #define KVM_ARCH_WANT_MMU_NOTIFIER int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end); -void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); +int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); @@ -285,7 +285,7 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot); struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr); -static inline bool kvm_arch_check_sve_has_vhe(void) { return true; } +static inline bool kvm_arch_requires_vhe(void) { return false; } static inline void kvm_arch_hardware_unsetup(void) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {} @@ -296,11 +296,6 @@ static inline void kvm_arm_init_debug(void) {} static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {} static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {} static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {} -static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, - struct kvm_run *run) -{ - return false; -} int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 1098ffc3d54b..3a875fc1b63c 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -82,6 +82,67 @@ void kvm_clear_hyp_idmap(void); #define kvm_mk_pud(pmdp) __pud(__pa(pmdp) | PMD_TYPE_TABLE) #define kvm_mk_pgd(pudp) ({ BUILD_BUG(); 0; }) +#define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot) +#define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot) +#define kvm_pfn_pud(pfn, prot) (__pud(0)) + +#define kvm_pud_pfn(pud) ({ WARN_ON(1); 0; }) + + +#define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd) +/* No support for pud hugepages */ +#define kvm_pud_mkhuge(pud) ( {WARN_ON(1); pud; }) + +/* + * The following kvm_*pud*() functions are provided strictly to allow + * sharing code with arm64. They should never be called in practice. + */ +static inline void kvm_set_s2pud_readonly(pud_t *pud) +{ + WARN_ON(1); +} + +static inline bool kvm_s2pud_readonly(pud_t *pud) +{ + WARN_ON(1); + return false; +} + +static inline void kvm_set_pud(pud_t *pud, pud_t new_pud) +{ + WARN_ON(1); +} + +static inline pud_t kvm_s2pud_mkwrite(pud_t pud) +{ + WARN_ON(1); + return pud; +} + +static inline pud_t kvm_s2pud_mkexec(pud_t pud) +{ + WARN_ON(1); + return pud; +} + +static inline bool kvm_s2pud_exec(pud_t *pud) +{ + WARN_ON(1); + return false; +} + +static inline pud_t kvm_s2pud_mkyoung(pud_t pud) +{ + BUG(); + return pud; +} + +static inline bool kvm_s2pud_young(pud_t pud) +{ + WARN_ON(1); + return false; +} + static inline pte_t kvm_s2pte_mkwrite(pte_t pte) { pte_val(pte) |= L_PTE_S2_RDWR; diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index 9e81b7c498d8..182163b55546 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h @@ -61,4 +61,15 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val); MODULE_ARCH_VERMAGIC_ARMTHUMB \ MODULE_ARCH_VERMAGIC_P2V +#ifdef CONFIG_THUMB2_KERNEL +#define HAVE_ARCH_KALLSYMS_SYMBOL_VALUE +static inline unsigned long kallsyms_symbol_value(const Elf_Sym *sym) +{ + if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) + return sym->st_value & ~1; + + return sym->st_value; +} +#endif + #endif /* _ASM_ARM_MODULE_H */ diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h index ef5f7b69443e..72a20c3a0a90 100644 --- a/arch/arm/include/asm/stackprotector.h +++ b/arch/arm/include/asm/stackprotector.h @@ -6,8 +6,10 @@ * the stack frame and verifying that it hasn't been overwritten when * returning from the function. The pattern is called stack canary * and gcc expects it to be defined by a global variable called - * "__stack_chk_guard" on ARM. This unfortunately means that on SMP - * we cannot have a different canary value per task. + * "__stack_chk_guard" on ARM. This prevents SMP systems from using a + * different value for each task unless we enable a GCC plugin that + * replaces these symbol references with references to each task's own + * value. */ #ifndef _ASM_STACKPROTECTOR_H @@ -16,6 +18,8 @@ #include <linux/random.h> #include <linux/version.h> +#include <asm/thread_info.h> + extern unsigned long __stack_chk_guard; /* @@ -33,7 +37,11 @@ static __always_inline void boot_init_stack_canary(void) canary ^= LINUX_VERSION_CODE; current->stack_canary = canary; +#ifndef CONFIG_STACKPROTECTOR_PER_TASK __stack_chk_guard = current->stack_canary; +#else + current_thread_info()->stack_canary = current->stack_canary; +#endif } #endif /* _ASM_STACKPROTECTOR_H */ diff --git a/arch/arm/include/asm/stage2_pgtable.h b/arch/arm/include/asm/stage2_pgtable.h index f6a7ea805232..c4b1d4fb1797 100644 --- a/arch/arm/include/asm/stage2_pgtable.h +++ b/arch/arm/include/asm/stage2_pgtable.h @@ -68,4 +68,12 @@ stage2_pmd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end) #define stage2_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp) #define stage2_pud_table_empty(kvm, pudp) false +static inline bool kvm_stage2_has_pud(struct kvm *kvm) +{ + return false; +} + +#define S2_PMD_MASK PMD_MASK +#define S2_PMD_SIZE PMD_SIZE + #endif /* __ARM_S2_PGTABLE_H_ */ diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 8f55dc520a3e..286eb61c632b 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -53,6 +53,9 @@ struct thread_info { struct task_struct *task; /* main task structure */ __u32 cpu; /* cpu */ __u32 cpu_domain; /* cpu domain */ +#ifdef CONFIG_STACKPROTECTOR_PER_TASK + unsigned long stack_canary; +#endif struct cpu_context_save cpu_context; /* cpu context */ __u32 syscall; /* syscall number */ __u8 used_cp[16]; /* thread used copro */ diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 3968d6c22455..28b27104ac0c 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -79,6 +79,10 @@ int main(void) #ifdef CONFIG_CRUNCH DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate)); #endif +#ifdef CONFIG_STACKPROTECTOR_PER_TASK + DEFINE(TI_STACK_CANARY, offsetof(struct thread_info, stack_canary)); +#endif + DEFINE(THREAD_SZ_ORDER, THREAD_SIZE_ORDER); BLANK(); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0)); DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1)); diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 82ab015bf42b..16601d1442d1 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -39,7 +39,7 @@ #include <asm/tls.h> #include <asm/vdso.h> -#ifdef CONFIG_STACKPROTECTOR +#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include <linux/stackprotector.h> unsigned long __stack_chk_guard __read_mostly; EXPORT_SYMBOL(__stack_chk_guard); @@ -267,6 +267,10 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, thread_notify(THREAD_NOTIFY_COPY, thread); +#ifdef CONFIG_STACKPROTECTOR_PER_TASK + thread->stack_canary = p->stack_canary; +#endif + return 0; } diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index cb094e55dc5f..222c1635bc7a 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -602,8 +602,8 @@ static int emulate_cp15(struct kvm_vcpu *vcpu, } } else { /* If access function fails, it should complain. */ - kvm_err("Unsupported guest CP15 access at: %08lx\n", - *vcpu_pc(vcpu)); + kvm_err("Unsupported guest CP15 access at: %08lx [%08lx]\n", + *vcpu_pc(vcpu), *vcpu_cpsr(vcpu)); print_cp_instr(params); kvm_inject_undefined(vcpu); } diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 8143756ff38b..09e439d4abf5 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -794,9 +794,9 @@ static __init void dm365_evm_init(void) /* maybe setup mmc1/etc ... _after_ mmc0 */ evm_init_cpld(); -#ifdef CONFIG_SND_DM365_AIC3X_CODEC +#ifdef CONFIG_SND_SOC_DM365_AIC3X_CODEC dm365_init_asp(); -#elif defined(CONFIG_SND_DM365_VOICE_CODEC) +#elif defined(CONFIG_SND_SOC_DM365_VOICE_CODEC) dm365_init_vc(); #endif dm365_init_rtc(); diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 41aa57581356..80ccb984d521 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -25,6 +25,7 @@ #include <linux/platform_data/video-ep93xx.h> #include <linux/platform_data/spi-ep93xx.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <mach/gpio-ep93xx.h> @@ -45,9 +46,15 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = { static struct mmc_spi_platform_data simone_mmc_spi_data = { .detect_delay = 500, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .flags = MMC_SPI_USE_CD_GPIO, - .cd_gpio = EP93XX_GPIO_LINE_EGPIO0, - .cd_debounce = 1, +}; + +static struct gpiod_lookup_table simone_mmc_spi_gpio_table = { + .dev_id = "mmc_spi.0", /* "mmc_spi" @ CS0 */ + .table = { + /* Card detect */ + GPIO_LOOKUP_IDX("A", 0, NULL, 0, GPIO_ACTIVE_LOW), + { }, + }, }; static struct spi_board_info simone_spi_devices[] __initdata = { @@ -105,6 +112,7 @@ static void __init simone_init_machine(void) ep93xx_register_fb(&simone_fb_info); ep93xx_register_i2c(simone_i2c_board_info, ARRAY_SIZE(simone_i2c_board_info)); + gpiod_add_lookup_table(&simone_mmc_spi_gpio_table); ep93xx_register_spi(&simone_spi_info, simone_spi_devices, ARRAY_SIZE(simone_spi_devices)); simone_register_audio(); diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 5a0b6187990a..767ee64628dc 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/fb.h> #include <linux/io.h> #include <linux/mtd/partitions.h> @@ -202,13 +203,20 @@ static struct mmc_spi_platform_data vision_spi_mmc_data = { .detect_delay = 100, .powerup_msecs = 100, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, - .cd_gpio = EP93XX_GPIO_LINE_EGPIO15, - .cd_debounce = 1, - .ro_gpio = EP93XX_GPIO_LINE_F(0), .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, }; +static struct gpiod_lookup_table vision_spi_mmc_gpio_table = { + .dev_id = "mmc_spi.2", /* "mmc_spi @ CS2 */ + .table = { + /* Card detect */ + GPIO_LOOKUP_IDX("B", 7, NULL, 0, GPIO_ACTIVE_LOW), + /* Write protect */ + GPIO_LOOKUP_IDX("F", 0, NULL, 1, GPIO_ACTIVE_HIGH), + { }, + }, +}; + /************************************************************************* * SPI Bus *************************************************************************/ @@ -286,6 +294,7 @@ static void __init vision_init_machine(void) ep93xx_register_i2c(vision_i2c_info, ARRAY_SIZE(vision_i2c_info)); + gpiod_add_lookup_table(&vision_spi_mmc_gpio_table); ep93xx_register_spi(&vision_spi_master, vision_spi_board_info, ARRAY_SIZE(vision_spi_board_info)); vision_register_i2s(); diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c index 243a108a940b..fd0053e47a15 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -110,7 +110,7 @@ int __init imx6sx_cpuidle_init(void) * except for power up sw2iso which need to be * larger than LDO ramp up time. */ - imx_gpc_set_arm_power_up_timing(2, 1); + imx_gpc_set_arm_power_up_timing(0xf, 1); imx_gpc_set_arm_power_down_timing(1, 1); return cpuidle_register(&imx6sx_cpuidle_driver, NULL); diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index e595e5368676..46ba3348e8f0 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c @@ -20,6 +20,7 @@ #include <linux/mtd/plat-ram.h> #include <linux/memory.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/smc911x.h> #include <linux/interrupt.h> #include <linux/delay.h> @@ -214,8 +215,6 @@ static const iomux_v3_cfg_t pcm043_pads[] __initconst = { #define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31) #define AC97_GPIO_TXD IMX_GPIO_NR(2, 28) #define AC97_GPIO_RESET IMX_GPIO_NR(2, 0) -#define SD1_GPIO_WP IMX_GPIO_NR(2, 23) -#define SD1_GPIO_CD IMX_GPIO_NR(2, 24) static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97) { @@ -341,12 +340,21 @@ static int __init pcm043_otg_mode(char *options) __setup("otg_mode=", pcm043_otg_mode); static struct esdhc_platform_data sd1_pdata = { - .wp_gpio = SD1_GPIO_WP, - .cd_gpio = SD1_GPIO_CD, .wp_type = ESDHC_WP_GPIO, .cd_type = ESDHC_CD_GPIO, }; +static struct gpiod_lookup_table sd1_gpio_table = { + .dev_id = "sdhci-esdhc-imx35.0", + .table = { + /* Card detect: bank 2 offset 24 */ + GPIO_LOOKUP("imx35-gpio.2", 24, "cd", GPIO_ACTIVE_LOW), + /* Write protect: bank 2 offset 23 */ + GPIO_LOOKUP("imx35-gpio.2", 23, "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + /* * Board specific initialization. */ @@ -391,6 +399,7 @@ static void __init pcm043_late_init(void) { imx35_add_imx_ssi(0, &pcm043_ssi_pdata); + gpiod_add_lookup_table(&sd1_gpio_table); imx35_add_sdhci_esdhc_imx(0, &sd1_pdata); } diff --git a/arch/arm/mach-mmp/cputype.h b/arch/arm/mach-mmp/cputype.h index 446edaeb78a7..a96abcf521b4 100644 --- a/arch/arm/mach-mmp/cputype.h +++ b/arch/arm/mach-mmp/cputype.h @@ -44,10 +44,12 @@ static inline int cpu_is_pxa910(void) #define cpu_is_pxa910() (0) #endif -#ifdef CONFIG_CPU_MMP2 +#if defined(CONFIG_CPU_MMP2) || defined(CONFIG_MACH_MMP2_DT) static inline int cpu_is_mmp2(void) { - return (((read_cpuid_id() >> 8) & 0xff) == 0x58); + return (((read_cpuid_id() >> 8) & 0xff) == 0x58) && + (((mmp_chip_id & 0xfff) == 0x410) || + ((mmp_chip_id & 0xfff) == 0x610)); } #else #define cpu_is_mmp2() (0) diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index e8ccf51c6f29..a7e9c6d19fb5 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -8,7 +8,7 @@ obj-y := io.o id.o sram-init.o sram.o time.o irq.o mux.o flash.o \ serial.o devices.o dma.o fb.o obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o -ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) +ifneq ($(CONFIG_SND_SOC_OMAP_MCBSP),) obj-y += mcbsp.o endif diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index b0dc7ddf5877..0324d0f209ea 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c @@ -103,7 +103,7 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip, } for (i = 0; i < ARRAY_SIZE(irq_data); i++) { - gpiod = gpiochip_request_own_desc(chip, i, pin_name[i]); + gpiod = gpiochip_request_own_desc(chip, i, pin_name[i], 0); if (IS_ERR(gpiod)) { pr_err("%s: failed to get GPIO pin %d (%ld)\n", __func__, i, PTR_ERR(gpiod)); diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 17886744dbe6..49e3adffbf5b 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -296,23 +296,13 @@ struct modem_private_data { static struct modem_private_data modem_priv; -static struct resource ams_delta_nand_resources[] = { - [0] = { - .start = OMAP1_MPUIO_BASE, - .end = OMAP1_MPUIO_BASE + - OMAP_MPUIO_IO_CNTL + sizeof(u32) - 1, - .flags = IORESOURCE_MEM, - }, -}; - static struct platform_device ams_delta_nand_device = { .name = "ams-delta-nand", .id = -1, - .num_resources = ARRAY_SIZE(ams_delta_nand_resources), - .resource = ams_delta_nand_resources, }; -#define OMAP_GPIO_LABEL "gpio-0-15" +#define OMAP_GPIO_LABEL "gpio-0-15" +#define OMAP_MPUIO_LABEL "mpuio" static struct gpiod_lookup_table ams_delta_nand_gpio_table = { .table = { @@ -324,6 +314,14 @@ static struct gpiod_lookup_table ams_delta_nand_gpio_table = { GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 0), GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0), GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 0, "data", 0, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 1, "data", 1, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 2, "data", 2, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 3, "data", 3, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 4, "data", 4, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 5, "data", 5, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 6, "data", 6, 0), + GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 7, "data", 7, 0), { }, }, }; @@ -603,7 +601,7 @@ static void __init modem_assign_irq(struct gpio_chip *chip) struct gpio_desc *gpiod; gpiod = gpiochip_request_own_desc(chip, AMS_DELTA_GPIO_PIN_MODEM_IRQ, - "modem_irq"); + "modem_irq", 0); if (IS_ERR(gpiod)) { pr_err("%s: modem IRQ GPIO request failed (%ld)\n", __func__, PTR_ERR(gpiod)); @@ -811,7 +809,7 @@ static void __init ams_delta_led_init(struct gpio_chip *chip) int i; for (i = LATCH1_PIN_LED_CAMERA; i < LATCH1_PIN_DOCKIT1; i++) { - gpiod = gpiochip_request_own_desc(chip, i, NULL); + gpiod = gpiochip_request_own_desc(chip, i, "camera-led", 0); if (IS_ERR(gpiod)) { pr_warn("%s: %s GPIO %d request failed (%ld)\n", __func__, LATCH1_LABEL, i, PTR_ERR(gpiod)); diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 01377c292db4..899c60fac159 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common) obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common) obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common) -ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) +ifneq ($(CONFIG_SND_SOC_OMAP_MCBSP),) obj-y += mcbsp.o endif diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 9fec5f84bf77..8a5b6ed4ec36 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -524,7 +524,7 @@ void omap_auxdata_legacy_init(struct device *dev) dev->platform_data = &twl_gpio_auxdata; } -#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP) +#if IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP) static struct omap_mcbsp_platform_data mcbsp_pdata; static void __init omap3_mcbsp_init(void) { @@ -572,7 +572,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", &am35xx_emac_pdata), /* McBSP modules with sidetone core */ -#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP) +#if IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP) OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49022000, "49022000.mcbsp", &mcbsp_pdata), OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49024000, "49024000.mcbsp", &mcbsp_pdata), #endif diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index c52c081eb6d9..4bcbd3d55b36 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -290,9 +290,6 @@ static unsigned long balloon3_mmc_pin_config[] __initdata = { static struct pxamci_platform_data balloon3_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, .detect_delay_ms = 200, }; diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index be4a66166d61..f7081a50dc67 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -12,6 +12,7 @@ #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/delay.h> #include <linux/platform_data/rtc-v3020.h> @@ -288,14 +289,23 @@ static inline void cmx270_init_ohci(void) {} #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) static struct pxamci_platform_data cmx270_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = GPIO83_MMC_IRQ, - .gpio_card_ro = -1, - .gpio_power = GPIO105_MMC_POWER, - .gpio_power_invert = 1, +}; + +static struct gpiod_lookup_table cmx270_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 83 */ + GPIO_LOOKUP("gpio-pxa", GPIO83_MMC_IRQ, "cd", GPIO_ACTIVE_LOW), + /* Power on GPIO 105 */ + GPIO_LOOKUP("gpio-pxa", GPIO105_MMC_POWER, + "power", GPIO_ACTIVE_LOW), + { }, + }, }; static void __init cmx270_init_mmc(void) { + gpiod_add_lookup_table(&cmx270_mci_gpio_table); pxa_set_mci_info(&cmx270_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index c5c0ab8ac9f9..109fab292f94 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -459,9 +459,17 @@ static inline void cm_x300_init_nand(void) {} static struct pxamci_platform_data cm_x300_mci_platform_data = { .detect_delay_ms = 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = GPIO82_MMC_IRQ, - .gpio_card_ro = GPIO85_MMC_WP, - .gpio_power = -1, +}; + +static struct gpiod_lookup_table cm_x300_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 82 */ + GPIO_LOOKUP("gpio-pxa", GPIO82_MMC_IRQ, "cd", GPIO_ACTIVE_LOW), + /* Write protect on GPIO 85 */ + GPIO_LOOKUP("gpio-pxa", GPIO85_MMC_WP, "wp", GPIO_ACTIVE_LOW), + { }, + }, }; /* The second MMC slot of CM-X300 is hardwired to Libertas card and has @@ -482,13 +490,11 @@ static struct pxamci_platform_data cm_x300_mci2_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .init = cm_x300_mci2_init, .exit = cm_x300_mci2_exit, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static void __init cm_x300_init_mmc(void) { + gpiod_add_lookup_table(&cm_x300_mci_gpio_table); pxa_set_mci_info(&cm_x300_mci_platform_data); pxa3xx_set_mci2_info(&cm_x300_mci2_platform_data); } diff --git a/arch/arm/mach-pxa/colibri-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c index 10e2278b7a28..2ccdef5de138 100644 --- a/arch/arm/mach-pxa/colibri-evalboard.c +++ b/arch/arm/mach-pxa/colibri-evalboard.c @@ -14,7 +14,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/interrupt.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <asm/mach-types.h> #include <mach/hardware.h> #include <asm/mach/arch.h> @@ -37,22 +37,44 @@ #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data colibri_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_power = -1, - .gpio_card_ro = -1, .detect_delay_ms = 200, }; +static struct gpiod_lookup_table colibri_pxa270_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO0_COLIBRI_PXA270_SD_DETECT, + "cd", GPIO_ACTIVE_LOW), + { }, + }, +}; + +static struct gpiod_lookup_table colibri_pxa300_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO13_COLIBRI_PXA300_SD_DETECT, + "cd", GPIO_ACTIVE_LOW), + { }, + }, +}; + +static struct gpiod_lookup_table colibri_pxa320_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO28_COLIBRI_PXA320_SD_DETECT, + "cd", GPIO_ACTIVE_LOW), + { }, + }, +}; + static void __init colibri_mmc_init(void) { if (machine_is_colibri()) /* PXA270 Colibri */ - colibri_mci_platform_data.gpio_card_detect = - GPIO0_COLIBRI_PXA270_SD_DETECT; + gpiod_add_lookup_table(&colibri_pxa270_mci_gpio_table); if (machine_is_colibri300()) /* PXA300 Colibri */ - colibri_mci_platform_data.gpio_card_detect = - GPIO13_COLIBRI_PXA300_SD_DETECT; + gpiod_add_lookup_table(&colibri_pxa300_mci_gpio_table); else /* PXA320 Colibri */ - colibri_mci_platform_data.gpio_card_detect = - GPIO28_COLIBRI_PXA320_SD_DETECT; + gpiod_add_lookup_table(&colibri_pxa320_mci_gpio_table); pxa_set_mci_info(&colibri_mci_platform_data); } diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index 3ccf2a95569b..d203dd30cdd0 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -14,7 +14,7 @@ #include <linux/bitops.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/leds.h> @@ -51,14 +51,25 @@ #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data income_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_power = -1, - .gpio_card_detect = GPIO0_INCOME_SD_DETECT, - .gpio_card_ro = GPIO0_INCOME_SD_RO, .detect_delay_ms = 200, }; +static struct gpiod_lookup_table income_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 0 */ + GPIO_LOOKUP("gpio-pxa", GPIO0_INCOME_SD_DETECT, + "cd", GPIO_ACTIVE_LOW), + /* Write protect on GPIO 1 */ + GPIO_LOOKUP("gpio-pxa", GPIO0_INCOME_SD_RO, + "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + static void __init income_mmc_init(void) { + gpiod_add_lookup_table(&income_mci_gpio_table); pxa_set_mci_info(&income_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 9a5a35e90769..c9732cace5e3 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -24,6 +24,7 @@ #include <linux/mtd/physmap.h> #include <linux/pm.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/backlight.h> #include <linux/i2c.h> #include <linux/platform_data/i2c-pxa.h> @@ -493,11 +494,23 @@ static struct platform_device corgi_audio_device = { static struct pxamci_platform_data corgi_mci_platform_data = { .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = CORGI_GPIO_nSD_DETECT, - .gpio_card_ro = CORGI_GPIO_nSD_WP, - .gpio_power = CORGI_GPIO_SD_PWR, }; +static struct gpiod_lookup_table corgi_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 9 */ + GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_nSD_DETECT, + "cd", GPIO_ACTIVE_LOW), + /* Write protect on GPIO 7 */ + GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_nSD_WP, + "wp", GPIO_ACTIVE_LOW), + /* Power on GPIO 33 */ + GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_SD_PWR, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; /* * Irda @@ -731,6 +744,7 @@ static void __init corgi_init(void) corgi_init_spi(); pxa_set_udc_info(&udc_info); + gpiod_add_lookup_table(&corgi_mci_gpio_table); pxa_set_mci_info(&corgi_mci_platform_data); pxa_set_ficp_info(&corgi_ficp_platform_data); pxa_set_i2c_info(NULL); diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index 271aedae7542..e26e7e60a169 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -11,7 +11,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/platform_device.h> #include <linux/mtd/physmap.h> #include <linux/mtd/partitions.h> @@ -129,9 +129,19 @@ static struct pxamci_platform_data csb726_mci = { .detect_delay_ms = 500, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, /* FIXME setpower */ - .gpio_card_detect = CSB726_GPIO_MMC_DETECT, - .gpio_card_ro = CSB726_GPIO_MMC_RO, - .gpio_power = -1, +}; + +static struct gpiod_lookup_table csb726_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 100 */ + GPIO_LOOKUP("gpio-pxa", CSB726_GPIO_MMC_DETECT, + "cd", GPIO_ACTIVE_LOW), + /* Write protect on GPIO 101 */ + GPIO_LOOKUP("gpio-pxa", CSB726_GPIO_MMC_RO, + "wp", GPIO_ACTIVE_LOW), + { }, + }, }; static struct pxaohci_platform_data csb726_ohci_platform_data = { @@ -264,6 +274,7 @@ static void __init csb726_init(void) pxa_set_stuart_info(NULL); pxa_set_i2c_info(NULL); pxa27x_set_i2c_power_info(NULL); + gpiod_add_lookup_table(&csb726_mci_gpio_table); pxa_set_mci_info(&csb726_mci); pxa_set_ohci_info(&csb726_ohci_platform_data); pxa_set_ac97_info(NULL); diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 67e37df637f5..32c1edeb3f14 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -20,6 +20,7 @@ #include <linux/input.h> #include <linux/gpio_keys.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/mfd/da903x.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> @@ -546,6 +547,15 @@ static inline void em_x270_init_ohci(void) {} #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) static struct regulator *em_x270_sdio_ldo; +static struct gpiod_lookup_table em_x270_mci_wp_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Write protect on GPIO 95 */ + GPIO_LOOKUP("gpio-pxa", GPIO95_MMC_WP, "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + static int em_x270_mci_init(struct device *dev, irq_handler_t em_x270_detect_int, void *data) @@ -567,15 +577,7 @@ static int em_x270_mci_init(struct device *dev, goto err_irq; } - if (machine_is_em_x270()) { - err = gpio_request(GPIO95_MMC_WP, "MMC WP"); - if (err) { - dev_err(dev, "can't request MMC write protect: %d\n", - err); - goto err_gpio_wp; - } - gpio_direction_input(GPIO95_MMC_WP); - } else { + if (!machine_is_em_x270()) { err = gpio_request(GPIO38_SD_PWEN, "sdio power"); if (err) { dev_err(dev, "can't request MMC power control : %d\n", @@ -615,17 +617,10 @@ static void em_x270_mci_exit(struct device *dev, void *data) free_irq(gpio_to_irq(mmc_cd), data); regulator_put(em_x270_sdio_ldo); - if (machine_is_em_x270()) - gpio_free(GPIO95_MMC_WP); - else + if (!machine_is_em_x270()) gpio_free(GPIO38_SD_PWEN); } -static int em_x270_mci_get_ro(struct device *dev) -{ - return gpio_get_value(GPIO95_MMC_WP); -} - static struct pxamci_platform_data em_x270_mci_platform_data = { .detect_delay_ms = 250, .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23| @@ -635,15 +630,12 @@ static struct pxamci_platform_data em_x270_mci_platform_data = { .init = em_x270_mci_init, .setpower = em_x270_mci_setpower, .exit = em_x270_mci_exit, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static void __init em_x270_init_mmc(void) { if (machine_is_em_x270()) - em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro; + gpiod_add_lookup_table(&em_x270_mci_wp_gpio_table); pxa_set_mci_info(&em_x270_mci_platform_data); } diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 9c5b2fb054f9..4764acca5480 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -90,9 +90,6 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_MMC_PXA static struct pxamci_platform_data gumstix_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static void __init gumstix_mmc_init(void) diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 88e0068f92a8..7bfc246a1d75 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -160,9 +160,6 @@ static struct pxafb_mach_info sharp_lm8v31 = { static struct pxamci_platform_data idp_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static void __init idp_init(void) diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 9e132b3e48c6..8e0b60a33026 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -20,7 +20,7 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/clk.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/spi/spi.h> #include <linux/spi/pxa2xx_spi.h> #include <linux/smc91x.h> @@ -51,8 +51,6 @@ #include "generic.h" -#define GPIO_MMC1_CARD_DETECT mfp_to_gpio(MFP_PIN_GPIO15) - /* Littleton MFP configurations */ static mfp_cfg_t littleton_mfp_cfg[] __initdata = { /* LCD */ @@ -278,13 +276,21 @@ static inline void littleton_init_keypad(void) {} static struct pxamci_platform_data littleton_mci_platform_data = { .detect_delay_ms = 200, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_card_detect = GPIO_MMC1_CARD_DETECT, - .gpio_card_ro = -1, - .gpio_power = -1, +}; + +static struct gpiod_lookup_table littleton_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on MFP (gpio-pxa) GPIO 15 */ + GPIO_LOOKUP("gpio-pxa", MFP_PIN_GPIO15, + "cd", GPIO_ACTIVE_LOW), + { }, + }, }; static void __init littleton_init_mmc(void) { + gpiod_add_lookup_table(&littleton_mci_gpio_table); pxa_set_mci_info(&littleton_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index fe2ef9b78602..c576e8462043 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -440,9 +440,6 @@ static struct pxamci_platform_data lubbock_mci_platform_data = { .init = lubbock_mci_init, .get_ro = lubbock_mci_get_ro, .exit = lubbock_mci_exit, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static void lubbock_irda_transceiver_mode(struct device *dev, int mode) diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 14c0f80bc9e7..08b079653c3f 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -775,12 +775,31 @@ static struct pxamci_platform_data magician_mci_info = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .init = magician_mci_init, .exit = magician_mci_exit, - .gpio_card_detect = -1, - .gpio_card_ro = EGPIO_MAGICIAN_nSD_READONLY, .gpio_card_ro_invert = 1, - .gpio_power = EGPIO_MAGICIAN_SD_POWER, }; +/* + * Write protect on EGPIO register 5 index 4, this is on the second HTC + * EGPIO chip which starts at register 4, so we need offset 8+4=12 on that + * particular chip. + */ +#define EGPIO_MAGICIAN_nSD_READONLY_OFFSET 12 +/* + * Power on EGPIO register 2 index 0, so this is on the first HTC EGPIO chip + * starting at register 0 so we need offset 2*8+0 = 16 on that chip. + */ +#define EGPIO_MAGICIAN_nSD_POWER_OFFSET 16 + +static struct gpiod_lookup_table magician_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("htc-egpio-1", EGPIO_MAGICIAN_nSD_READONLY_OFFSET, + "wp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("htc-egpio-0", EGPIO_MAGICIAN_nSD_POWER_OFFSET, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; /* * USB OHCI @@ -979,6 +998,7 @@ static void __init magician_init(void) i2c_register_board_info(1, ARRAY_AND_SIZE(magician_pwr_i2c_board_info)); + gpiod_add_lookup_table(&magician_mci_gpio_table); pxa_set_mci_info(&magician_mci_info); pxa_set_ohci_info(&magician_ohci_info); pxa_set_udc_info(&magician_udc_info); diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index afd62a94fdbf..9e39fc2ad2d9 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -361,9 +361,6 @@ static struct pxamci_platform_data mainstone_mci_platform_data = { .init = mainstone_mci_init, .setpower = mainstone_mci_setpower, .exit = mainstone_mci_exit, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static void mainstone_irda_transceiver_mode(struct device *dev, int mode) diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 04dc78d0809f..d0fa5c72622d 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -31,6 +31,7 @@ #include <linux/rtc.h> #include <linux/leds.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/pda_power.h> @@ -397,9 +398,22 @@ struct gpio_vbus_mach_info gpio_vbus_data = { static struct pxamci_platform_data mioa701_mci_info = { .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_card_detect = GPIO15_SDIO_INSERT, - .gpio_card_ro = GPIO78_SDIO_RO, - .gpio_power = GPIO91_SDIO_EN, +}; + +static struct gpiod_lookup_table mioa701_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 15 */ + GPIO_LOOKUP("gpio-pxa", GPIO15_SDIO_INSERT, + "cd", GPIO_ACTIVE_LOW), + /* Write protect on GPIO 78 */ + GPIO_LOOKUP("gpio-pxa", GPIO78_SDIO_RO, + "wp", GPIO_ACTIVE_LOW), + /* Power on GPIO 91 */ + GPIO_LOOKUP("gpio-pxa", GPIO91_SDIO_EN, + "power", GPIO_ACTIVE_HIGH), + { }, + }, }; /* FlashRAM */ @@ -743,6 +757,7 @@ static void __init mioa701_machine_init(void) pr_err("MioA701: Failed to request GPIOs: %d", rc); bootstrap_init(); pxa_set_fb_info(NULL, &mioa701_pxafb_info); + gpiod_add_lookup_table(&mioa701_mci_gpio_table); pxa_set_mci_info(&mioa701_mci_info); pxa_set_keypad_info(&mioa701_keypad_info); pxa_set_udc_info(&mioa701_udc_info); diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index 616b22397d73..e4248a3a8dfc 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c @@ -21,7 +21,7 @@ #include <linux/serial_8250.h> #include <linux/dm9000.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/platform_data/i2c-pxa.h> #include <linux/platform_data/mtd-nand-pxa3xx.h> @@ -326,13 +326,24 @@ static mfp_cfg_t mfp_cfg[] __initdata = { static struct pxamci_platform_data mxm_8x10_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .detect_delay_ms = 10, - .gpio_card_detect = MXM_8X10_SD_nCD, - .gpio_card_ro = MXM_8X10_SD_WP, - .gpio_power = -1 +}; + +static struct gpiod_lookup_table mxm_8x10_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + /* Card detect on GPIO 72 */ + GPIO_LOOKUP("gpio-pxa", MXM_8X10_SD_nCD, + "cd", GPIO_ACTIVE_LOW), + /* Write protect on GPIO 84 */ + GPIO_LOOKUP("gpio-pxa", MXM_8X10_SD_WP, + "wp", GPIO_ACTIVE_LOW), + { }, + }, }; void __init mxm_8x10_mmc_init(void) { + gpiod_add_lookup_table(&mxm_8x10_mci_gpio_table); pxa_set_mci_info(&mxm_8x10_mci_platform_data); } #endif diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 1efe9bcf07fa..b94c45f65215 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -49,14 +49,10 @@ static struct pxamci_platform_data palm27x_mci_platform_data = { .detect_delay_ms = 200, }; -void __init palm27x_mmc_init(int detect, int ro, int power, - int power_inverted) +void __init palm27x_mmc_init(struct gpiod_lookup_table *gtable) { - palm27x_mci_platform_data.gpio_card_detect = detect; - palm27x_mci_platform_data.gpio_card_ro = ro; - palm27x_mci_platform_data.gpio_power = power; - palm27x_mci_platform_data.gpio_power_invert = power_inverted; - + if (gtable) + gpiod_add_lookup_table(gtable); pxa_set_mci_info(&palm27x_mci_platform_data); } #endif diff --git a/arch/arm/mach-pxa/palm27x.h b/arch/arm/mach-pxa/palm27x.h index d4eac3d6ffb5..cd071f876132 100644 --- a/arch/arm/mach-pxa/palm27x.h +++ b/arch/arm/mach-pxa/palm27x.h @@ -12,12 +12,12 @@ #ifndef __INCLUDE_MACH_PALM27X__ #define __INCLUDE_MACH_PALM27X__ +#include <linux/gpio/machine.h> + #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) -extern void __init palm27x_mmc_init(int detect, int ro, int power, - int power_inverted); +extern void __init palm27x_mmc_init(struct gpiod_lookup_table *gtable); #else -static inline void palm27x_mmc_init(int detect, int ro, int power, - int power_inverted) +static inline void palm27x_mmc_init(struct gpiod_lookup_table *gtable) {} #endif diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 980f2847f5b5..bf2b0cfc86df 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -288,8 +288,20 @@ static struct platform_device palmld_ide_device = { .id = -1, }; +static struct gpiod_lookup_table palmld_ide_gpio_table = { + .dev_id = "pata_palmld", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_IDE_PWEN, + "power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_IDE_RESET, + "reset", GPIO_ACTIVE_LOW), + { }, + }, +}; + static void __init palmld_ide_init(void) { + gpiod_add_lookup_table(&palmld_ide_gpio_table); platform_device_register(&palmld_ide_device); } #else @@ -320,6 +332,19 @@ static void __init palmld_map_io(void) iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc)); } +static struct gpiod_lookup_table palmld_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_SD_POWER, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init palmld_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config)); @@ -327,8 +352,7 @@ static void __init palmld_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - palm27x_mmc_init(GPIO_NR_PALMLD_SD_DETECT_N, GPIO_NR_PALMLD_SD_READONLY, - GPIO_NR_PALMLD_SD_POWER, 0); + palm27x_mmc_init(&palmld_mci_gpio_table); palm27x_pm_init(PALMLD_STR_BASE); palm27x_lcd_init(-1, &palm_320x480_lcd_mode); palm27x_irda_init(GPIO_NR_PALMLD_IR_DISABLE); diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 876144aa3564..8811f11f670e 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -182,6 +182,19 @@ static void __init palmt5_reserve(void) memblock_reserve(0xa0200000, 0x1000); } +static struct gpiod_lookup_table palmt5_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMT5_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMT5_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMT5_SD_POWER, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init palmt5_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config)); @@ -189,8 +202,7 @@ static void __init palmt5_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - palm27x_mmc_init(GPIO_NR_PALMT5_SD_DETECT_N, GPIO_NR_PALMT5_SD_READONLY, - GPIO_NR_PALMT5_SD_POWER, 0); + palm27x_mmc_init(&palmt5_mci_gpio_table); palm27x_pm_init(PALMT5_STR_BASE); palm27x_lcd_init(-1, &palm_320x480_lcd_mode); palm27x_udc_init(GPIO_NR_PALMT5_USB_DETECT_N, diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 18946594a7c8..7ce4fc287115 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -20,7 +20,7 @@ #include <linux/input.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/input/matrix_keypad.h> #include <linux/ucb1400.h> #include <linux/power_supply.h> @@ -120,14 +120,25 @@ static unsigned long palmtc_pin_config[] __initdata = { #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data palmtc_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_power = GPIO_NR_PALMTC_SD_POWER, - .gpio_card_ro = GPIO_NR_PALMTC_SD_READONLY, - .gpio_card_detect = GPIO_NR_PALMTC_SD_DETECT_N, .detect_delay_ms = 200, }; +static struct gpiod_lookup_table palmtc_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_SD_POWER, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init palmtc_mmc_init(void) { + gpiod_add_lookup_table(&palmtc_mci_gpio_table); pxa_set_mci_info(&palmtc_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 36b46141a28b..e830005af8d0 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -19,6 +19,7 @@ #include <linux/delay.h> #include <linux/irq.h> #include <linux/gpio_keys.h> +#include <linux/gpio/machine.h> #include <linux/input.h> #include <linux/pda_power.h> #include <linux/pwm.h> @@ -101,9 +102,19 @@ static unsigned long palmte2_pin_config[] __initdata = { ******************************************************************************/ static struct pxamci_platform_data palmte2_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_card_detect = GPIO_NR_PALMTE2_SD_DETECT_N, - .gpio_card_ro = GPIO_NR_PALMTE2_SD_READONLY, - .gpio_power = GPIO_NR_PALMTE2_SD_POWER, +}; + +static struct gpiod_lookup_table palmte2_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_SD_POWER, + "power", GPIO_ACTIVE_HIGH), + { }, + }, }; #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) @@ -354,6 +365,7 @@ static void __init palmte2_init(void) pxa_set_stuart_info(NULL); pxa_set_fb_info(NULL, &palmte2_lcd_screen); + gpiod_add_lookup_table(&palmte2_mci_gpio_table); pxa_set_mci_info(&palmte2_mci_platform_data); palmte2_udc_init(); pxa_set_ac97_info(&palmte2_ac97_pdata); diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index b66b0b11d717..70f1a8a3aa94 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -480,23 +480,46 @@ void __init treo680_gpio_init(void) gpio_free(GPIO_NR_TREO680_LCD_EN_N); } +static struct gpiod_lookup_table treo680_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO680_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO680_SD_POWER, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init treo680_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config)); palmphone_common_init(); treo680_gpio_init(); - palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY, - GPIO_NR_TREO680_SD_POWER, 0); + palm27x_mmc_init(&treo680_mci_gpio_table); } #endif #ifdef CONFIG_MACH_CENTRO + +static struct gpiod_lookup_table centro685_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_CENTRO_SD_POWER, + "power", GPIO_ACTIVE_LOW), + { }, + }, +}; + static void __init centro_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config)); palmphone_common_init(); - palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, -1, - GPIO_NR_CENTRO_SD_POWER, 1); + palm27x_mmc_init(¢ro685_mci_gpio_table); } #endif diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 1d06a8e91d8f..ef71bf2abb47 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -337,6 +337,19 @@ static void __init palmtx_map_io(void) iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc)); } +static struct gpiod_lookup_table palmtx_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTX_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTX_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTX_SD_POWER, + "power", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init palmtx_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config)); @@ -344,8 +357,7 @@ static void __init palmtx_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - palm27x_mmc_init(GPIO_NR_PALMTX_SD_DETECT_N, GPIO_NR_PALMTX_SD_READONLY, - GPIO_NR_PALMTX_SD_POWER, 0); + palm27x_mmc_init(&palmtx_mci_gpio_table); palm27x_pm_init(PALMTX_STR_BASE); palm27x_lcd_init(-1, &palm_320x480_lcd_mode); palm27x_udc_init(GPIO_NR_PALMTX_USB_DETECT_N, diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index 4d475f6f4a77..ea1c7b2ed8d4 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -386,6 +386,19 @@ static void __init palmz72_camera_init(void) static inline void palmz72_camera_init(void) {} #endif +static struct gpiod_lookup_table palmz72_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMZ72_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMZ72_SD_RO, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMZ72_SD_POWER_N, + "power", GPIO_ACTIVE_LOW), + { }, + }, +}; + /****************************************************************************** * Machine init ******************************************************************************/ @@ -396,8 +409,7 @@ static void __init palmz72_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - palm27x_mmc_init(GPIO_NR_PALMZ72_SD_DETECT_N, GPIO_NR_PALMZ72_SD_RO, - GPIO_NR_PALMZ72_SD_POWER_N, 1); + palm27x_mmc_init(&palmz72_mci_gpio_table); palm27x_lcd_init(-1, &palm_320x320_lcd_mode); palm27x_udc_init(GPIO_NR_PALMZ72_USB_DETECT_N, GPIO_NR_PALMZ72_USB_PULLUP, 0); diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 973568d4b9ec..be19e3a4eacc 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -370,9 +370,6 @@ static struct pxamci_platform_data pcm990_mci_platform_data = { .init = pcm990_mci_init, .setpower = pcm990_mci_setpower, .exit = pcm990_mci_exit, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static struct pxaohci_platform_data pcm990_ohci_platform_data = { diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 1adde1251e2b..c2a43d4cfd3e 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -23,6 +23,7 @@ #include <linux/delay.h> #include <linux/mtd/physmap.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/i2c.h> #include <linux/platform_data/i2c-pxa.h> #include <linux/regulator/machine.h> @@ -288,11 +289,18 @@ static struct pxamci_platform_data poodle_mci_platform_data = { .init = poodle_mci_init, .setpower = poodle_mci_setpower, .exit = poodle_mci_exit, - .gpio_card_detect = POODLE_GPIO_nSD_DETECT, - .gpio_card_ro = POODLE_GPIO_nSD_WP, - .gpio_power = -1, }; +static struct gpiod_lookup_table poodle_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_DETECT, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_WP, + "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; /* * Irda @@ -439,6 +447,7 @@ static void __init poodle_init(void) pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); pxa_set_udc_info(&udc_info); + gpiod_add_lookup_table(&poodle_mci_gpio_table); pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data); pxa_set_i2c_info(NULL); diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index bd3c23ad6ce6..e1db072756f2 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -749,9 +749,6 @@ static struct pxamci_platform_data raumfeld_mci_platform_data = { .init = raumfeld_mci_init, .exit = raumfeld_mci_exit, .detect_delay_ms = 200, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; /* diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 5d50025492b7..306818e2cf54 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/gpio_keys.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/leds.h> #include <linux/i2c.h> #include <linux/platform_data/i2c-pxa.h> @@ -615,13 +616,22 @@ static struct pxamci_platform_data spitz_mci_platform_data = { .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .setpower = spitz_mci_setpower, - .gpio_card_detect = SPITZ_GPIO_nSD_DETECT, - .gpio_card_ro = SPITZ_GPIO_nSD_WP, - .gpio_power = -1, +}; + +static struct gpiod_lookup_table spitz_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_nSD_DETECT, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_nSD_WP, + "wp", GPIO_ACTIVE_LOW), + { }, + }, }; static void __init spitz_mmc_init(void) { + gpiod_add_lookup_table(&spitz_mci_gpio_table); pxa_set_mci_info(&spitz_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index bbea5fa9a140..e0d6c872270a 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -436,9 +436,6 @@ static int imote2_mci_get_ro(struct device *dev) static struct pxamci_platform_data imote2_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */ .get_ro = imote2_mci_get_ro, - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; static struct gpio_led imote2_led_pins[] = { diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index cb5cd8e78c94..e8a93c088c35 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -31,6 +31,7 @@ #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/power/gpio-charger.h> #include <linux/spi/spi.h> #include <linux/spi/pxa2xx_spi.h> @@ -291,9 +292,19 @@ static struct pxamci_platform_data tosa_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .init = tosa_mci_init, .exit = tosa_mci_exit, - .gpio_card_detect = TOSA_GPIO_nSD_DETECT, - .gpio_card_ro = TOSA_GPIO_SD_WP, - .gpio_power = TOSA_GPIO_PWR_ON, +}; + +static struct gpiod_lookup_table tosa_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_nSD_DETECT, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_SD_WP, + "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_PWR_ON, + "power", GPIO_ACTIVE_HIGH), + { }, + }, }; /* @@ -908,6 +919,7 @@ static void __init tosa_init(void) /* enable batt_fault */ PMCR = 0x01; + gpiod_add_lookup_table(&tosa_mci_gpio_table); pxa_set_mci_info(&tosa_mci_platform_data); pxa_set_ficp_info(&tosa_ficp_platform_data); pxa_set_i2c_info(NULL); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 55b8c501b6fc..c76f1daecfc9 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -355,9 +355,6 @@ static struct pxamci_platform_data trizeps4_mci_platform_data = { .exit = trizeps4_mci_exit, .get_ro = NULL, /* write-protection not supported */ .setpower = NULL, /* power-switching not supported */ - .gpio_card_detect = -1, - .gpio_card_ro = -1, - .gpio_power = -1, }; /**************************************************************************** diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index f65dfb6e20e2..829284406fa3 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -17,6 +17,7 @@ #include <linux/input.h> #include <linux/leds.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/usb/gpio_vbus.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -240,14 +241,23 @@ static void __init vpac270_onenand_init(void) {} #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data vpac270_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_power = -1, - .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, - .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, .detect_delay_ms = 200, }; +static struct gpiod_lookup_table vpac270_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO53_VPAC270_SD_DETECT_N, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", GPIO52_VPAC270_SD_READONLY, + "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + static void __init vpac270_mmc_init(void) { + gpiod_add_lookup_table(&vpac270_mci_gpio_table); pxa_set_mci_info(&vpac270_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index 6fffcfc4621e..e2353e75bb28 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -27,6 +27,7 @@ #include <linux/power_supply.h> #include <linux/mtd/physmap.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/gpio_keys.h> #include <linux/delay.h> #include <linux/regulator/machine.h> @@ -290,14 +291,21 @@ static inline void z2_lcd_init(void) {} #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data z2_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .gpio_card_detect = GPIO96_ZIPITZ2_SD_DETECT, - .gpio_power = -1, - .gpio_card_ro = -1, .detect_delay_ms = 200, }; +static struct gpiod_lookup_table z2_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO96_ZIPITZ2_SD_DETECT, + "cd", GPIO_ACTIVE_LOW), + { }, + }, +}; + static void __init z2_mmc_init(void) { + gpiod_add_lookup_table(&z2_mci_gpio_table); pxa_set_mci_info(&z2_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index d53ea12fc766..897ef59fbe0c 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -663,10 +663,18 @@ static struct pxafb_mach_info zeus_fb_info = { static struct pxamci_platform_data zeus_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .detect_delay_ms = 250, - .gpio_card_detect = ZEUS_MMC_CD_GPIO, - .gpio_card_ro = ZEUS_MMC_WP_GPIO, .gpio_card_ro_invert = 1, - .gpio_power = -1 +}; + +static struct gpiod_lookup_table zeus_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("gpio-pxa", ZEUS_MMC_CD_GPIO, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", ZEUS_MMC_WP_GPIO, + "wp", GPIO_ACTIVE_HIGH), + { }, + }, }; /* @@ -883,6 +891,7 @@ static void __init zeus_init(void) else pxa_set_fb_info(NULL, &zeus_fb_info); + gpiod_add_lookup_table(&zeus_mci_gpio_table); pxa_set_mci_info(&zeus_mci_platform_data); pxa_set_udc_info(&zeus_udc_info); pxa_set_ac97_info(&zeus_ac97_info); diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 52e70a5c1281..1f88d7bae849 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -19,7 +19,7 @@ #include <linux/leds.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/smc91x.h> @@ -227,33 +227,68 @@ static inline void zylonite_init_lcd(void) {} static struct pxamci_platform_data zylonite_mci_platform_data = { .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = EXT_GPIO(0), - .gpio_card_ro = EXT_GPIO(2), - .gpio_power = -1, +}; + +#define PCA9539A_MCI_CD 0 +#define PCA9539A_MCI1_CD 1 +#define PCA9539A_MCI_WP 2 +#define PCA9539A_MCI1_WP 3 +#define PCA9539A_MCI3_CD 30 +#define PCA9539A_MCI3_WP 31 + +static struct gpiod_lookup_table zylonite_mci_gpio_table = { + .dev_id = "pxa2xx-mci.0", + .table = { + GPIO_LOOKUP("i2c-pca9539-a", PCA9539A_MCI_CD, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("i2c-pca9539-a", PCA9539A_MCI_WP, + "wp", GPIO_ACTIVE_LOW), + { }, + }, }; static struct pxamci_platform_data zylonite_mci2_platform_data = { .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = EXT_GPIO(1), - .gpio_card_ro = EXT_GPIO(3), - .gpio_power = -1, +}; + +static struct gpiod_lookup_table zylonite_mci2_gpio_table = { + .dev_id = "pxa2xx-mci.1", + .table = { + GPIO_LOOKUP("i2c-pca9539-a", PCA9539A_MCI1_CD, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("i2c-pca9539-a", PCA9539A_MCI1_WP, + "wp", GPIO_ACTIVE_LOW), + { }, + }, }; static struct pxamci_platform_data zylonite_mci3_platform_data = { .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .gpio_card_detect = EXT_GPIO(30), - .gpio_card_ro = EXT_GPIO(31), - .gpio_power = -1, +}; + +static struct gpiod_lookup_table zylonite_mci3_gpio_table = { + .dev_id = "pxa2xx-mci.2", + .table = { + GPIO_LOOKUP("i2c-pca9539-a", PCA9539A_MCI3_CD, + "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("i2c-pca9539-a", PCA9539A_MCI3_WP, + "wp", GPIO_ACTIVE_LOW), + { }, + }, }; static void __init zylonite_init_mmc(void) { + gpiod_add_lookup_table(&zylonite_mci_gpio_table); pxa_set_mci_info(&zylonite_mci_platform_data); + gpiod_add_lookup_table(&zylonite_mci2_gpio_table); pxa3xx_set_mci2_info(&zylonite_mci2_platform_data); - if (cpu_is_pxa310()) + if (cpu_is_pxa310()) { + gpiod_add_lookup_table(&zylonite_mci3_gpio_table); pxa3xx_set_mci3_info(&zylonite_mci3_platform_data); + } } #else static inline void zylonite_init_mmc(void) {} diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 0ff4e218080f..8f930a9dd0fd 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -230,11 +230,13 @@ static struct pca953x_platform_data gpio_exp[] = { static struct i2c_board_info zylonite_i2c_board_info[] = { { .type = "pca9539", + .dev_name = "pca9539-a", .addr = 0x74, .platform_data = &gpio_exp[0], .irq = PXA_GPIO_TO_IRQ(18), }, { .type = "pca9539", + .dev_name = "pca9539-b", .addr = 0x75, .platform_data = &gpio_exp[1], .irq = PXA_GPIO_TO_IRQ(19), diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c index 68a4fa94257a..58c5ef3cf1d7 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/types.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/timer.h> @@ -136,7 +136,16 @@ static struct platform_device at2440evb_device_eth = { }; static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = { - .gpio_detect = S3C2410_GPG(10), + /* Intentionally left blank */ +}; + +static struct gpiod_lookup_table at2440evb_mci_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* Card detect S3C2410_GPG(10) */ + GPIO_LOOKUP("GPG", 10, "cd", GPIO_ACTIVE_LOW), + { }, + }, }; /* 7" LCD panel */ @@ -200,6 +209,7 @@ static void __init at2440evb_init_time(void) static void __init at2440evb_init(void) { s3c24xx_fb_set_platdata(&at2440evb_fb_info); + gpiod_add_lookup_table(&at2440evb_mci_gpio_table); s3c24xx_mci_set_platdata(&at2440evb_mci_pdata); s3c_nand_set_platdata(&at2440evb_nand_info); s3c_i2c0_set_platdata(NULL); diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index e064c73a57d3..74d6b68e91c7 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/input.h> #include <linux/gpio_keys.h> #include <linux/pwm.h> @@ -459,12 +460,21 @@ static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd) } static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = { - .gpio_detect = S3C2410_GPF(5), - .gpio_wprotect = S3C2410_GPH(8), .set_power = h1940_set_mmc_power, .ocr_avail = MMC_VDD_32_33, }; +static struct gpiod_lookup_table h1940_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* Card detect S3C2410_GPF(5) */ + GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW), + /* Write protect S3C2410_GPH(8) */ + GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + static struct pwm_lookup h1940_pwm_lookup[] = { PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296, PWM_POLARITY_NORMAL), @@ -680,6 +690,7 @@ static void __init h1940_init(void) u32 tmp; s3c24xx_fb_set_platdata(&h1940_fb_info); + gpiod_add_lookup_table(&h1940_mmc_gpio_table); s3c24xx_mci_set_platdata(&h1940_mmc_cfg); s3c24xx_udc_set_platdata(&h1940_udc_cfg); s3c24xx_ts_set_platdata(&h1940_ts_cfg); diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 50d67d760efd..9035f868fb34 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -15,6 +15,7 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/input.h> #include <linux/io.h> #include <linux/serial_core.h> @@ -234,13 +235,22 @@ static struct s3c2410fb_mach_info mini2440_fb_info __initdata = { /* MMC/SD */ static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = { - .gpio_detect = S3C2410_GPG(8), - .gpio_wprotect = S3C2410_GPH(8), .wprotect_invert = 1, .set_power = NULL, .ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34, }; +static struct gpiod_lookup_table mini2440_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* Card detect S3C2410_GPG(8) */ + GPIO_LOOKUP("GPG", 8, "cd", GPIO_ACTIVE_LOW), + /* Write protect S3C2410_GPH(8) */ + GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_HIGH), + { }, + }, +}; + /* NAND Flash on MINI2440 board */ static struct mtd_partition mini2440_default_nand_part[] __initdata = { @@ -696,6 +706,7 @@ static void __init mini2440_init(void) } s3c24xx_udc_set_platdata(&mini2440_udc_cfg); + gpiod_add_lookup_table(&mini2440_mmc_gpio_table); s3c24xx_mci_set_platdata(&mini2440_mmc_cfg); s3c_nand_set_platdata(&mini2440_nand_info); s3c_i2c0_set_platdata(NULL); diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c index eec51fadb14a..d856f23939af 100644 --- a/arch/arm/mach-s3c24xx/mach-n30.c +++ b/arch/arm/mach-s3c24xx/mach-n30.c @@ -17,6 +17,7 @@ #include <linux/gpio_keys.h> #include <linux/init.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/platform_device.h> @@ -350,12 +351,21 @@ static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd) } static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = { - .gpio_detect = S3C2410_GPF(1), - .gpio_wprotect = S3C2410_GPG(10), .ocr_avail = MMC_VDD_32_33, .set_power = n30_sdi_set_power, }; +static struct gpiod_lookup_table n30_mci_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* Card detect S3C2410_GPF(1) */ + GPIO_LOOKUP("GPF", 1, "cd", GPIO_ACTIVE_LOW), + /* Write protect S3C2410_GPG(10) */ + GPIO_LOOKUP("GPG", 10, "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + static struct platform_device *n30_devices[] __initdata = { &s3c_device_lcd, &s3c_device_wdt, @@ -549,6 +559,7 @@ static void __init n30_init(void) s3c24xx_fb_set_platdata(&n30_fb_info); s3c24xx_udc_set_platdata(&n30_udc_cfg); + gpiod_add_lookup_table(&n30_mci_gpio_table); s3c24xx_mci_set_platdata(&n30_mci_cfg); s3c_i2c0_set_platdata(&n30_i2ccfg); diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 7f5a18fa305b..29f9b345a531 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -14,6 +14,7 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/platform_device.h> #include <linux/serial_core.h> #include <linux/serial_s3c.h> @@ -558,12 +559,21 @@ static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd) } static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = { - .gpio_detect = S3C2410_GPF(5), - .gpio_wprotect = S3C2410_GPH(8), .set_power = rx1950_set_mmc_power, .ocr_avail = MMC_VDD_32_33, }; +static struct gpiod_lookup_table rx1950_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* Card detect S3C2410_GPF(5) */ + GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW), + /* Write protect S3C2410_GPH(8) */ + GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW), + { }, + }, +}; + static struct mtd_partition rx1950_nand_part[] = { [0] = { .name = "Boot0", @@ -762,6 +772,7 @@ static void __init rx1950_init_machine(void) s3c24xx_fb_set_platdata(&rx1950_lcd_cfg); s3c24xx_udc_set_platdata(&rx1950_udc_cfg); s3c24xx_ts_set_platdata(&rx1950_ts_cfg); + gpiod_add_lookup_table(&rx1950_mmc_gpio_table); s3c24xx_mci_set_platdata(&rx1950_mmc_cfg); s3c_i2c0_set_platdata(NULL); s3c_nand_set_platdata(&rx1950_nand_info); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 5aa472892465..76c4855a03bc 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -194,8 +194,8 @@ static struct wm8994_pdata wm8994_pdata = { 0x3, /* IRQ out, active high, CMOS */ }, .ldo = { - { .enable = S3C64XX_GPN(6), .init_data = &wm8994_ldo1, }, - { .enable = S3C64XX_GPN(4), .init_data = &wm8994_ldo2, }, + { .init_data = &wm8994_ldo1, }, + { .init_data = &wm8994_ldo2, }, }, }; @@ -203,6 +203,18 @@ static const struct i2c_board_info wm1277_devs[] = { { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */ .platform_data = &wm8994_pdata, .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, + .dev_name = "wm8958", + }, +}; + +static struct gpiod_lookup_table wm8994_gpiod_table = { + .dev_id = "i2c-wm8958", /* I2C device name */ + .table = { + GPIO_LOOKUP("GPION", 6, + "wlf,ldo1ena", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("GPION", 4, + "wlf,ldo2ena", GPIO_ACTIVE_HIGH), + { }, }, }; @@ -381,6 +393,7 @@ static int wlf_gf_module_probe(struct i2c_client *i2c, gpiod_add_lookup_table(&wm5102_reva_gpiod_table); gpiod_add_lookup_table(&wm5102_gpiod_table); + gpiod_add_lookup_table(&wm8994_gpiod_table); if (i < ARRAY_SIZE(gf_mods)) { dev_info(&i2c->dev, "%s revision %d\n", diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c index 712416ecd8e6..f304b10e23a4 100644 --- a/arch/arm/mm/dma-mapping-nommu.c +++ b/arch/arm/mm/dma-mapping-nommu.c @@ -22,7 +22,7 @@ #include "dma.h" /* - * dma_direct_ops is used if + * The generic direct mapping code is used if * - MMU/MPU is off * - cpu is v7m w/o cache support * - device is coherent @@ -209,16 +209,9 @@ const struct dma_map_ops arm_nommu_dma_ops = { }; EXPORT_SYMBOL(arm_nommu_dma_ops); -static const struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent) -{ - return coherent ? &dma_direct_ops : &arm_nommu_dma_ops; -} - void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, const struct iommu_ops *iommu, bool coherent) { - const struct dma_map_ops *dma_ops; - if (IS_ENABLED(CONFIG_CPU_V7M)) { /* * Cache support for v7m is optional, so can be treated as @@ -234,7 +227,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, dev->archdata.dma_coherent = (get_cr() & CR_M) ? coherent : true; } - dma_ops = arm_nommu_get_dma_map_ops(dev->archdata.dma_coherent); - - set_dma_ops(dev, dma_ops); + if (!dev->archdata.dma_coherent) + set_dma_ops(dev, &arm_nommu_dma_ops); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 78de138aa66d..f1e2922e447c 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -179,11 +179,6 @@ static void arm_dma_sync_single_for_device(struct device *dev, __dma_page_cpu_to_dev(page, offset, size, dir); } -static int arm_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return dma_addr == ARM_MAPPING_ERROR; -} - const struct dma_map_ops arm_dma_ops = { .alloc = arm_dma_alloc, .free = arm_dma_free, @@ -197,7 +192,6 @@ const struct dma_map_ops arm_dma_ops = { .sync_single_for_device = arm_dma_sync_single_for_device, .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, .sync_sg_for_device = arm_dma_sync_sg_for_device, - .mapping_error = arm_dma_mapping_error, .dma_supported = arm_dma_supported, }; EXPORT_SYMBOL(arm_dma_ops); @@ -217,7 +211,6 @@ const struct dma_map_ops arm_coherent_dma_ops = { .get_sgtable = arm_dma_get_sgtable, .map_page = arm_coherent_dma_map_page, .map_sg = arm_dma_map_sg, - .mapping_error = arm_dma_mapping_error, .dma_supported = arm_dma_supported, }; EXPORT_SYMBOL(arm_coherent_dma_ops); @@ -774,7 +767,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp &= ~(__GFP_COMP); args.gfp = gfp; - *handle = ARM_MAPPING_ERROR; + *handle = DMA_MAPPING_ERROR; allowblock = gfpflags_allow_blocking(gfp); cma = allowblock ? dev_get_cma_area(dev) : false; @@ -1217,7 +1210,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping, if (i == mapping->nr_bitmaps) { if (extend_iommu_mapping(mapping)) { spin_unlock_irqrestore(&mapping->lock, flags); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } start = bitmap_find_next_zero_area(mapping->bitmaps[i], @@ -1225,7 +1218,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping, if (start > mapping->bits) { spin_unlock_irqrestore(&mapping->lock, flags); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } bitmap_set(mapping->bitmaps[i], start, count); @@ -1409,7 +1402,7 @@ __iommu_create_mapping(struct device *dev, struct page **pages, size_t size, int i; dma_addr = __alloc_iova(mapping, size); - if (dma_addr == ARM_MAPPING_ERROR) + if (dma_addr == DMA_MAPPING_ERROR) return dma_addr; iova = dma_addr; @@ -1436,7 +1429,7 @@ __iommu_create_mapping(struct device *dev, struct page **pages, size_t size, fail: iommu_unmap(mapping->domain, dma_addr, iova-dma_addr); __free_iova(mapping, dma_addr, size); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t size) @@ -1497,7 +1490,7 @@ static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp, return NULL; *handle = __iommu_create_mapping(dev, &page, size, attrs); - if (*handle == ARM_MAPPING_ERROR) + if (*handle == DMA_MAPPING_ERROR) goto err_mapping; return addr; @@ -1525,7 +1518,7 @@ static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size, struct page **pages; void *addr = NULL; - *handle = ARM_MAPPING_ERROR; + *handle = DMA_MAPPING_ERROR; size = PAGE_ALIGN(size); if (coherent_flag == COHERENT || !gfpflags_allow_blocking(gfp)) @@ -1546,7 +1539,7 @@ static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size, return NULL; *handle = __iommu_create_mapping(dev, pages, size, attrs); - if (*handle == ARM_MAPPING_ERROR) + if (*handle == DMA_MAPPING_ERROR) goto err_buffer; if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) @@ -1696,10 +1689,10 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, int prot; size = PAGE_ALIGN(size); - *handle = ARM_MAPPING_ERROR; + *handle = DMA_MAPPING_ERROR; iova_base = iova = __alloc_iova(mapping, size); - if (iova == ARM_MAPPING_ERROR) + if (iova == DMA_MAPPING_ERROR) return -ENOMEM; for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) { @@ -1739,7 +1732,7 @@ static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, for (i = 1; i < nents; i++) { s = sg_next(s); - s->dma_address = ARM_MAPPING_ERROR; + s->dma_address = DMA_MAPPING_ERROR; s->dma_length = 0; if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { @@ -1914,7 +1907,7 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *p int ret, prot, len = PAGE_ALIGN(size + offset); dma_addr = __alloc_iova(mapping, len); - if (dma_addr == ARM_MAPPING_ERROR) + if (dma_addr == DMA_MAPPING_ERROR) return dma_addr; prot = __dma_info_to_prot(dir, attrs); @@ -1926,7 +1919,7 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *p return dma_addr + offset; fail: __free_iova(mapping, dma_addr, len); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } /** @@ -2020,7 +2013,7 @@ static dma_addr_t arm_iommu_map_resource(struct device *dev, size_t len = PAGE_ALIGN(size + offset); dma_addr = __alloc_iova(mapping, len); - if (dma_addr == ARM_MAPPING_ERROR) + if (dma_addr == DMA_MAPPING_ERROR) return dma_addr; prot = __dma_info_to_prot(dir, attrs) | IOMMU_MMIO; @@ -2032,7 +2025,7 @@ static dma_addr_t arm_iommu_map_resource(struct device *dev, return dma_addr + offset; fail: __free_iova(mapping, dma_addr, len); - return ARM_MAPPING_ERROR; + return DMA_MAPPING_ERROR; } /** @@ -2105,7 +2098,6 @@ const struct dma_map_ops iommu_ops = { .map_resource = arm_iommu_map_resource, .unmap_resource = arm_iommu_unmap_resource, - .mapping_error = arm_dma_mapping_error, .dma_supported = arm_dma_supported, }; @@ -2124,7 +2116,6 @@ const struct dma_map_ops iommu_coherent_ops = { .map_resource = arm_iommu_map_resource, .unmap_resource = arm_iommu_unmap_resource, - .mapping_error = arm_dma_mapping_error, .dma_supported = arm_dma_supported, }; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 32e4845af2b6..478ea8b7db87 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -50,26 +50,7 @@ unsigned long __init __clear_cr(unsigned long mask) } #endif -static phys_addr_t phys_initrd_start __initdata = 0; -static unsigned long phys_initrd_size __initdata = 0; - -static int __init early_initrd(char *p) -{ - phys_addr_t start; - unsigned long size; - char *endp; - - start = memparse(p, &endp); - if (*endp == ',') { - size = memparse(endp + 1, NULL); - - phys_initrd_start = start; - phys_initrd_size = size; - } - return 0; -} -early_param("initrd", early_initrd); - +#ifdef CONFIG_BLK_DEV_INITRD static int __init parse_tag_initrd(const struct tag *tag) { pr_warn("ATAG_INITRD is deprecated; " @@ -89,6 +70,7 @@ static int __init parse_tag_initrd2(const struct tag *tag) } __tagtable(ATAG_INITRD2, parse_tag_initrd2); +#endif static void __init find_limits(unsigned long *min, unsigned long *max_low, unsigned long *max_high) @@ -236,12 +218,6 @@ static void __init arm_initrd_init(void) phys_addr_t start; unsigned long size; - /* FDT scan will populate initrd_start */ - if (initrd_start && !phys_initrd_size) { - phys_initrd_start = __virt_to_phys(initrd_start); - phys_initrd_size = initrd_end - initrd_start; - } - initrd_start = initrd_end = 0; if (!phys_initrd_size) |