The Samsung architecture has been removed, remove the mci driver
only used on this architecture as well.

Signed-off-by: Sascha Hauer <s.ha...@pengutronix.de>
---
 drivers/mci/Kconfig  |   7 -
 drivers/mci/Makefile |   1 -
 drivers/mci/s3c.c    | 762 -------------------------------------------
 3 files changed, 770 deletions(-)
 delete mode 100644 drivers/mci/s3c.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 21d53c0c3f..bbdca67e9d 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -87,13 +87,6 @@ config MCI_ROCKCHIP_DWCMSHC
          Enable this entry to add support for a Rockchip derivation of the
          DWCMSHC controller found on some Rockchip SoCs like the RK3568.
 
-config MCI_S3C
-       bool "S3C"
-       depends on ARCH_S3C24xx
-       help
-         Enable this entry to add support to read and write SD cards on a
-         Samsung S3C24xx based system.
-
 config MCI_BCM283X
        bool "MCI support for BCM283X"
        depends on ARCH_BCM283X || COMPILE_TEST
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 55ec97b3fe..e3dc5ad8ae 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -14,7 +14,6 @@ pbl-$(CONFIG_MCI_IMX_ESDHC_PBL)       += imx-esdhc-pbl.o 
imx-esdhc-common.o
 obj-$(CONFIG_MCI_MXS)          += mxs.o
 obj-$(CONFIG_MCI_OMAP_HSMMC)   += omap_hsmmc.o
 obj-$(CONFIG_MCI_PXA)          += pxamci.o
-obj-$(CONFIG_MCI_S3C)          += s3c.o
 obj-$(CONFIG_MCI_ROCKCHIP_DWCMSHC)     += rockchip-dwcmshc-sdhci.o
 obj-$(CONFIG_MCI_TEGRA)                += tegra-sdmmc.o
 obj-$(CONFIG_MCI_SPI)          += mci_spi.o
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
deleted file mode 100644
index f1d00ecdc2..0000000000
--- a/drivers/mci/s3c.c
+++ /dev/null
@@ -1,762 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-// SPDX-FileCopyrightText: 2010 Juergen Beisert <juer...@kreuzholzen.de>
-// SPDX-FileCopyrightText: 2004-2006 Thomas Kleffel <t...@maintech.de>, 
maintech GmbH
-// SPDX-FileCopyrightText: 2008 Simtec Electronics <ben-li...@fluff.org>
-// SPDX-FileCopyrightText: 2006 OpenMoko, Inc (Harald Welte 
<lafo...@openmoko.org>)
-// SPDX-FileCopyrightText: 2005 Thomas Kleffel
-
-/*
- * This code is partially based on Linux and u-boot sources, among others the
- * u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c.
- */
-
-/**
- * @file
- * @brief MCI card host interface for S3C2440 CPU
- */
-
-/* #define DEBUG */
-
-#include <common.h>
-#include <init.h>
-#include <mci.h>
-#include <errno.h>
-#include <clock.h>
-#include <io.h>
-#include <linux/err.h>
-#include <mach/s3c-mci.h>
-#include <mach/s3c-generic.h>
-#include <mach/s3c-iomap.h>
-
-#define GET_HOST_DATA(x) (x->priv)
-#define GET_MCI_PDATA(x) (x->platform_data)
-
-#define SDICON 0x0
-# define SDICON_SDRESET (1 << 8)
-# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? 
*/
-# define SDICON_BYTEORDER (1 << 4)
-# define SDICON_SDIOIRQ (1 << 3)
-# define SDICON_RWAITEN (1 << 2)
-# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
-# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
-
-#define SDIPRE 0x4
-
-#define SDICMDARG 0x8
-
-#define SDICMDCON 0xc
-# define SDICMDCON_ABORT (1 << 12)
-# define SDICMDCON_WITHDATA (1 << 11)
-# define SDICMDCON_LONGRSP (1 << 10)
-# define SDICMDCON_WAITRSP (1 << 9)
-# define SDICMDCON_CMDSTART (1 << 8)
-# define SDICMDCON_SENDERHOST (1 << 6)
-# define SDICMDCON_INDEX (0x3f)
-
-#define SDICMDSTAT 0x10
-# define SDICMDSTAT_CRCFAIL (1 << 12)
-# define SDICMDSTAT_CMDSENT (1 << 11)
-# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
-# define SDICMDSTAT_RSPFIN (1 << 9)
-# define SDICMDSTAT_XFERING (1 << 8)
-# define SDICMDSTAT_INDEX (0xff)
-
-#define SDIRSP0 0x14
-#define SDIRSP1 0x18
-#define SDIRSP2 0x1C
-#define SDIRSP3 0x20
-
-#define SDITIMER 0x24
-#define SDIBSIZE 0x28
-
-#define SDIDCON 0x2c
-# define SDIDCON_DS_BYTE (0 << 22)
-# define SDIDCON_DS_HALFWORD (1 << 22)
-# define SDIDCON_DS_WORD (2 << 22)
-# define SDIDCON_IRQPERIOD (1 << 21)
-# define SDIDCON_TXAFTERRESP (1 << 20)
-# define SDIDCON_RXAFTERCMD (1 << 19)
-# define SDIDCON_BUSYAFTERCMD (1 << 18)
-# define SDIDCON_BLOCKMODE (1 << 17)
-# define SDIDCON_WIDEBUS (1 << 16)
-# define SDIDCON_DMAEN (1 << 15)
-# define SDIDCON_STOP (0 << 14)
-# define SDIDCON_DATSTART (1 << 14)
-# define SDIDCON_DATMODE (3 << 12)
-# define SDIDCON_BLKNUM (0xfff)
-# define SDIDCON_XFER_READY    (0 << 12)
-# define SDIDCON_XFER_CHKSTART (1 << 12)
-# define SDIDCON_XFER_RXSTART  (2 << 12)
-# define SDIDCON_XFER_TXSTART  (3 << 12)
-
-#define SDIDCNT 0x30
-# define SDIDCNT_BLKNUM_SHIFT 12
-
-#define SDIDSTA 0x34
-# define SDIDSTA_RDYWAITREQ (1 << 10)
-# define SDIDSTA_SDIOIRQDETECT (1 << 9)
-# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
-# define SDIDSTA_CRCFAIL (1 << 7)
-# define SDIDSTA_RXCRCFAIL (1 << 6)
-# define SDIDSTA_DATATIMEOUT (1 << 5)
-# define SDIDSTA_XFERFINISH (1 << 4)
-# define SDIDSTA_BUSYFINISH (1 << 3)
-# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
-# define SDIDSTA_TXDATAON (1 << 1)
-# define SDIDSTA_RXDATAON (1 << 0)
-
-#define SDIFSTA 0x38
-# define SDIFSTA_FIFORESET (1<<16)
-# define SDIFSTA_FIFOFAIL (3<<14)  /* 3 is correct (2 bits) */
-# define SDIFSTA_TFDET (1<<13)
-# define SDIFSTA_RFDET (1<<12)
-# define SDIFSTA_TFHALF (1<<11)
-# define SDIFSTA_TFEMPTY (1<<10)
-# define SDIFSTA_RFLAST (1<<9)
-# define SDIFSTA_RFFULL (1<<8)
-# define SDIFSTA_RFHALF (1<<7)
-# define SDIFSTA_COUNTMASK (0x7f)
-
-#define SDIIMSK 0x3C
-# define SDIIMSK_RESPONSECRC    (1<<17)
-# define SDIIMSK_CMDSENT        (1<<16)
-# define SDIIMSK_CMDTIMEOUT     (1<<15)
-# define SDIIMSK_RESPONSEND     (1<<14)
-# define SDIIMSK_READWAIT       (1<<13)
-# define SDIIMSK_SDIOIRQ        (1<<12)
-# define SDIIMSK_FIFOFAIL       (1<<11)
-# define SDIIMSK_CRCSTATUS      (1<<10)
-# define SDIIMSK_DATACRC        (1<<9)
-# define SDIIMSK_DATATIMEOUT    (1<<8)
-# define SDIIMSK_DATAFINISH     (1<<7)
-# define SDIIMSK_BUSYFINISH     (1<<6)
-# define SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
-# define SDIIMSK_TXFIFOHALF     (1<<4)
-# define SDIIMSK_TXFIFOEMPTY    (1<<3)
-# define SDIIMSK_RXFIFOLAST     (1<<2)
-# define SDIIMSK_RXFIFOFULL     (1<<1)
-# define SDIIMSK_RXFIFOHALF     (1<<0)
-
-#define SDIDATA 0x40
-
-struct s3c_mci_host {
-       struct mci_host host;
-       void __iomem    *base;
-       int             bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
-       unsigned        clock;  /* current clock in Hz */
-       unsigned        data_size;      /* data transfer in bytes */
-};
-
-#define to_s3c_host(h) container_of(h, struct s3c_mci_host, host)
-
-/**
- * Finish a request
- * @param hw_dev Host interface instance
- *
- * Just a little bit paranoia.
- */
-static void s3c_finish_request(struct s3c_mci_host *host_data)
-{
-       /* TODO ensure the engines are stopped */
-}
-
-/**
- * Setup a new clock frequency on this MCI bus
- * @param hw_dev Host interface instance
- * @param nc New clock value in Hz (can be 0)
- * @return New clock value (may differ from 'nc')
- */
-static unsigned s3c_setup_clock_speed(struct s3c_mci_host *host_data, unsigned 
nc)
-{
-       unsigned clock;
-       uint32_t mci_psc;
-
-       if (nc == 0)
-               return 0;
-
-       clock = s3c_get_pclk();
-       /* Calculate the required prescaler value to get the requested 
frequency */
-       mci_psc = (clock + (nc >> 2)) / nc;
-
-       if (mci_psc > 256) {
-               mci_psc = 256;
-               pr_warning("SD/MMC clock might be too high!\n");
-       }
-
-       writel(mci_psc - 1, host_data->base + SDIPRE);
-
-       return clock / mci_psc;
-}
-
-/**
- * Reset the MCI engine (the hard way)
- * @param hw_dev Host interface instance
- *
- * This will reset everything in all registers of this unit!
- */
-static void s3c_mci_reset(struct s3c_mci_host *host_data)
-{
-       /* reset the hardware */
-       writel(SDICON_SDRESET, host_data->base + SDICON);
-       /* wait until reset it finished */
-       while (readl(host_data->base + SDICON) & SDICON_SDRESET)
-               ;
-}
-
-/**
- * Initialize hard and software
- * @param hw_dev Host interface instance
- * @param mci_dev MCI device instance (might be NULL)
- */
-static int s3c_mci_initialize(struct s3c_mci_host *host_data,
-                             struct device *mci_dev)
-{
-       s3c_mci_reset(host_data);
-
-       /* restore last settings */
-       host_data->clock = s3c_setup_clock_speed(host_data, host_data->clock);
-       writel(0x007FFFFF, host_data->base + SDITIMER);
-       writel(SDICON_MMCCLOCK, host_data->base + SDICON);
-       writel(512, host_data->base + SDIBSIZE);
-
-       return 0;
-}
-
-/**
- * Prepare engine's bits for the next command transfer
- * @param cmd_flags MCI's command flags
- * @param data_flags MCI's data flags
- * @return Register bits for this transfer
- */
-static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned 
data_flags)
-{
-       uint32_t reg;
-
-       /* source (=host) */
-       reg = SDICMDCON_SENDERHOST;
-
-       if (cmd_flags & MMC_RSP_PRESENT) {
-               reg |= SDICMDCON_WAITRSP;
-               pr_debug("Command with response\n");
-       }
-       if (cmd_flags & MMC_RSP_136) {
-               reg |= SDICMDCON_LONGRSP;
-               pr_debug("Command with long response\n");
-       }
-       if (cmd_flags & MMC_RSP_CRC)
-               ; /* FIXME */
-       if (cmd_flags & MMC_RSP_BUSY)
-               ; /* FIXME */
-       if (cmd_flags & MMC_RSP_OPCODE)
-               ; /* FIXME */
-       if (data_flags != 0)
-               reg |= SDICMDCON_WITHDATA;
-
-       return reg;
-}
-
-/**
- * Prepare engine's bits for the next data transfer
- * @param hw_dev Host interface device instance
- * @param data_flags MCI's data flags
- * @return Register bits for this transfer
- */
-static uint32_t s3c_prepare_data_setup(struct s3c_mci_host *host_data, 
unsigned data_flags)
-{
-       uint32_t reg = SDIDCON_BLOCKMODE;       /* block mode only is supported 
*/
-
-       if (host_data->bus_width == 1)
-               reg |= SDIDCON_WIDEBUS;
-
-       /* enable any kind of data transfers on demand only */
-       if (data_flags & MMC_DATA_WRITE)
-               reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
-
-       if (data_flags & MMC_DATA_READ)
-               reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
-
-       /* TODO: Support more than the 2440 CPU */
-       reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
-
-       return reg;
-}
-
-/**
- * Terminate a current running transfer
- * @param hw_dev Host interface device instance
- * @return 0 on success
- *
- * Note: Try to stop a running transfer. This should not happen, as all
- * transfers must complete in this driver. But who knows... ;-)
- */
-static int s3c_terminate_transfer(struct s3c_mci_host *host_data)
-{
-       unsigned stoptries = 3;
-
-       while (readl(host_data->base + SDIDSTA) & (SDIDSTA_TXDATAON | 
SDIDSTA_RXDATAON)) {
-               pr_debug("Transfer still in progress.\n");
-
-               writel(SDIDCON_STOP, host_data->base + SDIDCON);
-               s3c_mci_initialize(host_data, NULL);
-
-               if ((stoptries--) == 0) {
-                       pr_warning("Cannot stop the engine!\n");
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * Setup registers for data transfer
- * @param hw_dev Host interface device instance
- * @param data The data information (buffer, direction aso.)
- * @return 0 on success
- */
-static int s3c_prepare_data_transfer(struct s3c_mci_host *host_data, struct 
mci_data *data)
-{
-       uint32_t reg;
-
-       writel(data->blocksize, host_data->base + SDIBSIZE);
-       reg = s3c_prepare_data_setup(host_data, data->flags);
-       reg |= data->blocks & SDIDCON_BLKNUM;
-       writel(reg, host_data->base + SDIDCON);
-       writel(0x007FFFFF, host_data->base + SDITIMER);
-
-       return 0;
-}
-
-/**
- * Send a command and receive the response
- * @param hw_dev Host interface device instance
- * @param cmd The command to handle
- * @param data The data information (buffer, direction aso.)
- * @return 0 on success
- */
-static int s3c_send_command(struct s3c_mci_host *host_data, struct mci_cmd 
*cmd,
-                               struct mci_data *data)
-{
-       uint32_t reg, t1;
-       int rc;
-
-       writel(0x007FFFFF, host_data->base + SDITIMER);
-
-       /* setup argument */
-       writel(cmd->cmdarg, host_data->base + SDICMDARG);
-
-       /* setup command and transfer characteristic */
-       reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? 
data->flags : 0);
-       reg |= cmd->cmdidx & SDICMDCON_INDEX;
-
-       /* run the command right now */
-       writel(reg | SDICMDCON_CMDSTART, host_data->base + SDICMDCON);
-       t1 = readl(host_data->base + SDICMDSTAT);
-       /* wait until command is done */
-       while (1) {
-               reg = readl(host_data->base + SDICMDSTAT);
-               /* done? */
-               if (cmd->resp_type & MMC_RSP_PRESENT) {
-                       if (reg & SDICMDSTAT_RSPFIN) {
-                               writel(SDICMDSTAT_RSPFIN,
-                                       host_data->base + SDICMDSTAT);
-                               rc = 0;
-                               break;
-                       }
-               } else {
-                       if (reg & SDICMDSTAT_CMDSENT) {
-                                       writel(SDICMDSTAT_CMDSENT,
-                                               host_data->base + SDICMDSTAT);
-                                       rc = 0;
-                                       break;
-                       }
-               }
-               /* timeout? */
-               if (reg & SDICMDSTAT_CMDTIMEOUT) {
-                       writel(SDICMDSTAT_CMDTIMEOUT,
-                               host_data->base + SDICMDSTAT);
-                       rc = -ETIMEDOUT;
-                       break;
-               }
-       }
-
-       if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
-               cmd->response[0] = readl(host_data->base + SDIRSP0);
-               cmd->response[1] = readl(host_data->base + SDIRSP1);
-               cmd->response[2] = readl(host_data->base + SDIRSP2);
-               cmd->response[3] = readl(host_data->base + SDIRSP3);
-       }
-       /* do not disable the clock! */
-       return rc;
-}
-
-/**
- * Clear major registers prior a new transaction
- * @param hw_dev Host interface device instance
- * @return 0 on success
- *
- * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
- */
-static int s3c_prepare_engine(struct s3c_mci_host *host_data)
-{
-       int rc;
-
-       rc = s3c_terminate_transfer(host_data);
-       if (rc != 0)
-               return rc;
-
-       writel(-1, host_data->base + SDICMDSTAT);
-       writel(-1, host_data->base + SDIDSTA);
-       writel(-1, host_data->base + SDIFSTA);
-
-       return 0;
-}
-
-/**
- * Handle MCI commands without data
- * @param hw_dev Host interface device instance
- * @param cmd The command to handle
- * @return 0 on success
- *
- * This functions handles the following MCI commands:
- * - "broadcast command (BC)" without a response
- * - "broadcast commands with response (BCR)"
- * - "addressed command (AC)" with response, but without data
- */
-static int s3c_mci_std_cmds(struct s3c_mci_host *host_data, struct mci_cmd 
*cmd)
-{
-       int rc;
-
-       rc = s3c_prepare_engine(host_data);
-       if (rc != 0)
-               return 0;
-
-       return s3c_send_command(host_data, cmd, NULL);
-}
-
-/**
- * Read one block of data from the FIFO
- * @param hw_dev Host interface device instance
- * @param data The data information (buffer, direction aso.)
- * @return 0 on success
- */
-static int s3c_mci_read_block(struct s3c_mci_host *host_data, struct mci_data 
*data)
-{
-       uint32_t *p;
-       unsigned cnt, data_size;
-
-#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | 
SDIDSTA_DATATIMEOUT)
-
-       p = (uint32_t*)data->dest;
-       data_size = data->blocksize * data->blocks;
-
-       while (data_size > 0) {
-
-               /* serious error? */
-               if (readl(host_data->base + SDIDSTA) & READ_REASON_TO_FAIL) {
-                       pr_err("Failed while reading data\n");
-                       return -EIO;
-               }
-
-               /* now check the FIFO status */
-               if (readl(host_data->base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
-                       pr_err("Data loss due to FIFO overflow when reading\n");
-                       return -EIO;
-               }
-
-               /* we only want to read full words */
-               cnt = (readl(host_data->base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 
2;
-
-               /* read one chunk of data from the FIFO */
-               while (cnt--) {
-                       *p = readl(host_data->base + SDIDATA);
-                       p++;
-                       if (data_size >= 4)
-                               data_size -= 4;
-                       else {
-                               data_size = 0;
-                               break;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/**
- * Write one block of data into the FIFO
- * @param hw_dev Host interface device instance
- * @param cmd The command to handle
- * @param data The data information (buffer, direction aso.)
- * @return 0 on success
- *
- * We must ensure data in the FIFO when the command phase changes into the
- * data phase. To ensure this, the FIFO gets filled first, then the command.
- */
-static int s3c_mci_write_block(struct s3c_mci_host *host_data, struct mci_cmd 
*cmd,
-                               struct mci_data *data)
-{
-       const uint32_t *p = (const uint32_t*)data->src;
-       unsigned cnt, data_size;
-       uint32_t reg;
-
-#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
-
-       data_size = data->blocksize * data->blocks;
-       /*
-        * With high clock rates we must fill the FIFO as early as possible
-        * Its size is 16 words. We assume its empty, when this function is
-        * entered.
-        */
-       cnt = 16;
-       while (cnt--) {
-               writel(*p, host_data->base + SDIDATA);
-               p++;
-               if (data_size >= 4)
-                       data_size -= 4;
-               else {
-                       data_size = 0;
-                       break;
-               }
-       }
-
-       /* data is now in place and waits for transmitt. Start the command 
right now */
-       s3c_send_command(host_data, cmd, data);
-
-       if ((reg = readl(host_data->base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
-               pr_err("Command fails immediatly due to FIFO underrun when 
writing %08X\n",
-                       reg);
-               return -EIO;
-       }
-
-       while (data_size > 0) {
-
-               if (readl(host_data->base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
-                       pr_err("Failed writing data\n");
-                       return -EIO;
-               }
-
-               /* now check the FIFO status */
-               if ((reg = readl(host_data->base + SDIFSTA)) & 
SDIFSTA_FIFOFAIL) {
-                       pr_err("Data loss due to FIFO underrun when writing 
%08X\n",
-                                       reg);
-                       return -EIO;
-               }
-
-               /* we only want to write full words */
-               cnt = 16 - (((readl(host_data->base + SDIFSTA) & 
SDIFSTA_COUNTMASK) + 3) >> 2);
-
-               /* fill the FIFO if it has free entries */
-               while (cnt--) {
-                       writel(*p, host_data->base + SDIDATA);
-                       p++;
-                       if (data_size >= 4)
-                               data_size -= 4;
-                       else {
-                               data_size = 0;
-                               break;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/**
- * Handle MCI commands with or without data
- * @param hw_dev Host interface device instance
- * @param cmd The command to handle
- * @param data The data information (buffer, direction aso.)
- * @return 0 on success
-*/
-static int s3c_mci_adtc(struct s3c_mci_host *host_data, struct mci_cmd *cmd,
-                       struct mci_data *data)
-{
-       int rc;
-
-       rc = s3c_prepare_engine(host_data);
-       if (rc != 0)
-               return rc;
-
-       rc = s3c_prepare_data_transfer(host_data, data);
-       if (rc != 0)
-               return rc;
-
-       if (data->flags & MMC_DATA_READ) {
-               s3c_send_command(host_data, cmd, data);
-               rc = s3c_mci_read_block(host_data, data);
-               if (rc == 0) {
-                       while (!(readl(host_data->base + SDIDSTA) & 
SDIDSTA_XFERFINISH))
-                               ;
-               } else
-                       s3c_terminate_transfer(host_data);
-       }
-
-       if (data->flags & MMC_DATA_WRITE) {
-               rc = s3c_mci_write_block(host_data, cmd, data);
-               if (rc == 0) {
-                       while (!(readl(host_data->base + SDIDSTA) & 
SDIDSTA_XFERFINISH))
-                               ;
-               } else
-                       s3c_terminate_transfer(host_data);
-       }
-       writel(0, host_data->base + SDIDCON);
-
-       return rc;
-}
-
-/* ------------------------- MCI API -------------------------------------- */
-
-/**
- * Keep the attached MMC/SD unit in a well know state
- * @param host MCI host
- * @param mci_dev MCI device instance
- * @return 0 on success, negative value else
- */
-static int mci_reset(struct mci_host *host, struct device *mci_dev)
-{
-       struct s3c_mci_host *host_data = to_s3c_host(host);
-
-       return s3c_mci_initialize(host_data, mci_dev);
-}
-
-/**
- * Process one command to the MCI card
- * @param host MCI host
- * @param cmd The command to process
- * @param data The data to handle in the command (can be NULL)
- * @return 0 on success, negative value else
- */
-static int mci_request(struct mci_host *host, struct mci_cmd *cmd,
-                       struct mci_data *data)
-{
-       struct s3c_mci_host *host_data = to_s3c_host(host);
-       int rc;
-
-       /* enable clock */
-       writel(readl(host_data->base + SDICON) | SDICON_CLKEN,
-               host_data->base + SDICON);
-
-       if ((cmd->resp_type == 0) || (data == NULL))
-               rc = s3c_mci_std_cmds(host_data, cmd);
-       else
-               rc = s3c_mci_adtc(host_data, cmd, data);        /* with 
response and data */
-
-       s3c_finish_request(host_data);
-
-       /* disable clock */
-       writel(readl(host_data->base + SDICON) & ~SDICON_CLKEN,
-               host_data->base + SDICON);
-       return rc;
-}
-
-/**
- * Setup the bus width and IO speed
- * @param host MCI host
- * @param bus_width New bus width value (1, 4 or 8)
- * @param clock New clock in Hz (can be '0' to disable the clock)
- */
-static void mci_set_ios(struct mci_host *host, struct mci_ios *ios)
-{
-       struct s3c_mci_host *host_data = to_s3c_host(host);
-       uint32_t reg;
-
-       switch (ios->bus_width) {
-       case MMC_BUS_WIDTH_4:
-               host_data->bus_width = 1;
-               break;
-       case MMC_BUS_WIDTH_1:
-               host_data->bus_width = 0;
-               break;
-       default:
-               return;
-       }
-
-       reg = readl(host_data->base + SDICON);
-       if (ios->clock) {
-               /* setup the IO clock frequency and enable it */
-               host_data->clock = s3c_setup_clock_speed(host_data, ios->clock);
-               reg |= SDICON_CLKEN;    /* enable the clock */
-       } else {
-               reg &= ~SDICON_CLKEN;   /* disable the clock */
-               host_data->clock = 0;
-       }
-       writel(reg, host_data->base + SDICON);
-
-       pr_debug("IO settings: bus width=%d, frequency=%u Hz\n",
-               host_data->bus_width, host_data->clock);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void s3c_info(struct device *hw_dev)
-{
-       struct s3c_mci_host *host = hw_dev->priv;
-       struct s3c_mci_platform_data *pd = hw_dev->platform_data;
-
-       printf("  Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
-       printf("  Bus frequency: %u Hz\n", host->clock);
-       printf("   Frequency limits: ");
-       if (pd->f_min == 0)
-               printf("no lower limit ");
-       else
-               printf("%u Hz lower limit ", pd->f_min);
-       if (pd->f_max == 0)
-               printf("- no upper limit");
-       else
-               printf("- %u Hz upper limit", pd->f_max);
-       printf("\n  Card detection support: %s\n",
-               pd->gpio_detect != 0 ? "yes" : "no");
-}
-
-static int s3c_mci_probe(struct device *hw_dev)
-{
-       struct resource *iores;
-       struct s3c_mci_host *s3c_host;
-       struct s3c_mci_platform_data *pd = hw_dev->platform_data;
-
-       s3c_host = xzalloc(sizeof(*s3c_host));
-       s3c_host->host.send_cmd = mci_request;
-       s3c_host->host.set_ios = mci_set_ios;
-       s3c_host->host.init = mci_reset;
-
-       /* TODO replace by the global func: enable the SDI unit clock */
-       writel(readl(S3C_CLOCK_POWER_BASE + 0x0c) | 0x200,
-               S3C_CLOCK_POWER_BASE + 0x0c);
-
-       if (pd == NULL) {
-               pr_err("Missing platform data\n");
-               return -EINVAL;
-       }
-
-       hw_dev->priv = s3c_host;
-       iores = dev_request_mem_resource(hw_dev, 0);
-       if (IS_ERR(iores))
-               return PTR_ERR(iores);
-       s3c_host->base = IOMEM(iores->start);
-
-       s3c_host->host.hw_dev = hw_dev;
-
-       /* feed forward the platform specific values */
-       s3c_host->host.voltages = pd->voltages;
-       s3c_host->host.host_caps = pd->caps;
-       s3c_host->host.f_min = pd->f_min == 0 ? s3c_get_pclk() / 256 : 
pd->f_min;
-       s3c_host->host.f_max = pd->f_max == 0 ? s3c_get_pclk() / 2 : pd->f_max;
-
-       if (IS_ENABLED(CONFIG_MCI_INFO))
-               hw_dev->info = s3c_info;
-
-       /*
-        * Start the clock to let the engine and the card finishes its startup
-        */
-       s3c_host->clock = s3c_setup_clock_speed(s3c_host, pd->f_min);
-       writel(SDICON_FIFORESET | SDICON_MMCCLOCK, s3c_host->base + SDICON);
-
-       return mci_register(&s3c_host->host);
-}
-
-static struct driver s3c_mci_driver = {
-        .name  = "s3c_mci",
-        .probe = s3c_mci_probe,
-};
-device_platform_driver(s3c_mci_driver);
-- 
2.30.2


Reply via email to