Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1597571
| Path | csiph.com!news.mixmin.net!aioe.org!news.servidellagleba.it!bofh.it!news.nic.it!robomod |
|---|---|
| From | Jan Glauber <jglauber@cavium.com> |
| Newsgroups | linux.kernel |
| Subject | [PATCH v12 5/9] mmc: cavium: Add support for Octeon cn7890 |
| Date | Fri, 10 Mar 2017 14:30:02 +0100 |
| Message-ID | <tjsMi-4Ar-19@gated-at.bofh.it> (permalink) |
| References | <tjsMh-4Ar-9@gated-at.bofh.it> |
| X-Original-To | Ulf Hansson <ulf.hansson@linaro.org> |
| X-Google-Dkim-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fIOj1R8Rfic4SqpD9TFsnO7BQVn0Sv0FoMhoa1Dw5Jc=; b=W+DYXFRIYicy5muIujzJwKYIrFex8vaOguV+r8oD6DxWmLauWB2fPn0Cgpck6hwL13 yZz4OURNKtYE4ayNdc/Ryw0emHj1VsfR9vn38/7ZAGnjQzKvg1g7hr7H4pX6cVzN0NYp XpmNs6KQgsY3PIrWxW/1/hPC7XS+9dnRovrnBWTDCoXMmreYt8rpOU95Q8yrR+OyIWXz RORk+el8Hg/hfGC8Ej84NF0ae2Bk3ljd1WHlcVUmaDrXanASdU9p5quDFGg70Oen/lUs FKSBM81SsrQPDdMrlFS5c7+pZMe1LJ3vHfo5MH3c+gqAu3KVod0ACjxLgOw0fFdUD7iC nMUQ== |
| X-Gm-Message-State | AMke39lhd8pLijYtWs47CLzU7AI7U0SnYTRu82cyZRFlgupevZwQ+NgMX6NkZvt4bEn92A== |
| X-Received | by 10.223.171.78 with SMTP id r14mr14825390wrc.113.1489152322067; Fri, 10 Mar 2017 05:25:22 -0800 (PST) |
| X-Mailer | git-send-email 2.9.0.rc0.21.g7777322 |
| Sender | robomod@news.nic.it |
| List-ID | <linux-kernel.vger.kernel.org> |
| X-Mailing-List | linux-kernel@vger.kernel.org |
| Approved | robomod@news.nic.it |
| Lines | 209 |
| Organization | linux.* mail to news gateway |
| X-Original-Cc | linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, David Daney <ddaney@caviumnetworks.com>, "Steven J . Hill" <Steven.Hill@cavium.com>, Jan Glauber <jglauber@cavium.com>, David Daney <david.daney@cavium.com>, "Steven J . Hill" <steven.hill@cavium.com> |
| X-Original-Date | Fri, 10 Mar 2017 14:25:03 +0100 |
| X-Original-Message-ID | <20170310132507.32025-6-jglauber@cavium.com> |
| X-Original-References | <20170310132507.32025-1-jglauber@cavium.com> |
| X-Original-Sender | linux-kernel-owner@vger.kernel.org |
| Xref | csiph.com linux.kernel:1597571 |
Show key headers only | View raw
The MMC unit on Octeon cn7890 differs in that it has multiple
interrupts. Requires a lock for the interrupt handler. DMA addresses
have a dedicated 64 bit register now, so use that when available.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Steven J. Hill <steven.hill@cavium.com>
---
drivers/mmc/host/cavium-mmc.c | 16 ++++++-
drivers/mmc/host/cavium-mmc.h | 7 +++
drivers/mmc/host/cavium-pltfm-octeon.c | 79 +++++++++++++++++++++++++++-------
3 files changed, 85 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/host/cavium-mmc.c b/drivers/mmc/host/cavium-mmc.c
index c1d3c65..c57abed 100644
--- a/drivers/mmc/host/cavium-mmc.c
+++ b/drivers/mmc/host/cavium-mmc.c
@@ -412,9 +412,15 @@ irqreturn_t cvm_mmc_interrupt(int irq, void *dev_id)
{
struct cvm_mmc_host *host = dev_id;
struct mmc_request *req;
+ unsigned long flags = 0;
u64 emm_int, rsp_sts;
bool host_done;
+ if (host->need_irq_handler_lock)
+ spin_lock_irqsave(&host->irq_handler_lock, flags);
+ else
+ __acquire(&host->irq_handler_lock);
+
/* Clear interrupt bits (write 1 clears ). */
emm_int = readq(host->base + MIO_EMM_INT(host));
writeq(emm_int, host->base + MIO_EMM_INT(host));
@@ -473,6 +479,10 @@ irqreturn_t cvm_mmc_interrupt(int irq, void *dev_id)
if (host_done)
host->release_bus(host);
out:
+ if (host->need_irq_handler_lock)
+ spin_unlock_irqrestore(&host->irq_handler_lock, flags);
+ else
+ __release(&host->irq_handler_lock);
return IRQ_RETVAL(emm_int != 0);
}
@@ -500,11 +510,15 @@ static u64 prepare_dma_single(struct cvm_mmc_host *host, struct mmc_data *data)
(sg_dma_len(&data->sg[0]) / 8) - 1);
addr = sg_dma_address(&data->sg[0]);
- dma_cfg |= FIELD_PREP(MIO_EMM_DMA_CFG_ADR, addr);
+ if (!host->big_dma_addr)
+ dma_cfg |= FIELD_PREP(MIO_EMM_DMA_CFG_ADR, addr);
writeq(dma_cfg, host->dma_base + MIO_EMM_DMA_CFG(host));
pr_debug("[%s] sg_dma_len: %u total sg_elem: %d\n",
(rw) ? "W" : "R", sg_dma_len(&data->sg[0]), count);
+
+ if (host->big_dma_addr)
+ writeq(addr, host->dma_base + MIO_EMM_DMA_ADR(host));
return addr;
}
diff --git a/drivers/mmc/host/cavium-mmc.h b/drivers/mmc/host/cavium-mmc.h
index 3ee6dae..4b22432 100644
--- a/drivers/mmc/host/cavium-mmc.h
+++ b/drivers/mmc/host/cavium-mmc.h
@@ -23,6 +23,7 @@
/* DMA register addresses */
#define MIO_EMM_DMA_CFG(x) (0x00 + x->reg_off_dma)
+#define MIO_EMM_DMA_ADR(x) (0x08 + x->reg_off_dma)
/* register addresses */
#define MIO_EMM_CFG(x) (0x00 + x->reg_off)
@@ -57,6 +58,12 @@ struct cvm_mmc_host {
struct sg_mapping_iter smi;
bool dma_active;
+ bool has_ciu3;
+ bool big_dma_addr;
+ bool need_irq_handler_lock;
+ spinlock_t irq_handler_lock;
+ struct semaphore mmc_serializer;
+
struct gpio_desc *global_pwr_gpiod;
struct cvm_mmc_slot *slot[CAVIUM_MAX_MMC];
diff --git a/drivers/mmc/host/cavium-pltfm-octeon.c b/drivers/mmc/host/cavium-pltfm-octeon.c
index 9dabfa4..e1fe78b 100644
--- a/drivers/mmc/host/cavium-pltfm-octeon.c
+++ b/drivers/mmc/host/cavium-pltfm-octeon.c
@@ -23,20 +23,28 @@ extern void l2c_unlock_mem_region(u64 start, u64 len);
static void octeon_mmc_acquire_bus(struct cvm_mmc_host *host)
{
- /* Switch the MMC controller onto the bus. */
- down(&octeon_bootbus_sem);
- writeq(0, (void __iomem *)CVMX_MIO_BOOT_CTL);
+ if (!host->has_ciu3) {
+ /* Switch the MMC controller onto the bus. */
+ down(&octeon_bootbus_sem);
+ writeq(0, (void __iomem *)CVMX_MIO_BOOT_CTL);
+ } else {
+ down(&host->mmc_serializer);
+ }
}
static void octeon_mmc_release_bus(struct cvm_mmc_host *host)
{
- up(&octeon_bootbus_sem);
+ if (!host->has_ciu3)
+ up(&octeon_bootbus_sem);
+ else
+ up(&host->mmc_serializer);
}
static void octeon_mmc_int_enable(struct cvm_mmc_host *host, u64 val)
{
writeq(val, host->base + MIO_EMM_INT(host));
- writeq(val, host->base + MIO_EMM_INT_EN(host));
+ if (!host->dma_active || (host->dma_active && !host->has_ciu3))
+ writeq(val, host->base + MIO_EMM_INT_EN(host));
}
static void octeon_mmc_dmar_fixup(struct cvm_mmc_host *host,
@@ -75,6 +83,9 @@ static int octeon_mmc_probe(struct platform_device *pdev)
if (!host)
return -ENOMEM;
+ spin_lock_init(&host->irq_handler_lock);
+ sema_init(&host->mmc_serializer, 1);
+
host->dev = &pdev->dev;
host->acquire_bus = octeon_mmc_acquire_bus;
host->release_bus = octeon_mmc_release_bus;
@@ -87,12 +98,34 @@ static int octeon_mmc_probe(struct platform_device *pdev)
host->sys_freq = octeon_get_io_clock_rate();
- /* First one is EMM second DMA */
- for (i = 0; i < 2; i++) {
- mmc_irq[i] = platform_get_irq(pdev, i);
- if (mmc_irq[i] < 0)
- return mmc_irq[i];
+ if (of_device_is_compatible(node, "cavium,octeon-7890-mmc")) {
+ host->big_dma_addr = true;
+ host->need_irq_handler_lock = true;
+ host->has_ciu3 = true;
+ /*
+ * First seven are the EMM_INT bits 0..6, then two for
+ * the EMM_DMA_INT bits
+ */
+ for (i = 0; i < 9; i++) {
+ mmc_irq[i] = platform_get_irq(pdev, i);
+ if (mmc_irq[i] < 0)
+ return mmc_irq[i];
+
+ /* work around legacy u-boot device trees */
+ irq_set_irq_type(mmc_irq[i], IRQ_TYPE_EDGE_RISING);
+ }
+ } else {
+ host->big_dma_addr = false;
+ host->need_irq_handler_lock = false;
+ host->has_ciu3 = false;
+ /* First one is EMM second DMA */
+ for (i = 0; i < 2; i++) {
+ mmc_irq[i] = platform_get_irq(pdev, i);
+ if (mmc_irq[i] < 0)
+ return mmc_irq[i];
+ }
}
+
host->last_slot = -1;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -124,12 +157,26 @@ static int octeon_mmc_probe(struct platform_device *pdev)
val = readq(host->base + MIO_EMM_INT(host));
writeq(val, host->base + MIO_EMM_INT(host));
- ret = devm_request_irq(&pdev->dev, mmc_irq[0],
- cvm_mmc_interrupt, 0, KBUILD_MODNAME, host);
- if (ret < 0) {
- dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
- mmc_irq[0]);
- return ret;
+ if (host->has_ciu3) {
+ /* Only CMD_DONE, DMA_DONE, CMD_ERR, DMA_ERR */
+ for (i = 1; i <= 4; i++) {
+ ret = devm_request_irq(&pdev->dev, mmc_irq[i],
+ cvm_mmc_interrupt,
+ 0, cvm_mmc_irq_names[i], host);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
+ mmc_irq[i]);
+ return ret;
+ }
+ }
+ } else {
+ ret = devm_request_irq(&pdev->dev, mmc_irq[0],
+ cvm_mmc_interrupt, 0, KBUILD_MODNAME, host);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
+ mmc_irq[0]);
+ return ret;
+ }
}
host->global_pwr_gpiod = devm_gpiod_get_optional(&pdev->dev, "power",
--
2.9.0.rc0.21.g7777322
Back to linux.kernel | Previous | Next | Find similar | Unroll thread
[PATCH v12 5/9] mmc: cavium: Add support for Octeon cn7890 Jan Glauber <jglauber@cavium.com> - 2017-03-10 14:30 +0100
csiph-web