From patchwork Wed Sep 9 08:30:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Qiang X-Patchwork-Id: 515759 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 33715140291 for ; Wed, 9 Sep 2015 18:40:14 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 126B01A2D7D for ; Wed, 9 Sep 2015 18:40:14 +1000 (AEST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2on0148.outbound.protection.outlook.com [207.46.100.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 5E31F1A2BB5 for ; Wed, 9 Sep 2015 18:36:10 +1000 (AEST) Received: from BN3PR0301CA0007.namprd03.prod.outlook.com (10.160.180.145) by BY2PR0301MB0775.namprd03.prod.outlook.com (10.160.64.11) with Microsoft SMTP Server (TLS) id 15.1.262.15; Wed, 9 Sep 2015 08:36:03 +0000 Received: from BN1BFFO11FD009.protection.gbl (2a01:111:f400:7c10::1:102) by BN3PR0301CA0007.outlook.office365.com (2a01:111:e400:4000::17) with Microsoft SMTP Server (TLS) id 15.1.262.15 via Frontend Transport; Wed, 9 Sep 2015 08:36:03 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BN1BFFO11FD009.mail.protection.outlook.com (10.58.144.72) with Microsoft SMTP Server (TLS) id 15.1.262.18 via Frontend Transport; Wed, 9 Sep 2015 08:36:02 +0000 Received: from titan.ap.freescale.net ([10.192.208.233]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t898Zmcs002376; Wed, 9 Sep 2015 01:35:59 -0700 From: Zhao Qiang To: Subject: [PATCH V8 3/4] qe_common: add qe_muram_ functions to manage muram Date: Wed, 9 Sep 2015 16:30:04 +0800 Message-ID: <1441787405-19944-3-git-send-email-qiang.zhao@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 In-Reply-To: <1441787405-19944-1-git-send-email-qiang.zhao@freescale.com> References: <1441787405-19944-1-git-send-email-qiang.zhao@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD009; 1:CJwmOWwxc4noATNjDevfzZQXqNorWOshy97q5TFrTNMqbShd5GiqqFeckNHxtROOF9uhCwDw6D4AgOyitf0fIVYflO2mJFCDeyg8mVTbFHmPbP0H15gi9fw0WtfqysBjs89wVW4Y7J2+LZchuhbiTLb6NXorFgYVfJTZD2Llj4rtPyx6sfjOH3IdYvRYg1sE7at9xNp5knWmLjxL8rn08qEPYBNyifO9jkLYr2ppd/Pn4CDgltpcVljE1xxCVEuhWk6tzMv6HafgfhMM/c/YVYEaLzCBX0bzRpsA8zGgK1hHASWP6ahkIqLYEVPjYx75HuqWOumnqnIpraLnGir3D1AGH4veWIBk6sgXQlM0yFPwO3NntioqKKAm44OgLcdryeVUoMzoaMscIH4N8dAatw== X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(1110001)(1109001)(339900001)(40224003)(199003)(189002)(77156002)(50466002)(85426001)(106466001)(105606002)(97736004)(87936001)(2371004)(36756003)(11100500001)(86362001)(4001540100001)(48376002)(69596002)(76176999)(46102003)(104016003)(62966003)(81156007)(77096005)(6806004)(2950100001)(229853001)(5001960100002)(5007970100001)(50226001)(5001860100001)(5003940100001)(4001450100002)(68736005)(33646002)(47776003)(50986999)(5001830100001)(64706001)(92566002)(19580405001)(189998001)(19580395003)(110136002)(5890100001)(2351001)(107886002)(2004002)(4001430100001); DIR:OUT; SFP:1102; SCL:1; SRVR:BY2PR0301MB0775; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BY2PR0301MB0775; 2:7w9CMoTM/ZCzzqG4xxMM7LhbrdEWO+VCE3/OhCTkayzN/kAdA4cQEnpari0fO339MXnl7BJMrLA+DZOPmu+sQq7LX88hNNsGdkr0yFEQUdafubfXfayCEm4UZ5Jlmsp6QKdGavItjxFybwF5k8H4TMTVGaPej2GQsFgQoWqmTSk=; 3:nt+7nLZ4vmt0B8XuNn3ymC5QgJoQlEGExveRByOWnH42Lfn/UvHeZVnfNQJryzaUdFCUdZdXdL7MLXEB5f+V3Qmhjwqn0xSgXdGMf6Ix8XjnNe+1dcE8sdH9/QVzMuf4P629HgIKl7kuqkzOP20CBRV+LoFhTe4viB/ONJ5WI8K9sD6pdhV4oRfF4qIUX34Mpp5lYH3dGX6uGx7mvb+ijQ1Nn0RqisMdTZ0GfZyGZec=; 25:oPpqUZ2SGmPlwhhOggrNR8B245Qrh1ezM3zdgdMC585fq+VVil/Ea6LjYUtekWkrDMxXfm5o7Cj7GeVAr4aOxd7Igwnig3ibrdYXF5mbPMzQftYa2/Y71NugkwqIYg9pduFBx3XgirssSj/69YI2ztnC+1YxAF0uCkfU0O+LtIsDtCroKJae3Hrhbv0ig+MX7OVWksDTMQPlFTGwHfZHdcVOyXiZZ2LOClrVQQGvaH33deU5RKXFm3pDQqmuyoBZ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR0301MB0775; X-Microsoft-Exchange-Diagnostics: 1; BY2PR0301MB0775; 20:50h1FBT+iDDGU47Uvk22ijdx4s3WUCrjSNFKt/Uvrpiwzgjou/Wdkvqvogw4e5zE2c7I3f47FbeceM3EXZXfzj82f+3hMMX2V2VYmpJE9I0xFF0cJlCyVH3lmuvTHgqcp6dxbU5kMWDSrtmrRnkLZKTpT8I+uyAfj0+ypQffPqLZp2igMURrmlElhSNRipJkBYYDOXxkCA8UxoNPdyxU/1Kb444bOE/9DWKk85qrTXUWnSYyerP5o5V+9AAY8sowSvZk9AfdMnl1wKxGMagjARcXQOTC6Se7gyAf427JOvLIw+dLg4hhoUCeBJnzp/jCSCGpKTiHmkXeQq2zgC2cbm8STktbag2XVV/scZOdDlc=; 4:j2mPi1lPjBeocY4oBmusYTkJ65YaFpNUk4uplSguSAVgNhTg9Ge9rSv4HLGNyuPr2+/m38c9TP3VFrth9lKqKNJwnCvxNMqolxq28YILsBVo84oFwT2hOTwFWGy/j9Y61Gmf2y5SQ7NjQd/vzIy2RjPy57qnUwLCVwc+Y/EGgylCZWpJDWcmYbqLyEmpAT8JJU7UEcZHya0DsmvNlYkcO2J3qhBOPe8NE1AiLutirXzP9TIeOu3zT9GpYZNNotnqkqcrFoiq17zxRyt1I7MHIl4RwqI1VwcGP+OqE8ynkJFnQN9h9mhdJX6dhxpysOLT X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(8121501046)(5005006)(3002001); SRVR:BY2PR0301MB0775; BCL:0; PCL:0; RULEID:; SRVR:BY2PR0301MB0775; X-Forefront-PRVS: 0694C54398 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR0301MB0775; 23:HA+oL/JPkI6dt0jJDafxQSI2y3Nv72YZRnwiXn3?= =?us-ascii?Q?846IPpGAC95PwexN4rVH/pgEcjIFEhn4yiZeZkxQ12Ko4trqw9NX0EJbY9r5?= =?us-ascii?Q?B2fcFWNL+dn68RL0hfNOY+5OBVlt7p3xEAEryZPgcl9fN2Iw6qvvvWr3Y2yf?= =?us-ascii?Q?q8fNswddMMsRSL1ttJRZJ5UmhraT+edwUzpdBV1eFDhR+xH4ePf6mwkXlku5?= =?us-ascii?Q?ayQKAmOTTbFRawCOiKLHddSBlaCyGkWbR2/n8S7yki6VjoEAMjapW5Q5Im1z?= =?us-ascii?Q?lmfLpnhOKapI5zC/PhPs0PRyObvmAREc6j8/Q4kXHsYXmSB0ojUK5co4bETR?= =?us-ascii?Q?u/7XsNMNrEPZUBZPwSjQs7uP+XrTHlRquNqibkhNtdy+NTqiD3i9uGhPPRXY?= =?us-ascii?Q?1mf5jsJSvUwWk6gmuvfXabvmbNXxte7P6a+bK+Cz1Aq2uJurENwPQ8qH1Sgw?= =?us-ascii?Q?PoNcTXesKeikkZTJc6LV53vIqQ8mxCFQHO51TbRk9V1VmisKlUtztY2uRQGT?= =?us-ascii?Q?LqZLfDtdL3whApCtTgDbG0+zRmiVDO53Qc/s+JHUY7RE6RnFZw2IlUMNazR2?= =?us-ascii?Q?SV5wHPL4z3UL33XG6AjLZ3SWTMRp78OSyu4X9vpJGD/QCdftPfh4M6VIfz7u?= =?us-ascii?Q?KAvwhddUFOaUu66z2FScqIaQeTcfgKmzK9CWUoWj0JiapGxTU+pKNNJT31Qm?= =?us-ascii?Q?0RfBj3eWlxST69VQVlD5otrll9XK3Bj1AfPogUVjxe0zYlrCOgnhUfrMeFha?= =?us-ascii?Q?kaNH2TBog4OBslouQJ9NswVeLGyIARff1t8ES3zan7DQI27H/tFuEgGOAwMb?= =?us-ascii?Q?8j3FE7EvG0B2fJ9O8B1BmCZ245YUJTvGjj1L56/2yAOJLR7jAAoFl487iObM?= =?us-ascii?Q?xi+mv/kyy/fnJvN2ud29mw84MCk6UjaLwT9FR7mUkzYKWSG1iuI28c+KHhoO?= =?us-ascii?Q?QEN7ijF8PH9FO9G5yYto9If6OXzjAQjHAI3yOkdkEGfkq7mObAhqhpVLs9DS?= =?us-ascii?Q?Dt5dcwMOBdJzREKhOccHhXjtzFB3baO/E2Yy4QmiQBSntFniQ83lBIY6iCsf?= =?us-ascii?Q?taXUq1cAOXnFwc88I0IX8JvdmjJvQw6N19d1A6WGk9Yom10JrkDik22/z5yD?= =?us-ascii?Q?X8v9ffhe01DMKdbx8K7lSHk54drXdd7nOD3KPrMiU7dkbGJ04h3FF65Nyo4N?= =?us-ascii?Q?pQEM4bM2/U+OG3AftMFbVSqMpEJ6TXPOjiWfkKw3M9NBriCw/047DcGhFuOR?= =?us-ascii?Q?2IJjFaFy621oFMwyD1/8TYODlp64HJgmGfzQGa7pXYJr4ZHnpb52er6EnwYo?= =?us-ascii?Q?h1D3qwWIKr2K6NDu7e+p5oEWexSywcWGRvE5NSJr1dBU1UzUh1Tgn3ESgDzm?= =?us-ascii?Q?aLhwEx0rU6qm1kK8sBAFyvxNapxp8rlMNg8df5zS9nyFHBGL3?= X-Microsoft-Exchange-Diagnostics: 1; BY2PR0301MB0775; 5:Mfwy2hVtqLbm4vglaTf/g2ca0Pf/1esqgluJ1olZmiu1OKg2FvrNYrZBGFNeCn/e+Md8grmtRXx0Qz9Oy9SPncTDnxjR+HGgaCW++NTovojxM130HI7wL8F06TqVsPONq7oN7pfv2hhn1hkX58Byow==; 24:UovXZFScWFQ8pRhCTmOkYkERQLWYRqdBAq0Xj9Xcowrm75wlhjCPmsVQWWQrQmo9CWk7ut+ggtWCUzoCkmnn6GYcVWXo5ZWei6Plw4zYq8c=; 20:mlFHPPYy1Ms0ayN8eSe/Th5ogzGEQGJoMQLwwmKoDvb4Q98NggqkFWOO7N7vnice+Oc+Y6i24JS5fgPFQCdgPA== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Sep 2015 08:36:02.8155 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR0301MB0775 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zhao Qiang , lauraa@codeaurora.org, linux-kernel@vger.kernel.org, paulus@samba.org, linuxppc-dev@lists.ozlabs.org, X.xie@freescale.com Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" muram is used for qe, add qe_muram_ functions to manage muram. Signed-off-by: Zhao Qiang --- Changes for v2: - no changes Changes for v3: - no changes Changes for v4: - no changes Changes for v5: - no changes Changes for v6: - using genalloc instead rheap to manage QE MURAM - remove qe_reset from platform file, using - subsys_initcall to call qe_init function. Changes for v7: - move this patch from 3/3 to 2/3 - convert cpm with genalloc - check for gen_pool allocation failure Changes for v8: - rebase - move BD_SC_* macro instead of copy arch/powerpc/include/asm/cpm.h | 59 -------- arch/powerpc/include/asm/qe.h | 49 ++++++- arch/powerpc/platforms/83xx/km83xx.c | 2 - arch/powerpc/platforms/83xx/mpc832x_mds.c | 2 - arch/powerpc/platforms/83xx/mpc832x_rdb.c | 2 - arch/powerpc/platforms/83xx/mpc836x_mds.c | 2 - arch/powerpc/platforms/83xx/mpc836x_rdk.c | 3 - arch/powerpc/platforms/85xx/common.c | 1 - arch/powerpc/platforms/Kconfig | 1 + arch/powerpc/sysdev/cpm_common.c | 141 +----------------- arch/powerpc/sysdev/qe_lib/Makefile | 2 +- arch/powerpc/sysdev/qe_lib/qe.c | 15 ++ arch/powerpc/sysdev/qe_lib/qe_common.c | 235 ++++++++++++++++++++++++++++++ 13 files changed, 295 insertions(+), 219 deletions(-) create mode 100644 arch/powerpc/sysdev/qe_lib/qe_common.c diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index 4398a6c..003a736 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -93,22 +93,6 @@ typedef struct cpm_buf_desc { */ #define BD_SC_EMPTY (0x8000) /* Receive is empty */ -#define BD_SC_READY (0x8000) /* Transmit is ready */ -#define BD_SC_WRAP (0x2000) /* Last buffer descriptor */ -#define BD_SC_INTRPT (0x1000) /* Interrupt on change */ -#define BD_SC_LAST (0x0800) /* Last buffer in frame */ -#define BD_SC_TC (0x0400) /* Transmit CRC */ -#define BD_SC_CM (0x0200) /* Continuous mode */ -#define BD_SC_ID (0x0100) /* Rec'd too many idles */ -#define BD_SC_P (0x0100) /* xmt preamble */ -#define BD_SC_BR (0x0020) /* Break received */ -#define BD_SC_FR (0x0010) /* Framing error */ -#define BD_SC_PR (0x0008) /* Parity error */ -#define BD_SC_NAK (0x0004) /* NAK - did not respond */ -#define BD_SC_OV (0x0002) /* Overrun */ -#define BD_SC_UN (0x0002) /* Underrun */ -#define BD_SC_CD (0x0001) /* */ -#define BD_SC_CL (0x0001) /* Collision */ /* Buffer descriptor control/status used by Ethernet receive. * Common to SCC and FCC. @@ -155,49 +139,6 @@ typedef struct cpm_buf_desc { */ #define BD_I2C_START (0x0400) -int cpm_muram_init(void); - -#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) -unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); -int cpm_muram_free(unsigned long offset); -unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); -void __iomem *cpm_muram_addr(unsigned long offset); -unsigned long cpm_muram_offset(void __iomem *addr); -dma_addr_t cpm_muram_dma(void __iomem *addr); -#else -static inline unsigned long cpm_muram_alloc(unsigned long size, - unsigned long align) -{ - return -ENOSYS; -} - -static inline int cpm_muram_free(unsigned long offset) -{ - return -ENOSYS; -} - -static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset, - unsigned long size) -{ - return -ENOSYS; -} - -static inline void __iomem *cpm_muram_addr(unsigned long offset) -{ - return NULL; -} - -static inline unsigned long cpm_muram_offset(void __iomem *addr) -{ - return -ENOSYS; -} - -static inline dma_addr_t cpm_muram_dma(void __iomem *addr) -{ - return 0; -} -#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */ - #ifdef CONFIG_CPM int cpm_command(u32 command, u8 opcode); #else diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h index 32b9bfa..eea7c4b 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/arch/powerpc/include/asm/qe.h @@ -16,10 +16,13 @@ #define _ASM_POWERPC_QE_H #ifdef __KERNEL__ +#include #include #include #include -#include +#include +#include +#include #include #define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */ @@ -187,12 +190,23 @@ static inline int qe_alive_during_sleep(void) } /* we actually use cpm_muram implementation, define this for convenience */ -#define qe_muram_init cpm_muram_init -#define qe_muram_alloc cpm_muram_alloc -#define qe_muram_alloc_fixed cpm_muram_alloc_fixed -#define qe_muram_free cpm_muram_free -#define qe_muram_addr cpm_muram_addr -#define qe_muram_offset cpm_muram_offset +#define cpm_muram_init qe_muram_init +#define cpm_muram_alloc qe_muram_alloc +#define cpm_muram_alloc_fixed qe_muram_alloc_fixed +#define cpm_muram_free qe_muram_free +#define cpm_muram_addr qe_muram_addr +#define cpm_muram_offset qe_muram_offset + +int qe_muram_init(void); + +#if defined(CONFIG_QUICC_ENGINE) +unsigned long qe_muram_alloc(unsigned long size, unsigned long align); +unsigned long qe_muram_alloc_fixed(unsigned long offset, unsigned long size); +int qe_muram_free(unsigned long offset); +void __iomem *qe_muram_addr(unsigned long offset); +unsigned long qe_muram_offset(void __iomem *addr); +dma_addr_t qe_muram_dma(void __iomem *addr); +#endif /* defined(CONFIG_QUICC_ENGINE) */ /* Structure that defines QE firmware binary files. * @@ -266,6 +280,27 @@ struct qe_bd { #define BD_STATUS_MASK 0xffff0000 #define BD_LENGTH_MASK 0x0000ffff +/* Buffer descriptor control/status used by serial + */ + +#define BD_SC_EMPTY (0x8000) /* Receive is empty */ +#define BD_SC_READY (0x8000) /* Transmit is ready */ +#define BD_SC_WRAP (0x2000) /* Last buffer descriptor */ +#define BD_SC_INTRPT (0x1000) /* Interrupt on change */ +#define BD_SC_LAST (0x0800) /* Last buffer in frame */ +#define BD_SC_TC (0x0400) /* Transmit CRC */ +#define BD_SC_CM (0x0200) /* Continuous mode */ +#define BD_SC_ID (0x0100) /* Rec'd too many idles */ +#define BD_SC_P (0x0100) /* xmt preamble */ +#define BD_SC_BR (0x0020) /* Break received */ +#define BD_SC_FR (0x0010) /* Framing error */ +#define BD_SC_PR (0x0008) /* Parity error */ +#define BD_SC_NAK (0x0004) /* NAK - did not respond */ +#define BD_SC_OV (0x0002) /* Overrun */ +#define BD_SC_UN (0x0002) /* Underrun */ +#define BD_SC_CD (0x0001) /* */ +#define BD_SC_CL (0x0001) /* Collision */ + /* Alignment */ #define QE_INTR_TABLE_ALIGN 16 /* ??? */ #define QE_ALIGNMENT_OF_BD 8 diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index bf4c447..ae111581 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -136,8 +136,6 @@ static void __init mpc83xx_km_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - np = of_find_node_by_name(NULL, "par_io"); if (np != NULL) { par_io_init(np); diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 8d76220..aacc43f 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -74,8 +74,6 @@ static void __init mpc832x_sys_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { par_io_init(np); of_node_put(np); diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index eff5baa..0c7a43e 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -203,8 +203,6 @@ static void __init mpc832x_rdb_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { par_io_init(np); of_node_put(np); diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 1a26d2f..eb24abd 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -82,8 +82,6 @@ static void __init mpc836x_mds_setup_arch(void) mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE - qe_reset(); - if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { par_io_init(np); of_node_put(np); diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index b63b42d..823e370 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c @@ -35,9 +35,6 @@ static void __init mpc836x_rdk_setup_arch(void) ppc_md.progress("mpc836x_rdk_setup_arch()", 0); mpc83xx_setup_pci(); -#ifdef CONFIG_QUICC_ENGINE - qe_reset(); -#endif } /* diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 7bfb9b1..0f91edc 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -105,7 +105,6 @@ void __init mpc85xx_qe_init(void) return; } - qe_reset(); of_node_put(np); } diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index b7f9c40..01f98a2 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -276,6 +276,7 @@ config QUICC_ENGINE bool "Freescale QUICC Engine (QE) Support" depends on FSL_SOC && PPC32 select PPC_LIB_RHEAP + select GENERIC_ALLOCATOR select CRC32 help The QUICC Engine (QE) is a new generation of communications diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 4f78695..328c3ec 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -27,8 +27,8 @@ #include #include -#include #include +#include #include @@ -65,151 +65,12 @@ void __init udbg_init_cpm(void) } #endif -static spinlock_t cpm_muram_lock; -static rh_block_t cpm_boot_muram_rh_block[16]; -static rh_info_t cpm_muram_info; static u8 __iomem *muram_vbase; static phys_addr_t muram_pbase; /* Max address size we deal with */ #define OF_MAX_ADDR_CELLS 4 -int cpm_muram_init(void) -{ - struct device_node *np; - struct resource r; - u32 zero[OF_MAX_ADDR_CELLS] = {}; - resource_size_t max = 0; - int i = 0; - int ret = 0; - - if (muram_pbase) - return 0; - - spin_lock_init(&cpm_muram_lock); - /* initialize the info header */ - rh_init(&cpm_muram_info, 1, - sizeof(cpm_boot_muram_rh_block) / - sizeof(cpm_boot_muram_rh_block[0]), - cpm_boot_muram_rh_block); - - np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); - if (!np) { - /* try legacy bindings */ - np = of_find_node_by_name(NULL, "data-only"); - if (!np) { - printk(KERN_ERR "Cannot find CPM muram data node"); - ret = -ENODEV; - goto out; - } - } - - muram_pbase = of_translate_address(np, zero); - if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { - printk(KERN_ERR "Cannot translate zero through CPM muram node"); - ret = -ENODEV; - goto out; - } - - while (of_address_to_resource(np, i++, &r) == 0) { - if (r.end > max) - max = r.end; - - rh_attach_region(&cpm_muram_info, r.start - muram_pbase, - resource_size(&r)); - } - - muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); - if (!muram_vbase) { - printk(KERN_ERR "Cannot map CPM muram"); - ret = -ENOMEM; - } - -out: - of_node_put(np); - return ret; -} - -/** - * cpm_muram_alloc - allocate the requested size worth of multi-user ram - * @size: number of bytes to allocate - * @align: requested alignment, in bytes - * - * This function returns an offset into the muram area. - * Use cpm_dpram_addr() to get the virtual address of the area. - * Use cpm_muram_free() to free the allocation. - */ -unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&cpm_muram_lock, flags); - cpm_muram_info.alignment = align; - start = rh_alloc(&cpm_muram_info, size, "commproc"); - memset(cpm_muram_addr(start), 0, size); - spin_unlock_irqrestore(&cpm_muram_lock, flags); - - return start; -} -EXPORT_SYMBOL(cpm_muram_alloc); - -/** - * cpm_muram_free - free a chunk of multi-user ram - * @offset: The beginning of the chunk as returned by cpm_muram_alloc(). - */ -int cpm_muram_free(unsigned long offset) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&cpm_muram_lock, flags); - ret = rh_free(&cpm_muram_info, offset); - spin_unlock_irqrestore(&cpm_muram_lock, flags); - - return ret; -} -EXPORT_SYMBOL(cpm_muram_free); - -/** - * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram - * @offset: the offset into the muram area to reserve - * @size: the number of bytes to reserve - * - * This function returns "start" on success, -ENOMEM on failure. - * Use cpm_dpram_addr() to get the virtual address of the area. - * Use cpm_muram_free() to free the allocation. - */ -unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&cpm_muram_lock, flags); - cpm_muram_info.alignment = 1; - start = rh_alloc_fixed(&cpm_muram_info, offset, size, "commproc"); - spin_unlock_irqrestore(&cpm_muram_lock, flags); - - return start; -} -EXPORT_SYMBOL(cpm_muram_alloc_fixed); - -/** - * cpm_muram_addr - turn a muram offset into a virtual address - * @offset: muram offset to convert - */ -void __iomem *cpm_muram_addr(unsigned long offset) -{ - return muram_vbase + offset; -} -EXPORT_SYMBOL(cpm_muram_addr); - -unsigned long cpm_muram_offset(void __iomem *addr) -{ - return addr - (void __iomem *)muram_vbase; -} -EXPORT_SYMBOL(cpm_muram_offset); - /** * cpm_muram_dma - turn a muram virtual address into a DMA address * @offset: virtual address from cpm_muram_addr() to convert diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile index f1855c1..9507a27 100644 --- a/arch/powerpc/sysdev/qe_lib/Makefile +++ b/arch/powerpc/sysdev/qe_lib/Makefile @@ -1,7 +1,7 @@ # # Makefile for the linux ppc-specific parts of QE # -obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o +obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o obj-$(CONFIG_UCC) += ucc.o obj-$(CONFIG_UCC_SLOW) += ucc_slow.o diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index c2518cd..3f9f596 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -671,6 +671,21 @@ unsigned int qe_get_num_of_snums(void) } EXPORT_SYMBOL(qe_get_num_of_snums); +static int __init qe_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,qe"); + if (!np) { + pr_err("%s: Could not find Quicc Engine node\n", __func__); + return -ENODEV; + } + qe_reset(); + of_node_put(np); + return 0; +} +subsys_initcall(qe_init); + #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) static int qe_resume(struct platform_device *ofdev) { diff --git a/arch/powerpc/sysdev/qe_lib/qe_common.c b/arch/powerpc/sysdev/qe_lib/qe_common.c new file mode 100644 index 0000000..4ad12ba --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe_common.c @@ -0,0 +1,235 @@ +/* + * Freescale QE common code + * + * Author: Zhao Qiang + * + * Copyright 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct gen_pool *muram_pool; +static struct genpool_data_align muram_pool_data; +static struct genpool_data_offset muram_pool_data_fixed; +static spinlock_t qe_muram_lock; +static u8 __iomem *muram_vbase; +static phys_addr_t muram_pbase; + +struct muram_block { + struct list_head head; + unsigned long start; + int size; +}; + +static LIST_HEAD(muram_block_list); + +/* max address size we deal with */ +#define OF_MAX_ADDR_CELLS 4 +#define GENPOOL_OFFSET 4096 + +int qe_muram_init(void) +{ + struct device_node *np; + struct resource r; + u32 zero[OF_MAX_ADDR_CELLS] = {}; + resource_size_t max = 0; + int i = 0; + int ret = 0; + + if (muram_pbase) + return 0; + + np = of_find_compatible_node(NULL, NULL, "fsl,qe-muram-data"); + if (!np) { + /* try legacy bindings */ + np = of_find_node_by_name(NULL, "data-only"); + if (!np) { + pr_err("Cannot find CPM muram data node"); + ret = -ENODEV; + goto out; + } + } + + muram_pool = gen_pool_create(1, -1); + muram_pbase = of_translate_address(np, zero); + if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { + pr_err("Cannot translate zero through CPM muram node"); + ret = -ENODEV; + goto err; + } + + while (of_address_to_resource(np, i++, &r) == 0) { + if (r.end > max) + max = r.end; + ret = gen_pool_add(muram_pool, r.start - muram_pbase + + GENPOOL_OFFSET, resource_size(&r), -1); + if (ret) { + pr_err("QE: couldn't add muram to pool!\n"); + goto err; + } + + } + + muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); + if (!muram_vbase) { + pr_err("Cannot map QE muram"); + ret = -ENOMEM; + goto err; + } + goto out; +err: + gen_pool_destroy(muram_pool); +out: + of_node_put(np); + return ret; +} + +/* + * qe_muram_alloc - allocate the requested size worth of multi-user ram + * @size: number of bytes to allocate + * @align: requested alignment, in bytes + * + * This function returns an offset into the muram area. + */ +unsigned long qe_muram_alloc(unsigned long size, unsigned long align) +{ + unsigned long start; + unsigned long flags; + struct muram_block *entry; + + spin_lock_irqsave(&qe_muram_lock, flags); + muram_pool_data.align = align; + gen_pool_set_algo(muram_pool, gen_pool_first_fit_align, + &muram_pool_data); + start = gen_pool_alloc(muram_pool, size); + if (!start) + goto out2; + start = start - GENPOOL_OFFSET; + memset(qe_muram_addr(start), 0, size); + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + goto out1; + entry->start = start; + entry->size = size; + list_add(&entry->head, &muram_block_list); + spin_unlock_irqrestore(&qe_muram_lock, flags); + + return start; +out1: + gen_pool_free(muram_pool, start, size); +out2: + spin_unlock_irqrestore(&qe_muram_lock, flags); + return (unsigned long) -ENOMEM; +} +EXPORT_SYMBOL(qe_muram_alloc); + +/* + * qe_muram_alloc_fixed - reserve a specific region of multi-user ram + * @size: number of bytes to allocate + * @offset: offset of allocation start address + * + * This function returns an offset into the muram area. + */ +unsigned long qe_muram_alloc_fixed(unsigned long offset, unsigned long size) +{ + + unsigned long start; + unsigned long flags; + struct muram_block *entry; + + spin_lock_irqsave(&qe_muram_lock, flags); + muram_pool_data_fixed.offset = offset + GENPOOL_OFFSET; + gen_pool_set_algo(muram_pool, gen_pool_first_fit_offset, + &muram_pool_data_fixed); + start = gen_pool_alloc(muram_pool, size); + if (!start) + goto out2; + start = start - GENPOOL_OFFSET; + memset(qe_muram_addr(start), 0, size); + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + goto out1; + entry->start = start; + entry->size = size; + list_add(&entry->head, &muram_block_list); + spin_unlock_irqrestore(&qe_muram_lock, flags); + + return start; +out1: + gen_pool_free(muram_pool, start, size); +out2: + spin_unlock_irqrestore(&qe_muram_lock, flags); + return (unsigned long) -ENOMEM; + + +} +EXPORT_SYMBOL(qe_muram_alloc_fixed); + +/** + * qe_muram_free - free a chunk of multi-user ram + * @offset: The beginning of the chunk as returned by qe_muram_alloc(). + */ +int qe_muram_free(unsigned long offset) +{ + unsigned long flags; + int size; + struct muram_block *tmp; + + size = 0; + spin_lock_irqsave(&qe_muram_lock, flags); + list_for_each_entry(tmp, &muram_block_list, head) { + if (tmp->start == offset) { + size = tmp->size; + list_del(&tmp->head); + kfree(tmp); + break; + } + } + gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size); + spin_unlock_irqrestore(&qe_muram_lock, flags); + + return size; +} +EXPORT_SYMBOL(qe_muram_free); + +/** + * qe_muram_addr - turn a muram offset into a virtual address + * @offset: muram offset to convert + */ +void __iomem *qe_muram_addr(unsigned long offset) +{ + return muram_vbase + offset; +} +EXPORT_SYMBOL(qe_muram_addr); + +unsigned long qe_muram_offset(void __iomem *addr) +{ + return addr - (void __iomem *)muram_vbase; +} +EXPORT_SYMBOL(qe_muram_offset); + +/** + * qe_muram_dma - turn a muram virtual address into a DMA address + * @offset: virtual address from qe_muram_addr() to convert + */ +dma_addr_t qe_muram_dma(void __iomem *addr) +{ + return muram_pbase + ((u8 __iomem *)addr - muram_vbase); +} +EXPORT_SYMBOL(qe_muram_dma);