[U-Boot] [PATCH v2 00/15] dm: sata: mmc: Convert a sunxi board to driver model for MMC, SATA

At present SCSI support for driver model works only with PCI controllers.
This series makes the following changes:
- Adjusts SATA/AHCI support to work with non-PCI controllers - Allows driver model to be used for MMC in U-Boot proper without requiring it to be used in SPL - Adjusts sunxi MMC and SATA drivers to support driver model - Enables this on a single board (Linksprite_pcDuino3)
Even with this series the AHCI uclass still does not have any operations. This will be needed for drivers which do not use SCSI. Further work is needed to complete this.
Changes in v2: - Drop debugging printf() now that the card detect is working - Add new patch to correct polarity of MMC card detect on Linksprite_pcDuino3
Simon Glass (15): ahci: Support non-PCI controllers dm: mmc: Allow disabling driver model in SPL fdt: Correct fdt_get_base_address() dm: scsi: Drop duplicate SCSI and DM_SCSI options dm: ahci: Correct uclass private data dm: mmc: sunxi: Rename struct sunxi_mmc_host to sunxi_mmc_priv dm: mmc: sunxi: Rename mmchost to priv dm: mmc: sunxi: Pass private data around explicitly dm: mmc: sunxi: Drop mmc_clk_io_on() dm: mmc: sunxi: Add support for driver model dm: sunxi: Linksprite_pcDuino3: Correct polarity of MMC card detect dm: scsi: Don't scan the SCSI bus when probing dm: sunxi: sata: Don't build sata support into SPL dm: sata: sunxi: Add support for driver model dm: sunxi: Move Linksprite_pcDuino3 to use DM for MMC, SATA
arch/arm/dts/sun7i-a20-pcduino3.dts | 2 +- arch/x86/cpu/ivybridge/sata.c | 2 +- board/sunxi/Makefile | 2 + board/sunxi/ahci.c | 61 +++++- common/fdt_support.c | 7 +- common/spl/spl_mmc.c | 4 +- configs/Linksprite_pcDuino3_defconfig | 7 +- drivers/ata/Kconfig | 18 -- drivers/ata/ahci-uclass.c | 2 + drivers/ata/ahci.c | 33 ++-- drivers/block/Kconfig | 12 ++ drivers/block/Makefile | 4 +- drivers/mmc/Kconfig | 21 ++ drivers/mmc/Makefile | 4 +- drivers/mmc/mmc-uclass.c | 6 +- drivers/mmc/mmc.c | 28 +-- drivers/mmc/mmc_legacy.c | 2 +- drivers/mmc/mmc_private.h | 6 +- drivers/mmc/omap_hsmmc.c | 20 +- drivers/mmc/sunxi_mmc.c | 359 +++++++++++++++++++++++----------- drivers/scsi/scsi.c | 2 +- include/ahci.h | 14 +- include/blk.h | 4 +- include/mmc.h | 12 +- 24 files changed, 431 insertions(+), 201 deletions(-)

At present the AHCI SCSI driver only supports PCI with driver model. Rename the existing function to indicate this and add support for adding a non-PCI controller .
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/cpu/ivybridge/sata.c | 2 +- drivers/ata/ahci.c | 26 +++++++++++++++++--------- include/ahci.h | 14 +++++++++++++- 3 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c index 462b7c09dd..7febb8cf88 100644 --- a/arch/x86/cpu/ivybridge/sata.c +++ b/arch/x86/cpu/ivybridge/sata.c @@ -236,7 +236,7 @@ static int bd82x6x_sata_probe(struct udevice *dev) bd82x6x_sata_enable(dev); else { bd82x6x_sata_init(dev, pch); - ret = ahci_probe_scsi(dev); + ret = ahci_probe_scsi_pci(dev); if (ret) return ret; } diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6da412d178..035db85b45 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -431,7 +431,7 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv) cap2 & (1 << 0) ? "boh " : ""); }
-#ifndef CONFIG_SCSI_AHCI_PLAT +#if defined(CONFIG_DM_SCSI) || !defined(CONFIG_SCSI_AHCI_PLAT) # if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI) static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev) # else @@ -1158,11 +1158,8 @@ int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp) return 0; }
-int ahci_probe_scsi(struct udevice *ahci_dev) +int ahci_probe_scsi(struct udevice *ahci_dev, ulong base) { -#ifdef CONFIG_SCSI_AHCI_PLAT - return -ENOSYS; /* TODO(sjg@chromium.org): Support non-PCI AHCI */ -#else struct ahci_uc_priv *uc_priv; struct scsi_platdata *uc_plat; struct udevice *dev; @@ -1172,11 +1169,11 @@ int ahci_probe_scsi(struct udevice *ahci_dev) if (!dev) return -ENODEV; uc_plat = dev_get_uclass_platdata(dev); - uc_plat->base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5, - PCI_REGION_MEM); + uc_plat->base = base; uc_plat->max_lun = 1; uc_plat->max_id = 2; - uc_priv = dev_get_uclass_priv(dev); + + uc_priv = dev_get_uclass_priv(ahci_dev); ret = ahci_init_one(uc_priv, dev); if (ret) return ret; @@ -1188,11 +1185,22 @@ int ahci_probe_scsi(struct udevice *ahci_dev) ret = scsi_scan_dev(dev, true); if (ret) return ret; -#endif
return 0; }
+#ifdef CONFIG_DM_PCI +int ahci_probe_scsi_pci(struct udevice *ahci_dev) +{ + ulong base; + + base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5, + PCI_REGION_MEM); + + return ahci_probe_scsi(ahci_dev, base); +} +#endif + struct scsi_ops scsi_ops = { .exec = ahci_scsi_exec, .bus_reset = ahci_scsi_bus_reset, diff --git a/include/ahci.h b/include/ahci.h index 818f34464e..29f4ba1d13 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -218,8 +218,20 @@ int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp); * devices it finds. * * @ahci_dev: AHCI parent device + * @base: Base address of AHCI port * @return 0 if OK, -ve on error */ -int ahci_probe_scsi(struct udevice *ahci_dev); +int ahci_probe_scsi(struct udevice *ahci_dev, ulong base); + +/** + * ahci_probe_scsi_pci() - probe and scan the attached SCSI bus on PCI + * + * Note that the SCSI device will itself bind block devices for any storage + * devices it finds. + * + * @ahci_dev: AHCI parent device + * @return 0 if OK, -ve on error + */ +int ahci_probe_scsi_pci(struct udevice *ahci_dev);
#endif

