diff options
-rw-r--r-- | drivers/mtd/mtdoops.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 34681bc91105..fd98e38f10bc 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
31 | #include <linux/delay.h> | ||
31 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
32 | #include <linux/mtd/mtd.h> | 33 | #include <linux/mtd/mtd.h> |
33 | 34 | ||
@@ -183,10 +184,8 @@ badblock: | |||
183 | goto badblock; | 184 | goto badblock; |
184 | } | 185 | } |
185 | 186 | ||
186 | static void mtdoops_workfunc_write(struct work_struct *work) | 187 | static void mtdoops_write(struct mtdoops_context *cxt, int panic) |
187 | { | 188 | { |
188 | struct mtdoops_context *cxt = | ||
189 | container_of(work, struct mtdoops_context, work_write); | ||
190 | struct mtd_info *mtd = cxt->mtd; | 189 | struct mtd_info *mtd = cxt->mtd; |
191 | size_t retlen; | 190 | size_t retlen; |
192 | int ret; | 191 | int ret; |
@@ -195,7 +194,11 @@ static void mtdoops_workfunc_write(struct work_struct *work) | |||
195 | memset(cxt->oops_buf + cxt->writecount, 0xff, | 194 | memset(cxt->oops_buf + cxt->writecount, 0xff, |
196 | OOPS_PAGE_SIZE - cxt->writecount); | 195 | OOPS_PAGE_SIZE - cxt->writecount); |
197 | 196 | ||
198 | ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE, | 197 | if (panic) |
198 | ret = mtd->panic_write(mtd, cxt->nextpage * OOPS_PAGE_SIZE, | ||
199 | OOPS_PAGE_SIZE, &retlen, cxt->oops_buf); | ||
200 | else | ||
201 | ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE, | ||
199 | OOPS_PAGE_SIZE, &retlen, cxt->oops_buf); | 202 | OOPS_PAGE_SIZE, &retlen, cxt->oops_buf); |
200 | 203 | ||
201 | cxt->writecount = 0; | 204 | cxt->writecount = 0; |
@@ -205,6 +208,15 @@ static void mtdoops_workfunc_write(struct work_struct *work) | |||
205 | cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); | 208 | cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); |
206 | 209 | ||
207 | mtdoops_inc_counter(cxt); | 210 | mtdoops_inc_counter(cxt); |
211 | } | ||
212 | |||
213 | |||
214 | static void mtdoops_workfunc_write(struct work_struct *work) | ||
215 | { | ||
216 | struct mtdoops_context *cxt = | ||
217 | container_of(work, struct mtdoops_context, work_write); | ||
218 | |||
219 | mtdoops_write(cxt, 0); | ||
208 | } | 220 | } |
209 | 221 | ||
210 | static void find_next_position(struct mtdoops_context *cxt) | 222 | static void find_next_position(struct mtdoops_context *cxt) |
@@ -314,7 +326,11 @@ static void mtdoops_console_sync(void) | |||
314 | cxt->ready = 0; | 326 | cxt->ready = 0; |
315 | spin_unlock_irqrestore(&cxt->writecount_lock, flags); | 327 | spin_unlock_irqrestore(&cxt->writecount_lock, flags); |
316 | 328 | ||
317 | schedule_work(&cxt->work_write); | 329 | if (mtd->panic_write && in_interrupt()) |
330 | /* Interrupt context, we're going to panic so try and log */ | ||
331 | mtdoops_write(cxt, 1); | ||
332 | else | ||
333 | schedule_work(&cxt->work_write); | ||
318 | } | 334 | } |
319 | 335 | ||
320 | static void | 336 | static void |