diff mbox

[U-Boot,v2,3/5] sunxi: When we've both mmc0 and mmc2, detect from which one we're booting

Message ID 1412618265-4053-4-git-send-email-hdegoede@redhat.com
State Superseded
Headers show

Commit Message

Hans de Goede Oct. 6, 2014, 5:57 p.m. UTC
sunxi SOCs can boot from both mmc0 and mmc2, detect from which one we're
booting, and make that one "mmc dev 0" so that a single u-boot binary can
be used for both the onboard eMMC and for external sdcards.

When we're booting from mmc2, we make it dev 0 because that is where the SPL
will load the tertiary payload (the actual u-boot binary in our case) from,
see: common/spl/spl_mmc.c, which has dev 0 hardcoded everywhere.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/include/asm/arch-sunxi/mmc.h |  2 +-
 board/sunxi/board.c                   | 25 +++++++++++++++++++++++--
 drivers/mmc/sunxi_mmc.c               |  7 ++-----
 3 files changed, 26 insertions(+), 8 deletions(-)

Comments

Ian Campbell Oct. 11, 2014, 3:43 p.m. UTC | #1
On Mon, 2014-10-06 at 19:57 +0200, Hans de Goede wrote:
> @@ -108,11 +109,31 @@ static void mmc_pinmux_setup(int sdc)
>  
>  int board_mmc_init(bd_t *bis)
>  {
> +	__maybe_unused struct mmc *mmc0, *mmc1;
> +	__maybe_unused char buf[512];
> +
>  	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
> -	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
> +	mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
>  #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
>  	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
> -	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
> +	mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
> +#endif
> +
> +#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
> +	/*
> +	 * Both mmc0 and mmc2 are bootable, figure out where we're booting
> +	 * from. Try mmc0 first, just like the brom does.
> +	 */
> +	if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&

If sunxi_mmx_init failed then mmc0 might be NULL here.

> +	    mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
> +		buf[12] = 0;
> +		if (strcmp(&buf[4], "eGON.BT0") == 0)
> +			return 0;
> +	}
> +
> +	/* no bootable card in mmc0, so we must be booting from mmc2, swap */
> +	mmc0->block_dev.dev = 1;
> +	mmc1->block_dev.dev = 0;

and mmc1 could be NULL here.

Ian.
Hans de Goede Oct. 12, 2014, 9:20 a.m. UTC | #2
Hi,

On 10/11/2014 05:43 PM, Ian Campbell wrote:
> On Mon, 2014-10-06 at 19:57 +0200, Hans de Goede wrote:
>> @@ -108,11 +109,31 @@ static void mmc_pinmux_setup(int sdc)
>>  
>>  int board_mmc_init(bd_t *bis)
>>  {
>> +	__maybe_unused struct mmc *mmc0, *mmc1;
>> +	__maybe_unused char buf[512];
>> +
>>  	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
>> -	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
>> +	mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
>>  #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
>>  	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
>> -	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
>> +	mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
>> +#endif
>> +
>> +#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
>> +	/*
>> +	 * Both mmc0 and mmc2 are bootable, figure out where we're booting
>> +	 * from. Try mmc0 first, just like the brom does.
>> +	 */
>> +	if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&
> 
> If sunxi_mmx_init failed then mmc0 might be NULL here.
> 
>> +	    mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
>> +		buf[12] = 0;
>> +		if (strcmp(&buf[4], "eGON.BT0") == 0)
>> +			return 0;
>> +	}
>> +
>> +	/* no bootable card in mmc0, so we must be booting from mmc2, swap */
>> +	mmc0->block_dev.dev = 1;
>> +	mmc1->block_dev.dev = 0;
> 
> and mmc1 could be NULL here.

Hmm, this only happens when the calloc in mmc_create fails. I'll fix this in
v3, but I really believe that we should just switch u-boot over to the glib
malloc model of malloc should never fail.

Regards,

Hans


> 
> Ian.
>
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 53196e3..ff2602d 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -120,5 +120,5 @@  struct sunxi_mmc {
 #define SUNXI_MMC_IDIE_TXIRQ		(0x1 << 0)
 #define SUNXI_MMC_IDIE_RXIRQ		(0x1 << 1)
 
-int sunxi_mmc_init(int sdc_no);
+struct mmc *sunxi_mmc_init(int sdc_no);
 #endif /* _SUNXI_MMC_H */
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 4d602ca..0a7be31 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -12,6 +12,7 @@ 
  */
 
 #include <common.h>
+#include <mmc.h>
 #ifdef CONFIG_AXP152_POWER
 #include <axp152.h>
 #endif
@@ -108,11 +109,31 @@  static void mmc_pinmux_setup(int sdc)
 
 int board_mmc_init(bd_t *bis)
 {
+	__maybe_unused struct mmc *mmc0, *mmc1;
+	__maybe_unused char buf[512];
+
 	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
-	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
+	mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
 #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
 	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
-	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+	mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+#endif
+
+#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
+	/*
+	 * Both mmc0 and mmc2 are bootable, figure out where we're booting
+	 * from. Try mmc0 first, just like the brom does.
+	 */
+	if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&
+	    mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
+		buf[12] = 0;
+		if (strcmp(&buf[4], "eGON.BT0") == 0)
+			return 0;
+	}
+
+	/* no bootable card in mmc0, so we must be booting from mmc2, swap */
+	mmc0->block_dev.dev = 1;
+	mmc1->block_dev.dev = 0;
 #endif
 
 	return 0;
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 0ea9f4d..7526540 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -370,7 +370,7 @@  static const struct mmc_ops sunxi_mmc_ops = {
 	.getcd		= sunxi_mmc_getcd,
 };
 
-int sunxi_mmc_init(int sdc_no)
+struct mmc *sunxi_mmc_init(int sdc_no)
 {
 	struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
 
@@ -393,8 +393,5 @@  int sunxi_mmc_init(int sdc_no)
 	mmc_resource_init(sdc_no);
 	mmc_clk_io_on(sdc_no);
 
-	if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL)
-		return -1;
-
-	return 0;
+	return mmc_create(cfg, &mmc_host[sdc_no]);
 }