At present if U-Boot proper uses driver model for MMC, then SPL has to also. While this is desirable, it places a significant barrier to moving to driver model in some cases. For example, with a space-constrained SPL it may be necessary to enable CONFIG_SPL_OF_PLATDATA which involves adjusting some drivers.
Add new SPL versions of the options for DM_MMC, DM_MMC_OPS and BLK. By default these follow their non-SPL versions, but this can be changed by boards which need it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
common/spl/spl_mmc.c | 4 ++-- drivers/block/Kconfig | 12 ++++++++++++ drivers/block/Makefile | 4 ++-- drivers/mmc/Kconfig | 21 +++++++++++++++++++++ drivers/mmc/Makefile | 4 ++-- drivers/mmc/mmc-uclass.c | 6 +++--- drivers/mmc/mmc.c | 28 ++++++++++++++-------------- drivers/mmc/mmc_legacy.c | 2 +- drivers/mmc/mmc_private.h | 6 +++--- drivers/mmc/omap_hsmmc.c | 20 ++++++++++---------- drivers/scsi/scsi.c | 2 +- include/blk.h | 4 ++-- include/mmc.h | 12 ++++++------ 13 files changed, 79 insertions(+), 46 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 18c1b59b22..953e484e27 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -115,7 +115,7 @@ int spl_mmc_get_device_index(u32 boot_device)
static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct udevice *dev; #endif int err, mmc_dev; @@ -132,7 +132,7 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) return err; }
-#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev); if (!err) *mmcp = mmc_get_mmc_dev(dev); diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ca7692d8a5..26760895f9 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -10,6 +10,18 @@ config BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition.
+config SPL_BLK + bool "Support block devices in SPL" + depends on SPL_DM && BLK + default y + help + Enable support for block devices, such as SCSI, MMC and USB + flash sticks. These provide a block-level interface which permits + reading, writing and (in some cases) erasing blocks. Block + devices often have a partition table which allows the device to + be partitioned into several areas, called 'partitions' in U-Boot. + A filesystem can be placed in each partition. + config BLOCK_CACHE bool "Use block device cache" default n diff --git a/drivers/block/Makefile b/drivers/block/Makefile index a5e7307c97..dea2c15c14 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -5,9 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_BLK) += blk-uclass.o +obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o
-ifndef CONFIG_BLK +ifndef CONFIG_$(SPL_)BLK obj-y += blk_legacy.o endif
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 82b8d75686..51a87cdd77 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -30,6 +30,27 @@ config DM_MMC_OPS option will be removed as soon as all DM_MMC drivers use it, as it will the only supported behaviour.
+config SPL_DM_MMC + bool "Enable MMC controllers using Driver Model in SPL" + depends on SPL_DM && DM_MMC + default y + help + This enables the MultiMediaCard (MMC) uclass which supports MMC and + Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.) + and non-removable (e.g. eMMC chip) devices are supported. These + appear as block devices in U-Boot and can support filesystems such + as EXT4 and FAT. + +config SPL_DM_MMC_OPS + bool "Support MMC controller operations using Driver Model in SPL" + depends on SPL_DM && DM_MMC_OPS + default y + help + Driver model provides a means of supporting device operations. This + option moves MMC operations under the control of driver model. The + option will be removed as soon as all DM_MMC drivers use it, as it + will the only supported behaviour. + if MMC
config SPL_MMC_TINY diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2d781c38a6..a6becb2309 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -6,9 +6,9 @@ #
obj-y += mmc.o -obj-$(CONFIG_DM_MMC) += mmc-uclass.o +obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
-ifndef CONFIG_BLK +ifndef CONFIG_$(SPL_)BLK obj-y += mmc_legacy.o endif
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 994d2686f4..3e907253ea 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -15,7 +15,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -91,7 +91,7 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev) return upriv->mmc; }
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct mmc *find_mmc_device(int dev_num) { struct udevice *dev, *mmc_dev; @@ -198,7 +198,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) struct udevice *bdev; int ret, devnum = -1;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) if (!mmc_get_ops(dev)) return -ENOSYS; #endif diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 3cdf6a4f3b..38e1c800e1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -53,7 +53,7 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) } #endif
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -149,7 +149,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) } #endif
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { int ret; @@ -261,14 +261,14 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, return blkcnt; }
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst) #else ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, void *dst) #endif { -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct blk_desc *block_dev = dev_get_uclass_platdata(dev); #endif int dev_num = block_dev->devnum; @@ -839,7 +839,7 @@ int mmc_hwpart_config(struct mmc *mmc, return 0; }
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) int mmc_getcd(struct mmc *mmc) { int cd; @@ -1075,7 +1075,7 @@ static const u8 multipliers[] = { 80, };
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) static void mmc_set_ios(struct mmc *mmc) { if (mmc->cfg->ops->set_ios) @@ -1608,7 +1608,7 @@ static int mmc_send_if_cond(struct mmc *mmc) return 0; }
-#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) /* board-specific MMC power initializations. */ __weak void board_mmc_power_init(void) { @@ -1617,7 +1617,7 @@ __weak void board_mmc_power_init(void)
static int mmc_power_init(struct mmc *mmc) { -#if defined(CONFIG_DM_MMC) +#if CONFIG_IS_ENABLED(DM_MMC) #if defined(CONFIG_DM_REGULATOR) && !defined(CONFIG_SPL_BUILD) struct udevice *vmmc_supply; int ret; @@ -1652,7 +1652,7 @@ int mmc_start_init(struct mmc *mmc)
/* we pretend there's no card when init is NULL */ no_card = mmc_getcd(mmc) == 0; -#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) no_card = no_card || (mmc->cfg->ops->init == NULL); #endif if (no_card) { @@ -1673,7 +1673,7 @@ int mmc_start_init(struct mmc *mmc) if (err) return err;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) /* The device has already been probed ready for use */ #else /* made sure it's not NULL earlier */ @@ -1739,7 +1739,7 @@ int mmc_init(struct mmc *mmc) { int err = 0; __maybe_unused unsigned start; -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
upriv->mmc = mmc; @@ -1783,12 +1783,12 @@ void mmc_set_preinit(struct mmc *mmc, int preinit) mmc->preinit = preinit; }
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(DM_MMC) && defined(CONFIG_SPL_BUILD) static int mmc_probe(bd_t *bis) { return 0; } -#elif defined(CONFIG_DM_MMC) +#elif CONFIG_IS_ENABLED(DM_MMC) static int mmc_probe(bd_t *bis) { int ret, i; @@ -1835,7 +1835,7 @@ int mmc_initialize(bd_t *bis) return 0; initialized = 1;
-#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) #if !CONFIG_IS_ENABLED(MMC_TINY) mmc_list_init(); #endif diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index bdf9d984dd..59dc3df35f 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -150,7 +150,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) cfg->f_max == 0 || cfg->b_max == 0) return NULL;
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) if (cfg->ops == NULL || cfg->ops->send_cmd == NULL) return NULL; #endif diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index 03bf24d5fe..1290eed590 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -20,7 +20,7 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len); void mmc_adapter_card_type_ident(void); #endif
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst); #else @@ -30,7 +30,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, const void *src); ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt); @@ -44,7 +44,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
/* declare dummies to reduce code size. */
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) static inline unsigned long mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) { diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index bb10caaf32..efa43896fc 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -62,11 +62,11 @@ struct omap2_mmc_platform_config {
struct omap_hsmmc_data { struct hsmmc *base_addr; -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) struct mmc_config cfg; #endif #ifdef OMAP_HSMMC_USE_GPIO -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct gpio_desc cd_gpio; /* Change Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ bool cd_inverted; @@ -86,7 +86,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) return dev_get_priv(mmc->dev); #else return (struct omap_hsmmc_data *)mmc->priv; @@ -94,7 +94,7 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc) } static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct omap_hsmmc_plat *plat = dev_get_platdata(mmc->dev); return &plat->cfg; #else @@ -102,7 +102,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) #endif }
- #if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC) +#if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC) static int omap_mmc_setup_gpio_in(int gpio, const char *label) { int ret; @@ -326,7 +326,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } } -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -564,7 +564,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, return 0; }
-#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_set_ios(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); @@ -630,7 +630,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev) }
#ifdef OMAP_HSMMC_USE_GPIO -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_getcd(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); @@ -688,7 +688,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc) #endif #endif
-#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) static const struct dm_mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, .set_ios = omap_hsmmc_set_ios, @@ -709,7 +709,7 @@ static const struct mmc_ops omap_hsmmc_ops = { }; #endif
-#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, int wp_gpio) { diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7ec7ecc295..f192ca597c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -451,7 +451,7 @@ static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc) dev_desc->product[0] = 0; dev_desc->revision[0] = 0; dev_desc->removable = false; -#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) dev_desc->block_read = scsi_read; dev_desc->block_write = scsi_write; #endif diff --git a/include/blk.h b/include/blk.h index ef29a07ee2..1e6239ac9e 100644 --- a/include/blk.h +++ b/include/blk.h @@ -62,7 +62,7 @@ struct blk_desc { char vendor[40+1]; /* IDE model, SCSI Vendor */ char product[20+1]; /* IDE Serial no, SCSI product */ char revision[8+1]; /* firmware revision */ -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) /* * For now we have a few functions which take struct blk_desc as a * parameter. This field allows them to look up the associated @@ -174,7 +174,7 @@ static inline void blkcache_invalidate(int iftype, int dev) {}
#endif
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct udevice;
/* Operations on block devices */ diff --git a/include/mmc.h b/include/mmc.h index 00576fa3d0..ad9716c057 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -321,7 +321,7 @@ struct mmc_data { /* forward decl. */ struct mmc;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) struct dm_mmc_ops { /** * send_cmd() - Send a command to the MMC device @@ -385,7 +385,7 @@ struct mmc_ops {
struct mmc_config { const char *name; -#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) const struct mmc_ops *ops; #endif uint host_caps; @@ -409,7 +409,7 @@ struct sd_ssr { * TODO struct mmc should be in mmc_private but it's hard to fix right now */ struct mmc { -#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) struct list_head link; #endif const struct mmc_config *cfg; /* provided configuration */ @@ -444,14 +444,14 @@ struct mmc { u64 capacity_gp[4]; u64 enh_user_start; u64 enh_user_size; -#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) struct blk_desc block_dev; #endif char op_cond_pending; /* 1 if we are waiting on an op_cond command */ char init_in_progress; /* 1 if we have done mmc_start_init() */ char preinit; /* start init as early as possible */ int ddr_mode; -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct udevice *dev; /* Device for this MMC controller */ #endif }; @@ -519,7 +519,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num); int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode);
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) int mmc_getcd(struct mmc *mmc); int board_mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc);

Hi Simon,
On 04/07/2017 21:31, Simon Glass wrote:
At present if U-Boot proper uses driver model for MMC, then SPL has to also. While this is desirable, it places a significant barrier to moving to driver model in some cases. For example, with a space-constrained SPL it may be necessary to enable CONFIG_SPL_OF_PLATDATA which involves adjusting some drivers.
Add new SPL versions of the options for DM_MMC, DM_MMC_OPS and BLK. By default these follow their non-SPL versions, but this can be changed by boards which need it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
common/spl/spl_mmc.c | 4 ++-- drivers/block/Kconfig | 12 ++++++++++++ drivers/block/Makefile | 4 ++-- drivers/mmc/Kconfig | 21 +++++++++++++++++++++ drivers/mmc/Makefile | 4 ++-- drivers/mmc/mmc-uclass.c | 6 +++--- drivers/mmc/mmc.c | 28 ++++++++++++++-------------- drivers/mmc/mmc_legacy.c | 2 +- drivers/mmc/mmc_private.h | 6 +++--- drivers/mmc/omap_hsmmc.c | 20 ++++++++++---------- drivers/scsi/scsi.c | 2 +- include/blk.h | 4 ++-- include/mmc.h | 12 ++++++------ 13 files changed, 79 insertions(+), 46 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 18c1b59b22..953e484e27 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -115,7 +115,7 @@ int spl_mmc_get_device_index(u32 boot_device)
static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct udevice *dev; #endif int err, mmc_dev; @@ -132,7 +132,7 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) return err; }
-#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev); if (!err) *mmcp = mmc_get_mmc_dev(dev); diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ca7692d8a5..26760895f9 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -10,6 +10,18 @@ config BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition.
+config SPL_BLK
- bool "Support block devices in SPL"
- depends on SPL_DM && BLK
- default y
- help
Enable support for block devices, such as SCSI, MMC and USB
flash sticks. These provide a block-level interface which permits
reading, writing and (in some cases) erasing blocks. Block
devices often have a partition table which allows the device to
be partitioned into several areas, called 'partitions' in U-Boot.
A filesystem can be placed in each partition.
config BLOCK_CACHE bool "Use block device cache" default n diff --git a/drivers/block/Makefile b/drivers/block/Makefile index a5e7307c97..dea2c15c14 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -5,9 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_BLK) += blk-uclass.o +obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o
-ifndef CONFIG_BLK +ifndef CONFIG_$(SPL_)BLK obj-y += blk_legacy.o endif
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 82b8d75686..51a87cdd77 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -30,6 +30,27 @@ config DM_MMC_OPS option will be removed as soon as all DM_MMC drivers use it, as it will the only supported behaviour.
+config SPL_DM_MMC
- bool "Enable MMC controllers using Driver Model in SPL"
- depends on SPL_DM && DM_MMC
- default y
- help
This enables the MultiMediaCard (MMC) uclass which supports MMC and
Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.)
and non-removable (e.g. eMMC chip) devices are supported. These
appear as block devices in U-Boot and can support filesystems such
as EXT4 and FAT.
+config SPL_DM_MMC_OPS
bool "Support MMC controller operations using Driver Model in SPL"
depends on SPL_DM && DM_MMC_OPS
default y
help
Driver model provides a means of supporting device operations. This
option moves MMC operations under the control of driver model. The
option will be removed as soon as all DM_MMC drivers use it, as it
will the only supported behaviour.
if MMC
config SPL_MMC_TINY
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2d781c38a6..a6becb2309 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -6,9 +6,9 @@ #
obj-y += mmc.o -obj-$(CONFIG_DM_MMC) += mmc-uclass.o +obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
-ifndef CONFIG_BLK +ifndef CONFIG_$(SPL_)BLK obj-y += mmc_legacy.o endif
There are numerous places where #if(n)defCONFIG_BLK is used, should they not all be replaced with #if CONFIG_IS_ENABLED(BLK) ? In my case common/env_mmc.c won't compile because of this.
Other than this problem with common/env_mmc.c and a few other adjustments not related to the mmc that unselecting DM_SPL required, this has been tested OK on a TI DRA72 evm.
Jean-Jacques
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 994d2686f4..3e907253ea 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -15,7 +15,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -91,7 +91,7 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev) return upriv->mmc; }
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct mmc *find_mmc_device(int dev_num) { struct udevice *dev, *mmc_dev; @@ -198,7 +198,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) struct udevice *bdev; int ret, devnum = -1;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) if (!mmc_get_ops(dev)) return -ENOSYS; #endif diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 3cdf6a4f3b..38e1c800e1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -53,7 +53,7 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) } #endif
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -149,7 +149,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) } #endif
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { int ret; @@ -261,14 +261,14 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, return blkcnt; }
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst) #else ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, void *dst) #endif { -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct blk_desc *block_dev = dev_get_uclass_platdata(dev); #endif int dev_num = block_dev->devnum; @@ -839,7 +839,7 @@ int mmc_hwpart_config(struct mmc *mmc, return 0; }
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) int mmc_getcd(struct mmc *mmc) { int cd; @@ -1075,7 +1075,7 @@ static const u8 multipliers[] = { 80, };
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) static void mmc_set_ios(struct mmc *mmc) { if (mmc->cfg->ops->set_ios) @@ -1608,7 +1608,7 @@ static int mmc_send_if_cond(struct mmc *mmc) return 0; }
-#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) /* board-specific MMC power initializations. */ __weak void board_mmc_power_init(void) { @@ -1617,7 +1617,7 @@ __weak void board_mmc_power_init(void)
static int mmc_power_init(struct mmc *mmc) { -#if defined(CONFIG_DM_MMC) +#if CONFIG_IS_ENABLED(DM_MMC) #if defined(CONFIG_DM_REGULATOR) && !defined(CONFIG_SPL_BUILD) struct udevice *vmmc_supply; int ret; @@ -1652,7 +1652,7 @@ int mmc_start_init(struct mmc *mmc)
/* we pretend there's no card when init is NULL */ no_card = mmc_getcd(mmc) == 0; -#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) no_card = no_card || (mmc->cfg->ops->init == NULL); #endif if (no_card) { @@ -1673,7 +1673,7 @@ int mmc_start_init(struct mmc *mmc) if (err) return err;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) /* The device has already been probed ready for use */ #else /* made sure it's not NULL earlier */ @@ -1739,7 +1739,7 @@ int mmc_init(struct mmc *mmc) { int err = 0; __maybe_unused unsigned start; -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
upriv->mmc = mmc; @@ -1783,12 +1783,12 @@ void mmc_set_preinit(struct mmc *mmc, int preinit) mmc->preinit = preinit; }
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(DM_MMC) && defined(CONFIG_SPL_BUILD) static int mmc_probe(bd_t *bis) { return 0; } -#elif defined(CONFIG_DM_MMC) +#elif CONFIG_IS_ENABLED(DM_MMC) static int mmc_probe(bd_t *bis) { int ret, i; @@ -1835,7 +1835,7 @@ int mmc_initialize(bd_t *bis) return 0; initialized = 1;
-#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) #if !CONFIG_IS_ENABLED(MMC_TINY) mmc_list_init(); #endif diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index bdf9d984dd..59dc3df35f 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -150,7 +150,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) cfg->f_max == 0 || cfg->b_max == 0) return NULL;
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) if (cfg->ops == NULL || cfg->ops->send_cmd == NULL) return NULL; #endif diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index 03bf24d5fe..1290eed590 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -20,7 +20,7 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len); void mmc_adapter_card_type_ident(void); #endif
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst); #else @@ -30,7 +30,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, const void *src); ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt); @@ -44,7 +44,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
/* declare dummies to reduce code size. */
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) static inline unsigned long mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) { diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index bb10caaf32..efa43896fc 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -62,11 +62,11 @@ struct omap2_mmc_platform_config {
struct omap_hsmmc_data { struct hsmmc *base_addr; -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) struct mmc_config cfg; #endif #ifdef OMAP_HSMMC_USE_GPIO -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct gpio_desc cd_gpio; /* Change Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ bool cd_inverted; @@ -86,7 +86,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) return dev_get_priv(mmc->dev); #else return (struct omap_hsmmc_data *)mmc->priv; @@ -94,7 +94,7 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc) } static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct omap_hsmmc_plat *plat = dev_get_platdata(mmc->dev); return &plat->cfg; #else @@ -102,7 +102,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) #endif }
- #if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC)
+#if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC) static int omap_mmc_setup_gpio_in(int gpio, const char *label) { int ret; @@ -326,7 +326,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } } -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -564,7 +564,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, return 0; }
-#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_set_ios(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); @@ -630,7 +630,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev) }
#ifdef OMAP_HSMMC_USE_GPIO -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_getcd(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); @@ -688,7 +688,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc) #endif #endif
-#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) static const struct dm_mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, .set_ios = omap_hsmmc_set_ios, @@ -709,7 +709,7 @@ static const struct mmc_ops omap_hsmmc_ops = { }; #endif
-#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, int wp_gpio) { diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7ec7ecc295..f192ca597c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -451,7 +451,7 @@ static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc) dev_desc->product[0] = 0; dev_desc->revision[0] = 0; dev_desc->removable = false; -#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) dev_desc->block_read = scsi_read; dev_desc->block_write = scsi_write; #endif diff --git a/include/blk.h b/include/blk.h index ef29a07ee2..1e6239ac9e 100644 --- a/include/blk.h +++ b/include/blk.h @@ -62,7 +62,7 @@ struct blk_desc { char vendor[40+1]; /* IDE model, SCSI Vendor */ char product[20+1]; /* IDE Serial no, SCSI product */ char revision[8+1]; /* firmware revision */ -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) /* * For now we have a few functions which take struct blk_desc as a * parameter. This field allows them to look up the associated @@ -174,7 +174,7 @@ static inline void blkcache_invalidate(int iftype, int dev) {}
#endif
-#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct udevice;
/* Operations on block devices */ diff --git a/include/mmc.h b/include/mmc.h index 00576fa3d0..ad9716c057 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -321,7 +321,7 @@ struct mmc_data { /* forward decl. */ struct mmc;
-#ifdef CONFIG_DM_MMC_OPS +#if CONFIG_IS_ENABLED(DM_MMC_OPS) struct dm_mmc_ops { /** * send_cmd() - Send a command to the MMC device @@ -385,7 +385,7 @@ struct mmc_ops {
struct mmc_config { const char *name; -#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) const struct mmc_ops *ops; #endif uint host_caps; @@ -409,7 +409,7 @@ struct sd_ssr {
- TODO struct mmc should be in mmc_private but it's hard to fix right now
*/ struct mmc { -#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) struct list_head link; #endif const struct mmc_config *cfg; /* provided configuration */ @@ -444,14 +444,14 @@ struct mmc { u64 capacity_gp[4]; u64 enh_user_start; u64 enh_user_size; -#ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(BLK) struct blk_desc block_dev; #endif char op_cond_pending; /* 1 if we are waiting on an op_cond command */ char init_in_progress; /* 1 if we have done mmc_start_init() */ char preinit; /* start init as early as possible */ int ddr_mode; -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct udevice *dev; /* Device for this MMC controller */ #endif }; @@ -519,7 +519,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num); int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode);
-#ifndef CONFIG_DM_MMC_OPS +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) int mmc_getcd(struct mmc *mmc); int board_mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc);

Hi Jean-Jacques,
On 6 July 2017 at 08:55, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
Hi Simon,
On 04/07/2017 21:31, Simon Glass wrote:
At present if U-Boot proper uses driver model for MMC, then SPL has to also. While this is desirable, it places a significant barrier to moving to driver model in some cases. For example, with a space-constrained SPL it may be necessary to enable CONFIG_SPL_OF_PLATDATA which involves adjusting some drivers.
Add new SPL versions of the options for DM_MMC, DM_MMC_OPS and BLK. By default these follow their non-SPL versions, but this can be changed by boards which need it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
common/spl/spl_mmc.c | 4 ++-- drivers/block/Kconfig | 12 ++++++++++++ drivers/block/Makefile | 4 ++-- drivers/mmc/Kconfig | 21 +++++++++++++++++++++ drivers/mmc/Makefile | 4 ++-- drivers/mmc/mmc-uclass.c | 6 +++--- drivers/mmc/mmc.c | 28 ++++++++++++++-------------- drivers/mmc/mmc_legacy.c | 2 +- drivers/mmc/mmc_private.h | 6 +++--- drivers/mmc/omap_hsmmc.c | 20 ++++++++++---------- drivers/scsi/scsi.c | 2 +- include/blk.h | 4 ++-- include/mmc.h | 12 ++++++------ 13 files changed, 79 insertions(+), 46 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 18c1b59b22..953e484e27 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -115,7 +115,7 @@ int spl_mmc_get_device_index(u32 boot_device) static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct udevice *dev; #endif int err, mmc_dev; @@ -132,7 +132,7 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) return err; } -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev); if (!err) *mmcp = mmc_get_mmc_dev(dev); diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ca7692d8a5..26760895f9 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -10,6 +10,18 @@ config BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition. +config SPL_BLK
bool "Support block devices in SPL"
depends on SPL_DM && BLK
default y
help
Enable support for block devices, such as SCSI, MMC and USB
flash sticks. These provide a block-level interface which
permits
reading, writing and (in some cases) erasing blocks. Block
devices often have a partition table which allows the device to
be partitioned into several areas, called 'partitions' in
U-Boot.
A filesystem can be placed in each partition.
config BLOCK_CACHE bool "Use block device cache" default n diff --git a/drivers/block/Makefile b/drivers/block/Makefile index a5e7307c97..dea2c15c14 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -5,9 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_BLK) += blk-uclass.o +obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o -ifndef CONFIG_BLK +ifndef CONFIG_$(SPL_)BLK obj-y += blk_legacy.o endif diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 82b8d75686..51a87cdd77 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -30,6 +30,27 @@ config DM_MMC_OPS option will be removed as soon as all DM_MMC drivers use it, as it will the only supported behaviour. +config SPL_DM_MMC
bool "Enable MMC controllers using Driver Model in SPL"
depends on SPL_DM && DM_MMC
default y
help
This enables the MultiMediaCard (MMC) uclass which supports MMC
and
Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD,
etc.)
and non-removable (e.g. eMMC chip) devices are supported. These
appear as block devices in U-Boot and can support filesystems
such
as EXT4 and FAT.
+config SPL_DM_MMC_OPS
bool "Support MMC controller operations using Driver Model in SPL"
depends on SPL_DM && DM_MMC_OPS
default y
help
Driver model provides a means of supporting device operations.
This
option moves MMC operations under the control of driver model.
The
option will be removed as soon as all DM_MMC drivers use it, as
it
will the only supported behaviour.
- if MMC config SPL_MMC_TINY
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2d781c38a6..a6becb2309 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -6,9 +6,9 @@ # obj-y += mmc.o -obj-$(CONFIG_DM_MMC) += mmc-uclass.o +obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o -ifndef CONFIG_BLK +ifndef CONFIG_$(SPL_)BLK obj-y += mmc_legacy.o endif
There are numerous places where #if(n)defCONFIG_BLK is used, should they not all be replaced with #if CONFIG_IS_ENABLED(BLK) ? In my case common/env_mmc.c won't compile because of this.
I don't see a build error, but I'll rebase to master and see if I can.
My approach was to change the common uses and ones I had to change, but not going an change all boards to do this. I suspect it is the right thing to do ultimately, but for many boards it doesn't matter.
Other than this problem with common/env_mmc.c and a few other adjustments not related to the mmc that unselecting DM_SPL required, this has been tested OK on a TI DRA72 evm.
Jean-Jacques
[...]
Regards, Simon

This function appears to obtain the value of the 'ranges' property rather than 'reg'. As such it does not behave as documented or expected.
In addition it picks up the second field of the property which is the size (with prop += naddr) rather than the first which is the address.
Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
common/fdt_support.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 5aa8e3422e..7ccf8b19fd 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1464,14 +1464,11 @@ int fdt_verify_alias_address(void *fdt, int anode, const char *alias, u64 addr) u64 fdt_get_base_address(const void *fdt, int node) { int size; - u32 naddr; const fdt32_t *prop;
- naddr = fdt_address_cells(fdt, node); + prop = fdt_getprop(fdt, node, "reg", &size);
- prop = fdt_getprop(fdt, node, "ranges", &size); - - return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0; + return prop ? fdt_translate_address(fdt, node, prop) : 0; }
/*

When the SATA code was moved into drivers/ata these Kconfig options were added to that directory. They already exist in drivers/scsi. Remove them from drivers/ata to fix the duplication.
Signed-off-by: Simon Glass sjg@chromium.org Fixes: 7f2b5f4 (sata: Move drivers into new drivers/ata directory) ---
Changes in v2: None
drivers/ata/Kconfig | 18 ------------------ 1 file changed, 18 deletions(-)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 6427f1b94a..a1bd12ebe9 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -20,24 +20,6 @@ config SATA
See also CMD_SATA which provides command-line support.
-config SCSI - bool "Support SCSI controllers" - help - This enables support for SCSI (Small Computer System Interface), - a parallel interface widely used with storage peripherals such as - hard drives and optical drives. The SCSI standards define physical - interfaces as well as protocols for controlling devices and - tranferring data. - -config DM_SCSI - bool "Support SCSI controllers with driver model" - depends on BLK - help - This option enables the SCSI (Small Computer System Interface) uclass - which supports SCSI and SATA HDDs. For every device configuration - (IDs/LUNs) a block device is created with RAW read/write and - filesystem support. - menu "SATA/SCSI device support"
config SATA_CEVA

This is expected to be attached to the uclass and the code operates that way, but the uclass has not been updated. Fix it to avoid using memory at address 0.
Signed-off-by: Simon Glass sjg@chromium.org Fixes: 47fc61a (dm: ahci: Drop use of probe_ent) ---
Changes in v2: None
drivers/ata/ahci-uclass.c | 2 ++ drivers/ata/ahci.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/ahci-uclass.c b/drivers/ata/ahci-uclass.c index 7b8c32699f..71600fed68 100644 --- a/drivers/ata/ahci-uclass.c +++ b/drivers/ata/ahci-uclass.c @@ -6,9 +6,11 @@ */
#include <common.h> +#include <ahci.h> #include <dm.h>
UCLASS_DRIVER(ahci) = { .id = UCLASS_AHCI, .name = "ahci", + .per_device_auto_alloc_size = sizeof(struct ahci_uc_priv), }; diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 035db85b45..066524758a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -935,7 +935,7 @@ static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) { struct ahci_uc_priv *uc_priv; #ifdef CONFIG_DM_SCSI - uc_priv = dev_get_uclass_priv(dev); + uc_priv = dev_get_uclass_priv(dev->parent); #else uc_priv = probe_ent; #endif

Use the driver-model naming convention for this structure. It is data private to the driver.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/mmc/sunxi_mmc.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index fd3fc2af40..e30db015ef 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -19,7 +19,7 @@ #include <asm/arch/mmc.h> #include <asm-generic/gpio.h>
-struct sunxi_mmc_host { +struct sunxi_mmc_priv { unsigned mmc_no; uint32_t *mclkreg; unsigned fatal_err; @@ -28,7 +28,7 @@ struct sunxi_mmc_host { };
/* support 4 mmc hosts */ -struct sunxi_mmc_host mmc_host[4]; +struct sunxi_mmc_priv mmc_host[4];
static int sunxi_mmc_getcd_gpio(int sdc_no) { @@ -43,7 +43,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no)
static int mmc_resource_init(int sdc_no) { - struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; + struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; int cd_pin, ret = 0;
@@ -84,7 +84,7 @@ static int mmc_resource_init(int sdc_no) return ret; }
-static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz) +static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz) { unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
@@ -156,7 +156,7 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
static int mmc_clk_io_on(int sdc_no) { - struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; + struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
debug("init mmc %d clock and io\n", sdc_no); @@ -179,7 +179,7 @@ static int mmc_clk_io_on(int sdc_no)
static int mmc_update_clk(struct mmc *mmc) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv; unsigned int cmd; unsigned timeout_msecs = 2000;
@@ -201,7 +201,7 @@ static int mmc_update_clk(struct mmc *mmc)
static int mmc_config_clock(struct mmc *mmc) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv; unsigned rval = readl(&mmchost->reg->clkcr);
/* Disable Clock */ @@ -229,7 +229,7 @@ static int mmc_config_clock(struct mmc *mmc)
static int sunxi_mmc_set_ios(struct mmc *mmc) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv;
debug("set ios: bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock); @@ -253,7 +253,7 @@ static int sunxi_mmc_set_ios(struct mmc *mmc)
static int sunxi_mmc_core_init(struct mmc *mmc) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv;
/* Reset controller */ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); @@ -264,7 +264,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv; const int reading = !!(data->flags & MMC_DATA_READ); const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : SUNXI_MMC_STATUS_FIFO_FULL; @@ -297,7 +297,7 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, unsigned int done_bit, const char *what) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv; unsigned int status;
do { @@ -317,7 +317,7 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv; unsigned int cmdval = SUNXI_MMC_CMD_START; unsigned int timeout_msecs; int error = 0; @@ -437,7 +437,7 @@ out:
static int sunxi_mmc_getcd(struct mmc *mmc) { - struct sunxi_mmc_host *mmchost = mmc->priv; + struct sunxi_mmc_priv *mmchost = mmc->priv; int cd_pin;
cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no); @@ -458,7 +458,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) { struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
- memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); + memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_priv));
cfg->name = "SUNXI SD/MMC"; cfg->ops = &sunxi_mmc_ops;

On Tue, Jul 04, 2017 at 01:31:23PM -0600, Simon Glass wrote:
Use the driver-model naming convention for this structure. It is data private to the driver.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Maxime

Use the driver-model naming convention for this structure. It is data private to the driver so the local variable should be called 'priv'.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/mmc/sunxi_mmc.c | 125 ++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 63 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index e30db015ef..9276a29d76 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -43,7 +43,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no)
static int mmc_resource_init(int sdc_no) { - struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no]; + struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; int cd_pin, ret = 0;
@@ -51,26 +51,26 @@ static int mmc_resource_init(int sdc_no)
switch (sdc_no) { case 0: - mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; - mmchost->mclkreg = &ccm->sd0_clk_cfg; + priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; + priv->mclkreg = &ccm->sd0_clk_cfg; break; case 1: - mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; - mmchost->mclkreg = &ccm->sd1_clk_cfg; + priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; + priv->mclkreg = &ccm->sd1_clk_cfg; break; case 2: - mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; - mmchost->mclkreg = &ccm->sd2_clk_cfg; + priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; + priv->mclkreg = &ccm->sd2_clk_cfg; break; case 3: - mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; - mmchost->mclkreg = &ccm->sd3_clk_cfg; + priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; + priv->mclkreg = &ccm->sd3_clk_cfg; break; default: printf("Wrong mmc number %d\n", sdc_no); return -1; } - mmchost->mmc_no = sdc_no; + priv->mmc_no = sdc_no;
cd_pin = sunxi_mmc_getcd_gpio(sdc_no); if (cd_pin >= 0) { @@ -84,7 +84,7 @@ static int mmc_resource_init(int sdc_no) return ret; }
-static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz) +static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) { unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
@@ -112,8 +112,8 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz) }
if (n > 3) { - printf("mmc %u error cannot set clock to %u\n", - mmchost->mmc_no, hz); + printf("mmc %u error cannot set clock to %u\n", priv->mmc_no, + hz); return -1; }
@@ -145,18 +145,17 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz)
writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) | CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_OCLK_DLY(oclk_dly) | - CCM_MMC_CTRL_M(div), mmchost->mclkreg); + CCM_MMC_CTRL_M(div), priv->mclkreg);
debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n", - mmchost->mmc_no, hz, pll_hz, 1u << n, div, - pll_hz / (1u << n) / div); + priv->mmc_no, hz, pll_hz, 1u << n, div, pll_hz / (1u << n) / div);
return 0; }
static int mmc_clk_io_on(int sdc_no) { - struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no]; + struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
debug("init mmc %d clock and io\n", sdc_no); @@ -174,53 +173,53 @@ static int mmc_clk_io_on(int sdc_no) SUNXI_MMC_COMMON_BASE + 4 * sdc_no); #endif
- return mmc_set_mod_clk(mmchost, 24000000); + return mmc_set_mod_clk(priv, 24000000); }
static int mmc_update_clk(struct mmc *mmc) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv; unsigned int cmd; unsigned timeout_msecs = 2000;
cmd = SUNXI_MMC_CMD_START | SUNXI_MMC_CMD_UPCLK_ONLY | SUNXI_MMC_CMD_WAIT_PRE_OVER; - writel(cmd, &mmchost->reg->cmd); - while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) { + writel(cmd, &priv->reg->cmd); + while (readl(&priv->reg->cmd) & SUNXI_MMC_CMD_START) { if (!timeout_msecs--) return -1; udelay(1000); }
/* clock update sets various irq status bits, clear these */ - writel(readl(&mmchost->reg->rint), &mmchost->reg->rint); + writel(readl(&priv->reg->rint), &priv->reg->rint);
return 0; }
static int mmc_config_clock(struct mmc *mmc) { - struct sunxi_mmc_priv *mmchost = mmc->priv; - unsigned rval = readl(&mmchost->reg->clkcr); + struct sunxi_mmc_priv *priv = mmc->priv; + unsigned rval = readl(&priv->reg->clkcr);
/* Disable Clock */ rval &= ~SUNXI_MMC_CLK_ENABLE; - writel(rval, &mmchost->reg->clkcr); + writel(rval, &priv->reg->clkcr); if (mmc_update_clk(mmc)) return -1;
/* Set mod_clk to new rate */ - if (mmc_set_mod_clk(mmchost, mmc->clock)) + if (mmc_set_mod_clk(priv, mmc->clock)) return -1;
/* Clear internal divider */ rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; - writel(rval, &mmchost->reg->clkcr); + writel(rval, &priv->reg->clkcr);
/* Re-enable Clock */ rval |= SUNXI_MMC_CLK_ENABLE; - writel(rval, &mmchost->reg->clkcr); + writel(rval, &priv->reg->clkcr); if (mmc_update_clk(mmc)) return -1;
@@ -229,34 +228,34 @@ static int mmc_config_clock(struct mmc *mmc)
static int sunxi_mmc_set_ios(struct mmc *mmc) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv;
debug("set ios: bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock);
/* Change clock first */ if (mmc->clock && mmc_config_clock(mmc) != 0) { - mmchost->fatal_err = 1; + priv->fatal_err = 1; return -EINVAL; }
/* Change bus width */ if (mmc->bus_width == 8) - writel(0x2, &mmchost->reg->width); + writel(0x2, &priv->reg->width); else if (mmc->bus_width == 4) - writel(0x1, &mmchost->reg->width); + writel(0x1, &priv->reg->width); else - writel(0x0, &mmchost->reg->width); + writel(0x0, &priv->reg->width);
return 0; }
static int sunxi_mmc_core_init(struct mmc *mmc) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv;
/* Reset controller */ - writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); udelay(1000);
return 0; @@ -264,7 +263,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv; const int reading = !!(data->flags & MMC_DATA_READ); const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : SUNXI_MMC_STATUS_FIFO_FULL; @@ -276,19 +275,19 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) timeout_usecs = 2000000;
/* Always read / write data through the CPU */ - setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); + setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
for (i = 0; i < (byte_cnt >> 2); i++) { - while (readl(&mmchost->reg->status) & status_bit) { + while (readl(&priv->reg->status) & status_bit) { if (!timeout_usecs--) return -1; udelay(1); }
if (reading) - buff[i] = readl(&mmchost->reg->fifo); + buff[i] = readl(&priv->reg->fifo); else - writel(buff[i], &mmchost->reg->fifo); + writel(buff[i], &priv->reg->fifo); }
return 0; @@ -297,11 +296,11 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, unsigned int done_bit, const char *what) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv; unsigned int status;
do { - status = readl(&mmchost->reg->rint); + status = readl(&priv->reg->rint); if (!timeout_msecs-- || (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { debug("%s timeout %x\n", what, @@ -317,14 +316,14 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv; unsigned int cmdval = SUNXI_MMC_CMD_START; unsigned int timeout_msecs; int error = 0; unsigned int status = 0; unsigned int bytecnt = 0;
- if (mmchost->fatal_err) + if (priv->fatal_err) return -1; if (cmd->resp_type & MMC_RSP_BUSY) debug("mmc cmd %d check rsp busy\n", cmd->cmdidx); @@ -351,16 +350,16 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, cmdval |= SUNXI_MMC_CMD_WRITE; if (data->blocks > 1) cmdval |= SUNXI_MMC_CMD_AUTO_STOP; - writel(data->blocksize, &mmchost->reg->blksz); - writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt); + writel(data->blocksize, &priv->reg->blksz); + writel(data->blocks * data->blocksize, &priv->reg->bytecnt); }
- debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no, + debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", priv->mmc_no, cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg); - writel(cmd->cmdarg, &mmchost->reg->arg); + writel(cmd->cmdarg, &priv->reg->arg);
if (!data) - writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
/* * transfer data and check status @@ -372,10 +371,10 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
bytecnt = data->blocksize * data->blocks; debug("trans data %d bytes\n", bytecnt); - writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + writel(cmdval | cmd->cmdidx, &priv->reg->cmd); ret = mmc_trans_data_by_cpu(mmc, data); if (ret) { - error = readl(&mmchost->reg->rint) & \ + error = readl(&priv->reg->rint) & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; error = -ETIMEDOUT; goto out; @@ -401,7 +400,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (cmd->resp_type & MMC_RSP_BUSY) { timeout_msecs = 2000; do { - status = readl(&mmchost->reg->status); + status = readl(&priv->reg->status); if (!timeout_msecs--) { debug("busy timeout\n"); error = -ETIMEDOUT; @@ -412,35 +411,35 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, }
if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = readl(&mmchost->reg->resp3); - cmd->response[1] = readl(&mmchost->reg->resp2); - cmd->response[2] = readl(&mmchost->reg->resp1); - cmd->response[3] = readl(&mmchost->reg->resp0); + cmd->response[0] = readl(&priv->reg->resp3); + cmd->response[1] = readl(&priv->reg->resp2); + cmd->response[2] = readl(&priv->reg->resp1); + cmd->response[3] = readl(&priv->reg->resp0); debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n", cmd->response[3], cmd->response[2], cmd->response[1], cmd->response[0]); } else { - cmd->response[0] = readl(&mmchost->reg->resp0); + cmd->response[0] = readl(&priv->reg->resp0); debug("mmc resp 0x%08x\n", cmd->response[0]); } out: if (error < 0) { - writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); mmc_update_clk(mmc); } - writel(0xffffffff, &mmchost->reg->rint); - writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, - &mmchost->reg->gctrl); + writel(0xffffffff, &priv->reg->rint); + writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, + &priv->reg->gctrl);
return error; }
static int sunxi_mmc_getcd(struct mmc *mmc) { - struct sunxi_mmc_priv *mmchost = mmc->priv; + struct sunxi_mmc_priv *priv = mmc->priv; int cd_pin;
- cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no); + cd_pin = sunxi_mmc_getcd_gpio(priv->mmc_no); if (cd_pin < 0) return 1;

On Tue, Jul 04, 2017 at 01:31:24PM -0600, Simon Glass wrote:
Use the driver-model naming convention for this structure. It is data private to the driver so the local variable should be called 'priv'.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Maxime

At present the driver-private data is obtained in various functions by various means. With driver model this is provided automatically. Without driver model it comes from a C array declared at the top of the file.
Adjust internal functions so that they are passed the private data as a parameter, allowing the caller to obtain it using either means.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/mmc/sunxi_mmc.c | 71 +++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 9276a29d76..bd41fbb752 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -176,9 +176,8 @@ static int mmc_clk_io_on(int sdc_no) return mmc_set_mod_clk(priv, 24000000); }
-static int mmc_update_clk(struct mmc *mmc) +static int mmc_update_clk(struct sunxi_mmc_priv *priv) { - struct sunxi_mmc_priv *priv = mmc->priv; unsigned int cmd; unsigned timeout_msecs = 2000;
@@ -198,15 +197,14 @@ static int mmc_update_clk(struct mmc *mmc) return 0; }
-static int mmc_config_clock(struct mmc *mmc) +static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc) { - struct sunxi_mmc_priv *priv = mmc->priv; unsigned rval = readl(&priv->reg->clkcr);
/* Disable Clock */ rval &= ~SUNXI_MMC_CLK_ENABLE; writel(rval, &priv->reg->clkcr); - if (mmc_update_clk(mmc)) + if (mmc_update_clk(priv)) return -1;
/* Set mod_clk to new rate */ @@ -220,21 +218,20 @@ static int mmc_config_clock(struct mmc *mmc) /* Re-enable Clock */ rval |= SUNXI_MMC_CLK_ENABLE; writel(rval, &priv->reg->clkcr); - if (mmc_update_clk(mmc)) + if (mmc_update_clk(priv)) return -1;
return 0; }
-static int sunxi_mmc_set_ios(struct mmc *mmc) +static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv, + struct mmc *mmc) { - struct sunxi_mmc_priv *priv = mmc->priv; - debug("set ios: bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock);
/* Change clock first */ - if (mmc->clock && mmc_config_clock(mmc) != 0) { + if (mmc->clock && mmc_config_clock(priv, mmc) != 0) { priv->fatal_err = 1; return -EINVAL; } @@ -261,9 +258,9 @@ static int sunxi_mmc_core_init(struct mmc *mmc) return 0; }
-static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) +static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc, + struct mmc_data *data) { - struct sunxi_mmc_priv *priv = mmc->priv; const int reading = !!(data->flags & MMC_DATA_READ); const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : SUNXI_MMC_STATUS_FIFO_FULL; @@ -293,10 +290,9 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) return 0; }
-static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, - unsigned int done_bit, const char *what) +static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc, + uint timeout_msecs, uint done_bit, const char *what) { - struct sunxi_mmc_priv *priv = mmc->priv; unsigned int status;
do { @@ -313,10 +309,10 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, return 0; }
-static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv, + struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) { - struct sunxi_mmc_priv *priv = mmc->priv; unsigned int cmdval = SUNXI_MMC_CMD_START; unsigned int timeout_msecs; int error = 0; @@ -372,7 +368,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, bytecnt = data->blocksize * data->blocks; debug("trans data %d bytes\n", bytecnt); writel(cmdval | cmd->cmdidx, &priv->reg->cmd); - ret = mmc_trans_data_by_cpu(mmc, data); + ret = mmc_trans_data_by_cpu(priv, mmc, data); if (ret) { error = readl(&priv->reg->rint) & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; @@ -381,14 +377,15 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } }
- error = mmc_rint_wait(mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE, "cmd"); + error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE, + "cmd"); if (error) goto out;
if (data) { timeout_msecs = 120; debug("cacl timeout %x msec\n", timeout_msecs); - error = mmc_rint_wait(mmc, timeout_msecs, + error = mmc_rint_wait(priv, mmc, timeout_msecs, data->blocks > 1 ? SUNXI_MMC_RINT_AUTO_COMMAND_DONE : SUNXI_MMC_RINT_DATA_OVER, @@ -425,7 +422,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, out: if (error < 0) { writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); - mmc_update_clk(mmc); + mmc_update_clk(priv); } writel(0xffffffff, &priv->reg->rint); writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, @@ -434,7 +431,22 @@ out: return error; }
-static int sunxi_mmc_getcd(struct mmc *mmc) +static int sunxi_mmc_set_ios_legacy(struct mmc *mmc) +{ + struct sunxi_mmc_priv *priv = mmc->priv; + + return sunxi_mmc_set_ios_common(priv, mmc); +} + +static int sunxi_mmc_send_cmd_legacy(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sunxi_mmc_priv *priv = mmc->priv; + + return sunxi_mmc_send_cmd_common(priv, mmc, cmd, data); +} + +static int sunxi_mmc_getcd_legacy(struct mmc *mmc) { struct sunxi_mmc_priv *priv = mmc->priv; int cd_pin; @@ -447,17 +459,18 @@ static int sunxi_mmc_getcd(struct mmc *mmc) }
static const struct mmc_ops sunxi_mmc_ops = { - .send_cmd = sunxi_mmc_send_cmd, - .set_ios = sunxi_mmc_set_ios, + .send_cmd = sunxi_mmc_send_cmd_legacy, + .set_ios = sunxi_mmc_set_ios_legacy, .init = sunxi_mmc_core_init, - .getcd = sunxi_mmc_getcd, + .getcd = sunxi_mmc_getcd_legacy, };
struct mmc *sunxi_mmc_init(int sdc_no) { - struct mmc_config *cfg = &mmc_host[sdc_no].cfg; + struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; + struct mmc_config *cfg = &priv->cfg;
- memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_priv)); + memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
cfg->name = "SUNXI SD/MMC"; cfg->ops = &sunxi_mmc_ops; @@ -479,5 +492,5 @@ struct mmc *sunxi_mmc_init(int sdc_no)
mmc_clk_io_on(sdc_no);
- return mmc_create(cfg, &mmc_host[sdc_no]); + return mmc_create(cfg, mmc_host); }

