summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/atmel-mci.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-07 13:18:06 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-07 13:18:06 +0000
commit638a9e433ecd61e64761352dbec1fa4f5874c941 (patch)
treefdbff74a238d7a5a7d1cef071b7230bc064b9f25 /drivers/mmc/host/atmel-mci.c
parentReleasing progress-linux version 6.9.12-1~progress7.99u1. (diff)
downloadlinux-638a9e433ecd61e64761352dbec1fa4f5874c941.tar.xz
linux-638a9e433ecd61e64761352dbec1fa4f5874c941.zip
Merging upstream version 6.10.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/mmc/host/atmel-mci.c')
-rw-r--r--drivers/mmc/host/atmel-mci.c309
1 files changed, 132 insertions, 177 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index dba826db73..8199d96200 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -224,18 +224,6 @@ struct mci_slot_pdata {
bool non_removable;
};
-/**
- * struct mci_platform_data - board-specific MMC/SDcard configuration
- * @dma_slave: DMA slave interface to use in data transfers.
- * @dma_filter: Filtering function to filter the DMA channel
- * @slot: Per-slot configuration data.
- */
-struct mci_platform_data {
- void *dma_slave;
- dma_filter_fn dma_filter;
- struct mci_slot_pdata slot[ATMCI_MAX_NR_SLOTS];
-};
-
struct atmel_mci_caps {
bool has_dma_conf_reg;
bool has_pdc;
@@ -300,7 +288,8 @@ struct atmel_mci_dma {
* rate and timeout calculations.
* @mapbase: Physical address of the MMIO registers.
* @mck: The peripheral bus clock hooked up to the MMC controller.
- * @pdev: Platform device associated with the MMC controller.
+ * @dev: Device associated with the MMC controller.
+ * @pdata: Per-slot configuration data.
* @slot: Slots sharing this MMC controller.
* @caps: MCI capabilities depending on MCI version.
* @prepare_data: function to setup MCI before data transfer which
@@ -377,8 +366,9 @@ struct atmel_mci {
unsigned long bus_hz;
unsigned long mapbase;
struct clk *mck;
- struct platform_device *pdev;
+ struct device *dev;
+ struct mci_slot_pdata pdata[ATMCI_MAX_NR_SLOTS];
struct atmel_mci_slot *slot[ATMCI_MAX_NR_SLOTS];
struct atmel_mci_caps caps;
@@ -530,6 +520,7 @@ static void atmci_show_status_reg(struct seq_file *s,
static int atmci_regs_show(struct seq_file *s, void *v)
{
struct atmel_mci *host = s->private;
+ struct device *dev = host->dev;
u32 *buf;
int ret = 0;
@@ -538,7 +529,7 @@ static int atmci_regs_show(struct seq_file *s, void *v)
if (!buf)
return -ENOMEM;
- pm_runtime_get_sync(&host->pdev->dev);
+ pm_runtime_get_sync(dev);
/*
* Grab a more or less consistent snapshot. Note that we're
@@ -549,8 +540,8 @@ static int atmci_regs_show(struct seq_file *s, void *v)
memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE);
spin_unlock_bh(&host->lock);
- pm_runtime_mark_last_busy(&host->pdev->dev);
- pm_runtime_put_autosuspend(&host->pdev->dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
seq_printf(s, "MR:\t0x%08x%s%s ",
buf[ATMCI_MR / 4],
@@ -626,7 +617,6 @@ static void atmci_init_debugfs(struct atmel_mci_slot *slot)
&host->completed_events);
}
-#if defined(CONFIG_OF)
static const struct of_device_id atmci_dt_ids[] = {
{ .compatible = "atmel,hsmci" },
{ /* sentinel */ }
@@ -634,79 +624,64 @@ static const struct of_device_id atmci_dt_ids[] = {
MODULE_DEVICE_TABLE(of, atmci_dt_ids);
-static struct mci_platform_data*
-atmci_of_init(struct platform_device *pdev)
+static int atmci_of_init(struct atmel_mci *host)
{
- struct device_node *np = pdev->dev.of_node;
+ struct device *dev = host->dev;
+ struct device_node *np = dev->of_node;
struct device_node *cnp;
- struct mci_platform_data *pdata;
u32 slot_id;
int err;
- if (!np) {
- dev_err(&pdev->dev, "device node not found\n");
- return ERR_PTR(-EINVAL);
- }
-
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return ERR_PTR(-ENOMEM);
+ if (!np)
+ return dev_err_probe(dev, -EINVAL, "device node not found\n");
for_each_child_of_node(np, cnp) {
if (of_property_read_u32(cnp, "reg", &slot_id)) {
- dev_warn(&pdev->dev, "reg property is missing for %pOF\n",
- cnp);
+ dev_warn(dev, "reg property is missing for %pOF\n", cnp);
continue;
}
if (slot_id >= ATMCI_MAX_NR_SLOTS) {
- dev_warn(&pdev->dev, "can't have more than %d slots\n",
+ dev_warn(dev, "can't have more than %d slots\n",
ATMCI_MAX_NR_SLOTS);
of_node_put(cnp);
break;
}
if (of_property_read_u32(cnp, "bus-width",
- &pdata->slot[slot_id].bus_width))
- pdata->slot[slot_id].bus_width = 1;
+ &host->pdata[slot_id].bus_width))
+ host->pdata[slot_id].bus_width = 1;
- pdata->slot[slot_id].detect_pin =
- devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(cnp),
+ host->pdata[slot_id].detect_pin =
+ devm_fwnode_gpiod_get(dev, of_fwnode_handle(cnp),
"cd", GPIOD_IN, "cd-gpios");
- err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].detect_pin);
+ err = PTR_ERR_OR_ZERO(host->pdata[slot_id].detect_pin);
if (err) {
if (err != -ENOENT) {
of_node_put(cnp);
- return ERR_PTR(err);
+ return err;
}
- pdata->slot[slot_id].detect_pin = NULL;
+ host->pdata[slot_id].detect_pin = NULL;
}
- pdata->slot[slot_id].non_removable =
+ host->pdata[slot_id].non_removable =
of_property_read_bool(cnp, "non-removable");
- pdata->slot[slot_id].wp_pin =
- devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(cnp),
+ host->pdata[slot_id].wp_pin =
+ devm_fwnode_gpiod_get(dev, of_fwnode_handle(cnp),
"wp", GPIOD_IN, "wp-gpios");
- err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].wp_pin);
+ err = PTR_ERR_OR_ZERO(host->pdata[slot_id].wp_pin);
if (err) {
if (err != -ENOENT) {
of_node_put(cnp);
- return ERR_PTR(err);
+ return err;
}
- pdata->slot[slot_id].wp_pin = NULL;
+ host->pdata[slot_id].wp_pin = NULL;
}
}
- return pdata;
-}
-#else /* CONFIG_OF */
-static inline struct mci_platform_data*
-atmci_of_init(struct platform_device *dev)
-{
- return ERR_PTR(-EINVAL);
+ return 0;
}
-#endif
static inline unsigned int atmci_get_version(struct atmel_mci *host)
{
@@ -738,11 +713,10 @@ static inline unsigned int atmci_convert_chksize(struct atmel_mci *host,
static void atmci_timeout_timer(struct timer_list *t)
{
- struct atmel_mci *host;
+ struct atmel_mci *host = from_timer(host, t, timer);
+ struct device *dev = host->dev;
- host = from_timer(host, t, timer);
-
- dev_dbg(&host->pdev->dev, "software timeout\n");
+ dev_dbg(dev, "software timeout\n");
if (host->mrq->cmd->data) {
host->mrq->cmd->data->error = -ETIMEDOUT;
@@ -860,15 +834,14 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
static void atmci_send_command(struct atmel_mci *host,
struct mmc_command *cmd, u32 cmd_flags)
{
+ struct device *dev = host->dev;
unsigned int timeout_ms = cmd->busy_timeout ? cmd->busy_timeout :
ATMCI_CMD_TIMEOUT_MS;
WARN_ON(host->cmd);
host->cmd = cmd;
- dev_vdbg(&host->pdev->dev,
- "start command: ARGR=0x%08x CMDR=0x%08x\n",
- cmd->arg, cmd_flags);
+ dev_vdbg(dev, "start command: ARGR=0x%08x CMDR=0x%08x\n", cmd->arg, cmd_flags);
atmci_writel(host, ATMCI_ARGR, cmd->arg);
atmci_writel(host, ATMCI_CMDR, cmd_flags);
@@ -878,7 +851,9 @@ static void atmci_send_command(struct atmel_mci *host,
static void atmci_send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
{
- dev_dbg(&host->pdev->dev, "send stop command\n");
+ struct device *dev = host->dev;
+
+ dev_dbg(dev, "send stop command\n");
atmci_send_command(host, data->stop, host->stop_cmdr);
atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
}
@@ -951,11 +926,10 @@ static void atmci_pdc_set_both_buf(struct atmel_mci *host, int dir)
static void atmci_pdc_cleanup(struct atmel_mci *host)
{
struct mmc_data *data = host->data;
+ struct device *dev = host->dev;
if (data)
- dma_unmap_sg(&host->pdev->dev,
- data->sg, data->sg_len,
- mmc_get_dma_dir(data));
+ dma_unmap_sg(dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
}
/*
@@ -965,6 +939,7 @@ static void atmci_pdc_cleanup(struct atmel_mci *host)
*/
static void atmci_pdc_complete(struct atmel_mci *host)
{
+ struct device *dev = host->dev;
int transfer_size = host->data->blocks * host->data->blksz;
int i;
@@ -981,7 +956,7 @@ static void atmci_pdc_complete(struct atmel_mci *host)
atmci_pdc_cleanup(host);
- dev_dbg(&host->pdev->dev, "(%s) set pending xfer complete\n", __func__);
+ dev_dbg(dev, "(%s) set pending xfer complete\n", __func__);
atmci_set_pending(host, EVENT_XFER_COMPLETE);
tasklet_schedule(&host->tasklet);
}
@@ -1003,8 +978,9 @@ static void atmci_dma_complete(void *arg)
{
struct atmel_mci *host = arg;
struct mmc_data *data = host->data;
+ struct device *dev = host->dev;
- dev_vdbg(&host->pdev->dev, "DMA complete\n");
+ dev_vdbg(dev, "DMA complete\n");
if (host->caps.has_dma_conf_reg)
/* Disable DMA hardware handshaking on MCI */
@@ -1017,8 +993,7 @@ static void atmci_dma_complete(void *arg)
* to send the stop command or waiting for NBUSY in this case.
*/
if (data) {
- dev_dbg(&host->pdev->dev,
- "(%s) set pending xfer complete\n", __func__);
+ dev_dbg(dev, "(%s) set pending xfer complete\n", __func__);
atmci_set_pending(host, EVENT_XFER_COMPLETE);
tasklet_schedule(&host->tasklet);
@@ -1092,6 +1067,7 @@ static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
static u32
atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
{
+ struct device *dev = host->dev;
u32 iflags, tmp;
int i;
@@ -1117,8 +1093,7 @@ atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
/* Configure PDC */
host->data_size = data->blocks * data->blksz;
- dma_map_sg(&host->pdev->dev, data->sg, data->sg_len,
- mmc_get_dma_dir(data));
+ dma_map_sg(dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
if ((!host->caps.has_rwproof)
&& (host->data->flags & MMC_DATA_WRITE)) {
@@ -1244,8 +1219,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
static void atmci_stop_transfer(struct atmel_mci *host)
{
- dev_dbg(&host->pdev->dev,
- "(%s) set pending xfer complete\n", __func__);
+ struct device *dev = host->dev;
+
+ dev_dbg(dev, "(%s) set pending xfer complete\n", __func__);
atmci_set_pending(host, EVENT_XFER_COMPLETE);
atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
}
@@ -1261,14 +1237,14 @@ static void atmci_stop_transfer_pdc(struct atmel_mci *host)
static void atmci_stop_transfer_dma(struct atmel_mci *host)
{
struct dma_chan *chan = host->data_chan;
+ struct device *dev = host->dev;
if (chan) {
dmaengine_terminate_all(chan);
atmci_dma_cleanup(host);
} else {
/* Data transfer was stopped by the interrupt handler */
- dev_dbg(&host->pdev->dev,
- "(%s) set pending xfer complete\n", __func__);
+ dev_dbg(dev, "(%s) set pending xfer complete\n", __func__);
atmci_set_pending(host, EVENT_XFER_COMPLETE);
atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
}
@@ -1281,6 +1257,7 @@ static void atmci_stop_transfer_dma(struct atmel_mci *host)
static void atmci_start_request(struct atmel_mci *host,
struct atmel_mci_slot *slot)
{
+ struct device *dev = host->dev;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
@@ -1296,7 +1273,7 @@ static void atmci_start_request(struct atmel_mci *host,
host->cmd_status = 0;
host->data_status = 0;
- dev_dbg(&host->pdev->dev, "start request: cmd %u\n", mrq->cmd->opcode);
+ dev_dbg(dev, "start request: cmd %u\n", mrq->cmd->opcode);
if (host->need_reset || host->caps.need_reset_after_xfer) {
iflags = atmci_readl(host, ATMCI_IMR);
@@ -1375,6 +1352,8 @@ static void atmci_start_request(struct atmel_mci *host,
static void atmci_queue_request(struct atmel_mci *host,
struct atmel_mci_slot *slot, struct mmc_request *mrq)
{
+ struct device *dev = host->dev;
+
dev_vdbg(&slot->mmc->class_dev, "queue request: state=%d\n",
host->state);
@@ -1384,7 +1363,7 @@ static void atmci_queue_request(struct atmel_mci *host,
host->state = STATE_SENDING_CMD;
atmci_start_request(host, slot);
} else {
- dev_dbg(&host->pdev->dev, "queue request\n");
+ dev_dbg(dev, "queue request\n");
list_add_tail(&slot->queue_node, &host->queue);
}
spin_unlock_bh(&host->lock);
@@ -1394,10 +1373,11 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct atmel_mci_slot *slot = mmc_priv(mmc);
struct atmel_mci *host = slot->host;
+ struct device *dev = host->dev;
struct mmc_data *data;
WARN_ON(slot->mrq);
- dev_dbg(&host->pdev->dev, "MRQ: cmd %u\n", mrq->cmd->opcode);
+ dev_dbg(dev, "MRQ: cmd %u\n", mrq->cmd->opcode);
/*
* We may "know" the card is gone even though there's still an
@@ -1607,6 +1587,7 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq)
{
struct atmel_mci_slot *slot = NULL;
struct mmc_host *prev_mmc = host->cur_slot->mmc;
+ struct device *dev = host->dev;
WARN_ON(host->cmd || host->data);
@@ -1629,12 +1610,11 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq)
slot = list_entry(host->queue.next,
struct atmel_mci_slot, queue_node);
list_del(&slot->queue_node);
- dev_vdbg(&host->pdev->dev, "list not empty: %s is next\n",
- mmc_hostname(slot->mmc));
+ dev_vdbg(dev, "list not empty: %s is next\n", mmc_hostname(slot->mmc));
host->state = STATE_SENDING_CMD;
atmci_start_request(host, slot);
} else {
- dev_vdbg(&host->pdev->dev, "list empty\n");
+ dev_vdbg(dev, "list empty\n");
host->state = STATE_IDLE;
}
@@ -1770,6 +1750,7 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
struct atmel_mci *host = from_tasklet(host, t, tasklet);
struct mmc_request *mrq = host->mrq;
struct mmc_data *data = host->data;
+ struct device *dev = host->dev;
enum atmel_mci_state state = host->state;
enum atmel_mci_state prev_state;
u32 status;
@@ -1778,14 +1759,13 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
state = host->state;
- dev_vdbg(&host->pdev->dev,
- "tasklet: state %u pending/completed/mask %lx/%lx/%x\n",
+ dev_vdbg(dev, "tasklet: state %u pending/completed/mask %lx/%lx/%x\n",
state, host->pending_events, host->completed_events,
atmci_readl(host, ATMCI_IMR));
do {
prev_state = state;
- dev_dbg(&host->pdev->dev, "FSM: state=%d\n", state);
+ dev_dbg(dev, "FSM: state=%d\n", state);
switch (state) {
case STATE_IDLE:
@@ -1798,18 +1778,17 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
* END_REQUEST by default, WAITING_NOTBUSY if it's a
* command needing it or DATA_XFER if there is data.
*/
- dev_dbg(&host->pdev->dev, "FSM: cmd ready?\n");
+ dev_dbg(dev, "FSM: cmd ready?\n");
if (!atmci_test_and_clear_pending(host,
EVENT_CMD_RDY))
break;
- dev_dbg(&host->pdev->dev, "set completed cmd ready\n");
+ dev_dbg(dev, "set completed cmd ready\n");
host->cmd = NULL;
atmci_set_completed(host, EVENT_CMD_RDY);
atmci_command_complete(host, mrq->cmd);
if (mrq->data) {
- dev_dbg(&host->pdev->dev,
- "command with data transfer");
+ dev_dbg(dev, "command with data transfer\n");
/*
* If there is a command error don't start
* data transfer.
@@ -1824,8 +1803,7 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
} else
state = STATE_DATA_XFER;
} else if ((!mrq->data) && (mrq->cmd->flags & MMC_RSP_BUSY)) {
- dev_dbg(&host->pdev->dev,
- "command response need waiting notbusy");
+ dev_dbg(dev, "command response need waiting notbusy\n");
atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
state = STATE_WAITING_NOTBUSY;
} else
@@ -1836,7 +1814,7 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
case STATE_DATA_XFER:
if (atmci_test_and_clear_pending(host,
EVENT_DATA_ERROR)) {
- dev_dbg(&host->pdev->dev, "set completed data error\n");
+ dev_dbg(dev, "set completed data error\n");
atmci_set_completed(host, EVENT_DATA_ERROR);
state = STATE_END_REQUEST;
break;
@@ -1849,14 +1827,12 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
* to the next step which is WAITING_NOTBUSY in write
* case and directly SENDING_STOP in read case.
*/
- dev_dbg(&host->pdev->dev, "FSM: xfer complete?\n");
+ dev_dbg(dev, "FSM: xfer complete?\n");
if (!atmci_test_and_clear_pending(host,
EVENT_XFER_COMPLETE))
break;
- dev_dbg(&host->pdev->dev,
- "(%s) set completed xfer complete\n",
- __func__);
+ dev_dbg(dev, "(%s) set completed xfer complete\n", __func__);
atmci_set_completed(host, EVENT_XFER_COMPLETE);
if (host->caps.need_notbusy_for_read_ops ||
@@ -1881,12 +1857,12 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
* included) or a write operation. In the latest case,
* we need to send a stop command.
*/
- dev_dbg(&host->pdev->dev, "FSM: not busy?\n");
+ dev_dbg(dev, "FSM: not busy?\n");
if (!atmci_test_and_clear_pending(host,
EVENT_NOTBUSY))
break;
- dev_dbg(&host->pdev->dev, "set completed not busy\n");
+ dev_dbg(dev, "set completed not busy\n");
atmci_set_completed(host, EVENT_NOTBUSY);
if (host->data) {
@@ -1916,12 +1892,12 @@ static void atmci_tasklet_func(struct tasklet_struct *t)
* in order to go to the end request state instead of
* sending stop again.
*/
- dev_dbg(&host->pdev->dev, "FSM: cmd ready?\n");
+ dev_dbg(dev, "FSM: cmd ready?\n");
if (!atmci_test_and_clear_pending(host,
EVENT_CMD_RDY))
break;
- dev_dbg(&host->pdev->dev, "FSM: cmd ready\n");
+ dev_dbg(dev, "FSM: cmd ready\n");
host->cmd = NULL;
data->bytes_xfered = data->blocks * data->blksz;
data->error = 0;
@@ -2120,6 +2096,7 @@ static void atmci_sdio_interrupt(struct atmel_mci *host, u32 status)
static irqreturn_t atmci_interrupt(int irq, void *dev_id)
{
struct atmel_mci *host = dev_id;
+ struct device *dev = host->dev;
u32 status, mask, pending;
unsigned int pass_count = 0;
@@ -2131,21 +2108,21 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
break;
if (pending & ATMCI_DATA_ERROR_FLAGS) {
- dev_dbg(&host->pdev->dev, "IRQ: data error\n");
+ dev_dbg(dev, "IRQ: data error\n");
atmci_writel(host, ATMCI_IDR, ATMCI_DATA_ERROR_FLAGS
| ATMCI_RXRDY | ATMCI_TXRDY
| ATMCI_ENDRX | ATMCI_ENDTX
| ATMCI_RXBUFF | ATMCI_TXBUFE);
host->data_status = status;
- dev_dbg(&host->pdev->dev, "set pending data error\n");
+ dev_dbg(dev, "set pending data error\n");
smp_wmb();
atmci_set_pending(host, EVENT_DATA_ERROR);
tasklet_schedule(&host->tasklet);
}
if (pending & ATMCI_TXBUFE) {
- dev_dbg(&host->pdev->dev, "IRQ: tx buffer empty\n");
+ dev_dbg(dev, "IRQ: tx buffer empty\n");
atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE);
atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
/*
@@ -2161,7 +2138,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
atmci_pdc_complete(host);
}
} else if (pending & ATMCI_ENDTX) {
- dev_dbg(&host->pdev->dev, "IRQ: end of tx buffer\n");
+ dev_dbg(dev, "IRQ: end of tx buffer\n");
atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
if (host->data_size) {
@@ -2172,7 +2149,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
}
if (pending & ATMCI_RXBUFF) {
- dev_dbg(&host->pdev->dev, "IRQ: rx buffer full\n");
+ dev_dbg(dev, "IRQ: rx buffer full\n");
atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF);
atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
/*
@@ -2188,7 +2165,7 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
atmci_pdc_complete(host);
}
} else if (pending & ATMCI_ENDRX) {
- dev_dbg(&host->pdev->dev, "IRQ: end of rx buffer\n");
+ dev_dbg(dev, "IRQ: end of rx buffer\n");
atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
if (host->data_size) {
@@ -2205,19 +2182,19 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
* The appropriate workaround is to use the BLKE signal.
*/
if (pending & ATMCI_BLKE) {
- dev_dbg(&host->pdev->dev, "IRQ: blke\n");
+ dev_dbg(dev, "IRQ: blke\n");
atmci_writel(host, ATMCI_IDR, ATMCI_BLKE);
smp_wmb();
- dev_dbg(&host->pdev->dev, "set pending notbusy\n");
+ dev_dbg(dev, "set pending notbusy\n");
atmci_set_pending(host, EVENT_NOTBUSY);
tasklet_schedule(&host->tasklet);
}
if (pending & ATMCI_NOTBUSY) {
- dev_dbg(&host->pdev->dev, "IRQ: not_busy\n");
+ dev_dbg(dev, "IRQ: not_busy\n");
atmci_writel(host, ATMCI_IDR, ATMCI_NOTBUSY);
smp_wmb();
- dev_dbg(&host->pdev->dev, "set pending notbusy\n");
+ dev_dbg(dev, "set pending notbusy\n");
atmci_set_pending(host, EVENT_NOTBUSY);
tasklet_schedule(&host->tasklet);
}
@@ -2228,11 +2205,11 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
atmci_write_data_pio(host);
if (pending & ATMCI_CMDRDY) {
- dev_dbg(&host->pdev->dev, "IRQ: cmd ready\n");
+ dev_dbg(dev, "IRQ: cmd ready\n");
atmci_writel(host, ATMCI_IDR, ATMCI_CMDRDY);
host->cmd_status = status;
smp_wmb();
- dev_dbg(&host->pdev->dev, "set pending cmd rdy\n");
+ dev_dbg(dev, "set pending cmd rdy\n");
atmci_set_pending(host, EVENT_CMD_RDY);
tasklet_schedule(&host->tasklet);
}
@@ -2264,11 +2241,12 @@ static int atmci_init_slot(struct atmel_mci *host,
struct mci_slot_pdata *slot_data, unsigned int id,
u32 sdc_reg, u32 sdio_irq)
{
+ struct device *dev = host->dev;
struct mmc_host *mmc;
struct atmel_mci_slot *slot;
int ret;
- mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev);
+ mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), dev);
if (!mmc)
return -ENOMEM;
@@ -2387,29 +2365,13 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
static int atmci_configure_dma(struct atmel_mci *host)
{
- host->dma.chan = dma_request_chan(&host->pdev->dev, "rxtx");
-
- if (PTR_ERR(host->dma.chan) == -ENODEV) {
- struct mci_platform_data *pdata = host->pdev->dev.platform_data;
- dma_cap_mask_t mask;
-
- if (!pdata || !pdata->dma_filter)
- return -ENODEV;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- host->dma.chan = dma_request_channel(mask, pdata->dma_filter,
- pdata->dma_slave);
- if (!host->dma.chan)
- host->dma.chan = ERR_PTR(-ENODEV);
- }
+ struct device *dev = host->dev;
+ host->dma.chan = dma_request_chan(dev, "rxtx");
if (IS_ERR(host->dma.chan))
return PTR_ERR(host->dma.chan);
- dev_info(&host->pdev->dev, "using %s for DMA transfers\n",
- dma_chan_name(host->dma.chan));
+ dev_info(dev, "using %s for DMA transfers\n", dma_chan_name(host->dma.chan));
host->dma_conf.src_addr = host->mapbase + ATMCI_RDR;
host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -2429,11 +2391,11 @@ static int atmci_configure_dma(struct atmel_mci *host)
*/
static void atmci_get_cap(struct atmel_mci *host)
{
+ struct device *dev = host->dev;
unsigned int version;
version = atmci_get_version(host);
- dev_info(&host->pdev->dev,
- "version: 0x%x\n", version);
+ dev_info(dev, "version: 0x%x\n", version);
host->caps.has_dma_conf_reg = false;
host->caps.has_pdc = true;
@@ -2474,15 +2436,14 @@ static void atmci_get_cap(struct atmel_mci *host)
break;
default:
host->caps.has_pdc = false;
- dev_warn(&host->pdev->dev,
- "Unmanaged mci version, set minimum capabilities\n");
+ dev_warn(dev, "Unmanaged mci version, set minimum capabilities\n");
break;
}
}
static int atmci_probe(struct platform_device *pdev)
{
- struct mci_platform_data *pdata;
+ struct device *dev = &pdev->dev;
struct atmel_mci *host;
struct resource *regs;
unsigned int nr_slots;
@@ -2492,32 +2453,28 @@ static int atmci_probe(struct platform_device *pdev)
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
return -ENXIO;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- pdata = atmci_of_init(pdev);
- if (IS_ERR(pdata)) {
- dev_err(&pdev->dev, "platform data not available\n");
- return PTR_ERR(pdata);
- }
- }
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
- host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
if (!host)
return -ENOMEM;
- host->pdev = pdev;
+ host->dev = dev;
spin_lock_init(&host->lock);
INIT_LIST_HEAD(&host->queue);
- host->mck = devm_clk_get(&pdev->dev, "mci_clk");
+ ret = atmci_of_init(host);
+ if (ret)
+ return dev_err_probe(dev, ret, "Slot information not available\n");
+
+ host->mck = devm_clk_get(dev, "mci_clk");
if (IS_ERR(host->mck))
return PTR_ERR(host->mck);
- host->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
+ host->regs = devm_ioremap(dev, regs->start, resource_size(regs));
if (!host->regs)
return -ENOMEM;
@@ -2532,7 +2489,7 @@ static int atmci_probe(struct platform_device *pdev)
tasklet_setup(&host->tasklet, atmci_tasklet_func);
- ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
+ ret = request_irq(irq, atmci_interrupt, 0, dev_name(dev), host);
if (ret) {
clk_disable_unprepare(host->mck);
return ret;
@@ -2548,12 +2505,12 @@ static int atmci_probe(struct platform_device *pdev)
host->submit_data = &atmci_submit_data_dma;
host->stop_transfer = &atmci_stop_transfer_dma;
} else if (host->caps.has_pdc) {
- dev_info(&pdev->dev, "using PDC\n");
+ dev_info(dev, "using PDC\n");
host->prepare_data = &atmci_prepare_data_pdc;
host->submit_data = &atmci_submit_data_pdc;
host->stop_transfer = &atmci_stop_transfer_pdc;
} else {
- dev_info(&pdev->dev, "using PIO\n");
+ dev_info(dev, "using PIO\n");
host->prepare_data = &atmci_prepare_data;
host->submit_data = &atmci_submit_data;
host->stop_transfer = &atmci_stop_transfer;
@@ -2563,25 +2520,25 @@ static int atmci_probe(struct platform_device *pdev)
timer_setup(&host->timer, atmci_timeout_timer, 0);
- pm_runtime_get_noresume(&pdev->dev);
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_DELAY);
- pm_runtime_use_autosuspend(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_DELAY);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
/* We need at least one slot to succeed */
nr_slots = 0;
ret = -ENODEV;
- if (pdata->slot[0].bus_width) {
- ret = atmci_init_slot(host, &pdata->slot[0],
+ if (host->pdata[0].bus_width) {
+ ret = atmci_init_slot(host, &host->pdata[0],
0, ATMCI_SDCSEL_SLOT_A, ATMCI_SDIOIRQA);
if (!ret) {
nr_slots++;
host->buf_size = host->slot[0]->mmc->max_req_size;
}
}
- if (pdata->slot[1].bus_width) {
- ret = atmci_init_slot(host, &pdata->slot[1],
+ if (host->pdata[1].bus_width) {
+ ret = atmci_init_slot(host, &host->pdata[1],
1, ATMCI_SDCSEL_SLOT_B, ATMCI_SDIOIRQB);
if (!ret) {
nr_slots++;
@@ -2592,27 +2549,25 @@ static int atmci_probe(struct platform_device *pdev)
}
if (!nr_slots) {
- dev_err(&pdev->dev, "init failed: no slot defined\n");
+ dev_err_probe(dev, ret, "init failed: no slot defined\n");
goto err_init_slot;
}
if (!host->caps.has_rwproof) {
- host->buffer = dma_alloc_coherent(&pdev->dev, host->buf_size,
+ host->buffer = dma_alloc_coherent(dev, host->buf_size,
&host->buf_phys_addr,
GFP_KERNEL);
if (!host->buffer) {
- ret = -ENOMEM;
- dev_err(&pdev->dev, "buffer allocation failed\n");
+ ret = dev_err_probe(dev, -ENOMEM, "buffer allocation failed\n");
goto err_dma_alloc;
}
}
- dev_info(&pdev->dev,
- "Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
- host->mapbase, irq, nr_slots);
+ dev_info(dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
+ host->mapbase, irq, nr_slots);
- pm_runtime_mark_last_busy(&host->pdev->dev);
- pm_runtime_put_autosuspend(&pdev->dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
return 0;
@@ -2624,8 +2579,8 @@ err_dma_alloc:
err_init_slot:
clk_disable_unprepare(host->mck);
- pm_runtime_disable(&pdev->dev);
- pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
del_timer_sync(&host->timer);
if (!IS_ERR(host->dma.chan))
@@ -2638,13 +2593,13 @@ err_dma_probe_defer:
static void atmci_remove(struct platform_device *pdev)
{
struct atmel_mci *host = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
unsigned int i;
- pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_get_sync(dev);
if (host->buffer)
- dma_free_coherent(&pdev->dev, host->buf_size,
- host->buffer, host->buf_phys_addr);
+ dma_free_coherent(dev, host->buf_size, host->buffer, host->buf_phys_addr);
for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
if (host->slot[i])
@@ -2663,8 +2618,8 @@ static void atmci_remove(struct platform_device *pdev)
clk_disable_unprepare(host->mck);
- pm_runtime_disable(&pdev->dev);
- pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
}
#ifdef CONFIG_PM
@@ -2701,7 +2656,7 @@ static struct platform_driver atmci_driver = {
.driver = {
.name = "atmel_mci",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
- .of_match_table = of_match_ptr(atmci_dt_ids),
+ .of_match_table = atmci_dt_ids,
.pm = &atmci_dev_pm_ops,
},
};