Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752709AbbHaJEa (ORCPT ); Mon, 31 Aug 2015 05:04:30 -0400 Received: from mail-bn1bon0138.outbound.protection.outlook.com ([157.56.111.138]:36894 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752174AbbHaJE1 (ORCPT ); Mon, 31 Aug 2015 05:04:27 -0400 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; From: Zhao Qiang To: CC: , , , , , , , Zhao Qiang Subject: [PATCH V7 2/3] qe_common: add qe_muram_ functions to manage muram Date: Mon, 31 Aug 2015 16:58:39 +0800 Message-ID: <1441011520-15424-2-git-send-email-qiang.zhao@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 In-Reply-To: <1441011520-15424-1-git-send-email-qiang.zhao@freescale.com> References: <1441011520-15424-1-git-send-email-qiang.zhao@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BL2FFO11FD024;1:Kica2wKfdtyPwP7szPMH1IAvHFf9IFWomXCC/bzcaV3pmnKE6QYr/xFGt3L7UMVORwT2ZVxImsd3YY0Rr6zK9Qdoum0gCzNa2HMBLbGZK4sM+0OIbF9KPAEE8ZCeFWXG4PJbj+Z2U9opjv3PIxZw05TiZLxNzofXN32DpGVH+mVSqGkFHnXkcteeQiAOT3z0/TKDauOaNSm13Wp2OCvDyECDTnboMbMNwuxkWcSju8vYe5vlLpnq/kJqLQSS4ZLt0UkUVbTAtdQlFnfk5KnrgvoprmmpaJ3AN0AgObvnLtAE0jiQ/GvYrvNuCCIkvJpyEhMGzw2dgMAR66Fjdv/bY39A/y3vXCSylJ1UeFgtX7I81IugqujXIYO1Jp4VcUPOkPo0SAMcPy6uxiVISrq/bw== X-Forefront-Antispam-Report: CIP:192.88.158.2;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(339900001)(3050300001)(189002)(40224003)(199003)(68736005)(2371004)(5890100001)(106466001)(47776003)(76176999)(4001450100002)(105606002)(64706001)(50986999)(5003940100001)(92566002)(2950100001)(85426001)(2351001)(107886002)(86362001)(77096005)(229853001)(77156002)(5001860100001)(104016003)(62966003)(87936001)(69596002)(110136002)(36756003)(5001830100001)(33646002)(5001960100002)(5007970100001)(4001540100001)(97736004)(50466002)(5001920100001)(48376002)(81156007)(189998001)(46102003)(6806004)(50226001)(19580395003)(19580405001)(2004002)(4001430100001);DIR:OUT;SFP:1102;SCL:1;SRVR:CY1PR0301MB0730;H:az84smr01.freescale.net;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;CY1PR0301MB0730;2:CCj6YSg9eArPY+vLK/x0psGbsll+ZIzb4ZxePfyr083AsMC6yMjovcPpzqQcVrH20dZ2+QU0MSMYtXi0VwtucOeU1m8CYOjgEiMd+/1yNKrGXQbZ6FNiI7LPT/rzDs7o2DY/QHQ1ep95mFJJ6DONQcdtY+J275vUS2X1z8NK868=;3:gi4p89oHicWFhXa4eIO5Ld0tF1tf3h+py8NZ/wvwgkLMYYmq2fBWxnRsNICHBgKHnqah/5iv+rK3i/gjKDwkmPMpfftzSQ/Is0x5eg/AIi3OCYJk33tGK58pCLx0hoEisCUla/wELRR18rAtgch5VF7Qx4gYXadK9EZVuCoR6R4ifnk+YDGxifvirB/JLZauacedn0Su+KLtnexoYwqgMeyT3CLp6rYeZvX2mTm7beo=;25:ne/n6IVc1ffH9rk4rfJk06ROdPOvq92zJPZZhzRn8O9aahFIyajzVo3MeNGpa1a85RvM1hhzE8QbhUhqbO6qKRlSZ6LAqDD7XZJP3uyNi3AzlE9nSsuIEv1/Ak97LW5xeYgfDW3MnA0RMNAaOmyI9qPr8iM438kNBLsIFv/Jj91rXoPDVAZceVOYDdaOqI3t7Czf3n4OsRKTXOLhTCpfbf9Jyd4kwdub37Fd9kEYkpwlhYx5+5SZ578m/d9u4zG/ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB0730; X-Microsoft-Exchange-Diagnostics: 1;CY1PR0301MB0730;20:SGhAULzPUT47tdKsFFYlFnRXQainsHudVmMo7MZY/jeiyAPF0n3cy8OY6RSBUjWAq3Nq2vT8hCIzUy9e0pFo0aEbBrDBPzb/zC923Pb0FB+AKYKag3op2h2WHfwYoNrjkGchAIUY07bxiJ8Z/SeFZoR1uHm1pdBBIO6hFE/kVOqPvWUn7OGbpA9uTj5zrTmXtLXZg1DsnPVjw6BKYdH8qsAL/5k/FdRCOtxuZUNjSMzBHB62grDsIfoZERsGWWsrMQMJlU0bKcpWprI4hsKjqSKFtACRdqle/3xN3Nlz4D/nqodUtfE+fsHJiQoCzR00Twfj5k0znjhDKtUceDjtptTEvODXRxximQpumossrMU=;4:6NDaI5OmK6QWSSYVaPUpC/cB4znclDahwSH/Sdea8f+b5yIKRQYLDBuRsuDoAGx8bLGGMVIwQZhwa61BIo5Qw4pWkJSm/Nn6smnePY9t4vaj0kpcfT9XIEmvMon/aMG62HpkW/z0JXE3xyWfC1Tr8ifHquuN7iT+Ho17UiAYnrf2SZK4Igi72covdTKjbZC0K1o2A0O2GIjIkz8W0fYJCwWJzJSp/XxnTNOqlHu9JaNHemVy5N9c+nE9/CNYT7aGY5hoy27RH+ZiPElegwndfATe0BXys1/yvBI7fU5JDYcDGhcK3hKzbiXYay7yVeEI 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:CY1PR0301MB0730;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB0730; X-Forefront-PRVS: 0685122203 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY1PR0301MB0730;23:+/jFpmiVZ2uiXLeOlZJ9bDTexoH2JmKTe32e5EE?= =?us-ascii?Q?7C6RbyrLf3baRfiLiMJADYTx77DhURIPyKHZFx1K8lUhnt/ZvCfIBQYEP/ZU?= =?us-ascii?Q?PKmWF7ztxgYGSiuNLrA/u+Lu2lBGs4LQXMVBlQSfDqXxv/aPsGWnYslROZs0?= =?us-ascii?Q?8cBLS0awopxIZqI3dEYmjJMLSNzd0Klgq2txnIJsSsw1xejzl8vow8OobIPa?= =?us-ascii?Q?wdC19zR2vq5Y3L0XC9Y96WaQUXqX5XY2anIZTATGPFXU8wLuEhm+83cR8Ybz?= =?us-ascii?Q?Z9LfVD1BlUv55Ytg8voQpaOCZ6TSHmhLlf9OQiACrSTqvhLp0BWw1M+Ip5kc?= =?us-ascii?Q?2p3l87vii82GWNh1zwR/zMVJln07EEciXXZeqT9hGP3CDIkjWt6Rdt3I4vR3?= =?us-ascii?Q?+XQ1q0oFXLaMGF4Lu6343/p5IJWeVAwFItj0s6v+iIAcsGbkQFEtdAcM/Y9X?= =?us-ascii?Q?LJyDpAQQCPKRtz7hXXp7zAPWwuDm4g7QZriIHBbJPhs6JS00dMu8BLjUaG5W?= =?us-ascii?Q?PLvmVLjYcLz/jOS152MIXb9QFLHfMtODuCsYJjcG0wsyMsrsWyjA7aZsUMUo?= =?us-ascii?Q?/+9QXzFoNOlbFyqdclCNvBHAxY6KYMWI3vXbKgn28kxS0J64Q0vW34Dy/ubE?= =?us-ascii?Q?Pjnqjedro4OaZ6BoFXpQNHbNxvUyIHUtajBT8vhlYCbbMWVxB0QWXdCHTfzn?= =?us-ascii?Q?iroqZuxxGUUH7Otw4ro0G4JBTmHTODh9s0FVin3aKNLVgIpfiaABAR/aYMvz?= =?us-ascii?Q?Vlk4nTSnwx4Vh1vK9S3o+Uia+5kP4xT7RXXOjt68esprGXXO3uQJAtm/3K9K?= =?us-ascii?Q?LhlGas69bMdZBiC9O8LZtlhgkn92cad6wb5ZC7xkxAUQcmRgI6LYxzIgDPFk?= =?us-ascii?Q?4YUEpErCCcpCnNWpsfDNhj+5xYDDZCIgcR5/fKu0T7RnxiTb2or9wctGtO1q?= =?us-ascii?Q?qFIJR3RvklTKY5McCa5Rt1KblD4sYfgZwOSTbXokzi+V2i5X3r4C2HhIVrFo?= =?us-ascii?Q?xgTAwtEyCHWhwnXGNgWnX2fhsf1wpKgapDljAnpQ4ahj9baX1ZnGfut+ZE7F?= =?us-ascii?Q?rnbUkSWwYiOHJf06foZ2gpHHILi2h4tfpWSllwHxAEb94oHCxTCpMLym8uuy?= =?us-ascii?Q?QQRkc/obunOKPyZzEKgIz5MWsg1DOO4hOg0cZUDnNBg3xg4jH3gcLkNqU842?= =?us-ascii?Q?mvOuueUj7bVnuJhnybRA1wBw4OJjwo+NcX+qbY65mvKfof+sBv+anx0/1vP5?= =?us-ascii?Q?bvShox9u+DJQaKnpdhLtCHEEuLo4ZTO+MXELAhIaLkU54lhy5dZFCZU1cFeN?= =?us-ascii?Q?KLj0Yhu6JIIe9idNAK7DgMVA1UTlQ5duw/RM7jP7/mERNeXCfYoYHZuR354J?= =?us-ascii?Q?q/HwsbFo4tGt79SHNbi6kP09lc73XqDgp35CbWehHOWEMKVSi?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR0301MB0730;5:RovPZA4ZD7WtlVl3tHbmn1WS7kNi23uzgyl0sls+XfCHiQ5stLcj6fMpzx2Hmc2pFmcg0emPLDmgNZp7UwYnTciASbVGzOvzDDRABxZhxNNJy8wPddq7sB8OU6Vw1L2IgeCOZYgLX9EJzyIOwNw8/Q==;24:Syo88P709fyh1xHfSEy/mkCvCPe1/7fQTmI5Ln27PIa3cGKG964VgUMPoKY7L3Lvs3HE1SQMCNF/LY0gPXfmm+traglpIOM+IMZ3VJsfPEg=;20:PTnF/pSbulB3EnteaQoqh8kwHhNn9hR4j+7qAeML8A7AeNYtScJduDu7WHYZkitP09xqWlOltxOqZu++0Sr3VA== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Aug 2015 09:04:23.8615 (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: CY1PR0301MB0730 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 20304 Lines: 702 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 arch/powerpc/include/asm/cpm.h | 43 ------ arch/powerpc/include/asm/qe.h | 51 ++++++- 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 | 222 ++++++++++++++++++++++++++++++ 13 files changed, 284 insertions(+), 203 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..05a1c15 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -155,49 +155,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..35257c8 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,25 @@ 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_common(unsigned long size, unsigned long align, + unsigned long offset); +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 +282,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..55079b9 --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/qe_common.c @@ -0,0 +1,222 @@ +/* + * 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 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); + gen_pool_set_algo(muram_pool, gen_pool_first_fit_align, + &muram_pool_data); + + 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) +{ + return qe_muram_alloc_common(size, align, 0); +} +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) +{ + return qe_muram_alloc_common(size, 1, offset); +} +EXPORT_SYMBOL(qe_muram_alloc_fixed); + +/* + * qe_muram_alloc_common - allocate the requested size worth of multi-user ram + * @size: number of bytes to allocate + * @align: requested alignment, in bytes + * @offset: offset of allocation start address + * + * This function returns an offset into the muram area. + */ +unsigned long qe_muram_alloc_common(unsigned long size, unsigned long align, + unsigned long offset) +{ + unsigned long start; + unsigned long flags; + struct muram_block *entry; + + spin_lock_irqsave(&qe_muram_lock, flags); + muram_pool_data.align = align; + muram_pool_data.offset = offset; + 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_common); + +/** + * 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); -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/