On Tue, Jul 04, 2017 at 01:31:25PM -0600, Simon Glass wrote:
At present the driver-private data is obtained in various functions by various means. With driver model this is provided automatically. Without driver model it comes from a C array declared at the top of the file.
Adjust internal functions so that they are passed the private data as a parameter, allowing the caller to obtain it using either means.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks! Maxime

Hi Simon,
On Wed, Jul 5, 2017 at 3:31 AM, Simon Glass sjg@chromium.org wrote:
At present the driver-private data is obtained in various functions by various means. With driver model this is provided automatically. Without driver model it comes from a C array declared at the top of the file.
Adjust internal functions so that they are passed the private data as a parameter, allowing the caller to obtain it using either means.
Signed-off-by: Simon Glass sjg@chromium.org
eMMC is currently broken for sunxi on my Orangepi Plus 2E. I've narrowed it down to this patch.
It seems the driver or device is now referencing the wrong controller. On versions before this patch, for MMC1 (or eMMC):
=> mmc dev 1 switch to partitions #0, OK mmc1(part 0) is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 15 OEM: 100 Name: AWPD3 Tran Speed: 52000000 Rd Block Len: 512 MMC version 5.0 High Capacity: Yes Capacity: 14.6 GiB Bus Width: 8-bit Erase Group Size: 512 KiB HC WP Group Size: 8 MiB User Capacity: 14.6 GiB WRREL Boot Capacity: 4 MiB ENH RPMB Capacity: 4 MiB ENH
On later versions I get:
=> mmc dev 1 switch to partitions #0, OK mmc1 is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 27 OEM: 5048 Name: SD08G Tran Speed: 50000000 Rd Block Len: 512 SD version 3.0 High Capacity: Yes Capacity: 7.4 GiB Bus Width: 1-bit Erase Group Size: 512 Bytes
For reference, mmc0 looks like:
=> mmc dev 0 switch to partitions #0, OK mmc0 is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 27 OEM: 5048 Name: SD08G Tran Speed: 50000000 Rd Block Len: 512 SD version 3.0 High Capacity: Yes Capacity: 7.4 GiB Bus Width: 4-bit Erase Group Size: 512 Bytes
So it seems somewhere down the line, the driver is getting passed the wrong set of priv data.
Regards ChenYu

