powerpc/qe: Make qe_reset() code path safe for repeated invocation
authorAnton Vorontsov <avorontsov@ru.mvista.com>
Tue, 15 Sep 2009 21:43:52 +0000 (01:43 +0400)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 12 Nov 2009 03:43:13 +0000 (21:43 -0600)
For MPC8569 CPUs we'll need to reset QE after each suspend, so make
qe_reset() code path suitable for repeated invocation, that is:

- Don't initialize rheap structures if already initialized;
- Don't allocate muram for SDMA if already allocated, just reinitialize
  registers with previously allocated muram offset;
- Remove __init attributes from qe_reset() and cpm_muram_init();

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/include/asm/qe.h
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/qe_lib/qe.c

index 28fee3b7887aac4e3edde2aaaf94dcfc4461b548..908f0b75745b44c2a47d62fe287f6ef6380962c5 100644 (file)
@@ -87,7 +87,7 @@ extern spinlock_t cmxgcr_lock;
 
 /* Export QE common operations */
 #ifdef CONFIG_QUICC_ENGINE
-extern void __init qe_reset(void);
+extern void qe_reset(void);
 #else
 static inline void qe_reset(void) {}
 #endif
index e4b6d66d93dedfe610193950ac74021dc797048d..9de72c96e6d1b9718631d9a63a9f8e326b133796 100644 (file)
@@ -72,7 +72,7 @@ static phys_addr_t muram_pbase;
 /* Max address size we deal with */
 #define OF_MAX_ADDR_CELLS      4
 
-int __init cpm_muram_init(void)
+int cpm_muram_init(void)
 {
        struct device_node *np;
        struct resource r;
@@ -81,6 +81,9 @@ int __init cpm_muram_init(void)
        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,
index fff2701b90dfaf6469139fb1a44649720ce6a405..1ed1a9fd9bcf689b49b11881503556c6054c1b65 100644 (file)
@@ -104,7 +104,7 @@ phys_addr_t get_qe_base(void)
 
 EXPORT_SYMBOL(get_qe_base);
 
-void __init qe_reset(void)
+void qe_reset(void)
 {
        if (qe_immr == NULL)
                qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
@@ -330,16 +330,18 @@ EXPORT_SYMBOL(qe_put_snum);
 static int qe_sdma_init(void)
 {
        struct sdma __iomem *sdma = &qe_immr->sdma;
-       unsigned long sdma_buf_offset;
+       static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
 
        if (!sdma)
                return -ENODEV;
 
        /* allocate 2 internal temporary buffers (512 bytes size each) for
         * the SDMA */
-       sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
-       if (IS_ERR_VALUE(sdma_buf_offset))
-               return -ENOMEM;
+       if (IS_ERR_VALUE(sdma_buf_offset)) {
+               sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
+               if (IS_ERR_VALUE(sdma_buf_offset))
+                       return -ENOMEM;
+       }
 
        out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
        out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |