diff options
author | Magnus Damm <damm@opensource.se> | 2010-03-10 04:31:01 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-03-19 03:45:31 -0400 |
commit | 01e9651a21bc0e6731da733593e4aaf4cf46b5e5 (patch) | |
tree | 133befa54fca69f3b4c4bc1ffcc621bb5fb4f9b0 /drivers/sh | |
parent | 39710479303fd3affb3e204e9a7a75cc676977b5 (diff) |
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) | |||
789 | generic_handle_irq((unsigned int)get_irq_data(irq)); | 789 | generic_handle_irq((unsigned int)get_irq_data(irq)); |
790 | } | 790 | } |
791 | 791 | ||
792 | void __init register_intc_controller(struct intc_desc *desc) | 792 | int __init register_intc_controller(struct intc_desc *desc) |
793 | { | 793 | { |
794 | unsigned int i, k, smp; | 794 | unsigned int i, k, smp; |
795 | struct intc_hw_desc *hw = &desc->hw; | 795 | struct intc_hw_desc *hw = &desc->hw; |
796 | struct intc_desc_int *d; | 796 | struct intc_desc_int *d; |
797 | 797 | ||
798 | d = kzalloc(sizeof(*d), GFP_NOWAIT); | 798 | d = kzalloc(sizeof(*d), GFP_NOWAIT); |
799 | if (!d) | ||
800 | goto err0; | ||
799 | 801 | ||
800 | INIT_LIST_HEAD(&d->list); | 802 | INIT_LIST_HEAD(&d->list); |
801 | list_add(&d->list, &intc_list); | 803 | list_add(&d->list, &intc_list); |
@@ -806,8 +808,13 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
806 | d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0; | 808 | d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0; |
807 | 809 | ||
808 | d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT); | 810 | d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT); |
811 | if (!d->reg) | ||
812 | goto err1; | ||
813 | |||
809 | #ifdef CONFIG_SMP | 814 | #ifdef CONFIG_SMP |
810 | d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT); | 815 | d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT); |
816 | if (!d->smp) | ||
817 | goto err2; | ||
811 | #endif | 818 | #endif |
812 | k = 0; | 819 | k = 0; |
813 | 820 | ||
@@ -822,6 +829,8 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
822 | if (hw->prio_regs) { | 829 | if (hw->prio_regs) { |
823 | d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio), | 830 | d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio), |
824 | GFP_NOWAIT); | 831 | GFP_NOWAIT); |
832 | if (!d->prio) | ||
833 | goto err3; | ||
825 | 834 | ||
826 | for (i = 0; i < hw->nr_prio_regs; i++) { | 835 | for (i = 0; i < hw->nr_prio_regs; i++) { |
827 | smp = IS_SMP(hw->prio_regs[i]); | 836 | smp = IS_SMP(hw->prio_regs[i]); |
@@ -833,6 +842,8 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
833 | if (hw->sense_regs) { | 842 | if (hw->sense_regs) { |
834 | d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense), | 843 | d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense), |
835 | GFP_NOWAIT); | 844 | GFP_NOWAIT); |
845 | if (!d->sense) | ||
846 | goto err4; | ||
836 | 847 | ||
837 | for (i = 0; i < hw->nr_sense_regs; i++) | 848 | for (i = 0; i < hw->nr_sense_regs; i++) |
838 | k += save_reg(d, k, hw->sense_regs[i].reg, 0); | 849 | k += save_reg(d, k, hw->sense_regs[i].reg, 0); |
@@ -912,6 +923,22 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
912 | /* enable bits matching force_enable after registering irqs */ | 923 | /* enable bits matching force_enable after registering irqs */ |
913 | if (desc->force_enable) | 924 | if (desc->force_enable) |
914 | intc_enable_disable_enum(desc, d, desc->force_enable, 1); | 925 | intc_enable_disable_enum(desc, d, desc->force_enable, 1); |
926 | |||
927 | return 0; | ||
928 | err4: | ||
929 | kfree(d->prio); | ||
930 | err3: | ||
931 | #ifdef CONFIG_SMP | ||
932 | kfree(d->smp); | ||
933 | err2: | ||
934 | #endif | ||
935 | kfree(d->reg); | ||
936 | err1: | ||
937 | kfree(d); | ||
938 | err0: | ||
939 | pr_err("unable to allocate INTC memory\n"); | ||
940 | |||
941 | return -ENOMEM; | ||
915 | } | 942 | } |
916 | 943 | ||
917 | static int intc_suspend(struct sys_device *dev, pm_message_t state) | 944 | static int intc_suspend(struct sys_device *dev, pm_message_t state) |