Hi Chen-Yu,
On 8 August 2017 at 21:27, Chen-Yu Tsai wens@csie.org wrote:
Hi Simon,
On Wed, Jul 5, 2017 at 3:31 AM, Simon Glass sjg@chromium.org wrote:
At present the driver-private data is obtained in various functions by various means. With driver model this is provided automatically. Without driver model it comes from a C array declared at the top of the file.
Adjust internal functions so that they are passed the private data as a parameter, allowing the caller to obtain it using either means.
Signed-off-by: Simon Glass sjg@chromium.org
eMMC is currently broken for sunxi on my Orangepi Plus 2E. I've narrowed it down to this patch.
It seems the driver or device is now referencing the wrong controller. On versions before this patch, for MMC1 (or eMMC):
=> mmc dev 1 switch to partitions #0, OK mmc1(part 0) is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 15 OEM: 100 Name: AWPD3 Tran Speed: 52000000 Rd Block Len: 512 MMC version 5.0 High Capacity: Yes Capacity: 14.6 GiB Bus Width: 8-bit Erase Group Size: 512 KiB HC WP Group Size: 8 MiB User Capacity: 14.6 GiB WRREL Boot Capacity: 4 MiB ENH RPMB Capacity: 4 MiB ENH
On later versions I get:
=> mmc dev 1 switch to partitions #0, OK mmc1 is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 27 OEM: 5048 Name: SD08G Tran Speed: 50000000 Rd Block Len: 512 SD version 3.0 High Capacity: Yes Capacity: 7.4 GiB Bus Width: 1-bit Erase Group Size: 512 Bytes
For reference, mmc0 looks like:
=> mmc dev 0 switch to partitions #0, OK mmc0 is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 27 OEM: 5048 Name: SD08G Tran Speed: 50000000 Rd Block Len: 512 SD version 3.0 High Capacity: Yes Capacity: 7.4 GiB Bus Width: 4-bit Erase Group Size: 512 Bytes
So it seems somewhere down the line, the driver is getting passed the wrong set of priv data.
Are you sure it was this patch?
The ordering may have changed because there was a strange hack in the code before. There was some discussion about it but unfortunately I cannot find the thread right now. Can you take a look?
Regards, Simon

