]> Git Repo - J-linux.git/commitdiff
Merge tag 'omap-for-v6.9/n8x0-fixes-signed' of git://git.kernel.org/pub/scm/linux...
authorArnd Bergmann <[email protected]>
Tue, 9 Apr 2024 14:17:28 +0000 (16:17 +0200)
committerArnd Bergmann <[email protected]>
Tue, 9 Apr 2024 14:17:37 +0000 (16:17 +0200)
GPIO regression fixes for n8x0

A series of fixes for n8x0 GPIO regressions caused by the changes to use
GPIO descriptors.

* tag 'omap-for-v6.9/n8x0-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP2+: fix USB regression on Nokia N8x0
  mmc: omap: restore original power up/down steps
  mmc: omap: fix deferred probe
  mmc: omap: fix broken slot switch lookup
  ARM: OMAP2+: fix N810 MMC gpiod table
  ARM: OMAP2+: fix bogus MMC GPIO labels on Nokia N8x0

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Arnd Bergmann <[email protected]>
1  2 
drivers/mmc/host/omap.c

diff --combined drivers/mmc/host/omap.c
index 088f8ed4fdc4640d706a98d317e79668a6942748,13fa8588e38c101a72e0323ea38cf2e6f6cb9815..a8ee0df471482393214c379169b3c7a340282296
@@@ -148,8 -148,10 +148,8 @@@ struct mmc_omap_host 
        struct work_struct      send_stop_work;
        struct mmc_data         *stop_data;
  
 +      struct sg_mapping_iter  sg_miter;
        unsigned int            sg_len;
 -      int                     sg_idx;
 -      u16 *                   buffer;
 -      u32                     buffer_bytes_left;
        u32                     total_bytes_left;
  
        unsigned                features;
@@@ -454,8 -456,6 +454,8 @@@ mmc_omap_xfer_done(struct mmc_omap_hos
  {
        if (host->dma_in_use)
                mmc_omap_release_dma(host, data, data->error);
 +      else
 +              sg_miter_stop(&host->sg_miter);
  
        host->data = NULL;
        host->sg_len = 0;
@@@ -651,6 -651,19 +651,6 @@@ mmc_omap_cmd_timer(struct timer_list *t
        spin_unlock_irqrestore(&host->slot_lock, flags);
  }
  
 -/* PIO only */
 -static void
 -mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 -{
 -      struct scatterlist *sg;
 -
 -      sg = host->data->sg + host->sg_idx;
 -      host->buffer_bytes_left = sg->length;
 -      host->buffer = sg_virt(sg);
 -      if (host->buffer_bytes_left > host->total_bytes_left)
 -              host->buffer_bytes_left = host->total_bytes_left;
 -}
 -
  static void
  mmc_omap_clk_timer(struct timer_list *t)
  {
  static void
  mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
  {
 +      struct sg_mapping_iter *sgm = &host->sg_miter;
        int n, nwords;
 +      u16 *buffer;
  
 -      if (host->buffer_bytes_left == 0) {
 -              host->sg_idx++;
 -              BUG_ON(host->sg_idx == host->sg_len);
 -              mmc_omap_sg_to_buf(host);
 +      if (!sg_miter_next(sgm)) {
 +              /* This should not happen */
 +              dev_err(mmc_dev(host->mmc), "ran out of scatterlist prematurely\n");
 +              return;
        }
 +      buffer = sgm->addr;
 +
        n = 64;
 -      if (n > host->buffer_bytes_left)
 -              n = host->buffer_bytes_left;
 +      if (n > sgm->length)
 +              n = sgm->length;
 +      if (n > host->total_bytes_left)
 +              n = host->total_bytes_left;
  
        /* Round up to handle odd number of bytes to transfer */
        nwords = DIV_ROUND_UP(n, 2);
  
 -      host->buffer_bytes_left -= n;
 +      sgm->consumed = n;
        host->total_bytes_left -= n;
        host->data->bytes_xfered += n;
  
        if (write) {
                __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA),
 -                            host->buffer, nwords);
 +                            buffer, nwords);
        } else {
                __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA),
 -                           host->buffer, nwords);
 +                           buffer, nwords);
        }
 -
 -      host->buffer += nwords;
  }
  
  #ifdef CONFIG_MMC_DEBUG
