]> Git Repo - linux.git/commitdiff
Merge tag 'mmc-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
authorLinus Torvalds <[email protected]>
Wed, 20 Nov 2024 20:51:32 +0000 (12:51 -0800)
committerLinus Torvalds <[email protected]>
Wed, 20 Nov 2024 20:51:32 +0000 (12:51 -0800)
Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Add support for Ultra Capacity SD cards (SDUC, 2TB to 128TB)
   - Add support for Ultra High-Speed II SD cards (UHS-II)
   - Use a reset control for pwrseq_simple
   - Add SD card quirk for broken poweroff notification
   - Use GFP_NOIO for SD ACMD22

  MMC host:
   - bcm2835: Introduce proper clock handling
   - mtk-sd: Add support for the Host-Software-Queue interface
   - mtk-sd: Add support for the mt7988/mt8196 variants
   - mtk-sd: Fix a couple of error paths in ->probe()
   - sdhci: Add interface to support UHS-II SD cards
   - sdhci_am654: Fixup support for changing the signal voltage level
   - sdhci-cadence: Add support for the Microchip PIC64GX variant
   - sdhci-esdhc-imx: Add support for eMMC HW-reset
   - sdhci-msm: Add support for the X1E80100/IPQ5424/SAR2130P/QCS615 variants
   - sdhci-of-arasan: Add support for eMMC HW-reset
   - sdhci-pci-gli: Add UHS-II support for the GL9767/GL9755 variants

  MEMSTICK:
   - A couple of minor updates"

* tag 'mmc-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (78 commits)
  mmc: pwrseq_simple: Handle !RESET_CONTROLLER properly
  mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting
  mmc: mtk-sd: Fix error handle of probe function
  mmc: core: Correction a warning caused by incorrect type in assignment for UHS-II
  mmc: sdhci-esdhc-imx: Update esdhc sysctl dtocv bitmask
  mmc: sdhci-esdhc-imx: Implement emmc hardware reset
  mmc: core: Correct type in variable assignment for UHS-II
  mmc: sdhci-uhs2: correction a warning caused by incorrect type in argument
  mmc: sdhci-uhs2: Remove unnecessary variables
  mmc: sdhci-uhs2: Correct incorrect type in argument
  mmc: sdhci: Make MMC_SDHCI_UHS2 config symbol invisible
  mmc: sdhci-uhs2: Remove unnecessary NULL check
  mmc: core: Fix error paths for UHS-II card init and re-init
  mmc: core: Add error handling of sd_uhs2_power_up()
  mmc: core: Simplify sd_uhs2_power_up()
  mmc: bcm2835: Introduce proper clock handling
  mmc: bcm2835: Fix type of current clock speed
  dt-bindings: mmc: Add sdhci compatible for QCS615
  mmc: core: Use GFP_NOIO in ACMD22
  dt-bindings: mmc: sdhci-msm: Add SAR2130P compatible
  ...

1  2 
drivers/mmc/core/block.c

diff --combined drivers/mmc/core/block.c
index 79f6fad97a80541e9d7e7f73d8e9886b9ee7ab63,a813fd7f39cc0b02bf6853bffc442fe82408291d..4830628510e6e2ff06e5cd25bff8e1dd39d9f838
@@@ -50,6 -50,7 +50,7 @@@
  #include <linux/mmc/sd.h>
  
  #include <linux/uaccess.h>
+ #include <linux/unaligned.h>
  
  #include "queue.h"
  #include "block.h"
