[PATCH 08/15] mci s3c: pass around the right pointer
Sascha Hauer
s.hauer at pengutronix.de
Thu Feb 9 06:53:51 EST 2012
The s3c driver passes around a struct device_d * internally in which
it is never interested in. Instead pass around a struct s3c_mci_host
and get rid of all this ugly void * derefs.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
drivers/mci/s3c.c | 103 +++++++++++++++++++++++------------------------------
1 files changed, 45 insertions(+), 58 deletions(-)
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
index 44c682e..6648d6f 100644
--- a/drivers/mci/s3c.c
+++ b/drivers/mci/s3c.c
@@ -160,13 +160,15 @@ struct s3c_mci_host {
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 device_d *hw_dev)
+static void s3c_finish_request(struct s3c_mci_host *host_data)
{
/* TODO ensure the engines are stopped */
}
@@ -177,11 +179,10 @@ static void s3c_finish_request(struct device_d *hw_dev)
* @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 device_d *hw_dev, unsigned nc)
+static unsigned s3c_setup_clock_speed(struct s3c_mci_host *host_data, unsigned nc)
{
unsigned clock;
uint32_t mci_psc;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
if (nc == 0)
return 0;
@@ -206,10 +207,8 @@ static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
*
* This will reset everything in all registers of this unit!
*/
-static void s3c_mci_reset(struct device_d *hw_dev)
+static void s3c_mci_reset(struct s3c_mci_host *host_data)
{
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
-
/* reset the hardware */
writel(SDICON_SDRESET, host_data->base + SDICON);
/* wait until reset it finished */
@@ -222,14 +221,12 @@ static void s3c_mci_reset(struct device_d *hw_dev)
* @param hw_dev Host interface instance
* @param mci_dev MCI device instance (might be NULL)
*/
-static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+static int s3c_mci_initialize(struct s3c_mci_host *host_data, struct device_d *mci_dev)
{
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
-
- s3c_mci_reset(hw_dev);
+ s3c_mci_reset(host_data);
/* restore last settings */
- host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
+ 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);
@@ -276,9 +273,8 @@ static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flag
* @param data_flags MCI's data flags
* @return Register bits for this transfer
*/
-static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
+static uint32_t s3c_prepare_data_setup(struct s3c_mci_host *host_data, unsigned data_flags)
{
- struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
uint32_t reg = SDIDCON_BLOCKMODE; /* block mode only is supported */
if (host_data->bus_width == 1)
@@ -305,16 +301,15 @@ static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_fl
* 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 device_d *hw_dev)
+static int s3c_terminate_transfer(struct s3c_mci_host *host_data)
{
unsigned stoptries = 3;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
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(hw_dev, NULL);
+ s3c_mci_initialize(host_data, NULL);
if ((stoptries--) == 0) {
pr_warning("Cannot stop the engine!\n");
@@ -331,13 +326,12 @@ static int s3c_terminate_transfer(struct device_d *hw_dev)
* @param data The data information (buffer, direction aso.)
* @return 0 on success
*/
-static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
+static int s3c_prepare_data_transfer(struct s3c_mci_host *host_data, struct mci_data *data)
{
uint32_t reg;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
writel(data->blocksize, host_data->base + SDIBSIZE);
- reg = s3c_prepare_data_setup(hw_dev, data->flags);
+ 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);
@@ -352,12 +346,11 @@ static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *d
* @param data The data information (buffer, direction aso.)
* @return 0 on success
*/
-static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd,
+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;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
writel(0x007FFFFF, host_data->base + SDITIMER);
@@ -416,12 +409,11 @@ static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd,
*
* FIFO clear is only necessary on 2440, but doesn't hurt on 2410
*/
-static int s3c_prepare_engine(struct device_d *hw_dev)
+static int s3c_prepare_engine(struct s3c_mci_host *host_data)
{
int rc;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
- rc = s3c_terminate_transfer(hw_dev);
+ rc = s3c_terminate_transfer(host_data);
if (rc != 0)
return rc;
@@ -443,15 +435,15 @@ static int s3c_prepare_engine(struct device_d *hw_dev)
* - "broadcast commands with response (BCR)"
* - "addressed command (AC)" with response, but without data
*/
-static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+static int s3c_mci_std_cmds(struct s3c_mci_host *host_data, struct mci_cmd *cmd)
{
int rc;
- rc = s3c_prepare_engine(hw_dev);
+ rc = s3c_prepare_engine(host_data);
if (rc != 0)
return 0;
- return s3c_send_command(hw_dev, cmd, NULL);
+ return s3c_send_command(host_data, cmd, NULL);
}
/**
@@ -460,11 +452,10 @@ static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
* @param data The data information (buffer, direction aso.)
* @return 0 on success
*/
-static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
+static int s3c_mci_read_block(struct s3c_mci_host *host_data, struct mci_data *data)
{
uint32_t *p;
unsigned cnt, data_size;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
@@ -514,13 +505,12 @@ static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
* 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 device_d *hw_dev, struct mci_cmd *cmd,
+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;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
@@ -543,7 +533,7 @@ static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd,
}
/* data is now in place and waits for transmitt. Start the command right now */
- s3c_send_command(hw_dev, cmd, data);
+ 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",
@@ -591,37 +581,36 @@ static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd,
* @param data The data information (buffer, direction aso.)
* @return 0 on success
*/
-static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
+static int s3c_mci_adtc(struct s3c_mci_host *host_data, struct mci_cmd *cmd,
struct mci_data *data)
{
int rc;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
- rc = s3c_prepare_engine(hw_dev);
+ rc = s3c_prepare_engine(host_data);
if (rc != 0)
return rc;
- rc = s3c_prepare_data_transfer(hw_dev, data);
+ rc = s3c_prepare_data_transfer(host_data, data);
if (rc != 0)
return rc;
if (data->flags & MMC_DATA_READ) {
- s3c_send_command(hw_dev, cmd, data);
- rc = s3c_mci_read_block(hw_dev, data);
+ 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(hw_dev);
+ s3c_terminate_transfer(host_data);
}
if (data->flags & MMC_DATA_WRITE) {
- rc = s3c_mci_write_block(hw_dev, cmd, data);
+ rc = s3c_mci_write_block(host_data, cmd, data);
if (rc == 0) {
while (!(readl(host_data->base + SDIDSTA) & SDIDSTA_XFERFINISH))
;
} else
- s3c_terminate_transfer(hw_dev);
+ s3c_terminate_transfer(host_data);
}
writel(0, host_data->base + SDIDCON);
@@ -632,29 +621,28 @@ static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
/**
* Keep the attached MMC/SD unit in a well know state
- * @param mci_pdata MCI platform data
+ * @param host MCI host
* @param mci_dev MCI device instance
* @return 0 on success, negative value else
*/
-static int mci_reset(struct mci_host *mci_pdata, struct device_d *mci_dev)
+static int mci_reset(struct mci_host *host, struct device_d *mci_dev)
{
- struct device_d *hw_dev = mci_pdata->hw_dev;
+ struct s3c_mci_host *host_data = to_s3c_host(host);
- return s3c_mci_initialize(hw_dev, mci_dev);
+ return s3c_mci_initialize(host_data, mci_dev);
}
/**
* Process one command to the MCI card
- * @param mci_pdata MCI platform data
+ * @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 *mci_pdata, struct mci_cmd *cmd,
+static int mci_request(struct mci_host *host, struct mci_cmd *cmd,
struct mci_data *data)
{
- struct device_d *hw_dev = mci_pdata->hw_dev;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
+ struct s3c_mci_host *host_data = to_s3c_host(host);
int rc;
/* enable clock */
@@ -662,11 +650,11 @@ static int mci_request(struct mci_host *mci_pdata, struct mci_cmd *cmd,
host_data->base + SDICON);
if ((cmd->resp_type == 0) || (data == NULL))
- rc = s3c_mci_std_cmds(hw_dev, cmd);
+ rc = s3c_mci_std_cmds(host_data, cmd);
else
- rc = s3c_mci_adtc(hw_dev, cmd, data); /* with response and data */
+ rc = s3c_mci_adtc(host_data, cmd, data); /* with response and data */
- s3c_finish_request(hw_dev);
+ s3c_finish_request(host_data);
/* disable clock */
writel(readl(host_data->base + SDICON) & ~SDICON_CLKEN,
@@ -676,16 +664,15 @@ static int mci_request(struct mci_host *mci_pdata, struct mci_cmd *cmd,
/**
* Setup the bus width and IO speed
- * @param mci_pdata MCI platform data
+ * @param host MCI host
* @param mci_dev MCI device instance
* @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 *mci_pdata, struct device_d *mci_dev,
+static void mci_set_ios(struct mci_host *host, struct device_d *mci_dev,
struct mci_ios *ios)
{
- struct device_d *hw_dev = mci_pdata->hw_dev;
- struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
+ struct s3c_mci_host *host_data = to_s3c_host(host);
uint32_t reg;
switch (ios->bus_width) {
@@ -702,7 +689,7 @@ static void mci_set_ios(struct mci_host *mci_pdata, struct device_d *mci_dev,
reg = readl(host_data->base + SDICON);
if (ios->clock) {
/* setup the IO clock frequency and enable it */
- host_data->clock = s3c_setup_clock_speed(hw_dev, ios->clock);
+ host_data->clock = s3c_setup_clock_speed(host_data, ios->clock);
reg |= SDICON_CLKEN; /* enable the clock */
} else {
reg &= ~SDICON_CLKEN; /* disable the clock */
@@ -770,7 +757,7 @@ static int s3c_mci_probe(struct device_d *hw_dev)
/*
* Start the clock to let the engine and the card finishes its startup
*/
- s3c_host->clock = s3c_setup_clock_speed(hw_dev, pd->f_min);
+ 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);
--
1.7.9
More information about the barebox
mailing list