On Tue, Aug 15, 2017 at 5:35 AM, Simon Glass sjg@chromium.org wrote:
Hi Chen-Yu,
On 8 August 2017 at 21:27, Chen-Yu Tsai wens@csie.org wrote:
Hi Simon,
On Wed, Jul 5, 2017 at 3:31 AM, Simon Glass sjg@chromium.org wrote:
At present the driver-private data is obtained in various functions by various means. With driver model this is provided automatically. Without driver model it comes from a C array declared at the top of the file.
Adjust internal functions so that they are passed the private data as a parameter, allowing the caller to obtain it using either means.
Signed-off-by: Simon Glass sjg@chromium.org
eMMC is currently broken for sunxi on my Orangepi Plus 2E. I've narrowed it down to this patch.
It seems the driver or device is now referencing the wrong controller. On versions before this patch, for MMC1 (or eMMC):
=> mmc dev 1 switch to partitions #0, OK mmc1(part 0) is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 15 OEM: 100 Name: AWPD3 Tran Speed: 52000000 Rd Block Len: 512 MMC version 5.0 High Capacity: Yes Capacity: 14.6 GiB Bus Width: 8-bit Erase Group Size: 512 KiB HC WP Group Size: 8 MiB User Capacity: 14.6 GiB WRREL Boot Capacity: 4 MiB ENH RPMB Capacity: 4 MiB ENH
On later versions I get:
=> mmc dev 1 switch to partitions #0, OK mmc1 is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 27 OEM: 5048 Name: SD08G Tran Speed: 50000000 Rd Block Len: 512 SD version 3.0 High Capacity: Yes Capacity: 7.4 GiB Bus Width: 1-bit Erase Group Size: 512 Bytes
For reference, mmc0 looks like:
=> mmc dev 0 switch to partitions #0, OK mmc0 is current device => mmc info Device: SUNXI SD/MMC Manufacturer ID: 27 OEM: 5048 Name: SD08G Tran Speed: 50000000 Rd Block Len: 512 SD version 3.0 High Capacity: Yes Capacity: 7.4 GiB Bus Width: 4-bit Erase Group Size: 512 Bytes
So it seems somewhere down the line, the driver is getting passed the wrong set of priv data.
Are you sure it was this patch?
The ordering may have changed because there was a strange hack in the code before. There was some discussion about it but unfortunately I cannot find the thread right now. Can you take a look?
Indeed it was this patch. Maxime's latest patch [1] fixes it. And looks like the hacks are on their way out as well.
ChenYu
[1] https://lists.denx.de/pipermail/u-boot/2017-August/303443.html