@@@ -993,11 -994,12 +994,12 @@@ static int mmc_sd_num_wr_blocks(struct 
        int err;
        u32 result;
        __be32 *blocks;
+       u8 resp_sz = mmc_card_ult_capacity(card) ? 8 : 4;
+       unsigned int noio_flag;
  
        struct mmc_request mrq = {};
        struct mmc_command cmd = {};
        struct mmc_data data = {};
        struct scatterlist sg;
  
        err = mmc_app_cmd(card->host, card);
        cmd.arg = 0;
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  
-       data.blksz = 4;
+       data.blksz = resp_sz;
        data.blocks = 1;
        data.flags = MMC_DATA_READ;
        data.sg = &sg;
        mrq.cmd = &cmd;
        mrq.data = &data;
  
-       blocks = kmalloc(4, GFP_KERNEL);
+       noio_flag = memalloc_noio_save();
+       blocks = kmalloc(resp_sz, GFP_KERNEL);
+       memalloc_noio_restore(noio_flag);
        if (!blocks)
                return -ENOMEM;
  
-       sg_init_one(&sg, blocks, 4);
+       sg_init_one(&sg, blocks, resp_sz);
  
        mmc_wait_for_req(card->host, &mrq);
  
-       result = ntohl(*blocks);
+       if (mmc_card_ult_capacity(card)) {
+               /*
+                * Normally, ACMD22 returns the number of written sectors as
+                * u32. SDUC, however, returns it as u64.  This is not a
+                * superfluous requirement, because SDUC writes may exceed 2TB.
+                * For Linux mmc however, the previously write operation could
+                * not be more than the block layer limits, thus just make room
+                * for a u64 and cast the response back to u32.
+                */
+               result = clamp_val(get_unaligned_be64(blocks), 0, UINT_MAX);
+       } else {
+               result = ntohl(*blocks);
+       }
        kfree(blocks);
  
        if (cmd.error || data.error)
@@@ -1199,7 -1215,8 +1215,8 @@@ static void mmc_blk_issue_erase_rq(stru
  {
        struct mmc_blk_data *md = mq->blkdata;
        struct mmc_card *card = md->queue.card;
-       unsigned int from, nr;
+       unsigned int nr;
+       sector_t from;
        int err = 0;
        blk_status_t status = BLK_STS_OK;
  
@@@ -1254,7 -1271,8 +1271,8 @@@ static void mmc_blk_issue_secdiscard_rq
  {
        struct mmc_blk_data *md = mq->blkdata;
        struct mmc_card *card = md->queue.card;
-       unsigned int from, nr, arg;
+       unsigned int nr, arg;
+       sector_t from;
        int err = 0, type = MMC_BLK_SECDISCARD;
        blk_status_t status = BLK_STS_OK;
  
@@@ -1759,6 -1777,11 +1777,11 @@@ static void mmc_blk_rw_rq_prep(struct m
                brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
                brq->mrq.sbc = &brq->sbc;
        }
+       if (mmc_card_ult_capacity(card)) {
+               brq->cmd.ext_addr = blk_rq_pos(req) >> 32;
+               brq->cmd.has_ext_addr = true;
+       }
  }
  
  #define MMC_MAX_RETRIES               5
@@@ -2501,56 -2524,6 +2524,56 @@@ static inline int mmc_blk_readonly(stru
               !(card->csd.cmdclass & CCC_BLOCK_WRITE);
  }
  
 +/*
 + * Search for a declared partitions node for the disk in mmc-card related node.
 + *
 + * This is to permit support for partition table defined in DT in special case
 + * where a partition table is not written in the disk and is expected to be
 + * passed from the running system.
 + *
 + * For the user disk, "partitions" node is searched.
 + * For the special HW disk, "partitions-" node with the appended name is used
 + * following this conversion table (to adhere to JEDEC naming)
 + * - boot0 -> partitions-boot1
 + * - boot1 -> partitions-boot2
 + * - gp0 -> partitions-gp1
 + * - gp1 -> partitions-gp2
 + * - gp2 -> partitions-gp3
 + * - gp3 -> partitions-gp4
 + */
 +static struct fwnode_handle *mmc_blk_get_partitions_node(struct device *mmc_dev,
 +                                                       const char *subname)
 +{
 +      const char *node_name = "partitions";
 +
 +      if (subname) {
 +              mmc_dev = mmc_dev->parent;
 +
 +              /*
 +               * Check if we are allocating a BOOT disk boot0/1 disk.
 +               * In DT we use the JEDEC naming boot1/2.
 +               */
 +              if (!strcmp(subname, "boot0"))
 +                      node_name = "partitions-boot1";
 +              if (!strcmp(subname, "boot1"))
 +                      node_name = "partitions-boot2";
 +              /*
 +               * Check if we are allocating a GP disk gp0/1/2/3 disk.
 +               * In DT we use the JEDEC naming gp1/2/3/4.
 +               */
 +              if (!strcmp(subname, "gp0"))
 +                      node_name = "partitions-gp1";
 +              if (!strcmp(subname, "gp1"))
 +                      node_name = "partitions-gp2";
 +              if (!strcmp(subname, "gp2"))
 +                      node_name = "partitions-gp3";
 +              if (!strcmp(subname, "gp3"))
 +                      node_name = "partitions-gp4";
 +      }
 +
 +      return device_get_named_child_node(mmc_dev, node_name);
 +}
 +
  static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
                                              struct device *parent,
                                              sector_t size,
                                              int area_type,
                                              unsigned int part_type)
  {
 +      struct fwnode_handle *disk_fwnode;
        struct mmc_blk_data *md;
        int devidx, ret;
        char cap_str[10];
        if (mmc_host_cmd23(card->host)) {
                if ((mmc_card_mmc(card) &&
                     card->csd.mmca_vsn >= CSD_SPEC_VER_3) ||
-                   (mmc_card_sd(card) &&
+                   (mmc_card_sd(card) && !mmc_card_ult_capacity(card) &&
                     card->scr.cmds & SD_SCR_CMD23_SUPPORT))
                        md->flags |= MMC_BLK_CMD23;
        }
        /* used in ->open, must be set before add_disk: */
        if (area_type == MMC_BLK_DATA_AREA_MAIN)
                dev_set_drvdata(&card->dev, md);
 -      ret = device_add_disk(md->parent, md->disk, mmc_disk_attr_groups);
 +      disk_fwnode = mmc_blk_get_partitions_node(parent, subname);
 +      ret = add_disk_fwnode(md->parent, md->disk, mmc_disk_attr_groups,
 +                            disk_fwnode);
        if (ret)
                goto err_put_disk;
        return md;
This page took 0.072485 seconds and 4 git commands to generate.