diff options
author | Jon Hunter <jon-hunter@ti.com> | 2012-10-17 10:41:25 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-10-17 12:01:14 -0400 |
commit | 8119024ef7363591fd958ec89ebfaee7c18209e3 (patch) | |
tree | 254fb2179b4ba243557177947d99ab87b29a7cc4 /arch/arm/mach-omap2/gpmc.c | |
parent | 64e29fd5ed42f5d0ff5b0ea9395b3abd5d43f89b (diff) |
ARM: OMAP2+: Allow kernel to boot even if GPMC fails to reserve memory
Currently, if the GPMC driver fails to reserve memory when probed we will
call BUG() and the kernel will not boot. Instead of calling BUG(), return
an error from probe and allow kernel to boot.
Boot tested on AM335x beagle bone board and OMAP4430 Panda board.
V2 changes:
- Ensure that clock and memory resources are released on error.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/gpmc.c')
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 5ac5cf30406a..92b5718fa722 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -868,9 +868,9 @@ static void __devexit gpmc_mem_exit(void) | |||
868 | 868 | ||
869 | } | 869 | } |
870 | 870 | ||
871 | static void __devinit gpmc_mem_init(void) | 871 | static int __devinit gpmc_mem_init(void) |
872 | { | 872 | { |
873 | int cs; | 873 | int cs, rc; |
874 | unsigned long boot_rom_space = 0; | 874 | unsigned long boot_rom_space = 0; |
875 | 875 | ||
876 | /* never allocate the first page, to facilitate bug detection; | 876 | /* never allocate the first page, to facilitate bug detection; |
@@ -890,13 +890,21 @@ static void __devinit gpmc_mem_init(void) | |||
890 | if (!gpmc_cs_mem_enabled(cs)) | 890 | if (!gpmc_cs_mem_enabled(cs)) |
891 | continue; | 891 | continue; |
892 | gpmc_cs_get_memconf(cs, &base, &size); | 892 | gpmc_cs_get_memconf(cs, &base, &size); |
893 | if (gpmc_cs_insert_mem(cs, base, size) < 0) | 893 | rc = gpmc_cs_insert_mem(cs, base, size); |
894 | BUG(); | 894 | if (IS_ERR_VALUE(rc)) { |
895 | while (--cs >= 0) | ||
896 | if (gpmc_cs_mem_enabled(cs)) | ||
897 | gpmc_cs_delete_mem(cs); | ||
898 | return rc; | ||
899 | } | ||
895 | } | 900 | } |
901 | |||
902 | return 0; | ||
896 | } | 903 | } |
897 | 904 | ||
898 | static __devinit int gpmc_probe(struct platform_device *pdev) | 905 | static __devinit int gpmc_probe(struct platform_device *pdev) |
899 | { | 906 | { |
907 | int rc; | ||
900 | u32 l; | 908 | u32 l; |
901 | struct resource *res; | 909 | struct resource *res; |
902 | 910 | ||
@@ -936,7 +944,13 @@ static __devinit int gpmc_probe(struct platform_device *pdev) | |||
936 | dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), | 944 | dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), |
937 | GPMC_REVISION_MINOR(l)); | 945 | GPMC_REVISION_MINOR(l)); |
938 | 946 | ||
939 | gpmc_mem_init(); | 947 | rc = gpmc_mem_init(); |
948 | if (IS_ERR_VALUE(rc)) { | ||
949 | clk_disable_unprepare(gpmc_l3_clk); | ||
950 | clk_put(gpmc_l3_clk); | ||
951 | dev_err(gpmc_dev, "failed to reserve memory\n"); | ||
952 | return rc; | ||
953 | } | ||
940 | 954 | ||
941 | if (IS_ERR_VALUE(gpmc_setup_irq())) | 955 | if (IS_ERR_VALUE(gpmc_setup_irq())) |
942 | dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); | 956 | dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); |