Received: by 10.213.65.68 with SMTP id h4csp869935imn; Thu, 22 Mar 2018 10:20:09 -0700 (PDT) X-Google-Smtp-Source: AG47ELsZmwnLixy7mVHSUjaaMdWLWOvEtNXpy9vWXuyU06KaYEMgbLcIG54LYjhCbapoyGy9JT/I X-Received: by 2002:a17:902:c6b:: with SMTP id 98-v6mr25661741pls.267.1521739209746; Thu, 22 Mar 2018 10:20:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521739209; cv=none; d=google.com; s=arc-20160816; b=MJfJ3FIHjrF4yNDYx/1qoL9cArApEvq1hWV6G3rlbowVtiIRY5nTGH/Bns6J5n6ezJ sLCOZUe/c/zBM01pTg5M7vYSPi4jN7/YE3NKhsCk7+SBSR2JPL0JjQlanKTiCnDfNBfD WlujvTkooIJqdX5w420vgx/EcUc6EZMfxTL3lRtqlyWbZVgVplZf5XPUTrYvCjqQp4pD 0Pz/L5F3K3MEIgc1vaID1KgTWCHjJt5S+HrvfB9XyJkTHsAuiJXEDrpP554OQsJASibc tVgIMZuJJoFV9Znx85i/KriXBICjD8Aftz1gcMznfGpTJRuhkxfRDnbtHrKFvpv1Ru/H XiWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:subject:references:in-reply-to:message-id :date:cc:to:from:arc-authentication-results; bh=qDyzAKlu3WJmi+9TYOtTUlJqJbVbNH2HBIbeQuy9ER4=; b=A1ibRoVETPH9ckkVp7OUEf9fwM4jY2OWLbrZYn2r4VNaZRku911Z7bcDMkxx2gj6RO iFFbOJZ2tyEvnr2t3tuF9hFnkElgWYgLdoCdkqMkIBvuONkRy2M1sdIfKbTbCnQ/PXbQ 17CnwbVcWPPjaWdeJPpbVxBdlWnQ5ALMwGCsqmUmCOOjLw4m8DhaPup36KocQuaOVvrj 6dQHhoDUutw0InydvMuEa7P6ftbC6R3bfFDHF2R8vzWdZxTE61W7PgT48xXJ26h/VyfK 4XMuXligZybhbvGmx+D+HiML3Hc9XbIprQbMJlw/u3zvIbacnh6DNmk2WgJD9DquDoxd bYPw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d81si5276710pfd.210.2018.03.22.10.19.54; Thu, 22 Mar 2018 10:20:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752247AbeCVRSj (ORCPT + 99 others); Thu, 22 Mar 2018 13:18:39 -0400 Received: from ale.deltatee.com ([207.54.116.67]:35258 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752066AbeCVRRR (ORCPT ); Thu, 22 Mar 2018 13:17:17 -0400 Received: from cgy1-donard.priv.deltatee.com ([172.16.1.31]) by ale.deltatee.com with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1ez3pu-00073K-Ty; Thu, 22 Mar 2018 11:17:15 -0600 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.89) (envelope-from ) id 1ez3pr-00018U-0O; Thu, 22 Mar 2018 11:17:07 -0600 From: Logan Gunthorpe To: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-ntb@googlegroups.com, linux-crypto@vger.kernel.org, Greg Kroah-Hartman Cc: Arnd Bergmann , Andy Shevchenko , =?UTF-8?q?Horia=20Geant=C4=83?= , Logan Gunthorpe , Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman , Suresh Warrier , Nicholas Piggin Date: Thu, 22 Mar 2018 11:16:59 -0600 Message-Id: <20180322171703.4300-7-logang@deltatee.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180322171703.4300-1-logang@deltatee.com> References: <20180322171703.4300-1-logang@deltatee.com> X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: linux-ntb@googlegroups.com, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-crypto@vger.kernel.org, gregkh@linuxfoundation.org, arnd@arndb.de, horia.geanta@nxp.com, logang@deltatee.com, benh@kernel.crashing.org, paulus@samba.org, mpe@ellerman.id.au, warrier@linux.vnet.ibm.com, andy.shevchenko@gmail.com, npiggin@gmail.com X-SA-Exim-Mail-From: gunthorp@deltatee.com X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on ale.deltatee.com X-Spam-Level: X-Spam-Status: No, score=-8.7 required=5.0 tests=ALL_TRUSTED,BAYES_00, GREYLIST_ISWHITE,MYRULES_NO_TEXT,T_RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.1 Subject: [PATCH v14 06/10] iomap: introduce io{read|write}64_{lo_hi|hi_lo} X-SA-Exim-Version: 4.2.1 (built Tue, 02 Aug 2016 21:08:31 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to provide non-atomic functions for io{read|write}64 that will use readq and writeq when appropriate. We define a number of variants of these functions in the generic iomap that will do non-atomic operations on pio but atomic operations on mmio. These functions are only defined if readq and writeq are defined. If they are not, then the wrappers that always use non-atomic operations from include/linux/io-64-nonatomic*.h will be used. Signed-off-by: Logan Gunthorpe Reviewed-by: Andy Shevchenko Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Arnd Bergmann Cc: Suresh Warrier Cc: Nicholas Piggin --- arch/powerpc/include/asm/io.h | 2 + include/asm-generic/iomap.h | 26 +++++++-- lib/iomap.c | 132 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index af074923d598..4cc420cfaa78 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -788,8 +788,10 @@ extern void __iounmap_at(void *ea, unsigned long size); #define mmio_read16be(addr) readw_be(addr) #define mmio_read32be(addr) readl_be(addr) +#define mmio_read64be(addr) readq_be(addr) #define mmio_write16be(val, addr) writew_be(val, addr) #define mmio_write32be(val, addr) writel_be(val, addr) +#define mmio_write64be(val, addr) writeq_be(val, addr) #define mmio_insb(addr, dst, count) readsb(addr, dst, count) #define mmio_insw(addr, dst, count) readsw(addr, dst, count) #define mmio_insl(addr, dst, count) readsl(addr, dst, count) diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h index 5b63b94ef6b5..5a4af0199b32 100644 --- a/include/asm-generic/iomap.h +++ b/include/asm-generic/iomap.h @@ -31,9 +31,16 @@ extern unsigned int ioread16(void __iomem *); extern unsigned int ioread16be(void __iomem *); extern unsigned int ioread32(void __iomem *); extern unsigned int ioread32be(void __iomem *); -#ifdef CONFIG_64BIT -extern u64 ioread64(void __iomem *); -extern u64 ioread64be(void __iomem *); + +#ifdef readq +#define ioread64_lo_hi ioread64_lo_hi +#define ioread64_hi_lo ioread64_hi_lo +#define ioread64be_lo_hi ioread64be_lo_hi +#define ioread64be_hi_lo ioread64be_hi_lo +extern u64 ioread64_lo_hi(void __iomem *addr); +extern u64 ioread64_hi_lo(void __iomem *addr); +extern u64 ioread64be_lo_hi(void __iomem *addr); +extern u64 ioread64be_hi_lo(void __iomem *addr); #endif extern void iowrite8(u8, void __iomem *); @@ -41,9 +48,16 @@ extern void iowrite16(u16, void __iomem *); extern void iowrite16be(u16, void __iomem *); extern void iowrite32(u32, void __iomem *); extern void iowrite32be(u32, void __iomem *); -#ifdef CONFIG_64BIT -extern void iowrite64(u64, void __iomem *); -extern void iowrite64be(u64, void __iomem *); + +#ifdef writeq +#define iowrite64_lo_hi iowrite64_lo_hi +#define iowrite64_hi_lo iowrite64_hi_lo +#define iowrite64be_lo_hi iowrite64be_lo_hi +#define iowrite64be_hi_lo iowrite64be_hi_lo +extern void iowrite64_lo_hi(u64 val, void __iomem *addr); +extern void iowrite64_hi_lo(u64 val, void __iomem *addr); +extern void iowrite64be_lo_hi(u64 val, void __iomem *addr); +extern void iowrite64be_hi_lo(u64 val, void __iomem *addr); #endif /* diff --git a/lib/iomap.c b/lib/iomap.c index 44645c4b516c..f3b7b2e4c625 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -67,6 +67,7 @@ static void bad_io_access(unsigned long port, const char *access) #ifndef mmio_read16be #define mmio_read16be(addr) be16_to_cpu((__be16 __force)__raw_readw(addr)) #define mmio_read32be(addr) be32_to_cpu((__be32 __force)__raw_readl(addr)) +#define mmio_read64be(addr) be64_to_cpu((__be64 __force)__raw_readq(addr)) #endif unsigned int ioread8(void __iomem *addr) @@ -100,6 +101,80 @@ EXPORT_SYMBOL(ioread16be); EXPORT_SYMBOL(ioread32); EXPORT_SYMBOL(ioread32be); +#ifdef readq +static u64 pio_read64_lo_hi(unsigned long port) +{ + u64 lo, hi; + + lo = inl(port); + hi = inl(port + sizeof(u32)); + + return lo | (hi << 32); +} + +static u64 pio_read64_hi_lo(unsigned long port) +{ + u64 lo, hi; + + hi = inl(port + sizeof(u32)); + lo = inl(port); + + return lo | (hi << 32); +} + +static u64 pio_read64be_lo_hi(unsigned long port) +{ + u64 lo, hi; + + lo = pio_read32be(port + sizeof(u32)); + hi = pio_read32be(port); + + return lo | (hi << 32); +} + +static u64 pio_read64be_hi_lo(unsigned long port) +{ + u64 lo, hi; + + hi = pio_read32be(port); + lo = pio_read32be(port + sizeof(u32)); + + return lo | (hi << 32); +} + +u64 ioread64_lo_hi(void __iomem *addr) +{ + IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr)); + return 0xffffffffffffffffULL; +} + +u64 ioread64_hi_lo(void __iomem *addr) +{ + IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr)); + return 0xffffffffffffffffULL; +} + +u64 ioread64be_lo_hi(void __iomem *addr) +{ + IO_COND(addr, return pio_read64be_lo_hi(port), + return mmio_read64be(addr)); + return 0xffffffffffffffffULL; +} + +u64 ioread64be_hi_lo(void __iomem *addr) +{ + IO_COND(addr, return pio_read64be_hi_lo(port), + return mmio_read64be(addr)); + return 0xffffffffffffffffULL; +} + +EXPORT_SYMBOL(ioread64_lo_hi); +EXPORT_SYMBOL(ioread64_hi_lo); +EXPORT_SYMBOL(ioread64be_lo_hi); +EXPORT_SYMBOL(ioread64be_hi_lo); + +#endif /* readq */ + #ifndef pio_write16be #define pio_write16be(val,port) outw(swab16(val),port) #define pio_write32be(val,port) outl(swab32(val),port) @@ -108,6 +183,7 @@ EXPORT_SYMBOL(ioread32be); #ifndef mmio_write16be #define mmio_write16be(val,port) __raw_writew((u16 __force)cpu_to_be16(val),port) #define mmio_write32be(val,port) __raw_writel((u32 __force)cpu_to_be32(val),port) +#define mmio_write64be(val,port) __raw_writeq((u64 __force)cpu_to_be64(val),port) #endif void iowrite8(u8 val, void __iomem *addr) @@ -136,6 +212,62 @@ EXPORT_SYMBOL(iowrite16be); EXPORT_SYMBOL(iowrite32); EXPORT_SYMBOL(iowrite32be); +#ifdef writeq +static void pio_write64_lo_hi(u64 val, unsigned long port) +{ + outl(val, port); + outl(val >> 32, port + sizeof(u32)); +} + +static void pio_write64_hi_lo(u64 val, unsigned long port) +{ + outl(val >> 32, port + sizeof(u32)); + outl(val, port); +} + +static void pio_write64be_lo_hi(u64 val, unsigned long port) +{ + pio_write32be(val, port + sizeof(u32)); + pio_write32be(val >> 32, port); +} + +static void pio_write64be_hi_lo(u64 val, unsigned long port) +{ + pio_write32be(val >> 32, port); + pio_write32be(val, port + sizeof(u32)); +} + +void iowrite64_lo_hi(u64 val, void __iomem *addr) +{ + IO_COND(addr, pio_write64_lo_hi(val, port), + writeq(val, addr)); +} + +void iowrite64_hi_lo(u64 val, void __iomem *addr) +{ + IO_COND(addr, pio_write64_hi_lo(val, port), + writeq(val, addr)); +} + +void iowrite64be_lo_hi(u64 val, void __iomem *addr) +{ + IO_COND(addr, pio_write64be_lo_hi(val, port), + mmio_write64be(val, addr)); +} + +void iowrite64be_hi_lo(u64 val, void __iomem *addr) +{ + IO_COND(addr, pio_write64be_hi_lo(val, port), + mmio_write64be(val, addr)); +} + +EXPORT_SYMBOL(iowrite64_lo_hi); +EXPORT_SYMBOL(iowrite64_hi_lo); +EXPORT_SYMBOL(iowrite64be_lo_hi); +EXPORT_SYMBOL(iowrite64be_hi_lo); + +#endif /* readq */ + /* * These are the "repeat MMIO read/write" functions. * Note the "__raw" accesses, since we don't want to -- 2.11.0