]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.8.5/soc-fsl-qe-fix-oops-on-cpm1-and-likely-cpm2.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.8.5 / soc-fsl-qe-fix-oops-on-cpm1-and-likely-cpm2.patch
1 From 4d486e0083796b54d5aeddd7a5794f897fca1008 Mon Sep 17 00:00:00 2001
2 From: Christophe Leroy <christophe.leroy@c-s.fr>
3 Date: Tue, 16 Aug 2016 08:26:20 +0200
4 Subject: soc/fsl/qe: fix Oops on CPM1 (and likely CPM2)
5
6 From: Christophe Leroy <christophe.leroy@c-s.fr>
7
8 commit 4d486e0083796b54d5aeddd7a5794f897fca1008 upstream.
9
10 Commit 0e6e01ff694ee ("CPM/QE: use genalloc to manage CPM/QE muram")
11 has changed the way muram is managed.
12 genalloc uses kmalloc(), hence requires the SLAB to be up and running.
13
14 On powerpc 8xx, cpm_reset() is called early during startup.
15 cpm_reset() then calls cpm_muram_init() before SLAB is available,
16 hence the following Oops.
17
18 cpm_reset() cannot be called during initcalls because the CPM is
19 needed for console.
20
21 This patch removes the call to cpm_muram_init() from cpm_reset().
22 cpm_muram_init() will be called from a new function called cpm_init()
23 which is declared as subsys_initcall, unless cpm_muram_alloc() is
24 called earlier for the serial console in which case cpm_muram_init()
25 will be called from there.
26
27 The reason for calling it from two places is that some drivers
28 (e.g. i2c-cpm) need some of the initialisations done by
29 cpm_muram_init() but don't call cpm_muram_alloc(). The console
30 driver calls cpm_muram_alloc() but some platforms might not use
31 the CPM serial ports for console.
32
33 [ 0.000000] Unable to handle kernel paging request for data at address 0x00000008
34 [ 0.000000] Faulting instruction address: 0xc01acce0
35 [ 0.000000] Oops: Kernel access of bad area, sig: 11 [#1]
36 [ 0.000000] PREEMPT CMPC885
37 [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.14-g0886ed8 #5
38 [ 0.000000] task: c05183e0 ti: c0536000 task.ti: c0536000
39 [ 0.000000] NIP: c01acce0 LR: c0011068 CTR: 00000000
40 [ 0.000000] REGS: c0537e50 TRAP: 0300 Not tainted (4.4.14-s3k-dev-g0886ed8-svn)
41 [ 0.000000] MSR: 00001032 <ME,IR,DR,RI> CR: 28044428 XER: 00000000
42 [ 0.000000] DAR: 00000008 DSISR: c0000000
43 GPR00: c0011068 c0537f00 c05183e0 00000000 00009000 ffffffff 00000bc0 ffffffff
44 GPR08: ff003000 ff00b000 ff003bbf 00000000 22044422 100d43a8 00000000 07ff94e8
45 GPR16: 00000000 07bb5d70 00000000 07ff81f4 07ff81f4 07ff81f4 00000000 00000000
46 GPR24: 07ffb3a0 07fe7628 c0550000 c7ffa190 c0540000 ff003bbf 00000000 00000001
47 [ 0.000000] NIP [c01acce0] gen_pool_add_virt+0x14/0xdc
48 [ 0.000000] LR [c0011068] cpm_muram_init+0xd4/0x18c
49 [ 0.000000] Call Trace:
50 [ 0.000000] [c0537f00] [00000200] 0x200 (unreliable)
51 [ 0.000000] [c0537f20] [c0011068] cpm_muram_init+0xd4/0x18c
52 [ 0.000000] [c0537f70] [c0494684] cpm_reset+0xb4/0xc8
53 [ 0.000000] [c0537f90] [c0494c64] cmpc885_setup_arch+0x10/0x30
54 [ 0.000000] [c0537fa0] [c0493cd4] setup_arch+0x130/0x168
55 [ 0.000000] [c0537fb0] [c04906bc] start_kernel+0x88/0x380
56 [ 0.000000] [c0537ff0] [c0002224] start_here+0x38/0x98
57 [ 0.000000] Instruction dump:
58 [ 0.000000] 91430010 91430014 80010014 83e1000c 7c0803a6 38210010 4e800020 7c0802a6
59 [ 0.000000] 9421ffe0 bf61000c 90010024 7c7e1b78 <80630008> 7c9c2378 7cc31c30 3863001f
60 [ 0.000000] ---[ end trace dc8fa200cb88537f ]---
61
62 fixes: 0e6e01ff694ee ("CPM/QE: use genalloc to manage CPM/QE muram")
63 Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
64 [scottwood: Removed some string changes unrelated to bugfix]
65 Signed-off-by: Scott Wood <oss@buserror.net>
66 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
67
68 ---
69 arch/powerpc/sysdev/cpm1.c | 2 --
70 arch/powerpc/sysdev/cpm2.c | 4 ----
71 arch/powerpc/sysdev/cpm_common.c | 15 +++++++++++++++
72 drivers/soc/fsl/qe/qe_common.c | 8 ++++++++
73 4 files changed, 23 insertions(+), 6 deletions(-)
74
75 --- a/arch/powerpc/sysdev/cpm1.c
76 +++ b/arch/powerpc/sysdev/cpm1.c
77 @@ -233,8 +233,6 @@ void __init cpm_reset(void)
78 else
79 out_be32(&siu_conf->sc_sdcr, 1);
80 immr_unmap(siu_conf);
81 -
82 - cpm_muram_init();
83 }
84
85 static DEFINE_SPINLOCK(cmd_lock);
86 --- a/arch/powerpc/sysdev/cpm2.c
87 +++ b/arch/powerpc/sysdev/cpm2.c
88 @@ -66,10 +66,6 @@ void __init cpm2_reset(void)
89 cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
90 #endif
91
92 - /* Reclaim the DP memory for our use.
93 - */
94 - cpm_muram_init();
95 -
96 /* Tell everyone where the comm processor resides.
97 */
98 cpmp = &cpm2_immr->im_cpm;
99 --- a/arch/powerpc/sysdev/cpm_common.c
100 +++ b/arch/powerpc/sysdev/cpm_common.c
101 @@ -37,6 +37,21 @@
102 #include <linux/of_gpio.h>
103 #endif
104
105 +static int __init cpm_init(void)
106 +{
107 + struct device_node *np;
108 +
109 + np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
110 + if (!np)
111 + np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
112 + if (!np)
113 + return -ENODEV;
114 + cpm_muram_init();
115 + of_node_put(np);
116 + return 0;
117 +}
118 +subsys_initcall(cpm_init);
119 +
120 #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
121 static u32 __iomem *cpm_udbg_txdesc;
122 static u8 __iomem *cpm_udbg_txbuf;
123 --- a/drivers/soc/fsl/qe/qe_common.c
124 +++ b/drivers/soc/fsl/qe/qe_common.c
125 @@ -70,6 +70,11 @@ int cpm_muram_init(void)
126 }
127
128 muram_pool = gen_pool_create(0, -1);
129 + if (!muram_pool) {
130 + pr_err("Cannot allocate memory pool for CPM/QE muram");
131 + ret = -ENOMEM;
132 + goto out_muram;
133 + }
134 muram_pbase = of_translate_address(np, zero);
135 if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) {
136 pr_err("Cannot translate zero through CPM muram node");
137 @@ -116,6 +121,9 @@ static unsigned long cpm_muram_alloc_com
138 struct muram_block *entry;
139 unsigned long start;
140
141 + if (!muram_pool && cpm_muram_init())
142 + goto out2;
143 +
144 start = gen_pool_alloc_algo(muram_pool, size, algo, data);
145 if (!start)
146 goto out2;