This function has #ifdefs in it which we want to avoid for driver model. Instead we should use different compatible strings and the .data field. It also uses the MMC device number which is not available in driver model except through aliases.
Move the function's into its caller so that the driver-model version can do things its own way.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/mmc/sunxi_mmc.c | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index bd41fbb752..23bef94f24 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -153,29 +153,6 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) return 0; }
-static int mmc_clk_io_on(int sdc_no) -{ - struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; - struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - debug("init mmc %d clock and io\n", sdc_no); - - /* config ahb clock */ - setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); - -#ifdef CONFIG_SUNXI_GEN_SUN6I - /* unassert reset */ - setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); -#endif -#if defined(CONFIG_MACH_SUN9I) - /* sun9i has a mmc-common module, also set the gate and reset there */ - writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET, - SUNXI_MMC_COMMON_BASE + 4 * sdc_no); -#endif - - return mmc_set_mod_clk(priv, 24000000); -} - static int mmc_update_clk(struct sunxi_mmc_priv *priv) { unsigned int cmd; @@ -467,8 +444,10 @@ static const struct mmc_ops sunxi_mmc_ops = {
struct mmc *sunxi_mmc_init(int sdc_no) { + struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; struct mmc_config *cfg = &priv->cfg; + int ret;
memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
@@ -490,7 +469,22 @@ struct mmc *sunxi_mmc_init(int sdc_no) if (mmc_resource_init(sdc_no) != 0) return NULL;
- mmc_clk_io_on(sdc_no); + /* config ahb clock */ + debug("init mmc %d clock and io\n", sdc_no); + setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); + +#ifdef CONFIG_SUNXI_GEN_SUN6I + /* unassert reset */ + setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); +#endif +#if defined(CONFIG_MACH_SUN9I) + /* sun9i has a mmc-common module, also set the gate and reset there */ + writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET, + SUNXI_MMC_COMMON_BASE + 4 * sdc_no); +#endif + ret = mmc_set_mod_clk(priv, 24000000); + if (ret) + return NULL;
return mmc_create(cfg, mmc_host); }

On Tue, Jul 04, 2017 at 01:31:26PM -0600, Simon Glass wrote:
This function has #ifdefs in it which we want to avoid for driver model. Instead we should use different compatible strings and the .data field. It also uses the MMC device number which is not available in driver model except through aliases.
Move the function's into its caller so that the driver-model version can do things its own way.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks! Maxime

Add a driver-model version of this driver which mostly uses the existing code. The old code can be removed once all boards are switched over.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Drop debugging printf() now that the card detect is working
drivers/mmc/sunxi_mmc.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 23bef94f24..588574fab6 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -9,6 +9,7 @@ */
#include <common.h> +#include <dm.h> #include <errno.h> #include <malloc.h> #include <mmc.h> @@ -19,14 +20,21 @@ #include <asm/arch/mmc.h> #include <asm-generic/gpio.h>
+struct sunxi_mmc_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + struct sunxi_mmc_priv { unsigned mmc_no; uint32_t *mclkreg; unsigned fatal_err; + struct gpio_desc cd_gpio; /* Change Detect GPIO */ struct sunxi_mmc *reg; struct mmc_config cfg; };
+#if !CONFIG_IS_ENABLED(DM_MMC) /* support 4 mmc hosts */ struct sunxi_mmc_priv mmc_host[4];
@@ -83,6 +91,7 @@ static int mmc_resource_init(int sdc_no)
return ret; } +#endif
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) { @@ -224,6 +233,7 @@ static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv, return 0; }
+#if !CONFIG_IS_ENABLED(DM_MMC) static int sunxi_mmc_core_init(struct mmc *mmc) { struct sunxi_mmc_priv *priv = mmc->priv; @@ -234,6 +244,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
return 0; } +#endif
static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc, struct mmc_data *data) @@ -408,6 +419,7 @@ out: return error; }
+#if !CONFIG_IS_ENABLED(DM_MMC) static int sunxi_mmc_set_ios_legacy(struct mmc *mmc) { struct sunxi_mmc_priv *priv = mmc->priv; @@ -488,3 +500,124 @@ struct mmc *sunxi_mmc_init(int sdc_no)
return mmc_create(cfg, mmc_host); } +#else + +static int sunxi_mmc_set_ios(struct udevice *dev) +{ + struct sunxi_mmc_plat *plat = dev_get_platdata(dev); + struct sunxi_mmc_priv *priv = dev_get_priv(dev); + + return sunxi_mmc_set_ios_common(priv, &plat->mmc); +} + +static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sunxi_mmc_plat *plat = dev_get_platdata(dev); + struct sunxi_mmc_priv *priv = dev_get_priv(dev); + + return sunxi_mmc_send_cmd_common(priv, &plat->mmc, cmd, data); +} + +static int sunxi_mmc_getcd(struct udevice *dev) +{ + struct sunxi_mmc_priv *priv = dev_get_priv(dev); + + if (dm_gpio_is_valid(&priv->cd_gpio)) + return dm_gpio_get_value(&priv->cd_gpio); + + return 1; +} + +static const struct dm_mmc_ops sunxi_mmc_ops = { + .send_cmd = sunxi_mmc_send_cmd, + .set_ios = sunxi_mmc_set_ios, + .get_cd = sunxi_mmc_getcd, +}; + +static int sunxi_mmc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sunxi_mmc_plat *plat = dev_get_platdata(dev); + struct sunxi_mmc_priv *priv = dev_get_priv(dev); + struct mmc_config *cfg = &plat->cfg; + struct ofnode_phandle_args args; + u32 *gate_reg; + int bus_width, ret; + + cfg->name = dev->name; + bus_width = dev_read_u32_default(dev, "bus-width", 1); + + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + cfg->host_caps = 0; + if (bus_width == 8) + cfg->host_caps |= MMC_MODE_8BIT; + if (bus_width >= 4) + cfg->host_caps |= MMC_MODE_4BIT; + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + cfg->f_min = 400000; + cfg->f_max = 52000000; + + priv->reg = (void *)dev_read_addr(dev); + + /* We don't have a sunxi clock driver so find the clock address here */ + ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, + 1, &args); + if (ret) + return ret; + priv->mclkreg = (u32 *)ofnode_get_addr(args.node); + + ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, + 0, &args); + if (ret) + return ret; + gate_reg = (u32 *)ofnode_get_addr(args.node); + setbits_le32(gate_reg, 1 << args.args[0]); + priv->mmc_no = args.args[0] - 8; + + ret = mmc_set_mod_clk(priv, 24000000); + if (ret) + return ret; + + /* This GPIO is optional */ + if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, + GPIOD_IS_IN)) { + int cd_pin = gpio_get_number(&priv->cd_gpio); + + sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP); + } + + upriv->mmc = &plat->mmc; + + /* Reset controller */ + writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); + udelay(1000); + + return 0; +} + +static int sunxi_mmc_bind(struct udevice *dev) +{ + struct sunxi_mmc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} + +static const struct udevice_id sunxi_mmc_ids[] = { + { .compatible = "allwinner,sun5i-a13-mmc" }, + { } +}; + +U_BOOT_DRIVER(sunxi_mmc_drv) = { + .name = "sunxi_mmc", + .id = UCLASS_MMC, + .of_match = sunxi_mmc_ids, + .bind = sunxi_mmc_bind, + .probe = sunxi_mmc_probe, + .ops = &sunxi_mmc_ops, + .platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat), + .priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv), +}; +#endif

