diff options
author | Magnus Damm <damm@opensource.se> | 2010-03-10 10:31:01 +0100 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-03-19 08:45:31 +0100 |
commit | 01e9651a21bc0e6731da733593e4aaf4cf46b5e5 (patch) | |
tree | 133befa54fca69f3b4c4bc1ffcc621bb5fb4f9b0 /drivers/sh | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vap... (diff) | |
download | linux-01e9651a21bc0e6731da733593e4aaf4cf46b5e5.tar.xz linux-01e9651a21bc0e6731da733593e4aaf4cf46b5e5.zip |
sh: add INTC out of memory error handling
Extend the INTC code to warn and return an error code
in the case of memory allocation failure.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/sh')
-rw-r--r-- | drivers/sh/intc.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index c2750391fd34..d4aa4d1e8dce 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -789,13 +789,15 @@ static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc) generic_handle_irq((unsigned int)get_irq_data(irq)); } -void __init register_intc_controller(struct intc_desc *desc) +int __init register_intc_controller(struct intc_desc *desc) { unsigned int i, k, smp; struct intc_hw_desc *hw = &desc->hw; struct intc_desc_int *d; d = kzalloc(sizeof(*d), GFP_NOWAIT); + if (!d) + goto err0; INIT_LIST_HEAD(&d->list); list_add(&d->list, &intc_list); @@ -806,8 +808,13 @@ void __init register_intc_controller(struct intc_desc *desc) d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0; d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT); + if (!d->reg) + goto err1; + #ifdef CONFIG_SMP d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT); + if (!d->smp) + goto err2; #endif k = 0; @@ -822,6 +829,8 @@ void __init register_intc_controller(struct intc_desc *desc) if (hw->prio_regs) { d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio), GFP_NOWAIT); + if (!d->prio) + goto err3; for (i = 0; i < hw->nr_prio_regs; i++) { smp = IS_SMP(hw->prio_regs[i]); @@ -833,6 +842,8 @@ void __init register_intc_controller(struct intc_desc *desc) if (hw->sense_regs) { d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense), GFP_NOWAIT); + if (!d->sense) + goto err4; for (i = 0; i < hw->nr_sense_regs; i++) k += save_reg(d, k, hw->sense_regs[i].reg, 0); @@ -912,6 +923,22 @@ void __init register_intc_controller(struct intc_desc *desc) /* enable bits matching force_enable after registering irqs */ if (desc->force_enable) intc_enable_disable_enum(desc, d, desc->force_enable, 1); + + return 0; + err4: + kfree(d->prio); + err3: +#ifdef CONFIG_SMP + kfree(d->smp); + err2: +#endif + kfree(d->reg); + err1: + kfree(d); + err0: + pr_err("unable to allocate INTC memory\n"); + + return -ENOMEM; } static int intc_suspend(struct sys_device *dev, pm_message_t state) |