Skip to content

Commit

Permalink
sh: add INTC out of memory error handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Mar 19, 2010
1 parent 3971047 commit 01e9651
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
29 changes: 28 additions & 1 deletion drivers/sh/intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;

Expand All @@ -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]);
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion include/linux/sh_intc.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ struct intc_desc symbol __initdata = { \
prio_regs, sense_regs, ack_regs), \
}

void __init register_intc_controller(struct intc_desc *desc);
int __init register_intc_controller(struct intc_desc *desc);
int intc_set_priority(unsigned int irq, unsigned int prio);

int reserve_irq_vector(unsigned int irq);
Expand Down

0 comments on commit 01e9651

Please sign in to comment.