On 07/04/2017 09:31 PM, Simon Glass wrote:
Add a driver-model version of this driver which mostly uses the existing code. The old code can be removed once all boards are switched over.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Drop debugging printf() now that the card detect is working
Unfortunately card detect is not working on the BananaPi:
I built Bananapi_defconfig which defaults to not using the driver model and U-Boot is able to read from the SD card:
MMC: SUNXI SD/MMC: 0
Loading Environment from FAT... *** Warning - bad CRC, using default environment
I added
CONFIG_BLK=y CONFIG_DM_MMC=y
And the same SD card is not recognized anymore.
MMC: mmc@01c0f000: 0
Loading Environment from FAT... MMC: no card present
mmc_init: -123, time 2
At least for clock registers there seem to be differences:
mmc_resource_init: priv->mclkreg = 01c20094 (without DM_MMC) sunxi_mmc_probe: priv->mclkreg = 01c20088 (with DM_MMC)
Best regards
Heinrich
drivers/mmc/sunxi_mmc.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 23bef94f24..588574fab6 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -9,6 +9,7 @@ */
#include <common.h> +#include <dm.h> #include <errno.h> #include <malloc.h> #include <mmc.h> @@ -19,14 +20,21 @@ #include <asm/arch/mmc.h> #include <asm-generic/gpio.h>
+struct sunxi_mmc_plat {
- struct mmc_config cfg;
- struct mmc mmc;
+};
struct sunxi_mmc_priv { unsigned mmc_no; uint32_t *mclkreg; unsigned fatal_err;
- struct gpio_desc cd_gpio; /* Change Detect GPIO */ struct sunxi_mmc *reg; struct mmc_config cfg;
};
+#if !CONFIG_IS_ENABLED(DM_MMC) /* support 4 mmc hosts */ struct sunxi_mmc_priv mmc_host[4];
@@ -83,6 +91,7 @@ static int mmc_resource_init(int sdc_no)
return ret; } +#endif
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) { @@ -224,6 +233,7 @@ static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv, return 0; }
+#if !CONFIG_IS_ENABLED(DM_MMC) static int sunxi_mmc_core_init(struct mmc *mmc) { struct sunxi_mmc_priv *priv = mmc->priv; @@ -234,6 +244,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
return 0; } +#endif
static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc, struct mmc_data *data) @@ -408,6 +419,7 @@ out: return error; }
+#if !CONFIG_IS_ENABLED(DM_MMC) static int sunxi_mmc_set_ios_legacy(struct mmc *mmc) { struct sunxi_mmc_priv *priv = mmc->priv; @@ -488,3 +500,124 @@ struct mmc *sunxi_mmc_init(int sdc_no)
return mmc_create(cfg, mmc_host); } +#else
+static int sunxi_mmc_set_ios(struct udevice *dev) +{
- struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
- struct sunxi_mmc_priv *priv = dev_get_priv(dev);
- return sunxi_mmc_set_ios_common(priv, &plat->mmc);
+}
+static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
+{
- struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
- struct sunxi_mmc_priv *priv = dev_get_priv(dev);
- return sunxi_mmc_send_cmd_common(priv, &plat->mmc, cmd, data);
+}
+static int sunxi_mmc_getcd(struct udevice *dev) +{
- struct sunxi_mmc_priv *priv = dev_get_priv(dev);
- if (dm_gpio_is_valid(&priv->cd_gpio))
return dm_gpio_get_value(&priv->cd_gpio);
- return 1;
+}
+static const struct dm_mmc_ops sunxi_mmc_ops = {
- .send_cmd = sunxi_mmc_send_cmd,
- .set_ios = sunxi_mmc_set_ios,
- .get_cd = sunxi_mmc_getcd,
+};
+static int sunxi_mmc_probe(struct udevice *dev) +{
- struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
- struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
- struct sunxi_mmc_priv *priv = dev_get_priv(dev);
- struct mmc_config *cfg = &plat->cfg;
- struct ofnode_phandle_args args;
- u32 *gate_reg;
- int bus_width, ret;
- cfg->name = dev->name;
- bus_width = dev_read_u32_default(dev, "bus-width", 1);
- cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
- cfg->host_caps = 0;
- if (bus_width == 8)
cfg->host_caps |= MMC_MODE_8BIT;
- if (bus_width >= 4)
cfg->host_caps |= MMC_MODE_4BIT;
- cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
- cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
- cfg->f_min = 400000;
- cfg->f_max = 52000000;
- priv->reg = (void *)dev_read_addr(dev);
- /* We don't have a sunxi clock driver so find the clock address here */
- ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
1, &args);
- if (ret)
return ret;
- priv->mclkreg = (u32 *)ofnode_get_addr(args.node);
- ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
0, &args);
- if (ret)
return ret;
- gate_reg = (u32 *)ofnode_get_addr(args.node);
- setbits_le32(gate_reg, 1 << args.args[0]);
- priv->mmc_no = args.args[0] - 8;
- ret = mmc_set_mod_clk(priv, 24000000);
- if (ret)
return ret;
- /* This GPIO is optional */
- if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
GPIOD_IS_IN)) {
int cd_pin = gpio_get_number(&priv->cd_gpio);
sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
- }
- upriv->mmc = &plat->mmc;
- /* Reset controller */
- writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
- udelay(1000);
- return 0;
+}
+static int sunxi_mmc_bind(struct udevice *dev) +{
- struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
- return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+static const struct udevice_id sunxi_mmc_ids[] = {
- { .compatible = "allwinner,sun5i-a13-mmc" },
- { }
+};
+U_BOOT_DRIVER(sunxi_mmc_drv) = {
- .name = "sunxi_mmc",
- .id = UCLASS_MMC,
- .of_match = sunxi_mmc_ids,
- .bind = sunxi_mmc_bind,
- .probe = sunxi_mmc_probe,
- .ops = &sunxi_mmc_ops,
- .platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat),
- .priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv),
+}; +#endif

Hi Heinrich,
On Wed, 2018-01-31 at 18:08 +0100, Heinrich Schuchardt wrote:
On 07/04/2017 09:31 PM, Simon Glass wrote:
Add a driver-model version of this driver which mostly uses the existing code. The old code can be removed once all boards are switched over.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Drop debugging printf() now that the card detect is working
Unfortunately card detect is not working on the BananaPi:
Most likely it's the problem of U-Boot interpreting the card detection DT properties differently from Linux. See this thread for details:

On 02/01/2018 04:11 PM, Tuomas Tynkkynen wrote:
Hi Heinrich,
On Wed, 2018-01-31 at 18:08 +0100, Heinrich Schuchardt wrote:
On 07/04/2017 09:31 PM, Simon Glass wrote:
Add a driver-model version of this driver which mostly uses the existing code. The old code can be removed once all boards are switched over.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Drop debugging printf() now that the card detect is working
Unfortunately card detect is not working on the BananaPi:
Most likely it's the problem of U-Boot interpreting the card detection DT properties differently from Linux. See this thread for details:
Thanks for your analysis
arch/arm/dts/sun7i-a20-bananapi.dts has 'cd-inverted' for MMC0.
The string 'cd-inverted' does not exist in drivers/mmc/sunxi_mmc.c.
sunxi_mmc_getcd(): return dm_gpio_get_value(&priv->cd_gpio);
sunxi_mmc_getcd_legacy(): return !gpio_get_value(cd_pin); /* Observe the NOT here */
I will keep you informed.
Regards
Heinrich

This is shown as active high in the schematics[1], so fix it.
[1] https://patchwork.ozlabs.org/patch/777890/
Signed-off-by: Simon Glass sjg@chromium.org Reported-by: Maxime Ripard maxime.ripard@free-electrons.com ---
Changes in v2: - Add new patch to correct polarity of MMC card detect on Linksprite_pcDuino3
arch/arm/dts/sun7i-a20-pcduino3.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/sun7i-a20-pcduino3.dts b/arch/arm/dts/sun7i-a20-pcduino3.dts index 1a8b39be1d..37b1e0ee9b 100644 --- a/arch/arm/dts/sun7i-a20-pcduino3.dts +++ b/arch/arm/dts/sun7i-a20-pcduino3.dts @@ -164,7 +164,7 @@ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; - cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ + cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */ cd-inverted; status = "okay"; };

Hi,
On Tue, Jul 04, 2017 at 01:31:28PM -0600, Simon Glass wrote:
This is shown as active high in the schematics[1], so fix it.
[1] https://patchwork.ozlabs.org/patch/777890/
Signed-off-by: Simon Glass sjg@chromium.org Reported-by: Maxime Ripard maxime.ripard@free-electrons.com
Changes in v2:
- Add new patch to correct polarity of MMC card detect on Linksprite_pcDuino3
arch/arm/dts/sun7i-a20-pcduino3.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/sun7i-a20-pcduino3.dts b/arch/arm/dts/sun7i-a20-pcduino3.dts index 1a8b39be1d..37b1e0ee9b 100644 --- a/arch/arm/dts/sun7i-a20-pcduino3.dts +++ b/arch/arm/dts/sun7i-a20-pcduino3.dts @@ -164,7 +164,7 @@ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; vmmc-supply = <®_vcc3v3>; bus-width = <4>;
- cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
- cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
Hmmm, are you sure? At least your commit log says otherwise :)
Maxime

Hi Maxime,
On 5 July 2017 at 08:43, Maxime Ripard maxime.ripard@free-electrons.com wrote:
Hi,
On Tue, Jul 04, 2017 at 01:31:28PM -0600, Simon Glass wrote:
This is shown as active high in the schematics[1], so fix it.
[1] https://patchwork.ozlabs.org/patch/777890/
Signed-off-by: Simon Glass sjg@chromium.org Reported-by: Maxime Ripard maxime.ripard@free-electrons.com
Changes in v2:
- Add new patch to correct polarity of MMC card detect on Linksprite_pcDuino3
arch/arm/dts/sun7i-a20-pcduino3.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/sun7i-a20-pcduino3.dts b/arch/arm/dts/sun7i-a20-pcduino3.dts index 1a8b39be1d..37b1e0ee9b 100644 --- a/arch/arm/dts/sun7i-a20-pcduino3.dts +++ b/arch/arm/dts/sun7i-a20-pcduino3.dts @@ -164,7 +164,7 @@ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; vmmc-supply = <®_vcc3v3>; bus-width = <4>;
cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
Hmmm, are you sure? At least your commit log says otherwise :)
The commit message is wrong, unfortunately. The schematics suggest it is active low and it does seem to work with this setting.
Regards, Simon

