* [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Simon Horman @ 2011-08-19 1:10 UTC (permalink / raw)
To: linux-mmc, linux-sh
Cc: Chris Ball, Paul Mundt, Guennadi Liakhovetski, Magnus Damm,
Simon Horman
In-Reply-To: <1313716221-20136-1-git-send-email-horms@verge.net.au>
Make use of per-source irq handles if the
platform (data) has multiple irq sources.
Also, as suggested by Guennadi Liakhovetski,
add and use defines the index or irqs in platform data.
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
v6
* As discussed with Guennadi Liakhovetski:
- The SDCARD/SDIO change in v5 was not implemented as described.
And the logic wasn't fully described in any case. This
version (hope to!) implement the following logic:
1) 1 IRQ: only resource #0 (CARD_DETECT, use tmio_mmc_irq())
2) 2 or 3 IRQs: compulsory SDCARD and any further IRQs: use respective
specialised ISRs.
v5
* As suggested by Guennadi Liakhovetski:
- Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
v4
* As suggested by Guennadi Liakhovetski:
- Correct inverted values of SH_MOBILE_SDHI_IRQ_SDCARD and
SH_MOBILE_SDHI_IRQ_CARD_DETECT
v3
* Update for changes to "mmc: tmio: Provide separate interrupt handlers"
* As suggested by Guennadi Liakhovetski:
- Merge in patch "mmc: sdhi: Add defines for platform irq indexes"
- Use an enum instead of defines for irq indexes
v2
* Update for changes to "mmc: tmio: Provide separate interrupt handlers"
* Make use of defines provided by
"mmc: sdhi: Add defines for platform irq indexes"
* As suggested by Guennadi Liakhovetski:
- Don't use a loop to initialise irq handlers, the unrolled version
is easier on the eyes (and exactly the same number of lines of code!)
---
drivers/mmc/host/sh_mobile_sdhi.c | 65 +++++++++++++++++++++++------------
include/linux/mmc/sh_mobile_sdhi.h | 7 ++++
2 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 774f643..2fa7bbc 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -96,7 +96,8 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
struct tmio_mmc_host *host;
char clk_name[8];
- int i, irq, ret;
+ int irq, ret, irq_count = 0;
+ irqreturn_t (*f)(int irq, void *devid);
priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
if (priv = NULL) {
@@ -153,27 +154,39 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
if (ret < 0)
goto eprobe;
- for (i = 0; i < 3; i++) {
- irq = platform_get_irq(pdev, i);
- if (irq < 0) {
- if (i) {
- continue;
- } else {
- ret = irq;
- goto eirq;
- }
- }
- ret = request_irq(irq, tmio_mmc_irq, 0,
+ /* Allow a single IRQ resource #0 (CARD_DETECT) which will
+ * use tmio_mmc_irq() or;
+ * Allow 2 or 3 IRQ resources in which case SDCARD is required
+ * and specialised ISRs are used.
+ */
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
+ if (irq >= 0) {
+ irq_count++;
+ ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
dev_name(&pdev->dev), host);
- if (ret) {
- while (i--) {
- irq = platform_get_irq(pdev, i);
- if (irq >= 0)
- free_irq(irq, host);
- }
- goto eirq;
- }
+ if (ret)
+ goto eirq_sdcard;
}
+
+ ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
+ if (irq_count && irq >= 0) {
+ irq_count++;
+ ret = request_irq(irq, tmio_mmc_sdio_irq, 0,
+ dev_name(&pdev->dev), host);
+ if (ret)
+ goto eirq_sdio;
+ } else if (!irq_count)
+ goto eirq_sdio;
+
+ ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
+ if (irq >= 0) {
+ f = irq_count ? tmio_mmc_card_detect_irq : tmio_mmc_irq;
+ ret = request_irq(irq, f, 0, dev_name(&pdev->dev), host);
+ if (ret)
+ goto eirq_card_detect;
+ } else if (irq_count < 2)
+ goto eirq_card_detect;
+
dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
mmc_hostname(host->mmc), (unsigned long)
(platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
@@ -181,7 +194,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
return ret;
-eirq:
+eirq_card_detect:
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
+ if (irq >= 0)
+ free_irq(irq, host);
+eirq_sdio:
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
+ if (irq >= 0)
+ free_irq(irq, host);
+eirq_sdcard:
tmio_mmc_host_remove(host);
eprobe:
clk_disable(priv->clk);
@@ -203,7 +224,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
tmio_mmc_host_remove(host);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < SH_MOBILE_SDHI_IRQ_MAX; i++) {
irq = platform_get_irq(pdev, i);
if (irq >= 0)
free_irq(irq, host);
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index bd50b36..80d3629 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -3,6 +3,13 @@
#include <linux/types.h>
+enum {
+ SH_MOBILE_SDHI_IRQ_CARD_DETECT = 0,
+ SH_MOBILE_SDHI_IRQ_SDCARD,
+ SH_MOBILE_SDHI_IRQ_SDIO,
+ SH_MOBILE_SDHI_IRQ_MAX
+};
+
struct platform_device;
struct tmio_mmc_data;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/4] mmc: tmio: Provide separate interrupt handlers
From: Simon Horman @ 2011-08-19 1:10 UTC (permalink / raw)
To: linux-mmc, linux-sh
Cc: Chris Ball, Paul Mundt, Guennadi Liakhovetski, Magnus Damm,
Simon Horman
In-Reply-To: <1313716221-20136-1-git-send-email-horms@verge.net.au>
Provide separate interrupt handlers which may be used by platforms where
SDHI has three interrupt sources.
This patch also removes the commented-out handling of CRC and other errors.
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
* SDCARD portion tested on AP4/Mackerel
* SDIO portion untested
v4
* As suggested by Guennadi Liakhovetski
- Use bool as return type for __tmio_mmc_sdcard_irq() and
__tmio_mmc_card_detect_irq()
v3
* Rebase for updated "mmc: tmio: Cache interrupt masks"
* As suggested by Guennadi Liakhovetski
- Do not alter logic to handle more than one interupt at once
- Add missing "static" to declartion of __tmio_mmc_sdcard_irq()
v2
* As suggested by Guennadi Liakhovetski
- Combine 3 patches into one
- Reduce the number of __tmio_..._irq() functions
- Rename "...card_access..." functions as "...sdcard..."
---
drivers/mmc/host/tmio_mmc.h | 3 +
drivers/mmc/host/tmio_mmc_pio.c | 131 ++++++++++++++++++++++++--------------
2 files changed, 86 insertions(+), 48 deletions(-)
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 1cf8db5..3020f98 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -97,6 +97,9 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host);
void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
irqreturn_t tmio_mmc_irq(int irq, void *devid);
+irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid);
+irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid);
+irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid);
static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
unsigned long *flags)
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index f0c7830..6275e3d 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -545,44 +545,20 @@ out:
spin_unlock(&host->lock);
}
-irqreturn_t tmio_mmc_irq(int irq, void *devid)
+static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
+ int *ireg, int *status)
{
- struct tmio_mmc_host *host = devid;
- struct mmc_host *mmc = host->mmc;
- struct tmio_mmc_data *pdata = host->pdata;
- unsigned int ireg, status;
- unsigned int sdio_ireg, sdio_status;
-
- pr_debug("MMC IRQ begin\n");
-
- status = sd_ctrl_read32(host, CTL_STATUS);
- ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
+ *status = sd_ctrl_read32(host, CTL_STATUS);
+ *ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
- sdio_ireg = 0;
- if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
- sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
- sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL &
- ~host->sdio_irq_mask;
-
- sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
-
- if (sdio_ireg && !host->sdio_irq_enabled) {
- pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
- sdio_status, host->sdio_irq_mask, sdio_ireg);
- tmio_mmc_enable_sdio_irq(mmc, 0);
- goto out;
- }
-
- if (mmc->caps & MMC_CAP_SDIO_IRQ &&
- sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
- mmc_signal_sdio_irq(mmc);
-
- if (sdio_ireg)
- goto out;
- }
+ pr_debug_status(*status);
+ pr_debug_status(*ireg);
+}
- pr_debug_status(status);
- pr_debug_status(ireg);
+static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
+ int ireg, int status)
+{
+ struct mmc_host *mmc = host->mmc;
/* Card insert / remove attempts */
if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
@@ -592,43 +568,102 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) &&
!work_pending(&mmc->detect.work))
mmc_detect_change(host->mmc, msecs_to_jiffies(100));
- goto out;
+ return true;
}
- /* CRC and other errors */
-/* if (ireg & TMIO_STAT_ERR_IRQ)
- * handled |= tmio_error_irq(host, irq, stat);
- */
+ return false;
+}
+
+irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid)
+{
+ unsigned int ireg, status;
+ struct tmio_mmc_host *host = devid;
+ tmio_mmc_card_irq_status(host, &ireg, &status);
+ __tmio_mmc_card_detect_irq(host, ireg, status);
+
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(tmio_mmc_card_detect_irq);
+
+static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
+ int ireg, int status)
+{
/* Command completion */
if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
tmio_mmc_ack_mmc_irqs(host,
TMIO_STAT_CMDRESPEND |
TMIO_STAT_CMDTIMEOUT);
tmio_mmc_cmd_irq(host, status);
- goto out;
+ return true;
}
/* Data transfer */
if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
tmio_mmc_pio_irq(host);
- goto out;
+ return true;
}
/* Data transfer completion */
if (ireg & TMIO_STAT_DATAEND) {
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
tmio_mmc_data_irq(host);
- goto out;
+ return true;
}
- pr_warning("tmio_mmc: Spurious irq, disabling! "
- "0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg);
- pr_debug_status(status);
- tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask);
+ return false;
+}
+
+irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid)
+{
+ unsigned int ireg, status;
+ struct tmio_mmc_host *host = devid;
+
+ tmio_mmc_card_irq_status(host, &ireg, &status);
+ __tmio_mmc_sdcard_irq(host, ireg, status);
+
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(tmio_mmc_sdcard_irq);
+
+irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
+{
+ struct tmio_mmc_host *host = devid;
+ struct mmc_host *mmc = host->mmc;
+ struct tmio_mmc_data *pdata = host->pdata;
+ unsigned int ireg, status;
+
+ if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
+ return IRQ_HANDLED;
+
+ status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
+ ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;
+
+ sd_ctrl_write16(host, CTL_SDIO_STATUS, status & ~TMIO_SDIO_MASK_ALL);
+
+ if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
+ mmc_signal_sdio_irq(mmc);
+
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(tmio_mmc_sdio_irq);
+
+irqreturn_t tmio_mmc_irq(int irq, void *devid)
+{
+ struct tmio_mmc_host *host = devid;
+ unsigned int ireg, status;
+
+ pr_debug("MMC IRQ begin\n");
+
+ tmio_mmc_card_irq_status(host, &ireg, &status);
+ if (__tmio_mmc_card_detect_irq(host, ireg, status))
+ return IRQ_HANDLED;
+ if (__tmio_mmc_sdcard_irq(host, ireg, status))
+ return IRQ_HANDLED;
+
+ tmio_mmc_sdio_irq(irq, devid);
-out:
return IRQ_HANDLED;
}
EXPORT_SYMBOL(tmio_mmc_irq);
--
1.7.5.4
^ permalink raw reply related
* [PATCH 1/4] mmc: tmio: Cache interrupt masks
From: Simon Horman @ 2011-08-19 1:10 UTC (permalink / raw)
To: linux-mmc, linux-sh
Cc: Chris Ball, Paul Mundt, Guennadi Liakhovetski, Magnus Damm,
Simon Horman
In-Reply-To: <1313716221-20136-1-git-send-email-horms@verge.net.au>
This avoids the need to look up the masks each time an interrupt
is handled.
As suggested by Guennadi.
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
* SDCARD portion tested on AP4/Mackerel
* SDIO portion untested
v3
* As suggested by Guennadi Liakhovetski
- Only read sdcard_irq_mask once and never read sdio_irq_mask,
instead use the cached values as much as possible
v2
* Initial release
---
drivers/mmc/host/tmio_mmc.h | 4 ++++
drivers/mmc/host/tmio_mmc_pio.c | 34 ++++++++++++++++++----------------
2 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index eeaf643..1cf8db5 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -79,6 +79,10 @@ struct tmio_mmc_host {
struct delayed_work delayed_reset_work;
struct work_struct done;
+ /* Cache IRQ mask */
+ u32 sdcard_irq_mask;
+ u32 sdio_irq_mask;
+
spinlock_t lock; /* protect host private data */
unsigned long last_req_ts;
struct mutex ios_lock; /* protect set_ios() context */
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 1f16357..f0c7830 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -48,14 +48,14 @@
void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
- u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ);
- sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
+ host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ);
+ sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
}
void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
- u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ);
- sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
+ host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ);
+ sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
}
static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
@@ -127,11 +127,13 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
if (enable) {
host->sdio_irq_enabled = 1;
+ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
+ ~TMIO_SDIO_STAT_IOIRQ;
sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
- (TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ));
+ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
} else {
- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL);
+ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
+ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
host->sdio_irq_enabled = 0;
}
@@ -548,26 +550,25 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
struct tmio_mmc_host *host = devid;
struct mmc_host *mmc = host->mmc;
struct tmio_mmc_data *pdata = host->pdata;
- unsigned int ireg, irq_mask, status;
- unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
+ unsigned int ireg, status;
+ unsigned int sdio_ireg, sdio_status;
pr_debug("MMC IRQ begin\n");
status = sd_ctrl_read32(host, CTL_STATUS);
- irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
- ireg = status & TMIO_MASK_IRQ & ~irq_mask;
+ ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
sdio_ireg = 0;
if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
- sdio_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK);
- sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask;
+ sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL &
+ ~host->sdio_irq_mask;
sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
if (sdio_ireg && !host->sdio_irq_enabled) {
pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
- sdio_status, sdio_irq_mask, sdio_ireg);
+ sdio_status, host->sdio_irq_mask, sdio_ireg);
tmio_mmc_enable_sdio_irq(mmc, 0);
goto out;
}
@@ -623,9 +624,9 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
}
pr_warning("tmio_mmc: Spurious irq, disabling! "
- "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
+ "0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg);
pr_debug_status(status);
- tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask);
+ tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask);
out:
return IRQ_HANDLED;
@@ -882,6 +883,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
tmio_mmc_clk_stop(_host);
tmio_mmc_reset(_host);
+ _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
tmio_mmc_enable_sdio_irq(mmc, 0);
--
1.7.5.4
^ permalink raw reply related
* [PATCH 0/4 v6] mmc: tmio, sdhi: provide multiple irq handlers
From: Simon Horman @ 2011-08-19 1:10 UTC (permalink / raw)
To: linux-mmc, linux-sh
Cc: Chris Ball, Paul Mundt, Guennadi Liakhovetski, Magnus Damm,
Simon Horman
The SDHI driver already supports making use of up to three interrupt
sources.
This series breaks up the existing interrupt handler into three handlers,
one for card access, one for card detect interrupts, and one for SDIO
interrupts. A cover-all handler, which makes use of these new broken-out
handlers is provided for for the case where there is only one interrupt
source.
This series also wires up the broken-out irq handlers in the SDHI driver
^ permalink raw reply
* [PATCH] mmc: sdhi: initialise mmc_data->flags before use
From: Simon Horman @ 2011-08-19 1:07 UTC (permalink / raw)
To: linux-mmc, linux-sh
Cc: Chris Ball, Guennadi Liakhovetski, Magnus Damm, Simon Horman
This corrects a logic error that I introduced in
"mmc: sdhi: Add write16_hook"
Reported-by: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
drivers/mmc/host/sh_mobile_sdhi.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 2fa7bbc..68702e4 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -121,11 +121,11 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
mmc_data->hclk = clk_get_rate(priv->clk);
mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
mmc_data->get_cd = sh_mobile_sdhi_get_cd;
- if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
- mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
if (p) {
mmc_data->flags = p->tmio_flags;
+ if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
+ mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
mmc_data->ocr_mask = p->tmio_ocr_mask;
mmc_data->capabilities |= p->tmio_caps;
--
1.7.5.4
^ permalink raw reply related
* [PATCH] dma: shdma: transfer based runtime PM
From: Guennadi Liakhovetski @ 2011-08-18 14:55 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-sh, Vinod Koul, Dan Williams, Paul Mundt
Currently the shdma dmaengine driver uses runtime PM to save power, when
no channel on the specific controller is requested by a user. This patch
switches the driver to count individual DMA transfers. That way the
controller can be powered down between transfers, even if some of its
channels are in use.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
tested on mackerel (sh7372) with dmatest, sh_mobile_sdhi and sh_mmcif with
runtime PM and STR.
drivers/dma/shdma.c | 94 +++++++++++++++++++++++++++++++++++++--------------
drivers/dma/shdma.h | 7 ++++
2 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index e7bb747..81809c2 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -259,15 +259,23 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
return 0;
}
+static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan);
+
static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
{
struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c;
struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan);
+ struct sh_dmae_slave *param = tx->chan->private;
dma_async_tx_callback callback = tx->callback;
dma_cookie_t cookie;
- unsigned long flags;
+ bool power_up;
- spin_lock_irqsave(&sh_chan->desc_lock, flags);
+ spin_lock_irq(&sh_chan->desc_lock);
+
+ if (list_empty(&sh_chan->ld_queue))
+ power_up = true;
+ else
+ power_up = false;
cookie = sh_chan->common.cookie;
cookie++;
@@ -303,7 +311,38 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
tx->cookie, &last->async_tx, sh_chan->id,
desc->hw.sar, desc->hw.tcr, desc->hw.dar);
- spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
+ if (power_up) {
+ sh_chan->pm_state = DMAE_PM_BUSY;
+
+ pm_runtime_get(sh_chan->dev);
+
+ spin_unlock_irq(&sh_chan->desc_lock);
+
+ pm_runtime_barrier(sh_chan->dev);
+
+ spin_lock_irq(&sh_chan->desc_lock);
+
+ /* Have we been reset, while waiting? */
+ if (sh_chan->pm_state != DMAE_PM_ESTABLISHED) {
+ dev_dbg(sh_chan->dev, "Bring up channel %d\n",
+ sh_chan->id);
+ if (param) {
+ const struct sh_dmae_slave_config *cfg + param->config;
+
+ dmae_set_dmars(sh_chan, cfg->mid_rid);
+ dmae_set_chcr(sh_chan, cfg->chcr);
+ } else {
+ dmae_init(sh_chan);
+ }
+
+ if (sh_chan->pm_state = DMAE_PM_PENDING)
+ sh_chan_xfer_ld_queue(sh_chan);
+ sh_chan->pm_state = DMAE_PM_ESTABLISHED;
+ }
+ }
+
+ spin_unlock_irq(&sh_chan->desc_lock);
return cookie;
}
@@ -347,8 +386,6 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
struct sh_dmae_slave *param = chan->private;
int ret;
- pm_runtime_get_sync(sh_chan->dev);
-
/*
* This relies on the guarantee from dmaengine that alloc_chan_resources
* never runs concurrently with itself or free_chan_resources.
@@ -368,11 +405,6 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
}
param->config = cfg;
-
- dmae_set_dmars(sh_chan, cfg->mid_rid);
- dmae_set_chcr(sh_chan, cfg->chcr);
- } else {
- dmae_init(sh_chan);
}
while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) {
@@ -401,7 +433,6 @@ edescalloc:
etestused:
efindslave:
chan->private = NULL;
- pm_runtime_put(sh_chan->dev);
return ret;
}
@@ -413,7 +444,6 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
struct sh_desc *desc, *_desc;
LIST_HEAD(list);
- int descs = sh_chan->descs_allocated;
/* Protect against ISR */
spin_lock_irq(&sh_chan->desc_lock);
@@ -440,9 +470,6 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
spin_unlock_irq(&sh_chan->desc_lock);
- if (descs > 0)
- pm_runtime_put(sh_chan->dev);
-
list_for_each_entry_safe(desc, _desc, &list, node)
kfree(desc);
}
@@ -676,7 +703,6 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
struct sh_desc, node);
desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
sh_chan->xmit_shift;
-
}
spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
@@ -761,7 +787,13 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
async_tx_test_ack(&desc->async_tx)) || all) {
/* Remove from ld_queue list */
desc->mark = DESC_IDLE;
+
list_move(&desc->node, &sh_chan->ld_free);
+
+ if (list_empty(&sh_chan->ld_queue)) {
+ dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
+ pm_runtime_put(sh_chan->dev);
+ }
}
}
@@ -791,16 +823,14 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
;
}
+/* Called under spin_lock_irq(&sh_chan->desc_lock) */
static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
{
struct sh_desc *desc;
- spin_lock_irq(&sh_chan->desc_lock);
/* DMA work check */
- if (dmae_is_busy(sh_chan)) {
- spin_unlock_irq(&sh_chan->desc_lock);
+ if (dmae_is_busy(sh_chan))
return;
- }
/* Find the first not transferred descriptor */
list_for_each_entry(desc, &sh_chan->ld_queue, node)
@@ -813,14 +843,18 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
dmae_start(sh_chan);
break;
}
-
- spin_unlock_irq(&sh_chan->desc_lock);
}
static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan)
{
struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
- sh_chan_xfer_ld_queue(sh_chan);
+
+ spin_lock_irq(&sh_chan->desc_lock);
+ if (sh_chan->pm_state = DMAE_PM_ESTABLISHED)
+ sh_chan_xfer_ld_queue(sh_chan);
+ else
+ sh_chan->pm_state = DMAE_PM_PENDING;
+ spin_unlock_irq(&sh_chan->desc_lock);
}
static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
@@ -913,6 +947,12 @@ static bool sh_dmae_reset(struct sh_dmae_device *shdev)
list_splice_init(&sh_chan->ld_queue, &dl);
+ if (!list_empty(&dl)) {
+ dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
+ pm_runtime_put(sh_chan->dev);
+ }
+ sh_chan->pm_state = DMAE_PM_ESTABLISHED;
+
spin_unlock(&sh_chan->desc_lock);
/* Complete all */
@@ -966,10 +1006,10 @@ static void dmae_do_tasklet(unsigned long data)
break;
}
}
- spin_unlock_irq(&sh_chan->desc_lock);
-
/* Next desc */
sh_chan_xfer_ld_queue(sh_chan);
+ spin_unlock_irq(&sh_chan->desc_lock);
+
sh_dmae_chan_ld_cleanup(sh_chan, false);
}
@@ -1037,7 +1077,9 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
return -ENOMEM;
}
- /* copy struct dma_device */
+ new_sh_chan->pm_state = DMAE_PM_ESTABLISHED;
+
+ /* reference struct dma_device */
new_sh_chan->common.device = &shdev->common;
new_sh_chan->dev = shdev->common.dev;
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index dc56576..2b55a27 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -23,6 +23,12 @@
struct device;
+enum dmae_pm_state {
+ DMAE_PM_ESTABLISHED,
+ DMAE_PM_BUSY,
+ DMAE_PM_PENDING,
+};
+
struct sh_dmae_chan {
dma_cookie_t completed_cookie; /* The maximum cookie completed */
spinlock_t desc_lock; /* Descriptor operation lock */
@@ -38,6 +44,7 @@ struct sh_dmae_chan {
u32 __iomem *base;
char dev_id[16]; /* unique name per DMAC of channel */
int pm_error;
+ enum dmae_pm_state pm_state;
};
struct sh_dmae_device {
--
1.7.2.5
^ permalink raw reply related
* [OOPS] sh-sci.c: sleeping in atomic context
From: Guennadi Liakhovetski @ 2011-08-18 8:21 UTC (permalink / raw)
To: linux-sh
Hi all
Looks like sleeping in serial_console_write() is not a good idea:
BUG: scheduling while atomic: dma1chan0-copy2/780/0x00000002
no locks held by dma1chan0-copy2/780.
Modules linked in: dmatest shdma
Backtrace:
[<c001249c>] (dump_backtrace+0x0/0x110) from [<c024e0fc>] (dump_stack+0x18/0x1c)
r6:00000000 r5:00000000 r4:cf7ad0c0 r3:60000013
[<c024e0e4>] (dump_stack+0x0/0x1c) from [<c001e7a8>] (__schedule_bug+0x60/0x6c)
[<c001e748>] (__schedule_bug+0x0/0x6c) from [<c024e7a0>] (schedule+0x5c/0x494)
r5:cf7ae000 r4:cf7ad0c0
[<c024e744>] (schedule+0x0/0x494) from [<c02502b0>] (mutex_lock_nested+0x1a4/0x2ec)
r9:c034fa98 r8:cf7ae000 r7:c0336a00 r6:cf7ad0c0 r5:60000013
r4:c03369dc
[<c025010c>] (mutex_lock_nested+0x0/0x2ec) from [<c017d41c>] (pm_genpd_runtime_resume+0x78/0x1fc)
r8:cf7ae000 r7:cf7ae000 r6:c03369dc r5:c0330650 r4:c0336978
[<c017d3a4>] (pm_genpd_runtime_resume+0x0/0x1fc) from [<c017b304>] (rpm_callback+0x4c/0x6c)
[<c017b2b8>] (rpm_callback+0x0/0x6c) from [<c017c03c>] (rpm_resume+0x300/0x3d4)
r6:00000000 r5:c034fa08 r4:c0330650 r3:c0336978
[<c017bd3c>] (rpm_resume+0x0/0x3d4) from [<c017c39c>] (__pm_runtime_resume+0x50/0x68)
[<c017c34c>] (__pm_runtime_resume+0x0/0x68) from [<c016d14c>] (sci_port_enable+0x24/0x44)
r7:60000093 r6:c036545b r5:00000052 r4:c0760ef8
[<c016d128>] (sci_port_enable+0x0/0x44) from [<c016d1d0>] (serial_console_write+0x28/0x80)
r4:c0760ef8 r3:c0760ef8
[<c016d1a8>] (serial_console_write+0x0/0x80) from [<c00246a0>] (__call_console_drivers+0x90/0xa8)
r6:0000a52d r5:0000a4db r4:c034f320 r3:c016d1a8
[<c0024610>] (__call_console_drivers+0x0/0xa8) from [<c0024738>] (_call_console_drivers+0x80/0x90)
r6:00000000 r5:c03437b4 r4:0000a52d r3:0000a4db
[<c00246b8>] (_call_console_drivers+0x0/0x90) from [<c00248a8>] (console_unlock+0x100/0x1cc)
r5:0000a52d r4:0000a52d
[<c00247a8>] (console_unlock+0x0/0x1cc) from [<c002500c>] (vprintk+0x3b0/0x438)
[<c0024c5c>] (vprintk+0x0/0x438) from [<c024e2c8>] (printk+0x24/0x2c)
[<c024e2a4>] (printk+0x0/0x2c) from [<bf007de0>] (dmatest_func+0xb04/0xbd4 [dmatest])
r3:00000000 r2:0000000a r1:cf7ad29c r0:bf008477
[<bf0072dc>] (dmatest_func+0x0/0xbd4 [dmatest]) from [<c003e238>] (kthread+0x8c/0x94)
[<c003e1ac>] (kthread+0x0/0x94) from [<c0027830>] (do_exit+0x0/0x630)
r7:00000013 r6:c0027830 r5:c003e1ac r4:cf403df0
Yes, I was experimenting with runtime PM, based on a bunch of
not-yet-mainlined patches, but the backtrace seems legitimate. In
principle looks like any printk to the console, which wakes it up, will
cause this.
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* [PATCH 07/07] ARM: mach-shmobile: Kota2 SDHI0 and SDHI1 support
From: Magnus Damm @ 2011-08-18 5:45 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
Add SDHI0 and SDHI1 support to the Kota2 board.
SDHI0 is hooked up to a microSD card slot and SDHI1
to a wireless module that also connects to SCIFB.
This depends on the recently merged code for
TMIO_MMC_HAS_IDLE_WAIT together with PFC support
for pull-ups on SDHI0 and SDHI1.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/board-kota2.c | 93 ++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
--- 0010/arch/arm/mach-shmobile/board-kota2.c
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-18 13:26:52.000000000 +0900
@@ -35,6 +35,8 @@
#include <linux/leds.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <mach/hardware.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
@@ -205,12 +207,86 @@ static struct platform_device mmcif_devi
.resource = mmcif_resources,
};
+static struct sh_mobile_sdhi_info sdhi0_info = {
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED,
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xee100000,
+ .end = 0xee1000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(83),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(84),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = gic_spi(85),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+static struct sh_mobile_sdhi_info sdhi1_info = {
+ .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xee120000,
+ .end = 0xee1200ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(87),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(88),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = gic_spi(89),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+};
+
static struct platform_device *kota2_devices[] __initdata = {
ð_device,
&keysc_device,
&gpio_keys_device,
&gpio_leds_device,
&mmcif_device,
+ &sdhi0_device,
+ &sdhi1_device,
};
static struct map_desc kota2_io_desc[] __initdata = {
@@ -319,6 +395,15 @@ static void __init kota2_init(void)
gpio_request(GPIO_PORT208, NULL); /* Reset */
gpio_direction_output(GPIO_PORT208, 1);
+ /* SDHI0 (microSD) */
+ gpio_request(GPIO_FN_SDHICD0_PU, NULL);
+ gpio_request(GPIO_FN_SDHICMD0_PU, NULL);
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHID0_3_PU, NULL);
+ gpio_request(GPIO_FN_SDHID0_2_PU, NULL);
+ gpio_request(GPIO_FN_SDHID0_1_PU, NULL);
+ gpio_request(GPIO_FN_SDHID0_0_PU, NULL);
+
/* SCIFB (BT) */
gpio_request(GPIO_FN_PORT159_SCIFB_SCK, NULL);
gpio_request(GPIO_FN_PORT160_SCIFB_TXD, NULL);
@@ -326,6 +411,14 @@ static void __init kota2_init(void)
gpio_request(GPIO_FN_PORT162_SCIFB_RXD, NULL);
gpio_request(GPIO_FN_PORT163_SCIFB_RTS_, NULL);
+ /* SDHI1 (BCM4330) */
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
+
#ifdef CONFIG_CACHE_L2X0
/* Early BRESP enable, Shared attribute override enable, 64K*8way */
l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
^ permalink raw reply
* [PATCH 06/07] ARM: mach-shmobile: Kota2 SCIFA4 and SCIFB support
From: Magnus Damm @ 2011-08-18 5:44 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
Add SCIFA4 and SCIFB support to the Kota2 board.
Only pins are configured since the SCIF platform
devices are already present in the sh73a0 code.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/board-kota2.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- 0009/arch/arm/mach-shmobile/board-kota2.c
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-17 22:41:42.000000000 +0900
@@ -256,6 +256,12 @@ static void __init kota2_init(void)
gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
+ /* SCIFA4 (UART1) */
+ gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA4_RXD, NULL);
+ gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
+ gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
+
/* SMSC911X */
gpio_request(GPIO_FN_D0_NAF0, NULL);
gpio_request(GPIO_FN_D1_NAF1, NULL);
@@ -313,6 +319,13 @@ static void __init kota2_init(void)
gpio_request(GPIO_PORT208, NULL); /* Reset */
gpio_direction_output(GPIO_PORT208, 1);
+ /* SCIFB (BT) */
+ gpio_request(GPIO_FN_PORT159_SCIFB_SCK, NULL);
+ gpio_request(GPIO_FN_PORT160_SCIFB_TXD, NULL);
+ gpio_request(GPIO_FN_PORT161_SCIFB_CTS_, NULL);
+ gpio_request(GPIO_FN_PORT162_SCIFB_RXD, NULL);
+ gpio_request(GPIO_FN_PORT163_SCIFB_RTS_, NULL);
+
#ifdef CONFIG_CACHE_L2X0
/* Early BRESP enable, Shared attribute override enable, 64K*8way */
l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
^ permalink raw reply
* [PATCH 05/07] ARM: mach-shmobile: Kota2 MMCIF support
From: Magnus Damm @ 2011-08-18 5:44 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
Add support for sh73a0 MMCIF hardware block on the
Kota2 board. A non-removable eMMC chip is used with
8 data bits on the MMC bus.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/board-kota2.c | 49 ++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
--- 0008/arch/arm/mach-shmobile/board-kota2.c
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-18 13:34:11.000000000 +0900
@@ -33,6 +33,8 @@
#include <linux/input/sh_keysc.h>
#include <linux/gpio_keys.h>
#include <linux/leds.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
#include <mach/hardware.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
@@ -171,11 +173,44 @@ static struct platform_device gpio_leds_
},
};
+static struct resource mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xe6bd0000,
+ .end = 0xe6bd00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(140),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(141),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_plat_data mmcif_info = {
+ .ocr = MMC_VDD_165_195,
+ .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+};
+
+static struct platform_device mmcif_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .platform_data = &mmcif_info,
+ },
+ .num_resources = ARRAY_SIZE(mmcif_resources),
+ .resource = mmcif_resources,
+};
+
static struct platform_device *kota2_devices[] __initdata = {
ð_device,
&keysc_device,
&gpio_keys_device,
&gpio_leds_device,
+ &mmcif_device,
};
static struct map_desc kota2_io_desc[] __initdata = {
@@ -264,6 +299,20 @@ static void __init kota2_init(void)
gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
gpio_request(GPIO_FN_KEYOUT8, NULL);
+ /* MMCIF */
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+ gpio_request(GPIO_FN_MMCD0_0, NULL);
+ gpio_request(GPIO_FN_MMCD0_1, NULL);
+ gpio_request(GPIO_FN_MMCD0_2, NULL);
+ gpio_request(GPIO_FN_MMCD0_3, NULL);
+ gpio_request(GPIO_FN_MMCD0_4, NULL);
+ gpio_request(GPIO_FN_MMCD0_5, NULL);
+ gpio_request(GPIO_FN_MMCD0_6, NULL);
+ gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_FN_MMCCMD0, NULL);
+ gpio_request(GPIO_PORT208, NULL); /* Reset */
+ gpio_direction_output(GPIO_PORT208, 1);
+
#ifdef CONFIG_CACHE_L2X0
/* Early BRESP enable, Shared attribute override enable, 64K*8way */
l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
^ permalink raw reply
* [PATCH 04/07] ARM: mach-shmobile: Kota2 GPIO LEDs support
From: Magnus Damm @ 2011-08-18 5:44 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
This patch ties in GPIO LEDs support on the Kota2
board. For now all LEDs are driven by the GPIO LED
driver, but in the not so distant future the LEDs
hooked up to TPU pin functions will be moved over
to the recently posted LED TPU driver.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/board-kota2.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
--- 0007/arch/arm/mach-shmobile/board-kota2.c
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-17 22:37:10.000000000 +0900
@@ -32,6 +32,7 @@
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
#include <linux/gpio_keys.h>
+#include <linux/leds.h>
#include <mach/hardware.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
@@ -145,10 +146,36 @@ static struct platform_device gpio_keys_
},
};
+#define GPIO_LED(n, g) { .name = n, .gpio = g }
+
+static struct gpio_led gpio_leds[] = {
+ GPIO_LED("V2513", GPIO_PORT153), /* PORT153 [TPU1T02] -> V2513 */
+ GPIO_LED("V2514", GPIO_PORT199), /* PORT199 [TPU4TO1] -> V2514 */
+ GPIO_LED("V2515", GPIO_PORT197), /* PORT197 [TPU2TO1] -> V2515 */
+ GPIO_LED("KEYLED", GPIO_PORT163), /* PORT163 [TPU3TO0] -> KEYLED */
+ GPIO_LED("G", GPIO_PORT20), /* PORT20 [GPO0] -> LED7 -> "G" */
+ GPIO_LED("H", GPIO_PORT21), /* PORT21 [GPO1] -> LED8 -> "H" */
+ GPIO_LED("J", GPIO_PORT22), /* PORT22 [GPO2] -> LED9 -> "J" */
+};
+
+static struct gpio_led_platform_data gpio_leds_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device gpio_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_leds_info,
+ },
+};
+
static struct platform_device *kota2_devices[] __initdata = {
ð_device,
&keysc_device,
&gpio_keys_device,
+ &gpio_leds_device,
};
static struct map_desc kota2_io_desc[] __initdata = {
^ permalink raw reply
* [PATCH 03/07] ARM: mach-shmobile: Kota2 GPIO Keys support
From: Magnus Damm @ 2011-08-18 5:44 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
This patch ties in GPIO Keys support on the Kota2
board. For now the keys are used in polling mode,
but after extending the sh73a0 PFC with IRQ support
we should be able to switch to the IRQ driven driver.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/board-kota2.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
--- 0006/arch/arm/mach-shmobile/board-kota2.c
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-17 22:37:04.000000000 +0900
@@ -31,6 +31,7 @@
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
+#include <linux/gpio_keys.h>
#include <mach/hardware.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
@@ -114,9 +115,40 @@ static struct platform_device keysc_devi
},
};
+#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+static struct gpio_keys_button gpio_buttons[] = {
+ GPIO_KEY(KEY_VOLUMEUP, GPIO_PORT56, "+"), /* S2: VOL+ [IRQ9] */
+ GPIO_KEY(KEY_VOLUMEDOWN, GPIO_PORT54, "-"), /* S3: VOL- [IRQ10] */
+ GPIO_KEY(KEY_MENU, GPIO_PORT27, "Menu"), /* S4: MENU [IRQ30] */
+ GPIO_KEY(KEY_HOMEPAGE, GPIO_PORT26, "Home"), /* S5: HOME [IRQ31] */
+ GPIO_KEY(KEY_BACK, GPIO_PORT11, "Back"), /* S6: BACK [IRQ0] */
+ GPIO_KEY(KEY_PHONE, GPIO_PORT238, "Tel"), /* S7: TEL [IRQ11] */
+ GPIO_KEY(KEY_POWER, GPIO_PORT239, "C1"), /* S8: CAM [IRQ13] */
+ GPIO_KEY(KEY_MAIL, GPIO_PORT224, "Mail"), /* S9: MAIL [IRQ3] */
+ /* Omitted button "C3?": GPIO_PORT223 - S10: CUST [IRQ8] */
+ GPIO_KEY(KEY_CAMERA, GPIO_PORT164, "C2"), /* S11: CAM_HALF [IRQ25] */
+ /* Omitted button "?": GPIO_PORT152 - S12: CAM_FULL [No IRQ] */
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+ .poll_interval = 250, /* polled for now */
+};
+
+static struct platform_device gpio_keys_device = {
+ .name = "gpio-keys-polled", /* polled for now */
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
static struct platform_device *kota2_devices[] __initdata = {
ð_device,
&keysc_device,
+ &gpio_keys_device,
};
static struct map_desc kota2_io_desc[] __initdata = {
^ permalink raw reply
* [PATCH 02/07] ARM: mach-shmobile: Kota2 KEYSC support
From: Magnus Damm @ 2011-08-18 5:44 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
This patch adds KEYSC support to the Kota2 board.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/board-kota2.c | 65 ++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
--- 0005/arch/arm/mach-shmobile/board-kota2.c
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-15 10:33:09.000000000 +0900
@@ -29,6 +29,8 @@
#include <linux/io.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
#include <mach/hardware.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
@@ -69,8 +71,52 @@ static struct platform_device eth_device
.num_resources = ARRAY_SIZE(smsc9220_resources),
};
+static struct sh_keysc_info keysc_platdata = {
+ .mode = SH_KEYSC_MODE_6,
+ .scan_timing = 3,
+ .delay = 100,
+ .keycodes = {
+ KEY_NUMERIC_STAR, KEY_NUMERIC_0, KEY_NUMERIC_POUND,
+ 0, 0, 0, 0, 0,
+ KEY_NUMERIC_7, KEY_NUMERIC_8, KEY_NUMERIC_9,
+ 0, KEY_DOWN, 0, 0, 0,
+ KEY_NUMERIC_4, KEY_NUMERIC_5, KEY_NUMERIC_6,
+ KEY_LEFT, KEY_ENTER, KEY_RIGHT, 0, 0,
+ KEY_NUMERIC_1, KEY_NUMERIC_2, KEY_NUMERIC_3,
+ 0, KEY_UP, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b0098 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(71),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_platdata,
+ },
+};
+
static struct platform_device *kota2_devices[] __initdata = {
ð_device,
+ &keysc_device,
};
static struct map_desc kota2_io_desc[] __initdata = {
@@ -140,6 +186,25 @@ static void __init kota2_init(void)
gpio_request(GPIO_PORT145, NULL); /* RESET */
gpio_direction_output(GPIO_PORT145, 1);
+ /* KEYSC */
+ gpio_request(GPIO_FN_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN6_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN7_PU, NULL);
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT59_KEYOUT6, NULL);
+ gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
+ gpio_request(GPIO_FN_KEYOUT8, NULL);
+
#ifdef CONFIG_CACHE_L2X0
/* Early BRESP enable, Shared attribute override enable, 64K*8way */
l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
^ permalink raw reply
* [PATCH 01/07] ARM: mach-shmobile: Kota2 SCIFA2 and SMSC911X support
From: Magnus Damm @ 2011-08-18 5:44 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
Kota2 base board support including the on-chip SCIFA2
serial console and the on-board SMSC911X ethernet port.
The s73a0 SMP bits are also updated to include Kota2.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
Needs the mach-type entry for Kota2 to build.
arch/arm/mach-shmobile/Kconfig | 7 +
arch/arm/mach-shmobile/Makefile | 1
arch/arm/mach-shmobile/board-kota2.c | 168 ++++++++++++++++++++++++++++++++++
arch/arm/mach-shmobile/platsmp.c | 10 +-
4 files changed, 182 insertions(+), 4 deletions(-)
--- 0001/arch/arm/mach-shmobile/Kconfig
+++ work/arch/arm/mach-shmobile/Kconfig 2011-08-18 14:16:17.000000000 +0900
@@ -69,6 +69,11 @@ config MACH_MACKEREL
depends on ARCH_SH7372
select ARCH_REQUIRE_GPIOLIB
+config MACH_KOTA2
+ bool "KOTA2 board"
+ select ARCH_REQUIRE_GPIOLIB
+ depends on ARCH_SH73A0
+
comment "SH-Mobile System Configuration"
menu "Memory configuration"
@@ -78,6 +83,7 @@ config MEMORY_START
default "0x50000000" if MACH_G3EVM
default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
MACH_MACKEREL
+ default "0x41000000" if MACH_KOTA2
default "0x00000000"
---help---
Tweak this only when porting to a new machine which does not
@@ -89,6 +95,7 @@ config MEMORY_SIZE
default "0x08000000" if MACH_G3EVM
default "0x08000000" if MACH_G4EVM
default "0x20000000" if MACH_AG5EVM
+ default "0x1e000000" if MACH_KOTA2
default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
default "0x04000000"
help
--- 0001/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile 2011-08-18 13:38:02.000000000 +0900
@@ -41,6 +41,7 @@ obj-$(CONFIG_MACH_G4EVM) += board-g4evm.
obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
+obj-$(CONFIG_MACH_KOTA2) += board-kota2.o
# Framework support
obj-$(CONFIG_SMP) += $(smp-y)
--- /dev/null
+++ work/arch/arm/mach-shmobile/board-kota2.c 2011-08-18 13:38:03.000000000 +0900
@@ -0,0 +1,168 @@
+/*
+ * kota2 board support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ * Copyright (C) 2010 Takashi Yoshii <yoshii.takashi.zj@renesas.com>
+ * Copyright (C) 2009 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <mach/sh73a0.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/traps.h>
+
+static struct resource smsc9220_resources[] = {
+ [0] = {
+ .start = 0x14000000, /* CS5A */
+ .end = 0x140000ff, /* A1->A7 */
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(33), /* PINTA2 @ PORT144 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc9220_platdata = {
+ .flags = SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device eth_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smsc9220_platdata,
+ },
+ .resource = smsc9220_resources,
+ .num_resources = ARRAY_SIZE(smsc9220_resources),
+};
+
+static struct platform_device *kota2_devices[] __initdata = {
+ ð_device,
+};
+
+static struct map_desc kota2_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init kota2_map_io(void)
+{
+ iotable_init(kota2_io_desc, ARRAY_SIZE(kota2_io_desc));
+
+ /* setup early devices and console here as well */
+ sh73a0_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define PINTER0A 0xe69000a0
+#define PINTCR0A 0xe69000b0
+
+void __init kota2_init_irq(void)
+{
+ sh73a0_init_irq();
+
+ /* setup PINT: enable PINTA2 as active low */
+ __raw_writel(1 << 29, PINTER0A);
+ __raw_writew(2 << 10, PINTCR0A);
+}
+
+static void __init kota2_init(void)
+{
+ sh73a0_pinmux_init();
+
+ /* SCIFA2 (UART2) */
+ gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
+ gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
+
+ /* SMSC911X */
+ gpio_request(GPIO_FN_D0_NAF0, NULL);
+ gpio_request(GPIO_FN_D1_NAF1, NULL);
+ gpio_request(GPIO_FN_D2_NAF2, NULL);
+ gpio_request(GPIO_FN_D3_NAF3, NULL);
+ gpio_request(GPIO_FN_D4_NAF4, NULL);
+ gpio_request(GPIO_FN_D5_NAF5, NULL);
+ gpio_request(GPIO_FN_D6_NAF6, NULL);
+ gpio_request(GPIO_FN_D7_NAF7, NULL);
+ gpio_request(GPIO_FN_D8_NAF8, NULL);
+ gpio_request(GPIO_FN_D9_NAF9, NULL);
+ gpio_request(GPIO_FN_D10_NAF10, NULL);
+ gpio_request(GPIO_FN_D11_NAF11, NULL);
+ gpio_request(GPIO_FN_D12_NAF12, NULL);
+ gpio_request(GPIO_FN_D13_NAF13, NULL);
+ gpio_request(GPIO_FN_D14_NAF14, NULL);
+ gpio_request(GPIO_FN_D15_NAF15, NULL);
+ gpio_request(GPIO_FN_CS5A_, NULL);
+ gpio_request(GPIO_FN_WE0__FWE, NULL);
+ gpio_request(GPIO_PORT144, NULL); /* PINTA2 */
+ gpio_direction_input(GPIO_PORT144);
+ gpio_request(GPIO_PORT145, NULL); /* RESET */
+ gpio_direction_output(GPIO_PORT145, 1);
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+#endif
+ sh73a0_add_standard_devices();
+ platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices));
+}
+
+static void __init kota2_timer_init(void)
+{
+ sh73a0_clock_init();
+ shmobile_timer.init();
+ return;
+}
+
+struct sys_timer kota2_timer = {
+ .init = kota2_timer_init,
+};
+
+MACHINE_START(KOTA2, "kota2")
+ .map_io = kota2_map_io,
+ .init_irq = kota2_init_irq,
+ .handle_irq = shmobile_handle_irq_gic,
+ .init_machine = kota2_init,
+ .timer = &kota2_timer,
+MACHINE_END
--- 0001/arch/arm/mach-shmobile/platsmp.c
+++ work/arch/arm/mach-shmobile/platsmp.c 2011-08-18 13:38:02.000000000 +0900
@@ -21,9 +21,11 @@
#include <asm/mach-types.h>
#include <mach/common.h>
+#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2())
+
static unsigned int __init shmobile_smp_get_core_count(void)
{
- if (machine_is_ag5evm())
+ if (is_sh73a0())
return sh73a0_get_core_count();
return 1;
@@ -31,7 +33,7 @@ static unsigned int __init shmobile_smp_
static void __init shmobile_smp_prepare_cpus(void)
{
- if (machine_is_ag5evm())
+ if (is_sh73a0())
sh73a0_smp_prepare_cpus();
}
@@ -39,13 +41,13 @@ void __cpuinit platform_secondary_init(u
{
trace_hardirqs_off();
- if (machine_is_ag5evm())
+ if (is_sh73a0())
sh73a0_secondary_init(cpu);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- if (machine_is_ag5evm())
+ if (is_sh73a0())
return sh73a0_boot_secondary(cpu);
return -ENOSYS;
^ permalink raw reply
* [PATCH 00/07] ARM: mach-shmobile: Initial Kota2 board support
From: Magnus Damm @ 2011-08-18 5:43 UTC (permalink / raw)
To: linux-sh
ARM: mach-shmobile: Initial Kota2 board support
[PATCH 01/07] ARM: mach-shmobile: Kota2 SCIFA2 and SMSC911X support
[PATCH 02/07] ARM: mach-shmobile: Kota2 KEYSC support
[PATCH 03/07] ARM: mach-shmobile: Kota2 GPIO Keys support
[PATCH 04/07] ARM: mach-shmobile: Kota2 GPIO LEDs support
[PATCH 05/07] ARM: mach-shmobile: Kota2 MMCIF support
[PATCH 06/07] ARM: mach-shmobile: Kota2 SCIFA4 and SCIFB support
[PATCH 07/07] ARM: mach-shmobile: Kota2 SDHI0 and SDHI1 support
These patches add initial Kota2 board support to mach-shmobile.
With these patches applied the Kota2 board has support for:
SCIFA2, SMSC911X, KEYSC, GPIO-Keys, GPIO-LEDs, MMCIF, SCIFA4,
SCIFB, SDHI0 and SDHI1.
Remaining device support includes LCDC, FSI and I2C.
On top of this support for Runtime PM and DMA Engine will be added.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
Depends on the Kota2 mach-type entry to build together with
[PATCH] ARM: mach-shmobile: sh73a0 PFC pull-up support for SDHI0+2
arch/arm/mach-shmobile/Kconfig | 7
arch/arm/mach-shmobile/Makefile | 1
arch/arm/mach-shmobile/board-kota2.c | 447 ++++++++++++++++++++++++++++++++++
arch/arm/mach-shmobile/platsmp.c | 10
4 files changed, 461 insertions(+), 4 deletions(-)
^ permalink raw reply
* [PATCH] ARM: mach-shmobile: sh73a0 PFC pull-up support for SDHI0+2
From: Magnus Damm @ 2011-08-18 4:32 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@opensource.se>
Extend the existing sh73a0 PFC code with pull-ups for
SDHI0 and SDHI2. Without this patch only SDHI1 has
pull-up support on sh73a0. Needed by boards that make
use of the internal pull-up resistor support built in
the SoC.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
arch/arm/mach-shmobile/include/mach/sh73a0.h | 13 ++++
arch/arm/mach-shmobile/pfc-sh73a0.c | 77 ++++++++++++++++++++------
2 files changed, 75 insertions(+), 15 deletions(-)
--- 0001/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ work/arch/arm/mach-shmobile/include/mach/sh73a0.h 2011-08-18 00:07:22.000000000 +0900
@@ -451,11 +451,23 @@ enum {
GPIO_FN_KEYIN5_PU,
GPIO_FN_KEYIN6_PU,
GPIO_FN_KEYIN7_PU,
+ GPIO_FN_SDHICD0_PU,
+ GPIO_FN_SDHID0_0_PU,
+ GPIO_FN_SDHID0_1_PU,
+ GPIO_FN_SDHID0_2_PU,
+ GPIO_FN_SDHID0_3_PU,
+ GPIO_FN_SDHICMD0_PU,
+ GPIO_FN_SDHIWP0_PU,
GPIO_FN_SDHID1_0_PU,
GPIO_FN_SDHID1_1_PU,
GPIO_FN_SDHID1_2_PU,
GPIO_FN_SDHID1_3_PU,
GPIO_FN_SDHICMD1_PU,
+ GPIO_FN_SDHID2_0_PU,
+ GPIO_FN_SDHID2_1_PU,
+ GPIO_FN_SDHID2_2_PU,
+ GPIO_FN_SDHID2_3_PU,
+ GPIO_FN_SDHICMD2_PU,
GPIO_FN_MMCCMD0_PU,
GPIO_FN_MMCCMD1_PU,
GPIO_FN_FSIACK_PU,
@@ -463,6 +475,7 @@ enum {
GPIO_FN_FSIAIBT_PU,
GPIO_FN_FSIAISLD_PU,
};
+
/* DMA slave IDs */
enum {
SHDMA_SLAVE_INVALID,
--- 0001/arch/arm/mach-shmobile/pfc-sh73a0.c
+++ work/arch/arm/mach-shmobile/pfc-sh73a0.c 2011-08-18 00:07:22.000000000 +0900
@@ -488,13 +488,26 @@ enum {
KEYIN5_PU_MARK,
KEYIN6_PU_MARK,
KEYIN7_PU_MARK,
+ SDHICD0_PU_MARK,
+ SDHID0_0_PU_MARK,
+ SDHID0_1_PU_MARK,
+ SDHID0_2_PU_MARK,
+ SDHID0_3_PU_MARK,
+ SDHICMD0_PU_MARK,
+ SDHIWP0_PU_MARK,
SDHID1_0_PU_MARK,
SDHID1_1_PU_MARK,
SDHID1_2_PU_MARK,
SDHID1_3_PU_MARK,
SDHICMD1_PU_MARK,
+ SDHID2_0_PU_MARK,
+ SDHID2_1_PU_MARK,
+ SDHID2_2_PU_MARK,
+ SDHID2_3_PU_MARK,
+ SDHICMD2_PU_MARK,
MMCCMD0_PU_MARK,
MMCCMD1_PU_MARK,
+ FSIBISLD_PU_MARK,
FSIACK_PU_MARK,
FSIAILR_PU_MARK,
FSIAIBT_PU_MARK,
@@ -1387,19 +1400,28 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3),
PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1),
PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0),
- PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, MSEL4CR_MSEL15_0),
- PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, MSEL4CR_MSEL15_0),
- PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, MSEL4CR_MSEL15_0),
- PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, MSEL4CR_MSEL15_0),
- PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, PORT271_IN_PU,
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, PORT272_IN_PU,
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, PORT273_IN_PU,
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, PORT274_IN_PU,
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, PORT275_IN_PU,
+ MSEL4CR_MSEL15_0), \
PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3),
- PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, PORT276_IN_PU,
+ MSEL4CR_MSEL15_0), \
PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3),
- PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, PORT277_IN_PU,
+ MSEL4CR_MSEL15_0), \
PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3),
- PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, PORT278_IN_PU,
+ MSEL4CR_MSEL15_0), \
PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3),
- PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, PORT279_IN_PU,
+ MSEL4CR_MSEL15_0),
PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \
PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2),
PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1),
@@ -1516,16 +1538,29 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU),
PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU),
- PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_IN_PU, PORT259_FN1),
- PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_IN_PU, PORT260_FN1),
- PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_IN_PU, PORT261_FN1),
- PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_IN_PU, PORT262_FN1),
- PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_IN_PU, PORT263_FN1),
+ PINMUX_DATA(SDHICD0_PU_MARK, PORT251_FN1, PORT251_IN_PU),
+ PINMUX_DATA(SDHID0_0_PU_MARK, PORT252_FN1, PORT252_IN_PU),
+ PINMUX_DATA(SDHID0_1_PU_MARK, PORT253_FN1, PORT253_IN_PU),
+ PINMUX_DATA(SDHID0_2_PU_MARK, PORT254_FN1, PORT254_IN_PU),
+ PINMUX_DATA(SDHID0_3_PU_MARK, PORT255_FN1, PORT255_IN_PU),
+ PINMUX_DATA(SDHICMD0_PU_MARK, PORT256_FN1, PORT256_IN_PU),
+ PINMUX_DATA(SDHIWP0_PU_MARK, PORT257_FN1, PORT256_IN_PU),
+ PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_FN1, PORT259_IN_PU),
+ PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_FN1, PORT260_IN_PU),
+ PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_FN1, PORT261_IN_PU),
+ PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_FN1, PORT262_IN_PU),
+ PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_FN1, PORT263_IN_PU),
+ PINMUX_DATA(SDHID2_0_PU_MARK, PORT265_FN1, PORT265_IN_PU),
+ PINMUX_DATA(SDHID2_1_PU_MARK, PORT266_FN1, PORT266_IN_PU),
+ PINMUX_DATA(SDHID2_2_PU_MARK, PORT267_FN1, PORT267_IN_PU),
+ PINMUX_DATA(SDHID2_3_PU_MARK, PORT268_FN1, PORT268_IN_PU),
+ PINMUX_DATA(SDHICMD2_PU_MARK, PORT269_FN1, PORT269_IN_PU),
PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU,
MSEL4CR_MSEL15_0),
- PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT279_IN_PU,
+ PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU,
MSEL4CR_MSEL15_1),
+ PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU),
PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU),
@@ -2181,11 +2216,23 @@ static struct pinmux_gpio pinmux_gpios[]
GPIO_FN(KEYIN5_PU),
GPIO_FN(KEYIN6_PU),
GPIO_FN(KEYIN7_PU),
+ GPIO_FN(SDHICD0_PU),
+ GPIO_FN(SDHID0_0_PU),
+ GPIO_FN(SDHID0_1_PU),
+ GPIO_FN(SDHID0_2_PU),
+ GPIO_FN(SDHID0_3_PU),
+ GPIO_FN(SDHICMD0_PU),
+ GPIO_FN(SDHIWP0_PU),
GPIO_FN(SDHID1_0_PU),
GPIO_FN(SDHID1_1_PU),
GPIO_FN(SDHID1_2_PU),
GPIO_FN(SDHID1_3_PU),
GPIO_FN(SDHICMD1_PU),
+ GPIO_FN(SDHID2_0_PU),
+ GPIO_FN(SDHID2_1_PU),
+ GPIO_FN(SDHID2_2_PU),
+ GPIO_FN(SDHID2_3_PU),
+ GPIO_FN(SDHICMD2_PU),
GPIO_FN(MMCCMD0_PU),
GPIO_FN(MMCCMD1_PU),
GPIO_FN(FSIACK_PU),
^ permalink raw reply
* [PATCH 3/4 v7] mmc: sdhi: Make use of per-source irq handlers
From: Guennadi Liakhovetski @ 2011-08-17 22:02 UTC (permalink / raw)
To: Simon Horman; +Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <20110817125728.GD13086@verge.net.au>
From: Simon Horman <horms@verge.net.au>
Make use of per-source irq handles if the
platform (data) has multiple irq sources.
Also, as suggested by Guennadi Liakhovetski,
add and use defines the index or irqs in platform data.
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
[g.liakhovetski@gmx.de: fixed IRQ requesting logic]
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
No, your last version was wrong too. Please, give this a go and tell me if
it works as expected.
Thanks
Guennadi
drivers/mmc/host/sh_mobile_sdhi.c | 67 ++++++++++++++++++++++++------------
include/linux/mmc/sh_mobile_sdhi.h | 7 ++++
2 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 774f643..2e3ec8b 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -96,7 +96,9 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
struct tmio_mmc_host *host;
char clk_name[8];
- int i, irq, ret;
+ int irq, ret;
+ irqreturn_t (*f)(int irq, void *devid);
+ bool multi_irq = false;
priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
if (priv = NULL) {
@@ -153,27 +155,40 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
if (ret < 0)
goto eprobe;
- for (i = 0; i < 3; i++) {
- irq = platform_get_irq(pdev, i);
- if (irq < 0) {
- if (i) {
- continue;
- } else {
- ret = irq;
- goto eirq;
- }
- }
- ret = request_irq(irq, tmio_mmc_irq, 0,
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
+ if (irq >= 0) {
+ multi_irq = true;
+ ret = request_irq(irq, tmio_mmc_sdio_irq, 0,
dev_name(&pdev->dev), host);
- if (ret) {
- while (i--) {
- irq = platform_get_irq(pdev, i);
- if (irq >= 0)
- free_irq(irq, host);
- }
- goto eirq;
- }
+ if (ret)
+ goto eirq_sdio;
}
+
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
+ if (irq >= 0) {
+ multi_irq = true;
+ ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
+ dev_name(&pdev->dev), host);
+ if (ret)
+ goto eirq_sdcard;
+ } else if (multi_irq) {
+ ret = irq;
+ goto eirq_sdcard;
+ }
+
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
+ if (irq >= 0) {
+ f = multi_irq ? tmio_mmc_card_detect_irq : tmio_mmc_irq;
+ ret = request_irq(irq, f, 0, dev_name(&pdev->dev), host);
+ if (ret)
+ goto eirq_card_detect;
+ } else if (!multi_irq) {
+ ret = irq;
+ goto eirq_card_detect;
+ } else {
+ ret = 0;
+ }
+
dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
mmc_hostname(host->mmc), (unsigned long)
(platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
@@ -181,7 +196,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
return ret;
-eirq:
+eirq_card_detect:
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
+ if (irq >= 0)
+ free_irq(irq, host);
+eirq_sdcard:
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
+ if (irq >= 0)
+ free_irq(irq, host);
+eirq_sdio:
tmio_mmc_host_remove(host);
eprobe:
clk_disable(priv->clk);
@@ -203,7 +226,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
tmio_mmc_host_remove(host);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < SH_MOBILE_SDHI_IRQ_MAX; i++) {
irq = platform_get_irq(pdev, i);
if (irq >= 0)
free_irq(irq, host);
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index bd50b36..80d3629 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -3,6 +3,13 @@
#include <linux/types.h>
+enum {
+ SH_MOBILE_SDHI_IRQ_CARD_DETECT = 0,
+ SH_MOBILE_SDHI_IRQ_SDCARD,
+ SH_MOBILE_SDHI_IRQ_SDIO,
+ SH_MOBILE_SDHI_IRQ_MAX
+};
+
struct platform_device;
struct tmio_mmc_data;
--
1.7.2.5
^ permalink raw reply related
* [GIT PULL] Power management build fix for 3.1
From: Rafael J. Wysocki @ 2011-08-17 18:41 UTC (permalink / raw)
To: Linus Torvalds; +Cc: LKML, linux-sh, Linux PM mailing list
Hi Linus,
Please pull a power management build fix for 3.1 from:
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git pm-fixes
This makes the new generic PM domains code build correctly
if CONFIG_PM_RUNTIME is unset.
Thanks!
drivers/base/power/domain.c | 30 +++++++++++++++---------------
include/linux/pm_domain.h | 10 +++++++---
kernel/power/Kconfig | 4 ++++
3 files changed, 26 insertions(+), 18 deletions(-)
---------------
Rafael J. Wysocki (1):
PM / Domains: Fix build for CONFIG_PM_RUNTIME unset
^ permalink raw reply
* Re: [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Simon Horman @ 2011-08-17 12:57 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <Pine.LNX.4.64.1108171416010.18317@axis700.grange>
On Wed, Aug 17, 2011 at 02:22:56PM +0200, Guennadi Liakhovetski wrote:
> On Wed, 17 Aug 2011, Simon Horman wrote:
>
> > On Wed, Aug 17, 2011 at 08:41:47PM +0900, Simon Horman wrote:
> > > On Wed, Aug 17, 2011 at 01:24:58PM +0200, Guennadi Liakhovetski wrote:
> > > > On Wed, 17 Aug 2011, Simon Horman wrote:
> > > >
> > > > > Make use of per-source irq handles if the
> > > > > platform (data) has multiple irq sources.
> > > > >
> > > > > Also, as suggested by Guennadi Liakhovetski,
> > > > > add and use defines the index or irqs in platform data.
> > > > >
> > > > > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > > > Cc: Magnus Damm <magnus.damm@gmail.com>
> > > > > Signed-off-by: Simon Horman <horms@verge.net.au>
> > > > >
> > > > > ---
> > > > >
> > > > > v5
> > > > > * As suggested by Guennadi Liakhovetski:
> > > > > - Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
> > > > > SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
> > > >
> > > > This means, CARD_DETECT is optional in a multi-irq configuration, agree.
> > >
> > > [snip]
> > >
> > > > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> > > > > + if (irq >= 0) {
> > > > > + multi_irq = true;
> > > > > + ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
> > > > > + dev_name(&pdev->dev), host);
> > > > > + if (ret)
> > > > > + goto eirq_sdcard;
> > > > > }
> > > >
> > > > This means SDCARD is optional in both single- and multi-irq
> > > > configurations.
> > > >
> > > > > +
> > > > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
> > > > > + if (irq < 0)
> > > > > + goto eirq_card_detect;
> > > >
> > > > This means, CARD_DETECT is compulsory in all configurations.
> > > >
> > > > One of us must be speaking klingonish today.
> > >
> > > Sorry, I messed that up a bit.
> > >
> > > I will make CARD_DETECT optional in multi-irq configurations.
> > > Likewise SDIO will be optional in multi-irq configurations.
> > >
> > > But SDCARD will always be required.
> >
> > Oops, that scheme won't work because in single-irq configuration
> > the only IRQ will be #0, but SDCARD != 0.
> >
> > So I have it in mind to allow the following combinations.
> >
> > i) SDIO, SDCARD, CARD_DETECT
> > ii) SDIO, SDCARD
> > iii) SDCARD, CARD_DETECT
> > iv) SDCARD only (sets multi_irq = true locally, but only one irq!)
> > v) CARD_DETECT only (uses tmio_mmc_irq(), traditional single-irq setup)
>
> I would make it simple:
>
> (1) 1 IRQ: only resource #0 (CARD_DETECT, use tmio_mmc_irq())
> (2) 2 or 3 IRQs: compulsory SDCARD and any further IRQs: use respective
> specialised ISRs.
>
> > Do you think iii and iv are necessary?
>
> Accordingly: iii - yes, iv - no.
Ok, how about this?
From 6514563c5637e65a397d0bf88cda95168a69dea1 Mon Sep 17 00:00:00 2001
From: Simon Horman <horms@verge.net.au>
Date: Tue, 16 Aug 2011 10:42:35 +0900
Subject: [PATCH] mmc: sdhi: Make use of per-source irq handlers
Make use of per-source irq handles if the
platform (data) has multiple irq sources.
Also, as suggested by Guennadi Liakhovetski,
add and use defines the index or irqs in platform data.
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
v6
* As discussed with Guennadi Liakhovetski:
- The SDCARD/SDIO change in v5 was not implemented as described.
And the logic wasn't fully described in any case. This
version (hope to!) implement the following logic:
1) 1 IRQ: only resource #0 (CARD_DETECT, use tmio_mmc_irq())
2) 2 or 3 IRQs: compulsory SDCARD and any further IRQs: use respective
specialised ISRs.
v5
* As suggested by Guennadi Liakhovetski:
- Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
v4
* As suggested by Guennadi Liakhovetski:
- Correct inverted values of SH_MOBILE_SDHI_IRQ_SDCARD and
SH_MOBILE_SDHI_IRQ_CARD_DETECT
v3
* Update for changes to "mmc: tmio: Provide separate interrupt handlers"
* As suggested by Guennadi Liakhovetski:
- Merge in patch "mmc: sdhi: Add defines for platform irq indexes"
- Use an enum instead of defines for irq indexes
v2
* Update for changes to "mmc: tmio: Provide separate interrupt handlers"
* Make use of defines provided by
"mmc: sdhi: Add defines for platform irq indexes"
* As suggested by Guennadi Liakhovetski:
- Don't use a loop to initialise irq handlers, the unrolled version
is easier on the eyes (and exactly the same number of lines of code!)
---
drivers/mmc/host/sh_mobile_sdhi.c | 65 +++++++++++++++++++++++------------
include/linux/mmc/sh_mobile_sdhi.h | 7 ++++
2 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 774f643..2fa7bbc 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -96,7 +96,8 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
struct tmio_mmc_host *host;
char clk_name[8];
- int i, irq, ret;
+ int irq, ret, irq_count = 0;
+ irqreturn_t (*f)(int irq, void *devid);
priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
if (priv = NULL) {
@@ -153,27 +154,39 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
if (ret < 0)
goto eprobe;
- for (i = 0; i < 3; i++) {
- irq = platform_get_irq(pdev, i);
- if (irq < 0) {
- if (i) {
- continue;
- } else {
- ret = irq;
- goto eirq;
- }
- }
- ret = request_irq(irq, tmio_mmc_irq, 0,
+ /* Allow a single IRQ resource #0 (CARD_DETECT) which will
+ * use tmio_mmc_irq() or;
+ * Allow 2 or 3 IRQ resources in which case SDCARD is required
+ * and specialised ISRs are used.
+ */
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
+ if (irq >= 0) {
+ irq_count++;
+ ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
dev_name(&pdev->dev), host);
- if (ret) {
- while (i--) {
- irq = platform_get_irq(pdev, i);
- if (irq >= 0)
- free_irq(irq, host);
- }
- goto eirq;
- }
+ if (ret)
+ goto eirq_sdcard;
}
+
+ ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
+ if (irq_count && irq >= 0) {
+ irq_count++;
+ ret = request_irq(irq, tmio_mmc_sdio_irq, 0,
+ dev_name(&pdev->dev), host);
+ if (ret)
+ goto eirq_sdio;
+ } else if (!irq_count)
+ goto eirq_sdio;
+
+ ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
+ if (irq >= 0) {
+ f = irq_count ? tmio_mmc_card_detect_irq : tmio_mmc_irq;
+ ret = request_irq(irq, f, 0, dev_name(&pdev->dev), host);
+ if (ret)
+ goto eirq_card_detect;
+ } else if (irq_count < 2)
+ goto eirq_card_detect;
+
dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
mmc_hostname(host->mmc), (unsigned long)
(platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
@@ -181,7 +194,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
return ret;
-eirq:
+eirq_card_detect:
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
+ if (irq >= 0)
+ free_irq(irq, host);
+eirq_sdio:
+ irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
+ if (irq >= 0)
+ free_irq(irq, host);
+eirq_sdcard:
tmio_mmc_host_remove(host);
eprobe:
clk_disable(priv->clk);
@@ -203,7 +224,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
tmio_mmc_host_remove(host);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < SH_MOBILE_SDHI_IRQ_MAX; i++) {
irq = platform_get_irq(pdev, i);
if (irq >= 0)
free_irq(irq, host);
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index bd50b36..80d3629 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -3,6 +3,13 @@
#include <linux/types.h>
+enum {
+ SH_MOBILE_SDHI_IRQ_CARD_DETECT = 0,
+ SH_MOBILE_SDHI_IRQ_SDCARD,
+ SH_MOBILE_SDHI_IRQ_SDIO,
+ SH_MOBILE_SDHI_IRQ_MAX
+};
+
struct platform_device;
struct tmio_mmc_data;
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Guennadi Liakhovetski @ 2011-08-17 12:22 UTC (permalink / raw)
To: Simon Horman; +Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <20110817120748.GB13086@verge.net.au>
On Wed, 17 Aug 2011, Simon Horman wrote:
> On Wed, Aug 17, 2011 at 08:41:47PM +0900, Simon Horman wrote:
> > On Wed, Aug 17, 2011 at 01:24:58PM +0200, Guennadi Liakhovetski wrote:
> > > On Wed, 17 Aug 2011, Simon Horman wrote:
> > >
> > > > Make use of per-source irq handles if the
> > > > platform (data) has multiple irq sources.
> > > >
> > > > Also, as suggested by Guennadi Liakhovetski,
> > > > add and use defines the index or irqs in platform data.
> > > >
> > > > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > > Cc: Magnus Damm <magnus.damm@gmail.com>
> > > > Signed-off-by: Simon Horman <horms@verge.net.au>
> > > >
> > > > ---
> > > >
> > > > v5
> > > > * As suggested by Guennadi Liakhovetski:
> > > > - Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
> > > > SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
> > >
> > > This means, CARD_DETECT is optional in a multi-irq configuration, agree.
> >
> > [snip]
> >
> > > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> > > > + if (irq >= 0) {
> > > > + multi_irq = true;
> > > > + ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
> > > > + dev_name(&pdev->dev), host);
> > > > + if (ret)
> > > > + goto eirq_sdcard;
> > > > }
> > >
> > > This means SDCARD is optional in both single- and multi-irq
> > > configurations.
> > >
> > > > +
> > > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
> > > > + if (irq < 0)
> > > > + goto eirq_card_detect;
> > >
> > > This means, CARD_DETECT is compulsory in all configurations.
> > >
> > > One of us must be speaking klingonish today.
> >
> > Sorry, I messed that up a bit.
> >
> > I will make CARD_DETECT optional in multi-irq configurations.
> > Likewise SDIO will be optional in multi-irq configurations.
> >
> > But SDCARD will always be required.
>
> Oops, that scheme won't work because in single-irq configuration
> the only IRQ will be #0, but SDCARD != 0.
>
> So I have it in mind to allow the following combinations.
>
> i) SDIO, SDCARD, CARD_DETECT
> ii) SDIO, SDCARD
> iii) SDCARD, CARD_DETECT
> iv) SDCARD only (sets multi_irq = true locally, but only one irq!)
> v) CARD_DETECT only (uses tmio_mmc_irq(), traditional single-irq setup)
I would make it simple:
(1) 1 IRQ: only resource #0 (CARD_DETECT, use tmio_mmc_irq())
(2) 2 or 3 IRQs: compulsory SDCARD and any further IRQs: use respective
specialised ISRs.
> Do you think iii and iv are necessary?
Accordingly: iii - yes, iv - no.
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* Re: [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Simon Horman @ 2011-08-17 12:07 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <20110817114147.GA13086@verge.net.au>
On Wed, Aug 17, 2011 at 08:41:47PM +0900, Simon Horman wrote:
> On Wed, Aug 17, 2011 at 01:24:58PM +0200, Guennadi Liakhovetski wrote:
> > On Wed, 17 Aug 2011, Simon Horman wrote:
> >
> > > Make use of per-source irq handles if the
> > > platform (data) has multiple irq sources.
> > >
> > > Also, as suggested by Guennadi Liakhovetski,
> > > add and use defines the index or irqs in platform data.
> > >
> > > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > Cc: Magnus Damm <magnus.damm@gmail.com>
> > > Signed-off-by: Simon Horman <horms@verge.net.au>
> > >
> > > ---
> > >
> > > v5
> > > * As suggested by Guennadi Liakhovetski:
> > > - Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
> > > SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
> >
> > This means, CARD_DETECT is optional in a multi-irq configuration, agree.
>
> [snip]
>
> > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> > > + if (irq >= 0) {
> > > + multi_irq = true;
> > > + ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
> > > + dev_name(&pdev->dev), host);
> > > + if (ret)
> > > + goto eirq_sdcard;
> > > }
> >
> > This means SDCARD is optional in both single- and multi-irq
> > configurations.
> >
> > > +
> > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
> > > + if (irq < 0)
> > > + goto eirq_card_detect;
> >
> > This means, CARD_DETECT is compulsory in all configurations.
> >
> > One of us must be speaking klingonish today.
>
> Sorry, I messed that up a bit.
>
> I will make CARD_DETECT optional in multi-irq configurations.
> Likewise SDIO will be optional in multi-irq configurations.
>
> But SDCARD will always be required.
Oops, that scheme won't work because in single-irq configuration
the only IRQ will be #0, but SDCARD != 0.
So I have it in mind to allow the following combinations.
i) SDIO, SDCARD, CARD_DETECT
ii) SDIO, SDCARD
iii) SDCARD, CARD_DETECT
iv) SDCARD only (sets multi_irq = true locally, but only one irq!)
v) CARD_DETECT only (uses tmio_mmc_irq(), traditional single-irq setup)
Do you think iii and iv are necessary?
^ permalink raw reply
* Re: [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Guennadi Liakhovetski @ 2011-08-17 11:54 UTC (permalink / raw)
To: Simon Horman; +Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <20110817114147.GA13086@verge.net.au>
On Wed, 17 Aug 2011, Simon Horman wrote:
> On Wed, Aug 17, 2011 at 01:24:58PM +0200, Guennadi Liakhovetski wrote:
> > On Wed, 17 Aug 2011, Simon Horman wrote:
> >
> > > Make use of per-source irq handles if the
> > > platform (data) has multiple irq sources.
> > >
> > > Also, as suggested by Guennadi Liakhovetski,
> > > add and use defines the index or irqs in platform data.
> > >
> > > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > Cc: Magnus Damm <magnus.damm@gmail.com>
> > > Signed-off-by: Simon Horman <horms@verge.net.au>
> > >
> > > ---
> > >
> > > v5
> > > * As suggested by Guennadi Liakhovetski:
> > > - Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
> > > SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
> >
> > This means, CARD_DETECT is optional in a multi-irq configuration, agree.
>
> [snip]
>
> > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> > > + if (irq >= 0) {
> > > + multi_irq = true;
> > > + ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
> > > + dev_name(&pdev->dev), host);
> > > + if (ret)
> > > + goto eirq_sdcard;
> > > }
> >
> > This means SDCARD is optional in both single- and multi-irq
> > configurations.
> >
> > > +
> > > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
> > > + if (irq < 0)
> > > + goto eirq_card_detect;
> >
> > This means, CARD_DETECT is compulsory in all configurations.
> >
> > One of us must be speaking klingonish today.
>
> Sorry, I messed that up a bit.
>
> I will make CARD_DETECT optional in multi-irq configurations.
> Likewise SDIO will be optional in multi-irq configurations.
>
> But SDCARD will always be required.
No, wrong again. This would break existing single-IRQ configurations,
which only use IRQ resource #0, which is CARD_DETECT.
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* Re: [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Simon Horman @ 2011-08-17 11:41 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <Pine.LNX.4.64.1108171320310.18317@axis700.grange>
On Wed, Aug 17, 2011 at 01:24:58PM +0200, Guennadi Liakhovetski wrote:
> On Wed, 17 Aug 2011, Simon Horman wrote:
>
> > Make use of per-source irq handles if the
> > platform (data) has multiple irq sources.
> >
> > Also, as suggested by Guennadi Liakhovetski,
> > add and use defines the index or irqs in platform data.
> >
> > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > Cc: Magnus Damm <magnus.damm@gmail.com>
> > Signed-off-by: Simon Horman <horms@verge.net.au>
> >
> > ---
> >
> > v5
> > * As suggested by Guennadi Liakhovetski:
> > - Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
> > SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
>
> This means, CARD_DETECT is optional in a multi-irq configuration, agree.
[snip]
> > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> > + if (irq >= 0) {
> > + multi_irq = true;
> > + ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
> > + dev_name(&pdev->dev), host);
> > + if (ret)
> > + goto eirq_sdcard;
> > }
>
> This means SDCARD is optional in both single- and multi-irq
> configurations.
>
> > +
> > + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
> > + if (irq < 0)
> > + goto eirq_card_detect;
>
> This means, CARD_DETECT is compulsory in all configurations.
>
> One of us must be speaking klingonish today.
Sorry, I messed that up a bit.
I will make CARD_DETECT optional in multi-irq configurations.
Likewise SDIO will be optional in multi-irq configurations.
But SDCARD will always be required.
^ permalink raw reply
* Re: [PATCH 3/4] mmc: sdhi: Make use of per-source irq handlers
From: Guennadi Liakhovetski @ 2011-08-17 11:24 UTC (permalink / raw)
To: Simon Horman; +Cc: linux-mmc, linux-sh, Chris Ball, Magnus Damm, Paul Mundt
In-Reply-To: <1313578756-10413-4-git-send-email-horms@verge.net.au>
On Wed, 17 Aug 2011, Simon Horman wrote:
> Make use of per-source irq handles if the
> platform (data) has multiple irq sources.
>
> Also, as suggested by Guennadi Liakhovetski,
> add and use defines the index or irqs in platform data.
>
> Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Signed-off-by: Simon Horman <horms@verge.net.au>
>
> ---
>
> v5
> * As suggested by Guennadi Liakhovetski:
> - Allow only SH_MOBILE_SDHI_IRQ_SDCARD and
> SH_MOBILE_SDHI_IRQ_SDIO to be specified in platform data
This means, CARD_DETECT is optional in a multi-irq configuration, agree.
>
> v4
> * As suggested by Guennadi Liakhovetski:
> - Correct inverted values of SH_MOBILE_SDHI_IRQ_SDCARD and
> SH_MOBILE_SDHI_IRQ_CARD_DETECT
>
> v3
> * Update for changes to "mmc: tmio: Provide separate interrupt handlers"
> * As suggested by Guennadi Liakhovetski:
> - Merge in patch "mmc: sdhi: Add defines for platform irq indexes"
> - Use an enum instead of defines for irq indexes
>
> v2
> * Update for changes to "mmc: tmio: Provide separate interrupt handlers"
> * Make use of defines provided by
> "mmc: sdhi: Add defines for platform irq indexes"
> * As suggested by Guennadi Liakhovetski:
> - Don't use a loop to initialise irq handlers, the unrolled version
> is easier on the eyes (and exactly the same number of lines of code!)
> ---
> drivers/mmc/host/sh_mobile_sdhi.c | 59 ++++++++++++++++++++++-------------
> include/linux/mmc/sh_mobile_sdhi.h | 7 ++++
> 2 files changed, 44 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
> index 774f643..73ecadb 100644
> --- a/drivers/mmc/host/sh_mobile_sdhi.c
> +++ b/drivers/mmc/host/sh_mobile_sdhi.c
> @@ -96,7 +96,9 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
> struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
> struct tmio_mmc_host *host;
> char clk_name[8];
> - int i, irq, ret;
> + int irq, ret;
> + irqreturn_t (*f)(int irq, void *devid);
> + bool multi_irq = false;
>
> priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
> if (priv = NULL) {
> @@ -153,27 +155,32 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
> if (ret < 0)
> goto eprobe;
>
> - for (i = 0; i < 3; i++) {
> - irq = platform_get_irq(pdev, i);
> - if (irq < 0) {
> - if (i) {
> - continue;
> - } else {
> - ret = irq;
> - goto eirq;
> - }
> - }
> - ret = request_irq(irq, tmio_mmc_irq, 0,
> + irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
> + if (irq >= 0) {
> + multi_irq = true;
> + ret = request_irq(irq, tmio_mmc_sdio_irq, 0,
> dev_name(&pdev->dev), host);
> - if (ret) {
> - while (i--) {
> - irq = platform_get_irq(pdev, i);
> - if (irq >= 0)
> - free_irq(irq, host);
> - }
> - goto eirq;
> - }
> + if (ret)
> + goto eirq_sdio;
> + }
> +
> + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> + if (irq >= 0) {
> + multi_irq = true;
> + ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
> + dev_name(&pdev->dev), host);
> + if (ret)
> + goto eirq_sdcard;
> }
This means SDCARD is optional in both single- and multi-irq
configurations.
> +
> + ret = irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
> + if (irq < 0)
> + goto eirq_card_detect;
This means, CARD_DETECT is compulsory in all configurations.
One of us must be speaking klingonish today.
> + f = multi_irq ? tmio_mmc_card_detect_irq : tmio_mmc_irq;
> + ret = request_irq(irq, f, 0, dev_name(&pdev->dev), host);
> + if (ret)
> + goto eirq_card_detect;
> +
> dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
> mmc_hostname(host->mmc), (unsigned long)
> (platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
> @@ -181,7 +188,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
>
> return ret;
>
> -eirq:
> +eirq_card_detect:
> + irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
> + if (irq >= 0)
> + free_irq(irq, host);
> +eirq_sdcard:
> + irq = platform_get_irq(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
> + if (irq >= 0)
> + free_irq(irq, host);
> +eirq_sdio:
> tmio_mmc_host_remove(host);
> eprobe:
> clk_disable(priv->clk);
> @@ -203,7 +218,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
>
> tmio_mmc_host_remove(host);
>
> - for (i = 0; i < 3; i++) {
> + for (i = 0; i < SH_MOBILE_SDHI_IRQ_MAX; i++) {
> irq = platform_get_irq(pdev, i);
> if (irq >= 0)
> free_irq(irq, host);
> diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
> index bd50b36..80d3629 100644
> --- a/include/linux/mmc/sh_mobile_sdhi.h
> +++ b/include/linux/mmc/sh_mobile_sdhi.h
> @@ -3,6 +3,13 @@
>
> #include <linux/types.h>
>
> +enum {
> + SH_MOBILE_SDHI_IRQ_CARD_DETECT = 0,
> + SH_MOBILE_SDHI_IRQ_SDCARD,
> + SH_MOBILE_SDHI_IRQ_SDIO,
> + SH_MOBILE_SDHI_IRQ_MAX
> +};
> +
> struct platform_device;
> struct tmio_mmc_data;
>
> --
> 1.7.5.4
>
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* [PATCH 4/4] ARM: shmobile: ag5evm, ap4: Make use of irq index enum
From: Simon Horman @ 2011-08-17 10:59 UTC (permalink / raw)
To: linux-mmc, linux-sh
Cc: Chris Ball, Guennadi Liakhovetski, Magnus Damm, Paul Mundt,
Simon Horman
In-Reply-To: <1313578756-10413-1-git-send-email-horms@verge.net.au>
This is intended to make it easier to correctly order IRQs.
As suggested by Guennadi Liakhovetski.
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Depends on "mmc: sdhi: Make use of per-source irq handlers"
v4
* Update for corrected ordering of SH_MOBILE_SDHI_IRQ_SDCARD and
SH_MOBILE_SDHI_IRQ_CARD_DETECT
v2
* Initial release
---
arch/arm/mach-shmobile/board-ag5evm.c | 12 ++++++------
arch/arm/mach-shmobile/board-mackerel.c | 18 +++++++++---------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index ce5c251..0d543bb 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -352,15 +352,15 @@ static struct resource sdhi0_resources[] = {
.end = 0xee1000ff,
.flags = IORESOURCE_MEM,
},
- [1] = {
+ [1 + SH_MOBILE_SDHI_IRQ_CARD_DETECT] = {
.start = gic_spi(83),
.flags = IORESOURCE_IRQ,
},
- [2] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDCARD] = {
.start = gic_spi(84),
.flags = IORESOURCE_IRQ,
},
- [3] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDIO] = {
.start = gic_spi(85),
.flags = IORESOURCE_IRQ,
},
@@ -395,15 +395,15 @@ static struct resource sdhi1_resources[] = {
.end = 0xee1200ff,
.flags = IORESOURCE_MEM,
},
- [1] = {
+ [1 + SH_MOBILE_SDHI_IRQ_CARD_DETECT] = {
.start = gic_spi(87),
.flags = IORESOURCE_IRQ,
},
- [2] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDCARD] = {
.start = gic_spi(88),
.flags = IORESOURCE_IRQ,
},
- [3] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDIO] = {
.start = gic_spi(89),
.flags = IORESOURCE_IRQ,
},
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index d41c01f..f9d3a93 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1022,15 +1022,15 @@ static struct resource sdhi0_resources[] = {
.end = 0xe68500ff,
.flags = IORESOURCE_MEM,
},
- [1] = {
+ [1 + SH_MOBILE_SDHI_IRQ_CARD_DETECT] = {
.start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
.flags = IORESOURCE_IRQ,
},
- [2] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDCARD] = {
.start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
.flags = IORESOURCE_IRQ,
},
- [3] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDIO] = {
.start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
.flags = IORESOURCE_IRQ,
},
@@ -1065,15 +1065,15 @@ static struct resource sdhi1_resources[] = {
.end = 0xe68600ff,
.flags = IORESOURCE_MEM,
},
- [1] = {
+ [1 + SH_MOBILE_SDHI_IRQ_CARD_DETECT] = {
.start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
.flags = IORESOURCE_IRQ,
},
- [2] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDCARD] = {
.start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
.flags = IORESOURCE_IRQ,
},
- [3] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDIO] = {
.start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
.flags = IORESOURCE_IRQ,
},
@@ -1116,15 +1116,15 @@ static struct resource sdhi2_resources[] = {
.end = 0xe68700ff,
.flags = IORESOURCE_MEM,
},
- [1] = {
+ [1 + SH_MOBILE_SDHI_IRQ_CARD_DETECT] = {
.start = evt2irq(0x1200), /* SDHI2_SDHI2I0 */
.flags = IORESOURCE_IRQ,
},
- [2] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDCARD] = {
.start = evt2irq(0x1220), /* SDHI2_SDHI2I1 */
.flags = IORESOURCE_IRQ,
},
- [3] = {
+ [1 + SH_MOBILE_SDHI_IRQ_SDIO] = {
.start = evt2irq(0x1240), /* SDHI2_SDHI2I2 */
.flags = IORESOURCE_IRQ,
},
--
1.7.5.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox