linux/drivers/mmc/host/sh_mmcif.c

// SPDX-License-Identifier: GPL-2.0
/*
 * MMCIF eMMC driver.
 *
 * Copyright (C) 2010 Renesas Solutions Corp.
 * Yusuke Goda <[email protected]>
 */

/*
 * The MMCIF driver is now processing MMC requests asynchronously, according
 * to the Linux MMC API requirement.
 *
 * The MMCIF driver processes MMC requests in up to 3 stages: command, optional
 * data, and optional stop. To achieve asynchronous processing each of these
 * stages is split into two halves: a top and a bottom half. The top half
 * initialises the hardware, installs a timeout handler to handle completion
 * timeouts, and returns. In case of the command stage this immediately returns
 * control to the caller, leaving all further processing to run asynchronously.
 * All further request processing is performed by the bottom halves.
 *
 * The bottom half further consists of a "hard" IRQ handler, an IRQ handler
 * thread, a DMA completion callback, if DMA is used, a timeout work, and
 * request- and stage-specific handler methods.
 *
 * Each bottom half run begins with either a hardware interrupt, a DMA callback
 * invocation, or a timeout work run. In case of an error or a successful
 * processing completion, the MMC core is informed and the request processing is
 * finished. In case processing has to continue, i.e., if data has to be read
 * from or written to the card, or if a stop command has to be sent, the next
 * top half is called, which performs the necessary hardware handling and
 * reschedules the timeout work. This returns the driver state machine into the
 * bottom half waiting state.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/mmc/card.h>
#include <linux/mmc/core.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/pagemap.h>
#include <linux/platform_data/sh_mmcif.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
#include <linux/pm_runtime.h>
#include <linux/sh_dma.h>
#include <linux/spinlock.h>
#include <linux/module.h>

#define DRIVER_NAME

/* CE_CMD_SET */
#define CMD_MASK
#define CMD_SET_RTYP_NO
#define CMD_SET_RTYP_6B
#define CMD_SET_RTYP_17B
#define CMD_SET_RBSY
#define CMD_SET_CCSEN
#define CMD_SET_WDAT
#define CMD_SET_DWEN
#define CMD_SET_CMLTE
#define CMD_SET_CMD12EN
#define CMD_SET_RIDXC_INDEX
#define CMD_SET_RIDXC_BITS
#define CMD_SET_RIDXC_NO
#define CMD_SET_CRC7C
#define CMD_SET_CRC7C_BITS
#define CMD_SET_CRC7C_INTERNAL
#define CMD_SET_CRC16C
#define CMD_SET_CRCSTE
#define CMD_SET_TBIT
#define CMD_SET_OPDM
#define CMD_SET_CCSH
#define CMD_SET_DARS
#define CMD_SET_DATW_1
#define CMD_SET_DATW_4
#define CMD_SET_DATW_8

/* CE_CMD_CTRL */
#define CMD_CTRL_BREAK

/* CE_BLOCK_SET */
#define BLOCK_SIZE_MASK

/* CE_INT */
#define INT_CCSDE
#define INT_CMD12DRE
#define INT_CMD12RBE
#define INT_CMD12CRE
#define INT_DTRANE
#define INT_BUFRE
#define INT_BUFWEN
#define INT_BUFREN
#define INT_CCSRCV
#define INT_RBSYE
#define INT_CRSPE
#define INT_CMDVIO
#define INT_BUFVIO
#define INT_WDATERR
#define INT_RDATERR
#define INT_RIDXERR
#define INT_RSPERR
#define INT_CCSTO
#define INT_CRCSTO
#define INT_WDATTO
#define INT_RDATTO
#define INT_RBSYTO
#define INT_RSPTO
#define INT_ERR_STS

#define INT_ALL

#define INT_CCS

/* CE_INT_MASK */
#define MASK_ALL
#define MASK_MCCSDE
#define MASK_MCMD12DRE
#define MASK_MCMD12RBE
#define MASK_MCMD12CRE
#define MASK_MDTRANE
#define MASK_MBUFRE
#define MASK_MBUFWEN
#define MASK_MBUFREN
#define MASK_MCCSRCV
#define MASK_MRBSYE
#define MASK_MCRSPE
#define MASK_MCMDVIO
#define MASK_MBUFVIO
#define MASK_MWDATERR
#define MASK_MRDATERR
#define MASK_MRIDXERR
#define MASK_MRSPERR
#define MASK_MCCSTO
#define MASK_MCRCSTO
#define MASK_MWDATTO
#define MASK_MRDATTO
#define MASK_MRBSYTO
#define MASK_MRSPTO

#define MASK_START_CMD

#define MASK_CLEAN

/* CE_HOST_STS1 */
#define STS1_CMDSEQ

/* CE_HOST_STS2 */
#define STS2_CRCSTE
#define STS2_CRC16E
#define STS2_AC12CRCE
#define STS2_RSPCRC7E
#define STS2_CRCSTEBE
#define STS2_RDATEBE
#define STS2_AC12REBE
#define STS2_RSPEBE
#define STS2_AC12IDXE
#define STS2_RSPIDXE
#define STS2_CCSTO
#define STS2_RDATTO
#define STS2_DATBSYTO
#define STS2_CRCSTTO
#define STS2_AC12BSYTO
#define STS2_RSPBSYTO
#define STS2_AC12RSPTO
#define STS2_RSPTO
#define STS2_CRC_ERR
#define STS2_TIMEOUT_ERR

#define CLKDEV_EMMC_DATA
#define CLKDEV_MMC_DATA
#define CLKDEV_INIT

enum sh_mmcif_state {};

enum sh_mmcif_wait_for {};

/*
 * difference for each SoC
 */
struct sh_mmcif_host {};

static const struct of_device_id sh_mmcif_of_match[] =;
MODULE_DEVICE_TABLE(of, sh_mmcif_of_match);

#define sh_mmcif_host_to_dev(host)

static inline void sh_mmcif_bitset(struct sh_mmcif_host *host,
					unsigned int reg, u32 val)
{}

static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
					unsigned int reg, u32 val)
{}

static void sh_mmcif_dma_complete(void *arg)
{}

static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
{}

static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
{}

static struct dma_chan *
sh_mmcif_request_dma_pdata(struct sh_mmcif_host *host, uintptr_t slave_id)
{}

static int sh_mmcif_dma_slave_config(struct sh_mmcif_host *host,
				     struct dma_chan *chan,
				     enum dma_transfer_direction direction)
{}

static void sh_mmcif_request_dma(struct sh_mmcif_host *host)
{}

static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
{}

static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
{}

static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
{}

static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
{}

static void sh_mmcif_single_read(struct sh_mmcif_host *host,
				 struct mmc_request *mrq)
{}

static bool sh_mmcif_read_block(struct sh_mmcif_host *host)
{}

static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
				struct mmc_request *mrq)
{}

static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
{}

static void sh_mmcif_single_write(struct sh_mmcif_host *host,
					struct mmc_request *mrq)
{}

static bool sh_mmcif_write_block(struct sh_mmcif_host *host)
{}

static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
				struct mmc_request *mrq)
{}

static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
{}

static void sh_mmcif_get_response(struct sh_mmcif_host *host,
						struct mmc_command *cmd)
{}

static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
						struct mmc_command *cmd)
{}

static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
			    struct mmc_request *mrq)
{}

static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
			       struct mmc_request *mrq, u32 opc)
{}

static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
			       struct mmc_request *mrq)
{}

static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
			      struct mmc_request *mrq)
{}

static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
{}

static void sh_mmcif_clk_setup(struct sh_mmcif_host *host)
{}

static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{}

static const struct mmc_host_ops sh_mmcif_ops =;

static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
{}

static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
{}

static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
{}

static void sh_mmcif_timeout_work(struct work_struct *work)
{}

static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
{}

static int sh_mmcif_probe(struct platform_device *pdev)
{}

static void sh_mmcif_remove(struct platform_device *pdev)
{}

#ifdef CONFIG_PM_SLEEP
static int sh_mmcif_suspend(struct device *dev)
{}

static int sh_mmcif_resume(struct device *dev)
{}
#endif

static const struct dev_pm_ops sh_mmcif_dev_pm_ops =;

static struct platform_driver sh_mmcif_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS();
MODULE_AUTHOR();