The 'scsi scan' function handles this at present and we don't want to do it twice. With driver model we want to adopt U-Boot's lazy init approach where possible.
Drop the automatic scan when probing a SCSI bus.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/ata/ahci.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 066524758a..5e4df19386 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1181,11 +1181,6 @@ int ahci_probe_scsi(struct udevice *ahci_dev, ulong base) if (ret) return ret;
- debug("Scanning %s\n", dev->name); - ret = scsi_scan_dev(dev, true); - if (ret) - return ret; - return 0; }

Hi Simon,
On Wed, Jul 5, 2017 at 3:31 AM, Simon Glass sjg@chromium.org wrote:
The 'scsi scan' function handles this at present and we don't want to do it twice. With driver model we want to adopt U-Boot's lazy init approach where possible.
Drop the automatic scan when probing a SCSI bus.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
drivers/ata/ahci.c | 5 ----- 1 file changed, 5 deletions(-)
This is a duplicated patch of http://patchwork.ozlabs.org/patch/777313/
BTW: when will plan to apply that series?
Regards, Bin

Hi Bin,
On 22 July 2017 at 22:42, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Wed, Jul 5, 2017 at 3:31 AM, Simon Glass sjg@chromium.org wrote:
The 'scsi scan' function handles this at present and we don't want to do it twice. With driver model we want to adopt U-Boot's lazy init approach where possible.
Drop the automatic scan when probing a SCSI bus.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
drivers/ata/ahci.c | 5 ----- 1 file changed, 5 deletions(-)
This is a duplicated patch of http://patchwork.ozlabs.org/patch/777313/
BTW: when will plan to apply that series?
Hopefully tomorrow. Have been waiting for the tegra livetree series but it is tested now.
Regards, Simon

This is not used in SPL so we do not need to compile it. Make this change before adding driver-model support to the driver, to avoid build errors. With driver model we define a U_BOOT_DRIVER() which would otherwise be present in SPL and not be garbage-collected when building.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
board/sunxi/Makefile | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 43766e0ef4..f4411f01c3 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -10,7 +10,9 @@ # obj-y += board.o obj-$(CONFIG_SUNXI_GMAC) += gmac.o +ifndef CONFIG_SPL_BUILD obj-$(CONFIG_SUNXI_AHCI) += ahci.o +endif obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o

On Tue, Jul 04, 2017 at 01:31:30PM -0600, Simon Glass wrote:
This is not used in SPL so we do not need to compile it. Make this change before adding driver-model support to the driver, to avoid build errors. With driver model we define a U_BOOT_DRIVER() which would otherwise be present in SPL and not be garbage-collected when building.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks! Maxime

Adjust SATA setup to support driver model.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
board/sunxi/ahci.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-)
diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c index 522e54ab16..a79b80ca1e 100644 --- a/board/sunxi/ahci.c +++ b/board/sunxi/ahci.c @@ -1,5 +1,6 @@ #include <common.h> #include <ahci.h> +#include <dm.h> #include <scsi.h> #include <errno.h> #include <asm/io.h> @@ -13,9 +14,8 @@ /* This magic PHY initialisation was taken from the Allwinner releases * and Linux driver, but is completely undocumented. */ -static int sunxi_ahci_phy_init(u32 base) +static int sunxi_ahci_phy_init(u8 *reg_base) { - u8 *reg_base = (u8 *)base; u32 reg_val; int timeout;
@@ -70,10 +70,65 @@ static int sunxi_ahci_phy_init(u32 base) return 0; }
+#ifndef CONFIG_DM_SCSI void scsi_init(void) { - if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0) + if (sunxi_ahci_phy_init((u8 *)SUNXI_SATA_BASE) < 0) return;
ahci_init((void __iomem *)SUNXI_SATA_BASE); } +#else +static int sunxi_sata_probe(struct udevice *dev) +{ + ulong base; + u8 *reg; + int ret; + + base = dev_read_addr(dev); + if (base == FDT_ADDR_T_NONE) { + debug("%s: Failed to find address (err=%d\n)", __func__, ret); + return -EINVAL; + } + reg = (u8 *)base; + ret = sunxi_ahci_phy_init(reg); + if (ret) { + debug("%s: Failed to init phy (err=%d\n)", __func__, ret); + return ret; + } + ret = ahci_probe_scsi(dev, base); + if (ret) { + debug("%s: Failed to probe (err=%d\n)", __func__, ret); + return ret; + } + + return 0; +} + +static int sunxi_sata_bind(struct udevice *dev) +{ + struct udevice *scsi_dev; + int ret; + + ret = ahci_bind_scsi(dev, &scsi_dev); + if (ret) { + debug("%s: Failed to bind (err=%d\n)", __func__, ret); + return ret; + } + + return 0; +} + +static const struct udevice_id sunxi_ahci_ids[] = { + { .compatible = "allwinner,sun4i-a10-ahci" }, + { } +}; + +U_BOOT_DRIVER(ahci_sunxi_drv) = { + .name = "ahci_sunxi", + .id = UCLASS_AHCI, + .of_match = sunxi_ahci_ids, + .bind = sunxi_sata_bind, + .probe = sunxi_sata_probe, +}; +#endif

On Tue, Jul 04, 2017 at 01:31:31PM -0600, Simon Glass wrote:
Adjust SATA setup to support driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks! Maxime

Move this board over to driver model for MMC and SATA. This means that it uses CONFIG_BLK as well. In SPL these options remain turned off since it increases the code size. One option would be to use CONFIG_SPL_OF_PLATDATA to avoid device-tree overhead.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
configs/Linksprite_pcDuino3_defconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig index 6f4a02f8d4..f0d382c002 100644 --- a/configs/Linksprite_pcDuino3_defconfig +++ b/configs/Linksprite_pcDuino3_defconfig @@ -15,7 +15,12 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set -CONFIG_SCSI=y +# CONFIG_SPL_BLK is not set +CONFIG_DM_MMC=y +# CONFIG_SPL_DM_MMC is not set +# CONFIG_SPL_DM_MMC_OPS is not set CONFIG_ETH_DESIGNWARE=y CONFIG_SUN7I_GMAC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_USB_EHCI_HCD=y

Dear Simon,
On 07/05/2017 04:31 AM, Simon Glass wrote:
At present SCSI support for driver model works only with PCI controllers.
This series makes the following changes:
- Adjusts SATA/AHCI support to work with non-PCI controllers
- Allows driver model to be used for MMC in U-Boot proper without
requiring it to be used in SPL
- Adjusts sunxi MMC and SATA drivers to support driver model
- Enables this on a single board (Linksprite_pcDuino3)
Even with this series the AHCI uclass still does not have any operations. This will be needed for drivers which do not use SCSI. Further work is needed to complete this.
Changes in v2:
- Drop debugging printf() now that the card detect is working
- Add new patch to correct polarity of MMC card detect on Linksprite_pcDuino3
Applied to u-boot-mmc. Thanks!
Best Regards, Jaehoon Chung
Simon Glass (15): ahci: Support non-PCI controllers dm: mmc: Allow disabling driver model in SPL fdt: Correct fdt_get_base_address() dm: scsi: Drop duplicate SCSI and DM_SCSI options dm: ahci: Correct uclass private data dm: mmc: sunxi: Rename struct sunxi_mmc_host to sunxi_mmc_priv dm: mmc: sunxi: Rename mmchost to priv dm: mmc: sunxi: Pass private data around explicitly dm: mmc: sunxi: Drop mmc_clk_io_on() dm: mmc: sunxi: Add support for driver model dm: sunxi: Linksprite_pcDuino3: Correct polarity of MMC card detect dm: scsi: Don't scan the SCSI bus when probing dm: sunxi: sata: Don't build sata support into SPL dm: sata: sunxi: Add support for driver model dm: sunxi: Move Linksprite_pcDuino3 to use DM for MMC, SATA
arch/arm/dts/sun7i-a20-pcduino3.dts | 2 +- arch/x86/cpu/ivybridge/sata.c | 2 +- board/sunxi/Makefile | 2 + board/sunxi/ahci.c | 61 +++++- common/fdt_support.c | 7 +- common/spl/spl_mmc.c | 4 +- configs/Linksprite_pcDuino3_defconfig | 7 +- drivers/ata/Kconfig | 18 -- drivers/ata/ahci-uclass.c | 2 + drivers/ata/ahci.c | 33 ++-- drivers/block/Kconfig | 12 ++ drivers/block/Makefile | 4 +- drivers/mmc/Kconfig | 21 ++ drivers/mmc/Makefile | 4 +- drivers/mmc/mmc-uclass.c | 6 +- drivers/mmc/mmc.c | 28 +-- drivers/mmc/mmc_legacy.c | 2 +- drivers/mmc/mmc_private.h | 6 +- drivers/mmc/omap_hsmmc.c | 20 +- drivers/mmc/sunxi_mmc.c | 359 +++++++++++++++++++++++----------- drivers/scsi/scsi.c | 2 +- include/ahci.h | 14 +- include/blk.h | 4 +- include/mmc.h | 12 +- 24 files changed, 431 insertions(+), 201 deletions(-)

Hi Simon
On Fri, Jul 28, 2017 at 1:27 PM, Jaehoon Chung jh80.chung@samsung.com wrote:
Dear Simon,
On 07/05/2017 04:31 AM, Simon Glass wrote:
At present SCSI support for driver model works only with PCI controllers.
This series makes the following changes:
- Adjusts SATA/AHCI support to work with non-PCI controllers
- Allows driver model to be used for MMC in U-Boot proper without
requiring it to be used in SPL
- Adjusts sunxi MMC and SATA drivers to support driver model
- Enables this on a single board (Linksprite_pcDuino3)
Even with this series the AHCI uclass still does not have any operations. This will be needed for drivers which do not use SCSI. Further work is needed to complete this.
Changes in v2:
- Drop debugging printf() now that the card detect is working
- Add new patch to correct polarity of MMC card detect on Linksprite_pcDuino3
Applied to u-boot-mmc. Thanks!
Best Regards, Jaehoon Chung
Simon Glass (15): ahci: Support non-PCI controllers dm: mmc: Allow disabling driver model in SPL fdt: Correct fdt_get_base_address() dm: scsi: Drop duplicate SCSI and DM_SCSI options dm: ahci: Correct uclass private data dm: mmc: sunxi: Rename struct sunxi_mmc_host to sunxi_mmc_priv dm: mmc: sunxi: Rename mmchost to priv dm: mmc: sunxi: Pass private data around explicitly dm: mmc: sunxi: Drop mmc_clk_io_on() dm: mmc: sunxi: Add support for driver model dm: sunxi: Linksprite_pcDuino3: Correct polarity of MMC card detect dm: scsi: Don't scan the SCSI bus when probing dm: sunxi: sata: Don't build sata support into SPL dm: sata: sunxi: Add support for driver model dm: sunxi: Move Linksprite_pcDuino3 to use DM for MMC, SATA
So I was playing around with this for the Pine64 based on your pcDuino3 example patch and it doesn't find the MMC controller, is there other DM conversions that might be needed for some of the sunxi devices?
Peter
participants (9)
-
Bin Meng
-
Chen-Yu Tsai
-
Heinrich Schuchardt
-
Jaehoon Chung
-
Jean-Jacques Hiblot
-
Maxime Ripard
-
Peter Robinson
-
Simon Glass
-
Tuomas Tynkkynen