@@@ -947,7 -956,6 +947,7 @@@ static inline void set_data_timeout(str
  static void
  mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
  {
 +      unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */
        struct mmc_data *data = req->data;
        int i, use_dma = 1, block_size;
        struct scatterlist *sg;
                }
        }
  
 -      host->sg_idx = 0;
        if (use_dma) {
                enum dma_data_direction dma_data_dir;
                struct dma_async_tx_descriptor *tx;
        OMAP_MMC_WRITE(host, BUF, 0x1f1f);
        host->total_bytes_left = data->blocks * block_size;
        host->sg_len = sg_len;
 -      mmc_omap_sg_to_buf(host);
 +      if (data->flags & MMC_DATA_READ)
 +              miter_flags |= SG_MITER_TO_SG;
 +      else
 +              miter_flags |= SG_MITER_FROM_SG;
 +      sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags);
        host->dma_in_use = 0;
  }
  
@@@ -1114,10 -1119,25 +1114,25 @@@ static void mmc_omap_set_power(struct m
  
        host = slot->host;
  
-       if (slot->vsd)
-               gpiod_set_value(slot->vsd, power_on);
-       if (slot->vio)
-               gpiod_set_value(slot->vio, power_on);
+       if (power_on) {
+               if (slot->vsd) {
+                       gpiod_set_value(slot->vsd, power_on);
+                       msleep(1);
+               }
+               if (slot->vio) {
+                       gpiod_set_value(slot->vio, power_on);
+                       msleep(1);
+               }
+       } else {
+               if (slot->vio) {
+                       gpiod_set_value(slot->vio, power_on);
+                       msleep(50);
+               }
+               if (slot->vsd) {
+                       gpiod_set_value(slot->vsd, power_on);
+                       msleep(50);
+               }
+       }
  
        if (slot->pdata->set_power != NULL)
                slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
@@@ -1254,18 -1274,18 +1269,18 @@@ static int mmc_omap_new_slot(struct mmc
        slot->pdata = &host->pdata->slots[id];
  
        /* Check for some optional GPIO controls */
-       slot->vsd = gpiod_get_index_optional(host->dev, "vsd",
-                                            id, GPIOD_OUT_LOW);
+       slot->vsd = devm_gpiod_get_index_optional(host->dev, "vsd",
+                                                 id, GPIOD_OUT_LOW);
        if (IS_ERR(slot->vsd))
                return dev_err_probe(host->dev, PTR_ERR(slot->vsd),
                                     "error looking up VSD GPIO\n");
-       slot->vio = gpiod_get_index_optional(host->dev, "vio",
-                                            id, GPIOD_OUT_LOW);
+       slot->vio = devm_gpiod_get_index_optional(host->dev, "vio",
+                                                 id, GPIOD_OUT_LOW);
        if (IS_ERR(slot->vio))
                return dev_err_probe(host->dev, PTR_ERR(slot->vio),
                                     "error looking up VIO GPIO\n");
-       slot->cover = gpiod_get_index_optional(host->dev, "cover",
-                                               id, GPIOD_IN);
+       slot->cover = devm_gpiod_get_index_optional(host->dev, "cover",
+                                                   id, GPIOD_IN);
        if (IS_ERR(slot->cover))
                return dev_err_probe(host->dev, PTR_ERR(slot->cover),
                                     "error looking up cover switch GPIO\n");
@@@ -1379,13 -1399,6 +1394,6 @@@ static int mmc_omap_probe(struct platfo
        if (IS_ERR(host->virt_base))
                return PTR_ERR(host->virt_base);
  
-       host->slot_switch = gpiod_get_optional(host->dev, "switch",
-                                              GPIOD_OUT_LOW);
-       if (IS_ERR(host->slot_switch))
-               return dev_err_probe(host->dev, PTR_ERR(host->slot_switch),
-                                    "error looking up slot switch GPIO\n");
        INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work);
        INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work);
  
        host->dev = &pdev->dev;
        platform_set_drvdata(pdev, host);
  
+       host->slot_switch = devm_gpiod_get_optional(host->dev, "switch",
+                                                   GPIOD_OUT_LOW);
+       if (IS_ERR(host->slot_switch))
+               return dev_err_probe(host->dev, PTR_ERR(host->slot_switch),
+                                    "error looking up slot switch GPIO\n");
        host->id = pdev->id;
        host->irq = irq;
        host->phys_base = res->start;
This page took 0.060748 seconds and 4 git commands to generate.