* Re: [PATCH v4 REPOST 3/5] omap4: Unconditionally require l2x0 L2
From: Tony Lindgren @ 2011-12-14 18:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111214183030.GB9331@linaro.org>
* Dave Martin <dave.martin@linaro.org> [111214 09:58]:
> On Wed, Dec 14, 2011 at 10:14:25AM -0800, Tony Lindgren wrote:
> > * Dave Martin <dave.martin@linaro.org> [111214 03:08]:
> > > If running in the Normal World on a TrustZone-enabled SoC, Linux
> > > does not have complete control over the L2 cache controller
> > > configuration. The kernel cannot work reliably on such platforms
> > > without the l2x0 cache support code built in.
> >
> > There are HS and GP omaps (High Security and General Purpose).
> > GP omaps do have full control of the L2. Also HS omaps most likely
> > provide control over enabling and disabling L2 depending how the
> > secure code is implemented.
> >
> > BTW, the real problem is that because the secure code is implemented
> > in various ways, we don't really have any handling for it in Linux.
> >
> > The SMI instruction numbers don't seem to be standardized at all,
> > and can mean different things on different boards, even different
> > board versions :(
> >
> > Sounds like devicetree is the only safe way to deal with the L2
> > control options.
> >
> > Regards,
> >
> > Tony
> >
> >
> > > This patch unconditionally enables l2x0 support for the OMAP4 SoCs.
> > >
> > > Thanks to Rob Herring for this suggestion. [1]
> > >
> > > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > >
> > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
> > > ---
> > > arch/arm/mach-omap2/Kconfig | 2 +-
> > > 1 files changed, 1 insertions(+), 1 deletions(-)
> > >
> > > diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> > > index bb1b670..94e568a 100644
> > > --- a/arch/arm/mach-omap2/Kconfig
> > > +++ b/arch/arm/mach-omap2/Kconfig
> > > @@ -41,11 +41,11 @@ config ARCH_OMAP4
> > > bool "TI OMAP4"
> > > default y
> > > depends on ARCH_OMAP2PLUS
> > > + select CACHE_L2X0
> > > select CPU_V7
> > > select ARM_GIC
> > > select HAVE_SMP
> > > select LOCAL_TIMERS if SMP
> > > - select MIGHT_HAVE_CACHE_L2X0
> > > select PL310_ERRATA_588369
> > > select PL310_ERRATA_727915
> > > select ARM_ERRATA_720789
> > > --
> > > 1.7.4.1
> > >
>
> To clarify, are you suggesting we retain this patch, or not?
I think we should keep L2 configurable for omaps until we have some
way of getting the configuration dynamically or from device tree.
> (If we only know what l2x0 support will be needed once the dts is
> parsed at runtime, there could be an argument for keeping the
> select CACHE_L2X0 here -- unless we have specific kconfigs for
> the different security variants of omap.)
Well we can detect if it's an HS omap, but we may not know what
SMI it uses for enabling and disabling L2.. That can depend on
the board version.
Is there some problem keeping MIGHT_HAVE_CACHE_L2X0? This is
pretty important from debugging cache issues point of view.
Regards,
Tony
^ permalink raw reply
* [PATCH 4/4] mmc: sh_mmcif: remove now superfluous sh_mmcif_host::data member
From: Guennadi Liakhovetski @ 2011-12-14 18:31 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-sh, Chris Ball, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1111301553330.22197@axis700.grange>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
drivers/mmc/host/sh_mmcif.c | 94 +++++++++++++++++++++++--------------------
1 files changed, 50 insertions(+), 44 deletions(-)
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index ec6805c..29bcb75 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -207,7 +207,6 @@ enum mmcif_wait_for {
struct sh_mmcif_host {
struct mmc_host *mmc;
- struct mmc_data *data;
struct mmc_request *mrq;
struct platform_device *pd;
struct clk *hclk;
@@ -250,19 +249,21 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
static void mmcif_dma_complete(void *arg)
{
struct sh_mmcif_host *host = arg;
+ struct mmc_data *data = host->mrq->data;
+
dev_dbg(&host->pd->dev, "Command completed\n");
- if (WARN(!host->data, "%s: NULL data in DMA completion!\n",
+ if (WARN(!data, "%s: NULL data in DMA completion!\n",
dev_name(&host->pd->dev)))
return;
- if (host->data->flags & MMC_DATA_READ)
+ if (data->flags & MMC_DATA_READ)
dma_unmap_sg(host->chan_rx->device->dev,
- host->data->sg, host->data->sg_len,
+ data->sg, data->sg_len,
DMA_FROM_DEVICE);
else
dma_unmap_sg(host->chan_tx->device->dev,
- host->data->sg, host->data->sg_len,
+ data->sg, data->sg_len,
DMA_TO_DEVICE);
complete(&host->dma_complete);
@@ -270,13 +271,14 @@ static void mmcif_dma_complete(void *arg)
static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
{
- struct scatterlist *sg = host->data->sg;
+ struct mmc_data *data = host->mrq->data;
+ struct scatterlist *sg = data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_rx;
dma_cookie_t cookie = -EINVAL;
int ret;
- ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len,
+ ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
DMA_FROM_DEVICE);
if (ret > 0) {
host->dma_active = true;
@@ -292,7 +294,7 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
dma_async_issue_pending(chan);
}
dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
- __func__, host->data->sg_len, ret, cookie);
+ __func__, data->sg_len, ret, cookie);
if (!desc) {
/* DMA failed, fall back to PIO */
@@ -313,18 +315,19 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
}
dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
- desc, cookie, host->data->sg_len);
+ desc, cookie, data->sg_len);
}
static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
{
- struct scatterlist *sg = host->data->sg;
+ struct mmc_data *data = host->mrq->data;
+ struct scatterlist *sg = data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_tx;
dma_cookie_t cookie = -EINVAL;
int ret;
- ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len,
+ ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
DMA_TO_DEVICE);
if (ret > 0) {
host->dma_active = true;
@@ -340,7 +343,7 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
dma_async_issue_pending(chan);
}
dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
- __func__, host->data->sg_len, ret, cookie);
+ __func__, data->sg_len, ret, cookie);
if (!desc) {
/* DMA failed, fall back to PIO */
@@ -698,8 +701,11 @@ static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
}
static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
- struct mmc_request *mrq, struct mmc_command *cmd, u32 opc)
+ struct mmc_request *mrq)
{
+ struct mmc_data *data = mrq->data;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 opc = cmd->opcode;
u32 tmp = 0;
/* Response Type check */
@@ -731,7 +737,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
break;
}
/* WDAT / DATW */
- if (host->data) {
+ if (data) {
tmp |= CMD_SET_WDAT;
switch (host->bus_width) {
case MMC_BUS_WIDTH_1:
@@ -755,7 +761,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
if (opc = MMC_READ_MULTIPLE_BLOCK || opc = MMC_WRITE_MULTIPLE_BLOCK) {
tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN;
sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET,
- mrq->data->blocks << 16);
+ data->blocks << 16);
}
/* RIDXC[1:0] check bits */
if (opc = MMC_SEND_OP_COND || opc = MMC_ALL_SEND_CID ||
@@ -769,7 +775,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
opc = MMC_SEND_CSD || opc = MMC_SEND_CID)
tmp |= CMD_SET_CRC7C_INTERNAL;
- return opc = ((opc << 24) | tmp);
+ return (opc << 24) | tmp;
}
static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
@@ -817,12 +823,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
break;
}
- if (host->data) {
+ if (mrq->data) {
sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET,
mrq->data->blksz);
}
- opc = sh_mmcif_set_cmd(host, mrq, cmd, opc);
+ opc = sh_mmcif_set_cmd(host, mrq);
sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0);
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
@@ -838,15 +844,16 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
struct mmc_request *mrq)
{
- struct mmc_command *cmd = mrq->stop;
-
- if (mrq->cmd->opcode = MMC_READ_MULTIPLE_BLOCK)
+ switch (mrq->cmd->opcode) {
+ case MMC_READ_MULTIPLE_BLOCK:
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
- else if (mrq->cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK)
+ break;
+ case MMC_WRITE_MULTIPLE_BLOCK:
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
- else {
+ break;
+ default:
dev_err(&host->pd->dev, "unsupported stop cmd\n");
- cmd->error = sh_mmcif_error_manage(host);
+ mrq->stop->error = sh_mmcif_error_manage(host);
return;
}
@@ -892,7 +899,6 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
host->mrq = mrq;
- host->data = mrq->data;
sh_mmcif_start_cmd(host, mrq);
}
@@ -972,6 +978,7 @@ static struct mmc_host_ops sh_mmcif_ops = {
static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
{
struct mmc_command *cmd = host->mrq->cmd;
+ struct mmc_data *data = host->mrq->data;
long time;
if (host->sd_error) {
@@ -997,10 +1004,10 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
sh_mmcif_get_response(host, cmd);
- if (!host->data)
+ if (!data)
return false;
- if (host->mrq->data->flags & MMC_DATA_READ) {
+ if (data->flags & MMC_DATA_READ) {
if (host->chan_rx)
sh_mmcif_start_dma_rx(host);
} else {
@@ -1009,8 +1016,8 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
}
if (!host->dma_active) {
- host->data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
- if (!host->data->error)
+ data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
+ if (!data->error)
return true;
return false;
}
@@ -1022,22 +1029,22 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
dev_err(host->mmc->parent,
"Error IRQ while waiting for DMA completion!\n");
/* Woken up by an error IRQ: abort DMA */
- if (host->data->flags & MMC_DATA_READ)
+ if (data->flags & MMC_DATA_READ)
dmaengine_terminate_all(host->chan_rx);
else
dmaengine_terminate_all(host->chan_tx);
- host->data->error = sh_mmcif_error_manage(host);
+ data->error = sh_mmcif_error_manage(host);
} else if (!time) {
- host->data->error = -ETIMEDOUT;
+ data->error = -ETIMEDOUT;
} else if (time < 0) {
- host->data->error = time;
+ data->error = time;
}
sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
host->dma_active = false;
- if (host->data->error)
- host->data->bytes_xfered = 0;
+ if (data->error)
+ data->bytes_xfered = 0;
return false;
}
@@ -1046,6 +1053,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
{
struct sh_mmcif_host *host = dev_id;
struct mmc_request *mrq = host->mrq;
+ struct mmc_data *data = mrq->data;
cancel_delayed_work_sync(&host->timeout_work);
@@ -1093,20 +1101,18 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
case MMCIF_WAIT_FOR_READ_END:
case MMCIF_WAIT_FOR_WRITE_END:
if (host->sd_error)
- mrq->data->error = sh_mmcif_error_manage(host);
+ data->error = sh_mmcif_error_manage(host);
break;
default:
BUG();
}
if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
- host->data = NULL;
+ if (!mrq->cmd->error && data && !data->error)
+ data->bytes_xfered + data->blocks * data->blksz;
- if (!mrq->cmd->error && mrq->data && !mrq->data->error)
- mrq->data->bytes_xfered - mrq->data->blocks * mrq->data->blksz;
-
- if (mrq->stop && !mrq->cmd->error && (!mrq->data || !mrq->data->error)) {
+ if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
sh_mmcif_stop_cmd(host, mrq);
if (!mrq->stop->error)
return IRQ_HANDLED;
@@ -1115,6 +1121,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
host->wait_for = MMCIF_WAIT_FOR_REQUEST;
host->state = STATE_IDLE;
+ host->mrq = NULL;
mmc_request_done(host->mmc, mrq);
return IRQ_HANDLED;
@@ -1210,7 +1217,7 @@ static void mmcif_timeout_work(struct work_struct *work)
case MMCIF_WAIT_FOR_WRITE:
case MMCIF_WAIT_FOR_READ_END:
case MMCIF_WAIT_FOR_WRITE_END:
- host->data->error = sh_mmcif_error_manage(host);
+ mrq->data->error = sh_mmcif_error_manage(host);
break;
default:
BUG();
@@ -1218,7 +1225,6 @@ static void mmcif_timeout_work(struct work_struct *work)
host->state = STATE_IDLE;
host->wait_for = MMCIF_WAIT_FOR_REQUEST;
- host->data = NULL;
host->mrq = NULL;
mmc_request_done(host->mmc, mrq);
}
--
1.7.2.5
^ permalink raw reply related
* [PATCH 3/4 v2] mmc: sh_mmcif: process requests asynchronously
From: Guennadi Liakhovetski @ 2011-12-14 18:31 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-sh, Chris Ball, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1111301553330.22197@axis700.grange>
This patch converts the sh_mmcif MMC host driver to process requests
asynchronously instead of waiting in its .request() method for completion.
This is achieved by using threaded IRQs.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
drivers/mmc/host/sh_mmcif.c | 588 ++++++++++++++++++++++++++++++-------------
1 files changed, 416 insertions(+), 172 deletions(-)
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index d6a534c..ec6805c 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -16,6 +16,32 @@
*
*/
+/*
+ * The MMCIF driver is now processing MMC requests asynchronously, according
+ * to the Linux MMC API requirement.
+ *
+ * The MMCIF driver processes MMC requests in up to 3 stages: command, optional
+ * data, and optional stop. To achieve asynchronous processing each of these
+ * stages is split into two halves: a top and a bottom half. The top half
+ * initialises the hardware, installs a timeout handler to handle completion
+ * timeouts, and returns. In case of the command stage this immediately returns
+ * control to the caller, leaving all further processing to run asynchronously.
+ * All further request processing is performed by the bottom halves.
+ *
+ * The bottom half further consists of a "hard" IRQ handler, an IRQ handler
+ * thread, a DMA completion callback, if DMA is used, a timeout work, and
+ * request- and stage-specific handler methods.
+ *
+ * Each bottom half run begins with either a hardware interrupt, a DMA callback
+ * invocation, or a timeout work run. In case of an error or a successful
+ * processing completion, the MMC core is informed and the request processing is
+ * finished. In case processing has to continue, i.e., if data has to be read
+ * from or written to the card, or if a stop command has to be sent, the next
+ * top half is called, which performs the necessary hardware handling and
+ * reschedules the timeout work. This returns the driver state machine into the
+ * bottom half waiting state.
+ */
+
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/completion.h>
@@ -167,19 +193,38 @@ enum mmcif_state {
STATE_IOS,
};
+enum mmcif_wait_for {
+ MMCIF_WAIT_FOR_REQUEST,
+ MMCIF_WAIT_FOR_CMD,
+ MMCIF_WAIT_FOR_MREAD,
+ MMCIF_WAIT_FOR_MWRITE,
+ MMCIF_WAIT_FOR_READ,
+ MMCIF_WAIT_FOR_WRITE,
+ MMCIF_WAIT_FOR_READ_END,
+ MMCIF_WAIT_FOR_WRITE_END,
+ MMCIF_WAIT_FOR_STOP,
+};
+
struct sh_mmcif_host {
struct mmc_host *mmc;
struct mmc_data *data;
+ struct mmc_request *mrq;
struct platform_device *pd;
struct clk *hclk;
unsigned int clk;
int bus_width;
bool sd_error;
+ bool dying;
long timeout;
void __iomem *addr;
- struct completion intr_wait;
+ u32 *pio_ptr;
spinlock_t lock; /* protect sh_mmcif_host::state */
enum mmcif_state state;
+ enum mmcif_wait_for wait_for;
+ struct delayed_work timeout_work;
+ size_t blocksize;
+ int sg_idx;
+ int sg_blkidx;
bool power;
bool card_present;
@@ -455,125 +500,183 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
return ret;
}
-static int sh_mmcif_single_read(struct sh_mmcif_host *host,
- struct mmc_request *mrq)
+static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p)
{
- struct mmc_data *data = mrq->data;
- long time;
- u32 blocksize, i, *p = sg_virt(data->sg);
+ struct mmc_data *data = host->mrq->data;
+
+ host->sg_blkidx += host->blocksize;
+
+ /* data->sg->length must be a multiple of host->blocksize? */
+ BUG_ON(host->sg_blkidx > data->sg->length);
+
+ if (host->sg_blkidx = data->sg->length) {
+ host->sg_blkidx = 0;
+ if (++host->sg_idx < data->sg_len)
+ host->pio_ptr = sg_virt(++data->sg);
+ } else {
+ host->pio_ptr = p;
+ }
+
+ if (host->sg_idx = data->sg_len)
+ return false;
+
+ return true;
+}
+
+static void sh_mmcif_single_read(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
+{
+ host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK) + 3;
+
+ host->wait_for = MMCIF_WAIT_FOR_READ;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
/* buf read enable */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- blocksize = (BLOCK_SIZE_MASK &
- sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
- for (i = 0; i < blocksize / 4; i++)
+}
+
+static bool sh_mmcif_read_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = sg_virt(data->sg);
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
+ }
+
+ for (i = 0; i < host->blocksize / 4; i++)
*p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
/* buffer read end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
+ host->wait_for = MMCIF_WAIT_FOR_READ_END;
- return 0;
+ return true;
}
-static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
- struct mmc_request *mrq)
+static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
{
struct mmc_data *data = mrq->data;
- long time;
- u32 blocksize, i, j, sec, *p;
-
- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
- MMCIF_CE_BLOCK_SET);
- for (j = 0; j < data->sg_len; j++) {
- p = sg_virt(data->sg);
- for (sec = 0; sec < data->sg->length / blocksize; sec++) {
- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
- /* buf read enable */
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
-
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- for (i = 0; i < blocksize / 4; i++)
- *p++ = sh_mmcif_readl(host->addr,
- MMCIF_CE_DATA);
- }
- if (j < data->sg_len - 1)
- data->sg++;
+
+ if (!data->sg_len || !data->sg->length)
+ return;
+
+ host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK;
+
+ host->wait_for = MMCIF_WAIT_FOR_MREAD;
+ host->sg_idx = 0;
+ host->sg_blkidx = 0;
+ host->pio_ptr = sg_virt(data->sg);
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
+}
+
+static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = host->pio_ptr;
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
}
- return 0;
+
+ BUG_ON(!data->sg->length);
+
+ for (i = 0; i < host->blocksize / 4; i++)
+ *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+
+ if (!sh_mmcif_next_block(host, p))
+ return false;
+
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
+
+ return true;
}
-static int sh_mmcif_single_write(struct sh_mmcif_host *host,
+static void sh_mmcif_single_write(struct sh_mmcif_host *host,
struct mmc_request *mrq)
{
- struct mmc_data *data = mrq->data;
- long time;
- u32 blocksize, i, *p = sg_virt(data->sg);
+ host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK) + 3;
- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+ host->wait_for = MMCIF_WAIT_FOR_WRITE;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
/* buf write enable */
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- blocksize = (BLOCK_SIZE_MASK &
- sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
- for (i = 0; i < blocksize / 4; i++)
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+}
+
+static bool sh_mmcif_write_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = sg_virt(data->sg);
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
+ }
+
+ for (i = 0; i < host->blocksize / 4; i++)
sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
/* buffer write end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
+ host->wait_for = MMCIF_WAIT_FOR_WRITE_END;
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- return 0;
+ return true;
}
-static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
- struct mmc_request *mrq)
+static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
{
struct mmc_data *data = mrq->data;
- long time;
- u32 i, sec, j, blocksize, *p;
- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
- MMCIF_CE_BLOCK_SET);
+ if (!data->sg_len || !data->sg->length)
+ return;
- for (j = 0; j < data->sg_len; j++) {
- p = sg_virt(data->sg);
- for (sec = 0; sec < data->sg->length / blocksize; sec++) {
- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
- /* buf write enable*/
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
+ host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK;
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
+ host->wait_for = MMCIF_WAIT_FOR_MWRITE;
+ host->sg_idx = 0;
+ host->sg_blkidx = 0;
+ host->pio_ptr = sg_virt(data->sg);
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+}
- for (i = 0; i < blocksize / 4; i++)
- sh_mmcif_writel(host->addr,
- MMCIF_CE_DATA, *p++);
- }
- if (j < data->sg_len - 1)
- data->sg++;
+static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = host->pio_ptr;
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
}
- return 0;
+
+ BUG_ON(!data->sg->length);
+
+ for (i = 0; i < host->blocksize / 4; i++)
+ sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
+
+ if (!sh_mmcif_next_block(host, p))
+ return false;
+
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+
+ return true;
}
static void sh_mmcif_get_response(struct sh_mmcif_host *host,
@@ -670,18 +773,22 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
}
static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
- struct mmc_request *mrq, u32 opc)
+ struct mmc_request *mrq, u32 opc)
{
switch (opc) {
case MMC_READ_MULTIPLE_BLOCK:
- return sh_mmcif_multi_read(host, mrq);
+ sh_mmcif_multi_read(host, mrq);
+ return 0;
case MMC_WRITE_MULTIPLE_BLOCK:
- return sh_mmcif_multi_write(host, mrq);
+ sh_mmcif_multi_write(host, mrq);
+ return 0;
case MMC_WRITE_BLOCK:
- return sh_mmcif_single_write(host, mrq);
+ sh_mmcif_single_write(host, mrq);
+ return 0;
case MMC_READ_SINGLE_BLOCK:
case MMC_SEND_EXT_CSD:
- return sh_mmcif_single_read(host, mrq);
+ sh_mmcif_single_read(host, mrq);
+ return 0;
default:
dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
return -EINVAL;
@@ -692,9 +799,8 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
struct mmc_request *mrq)
{
struct mmc_command *cmd = mrq->cmd;
- long time;
- int ret = 0;
- u32 mask, opc = cmd->opcode;
+ u32 opc = cmd->opcode;
+ u32 mask;
switch (opc) {
/* response busy check */
@@ -725,62 +831,14 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
/* set cmd */
sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0) {
- cmd->error = sh_mmcif_error_manage(host);
- return;
- }
- if (host->sd_error) {
- switch (cmd->opcode) {
- case MMC_ALL_SEND_CID:
- case MMC_SELECT_CARD:
- case MMC_APP_CMD:
- cmd->error = -ETIMEDOUT;
- break;
- default:
- dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n",
- cmd->opcode);
- cmd->error = sh_mmcif_error_manage(host);
- break;
- }
- host->sd_error = false;
- return;
- }
- if (!(cmd->flags & MMC_RSP_PRESENT)) {
- cmd->error = 0;
- return;
- }
- sh_mmcif_get_response(host, cmd);
- if (host->data) {
- if (!host->dma_active) {
- ret = sh_mmcif_data_trans(host, mrq, cmd->opcode);
- } else {
- long time - wait_for_completion_interruptible_timeout(&host->dma_complete,
- host->timeout);
- if (!time)
- ret = -ETIMEDOUT;
- else if (time < 0)
- ret = time;
- sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
- BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
- host->dma_active = false;
- }
- if (ret < 0)
- mrq->data->bytes_xfered = 0;
- else
- mrq->data->bytes_xfered - mrq->data->blocks * mrq->data->blksz;
- }
- cmd->error = ret;
+ host->wait_for = MMCIF_WAIT_FOR_CMD;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
}
static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
struct mmc_request *mrq)
{
struct mmc_command *cmd = mrq->stop;
- long time;
if (mrq->cmd->opcode = MMC_READ_MULTIPLE_BLOCK)
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
@@ -792,14 +850,8 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
return;
}
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error) {
- cmd->error = sh_mmcif_error_manage(host);
- return;
- }
- sh_mmcif_get_cmd12response(host, cmd);
- cmd->error = 0;
+ host->wait_for = MMCIF_WAIT_FOR_STOP;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
}
static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -838,23 +890,11 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
default:
break;
}
+
+ host->mrq = mrq;
host->data = mrq->data;
- if (mrq->data) {
- if (mrq->data->flags & MMC_DATA_READ) {
- if (host->chan_rx)
- sh_mmcif_start_dma_rx(host);
- } else {
- if (host->chan_tx)
- sh_mmcif_start_dma_tx(host);
- }
- }
- sh_mmcif_start_cmd(host, mrq);
- host->data = NULL;
- if (!mrq->cmd->error && mrq->stop)
- sh_mmcif_stop_cmd(host, mrq);
- host->state = STATE_IDLE;
- mmc_request_done(mmc, mrq);
+ sh_mmcif_start_cmd(host, mrq);
}
static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -929,6 +969,157 @@ static struct mmc_host_ops sh_mmcif_ops = {
.get_cd = sh_mmcif_get_cd,
};
+static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
+{
+ struct mmc_command *cmd = host->mrq->cmd;
+ long time;
+
+ if (host->sd_error) {
+ switch (cmd->opcode) {
+ case MMC_ALL_SEND_CID:
+ case MMC_SELECT_CARD:
+ case MMC_APP_CMD:
+ cmd->error = -ETIMEDOUT;
+ host->sd_error = false;
+ break;
+ default:
+ cmd->error = sh_mmcif_error_manage(host);
+ dev_dbg(&host->pd->dev, "Cmd(d'%d) error %d\n",
+ cmd->opcode, cmd->error);
+ break;
+ }
+ return false;
+ }
+ if (!(cmd->flags & MMC_RSP_PRESENT)) {
+ cmd->error = 0;
+ return false;
+ }
+
+ sh_mmcif_get_response(host, cmd);
+
+ if (!host->data)
+ return false;
+
+ if (host->mrq->data->flags & MMC_DATA_READ) {
+ if (host->chan_rx)
+ sh_mmcif_start_dma_rx(host);
+ } else {
+ if (host->chan_tx)
+ sh_mmcif_start_dma_tx(host);
+ }
+
+ if (!host->dma_active) {
+ host->data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
+ if (!host->data->error)
+ return true;
+ return false;
+ }
+
+ /* Running in the IRQ thread, can sleep */
+ time = wait_for_completion_interruptible_timeout(&host->dma_complete,
+ host->timeout);
+ if (host->sd_error) {
+ dev_err(host->mmc->parent,
+ "Error IRQ while waiting for DMA completion!\n");
+ /* Woken up by an error IRQ: abort DMA */
+ if (host->data->flags & MMC_DATA_READ)
+ dmaengine_terminate_all(host->chan_rx);
+ else
+ dmaengine_terminate_all(host->chan_tx);
+ host->data->error = sh_mmcif_error_manage(host);
+ } else if (!time) {
+ host->data->error = -ETIMEDOUT;
+ } else if (time < 0) {
+ host->data->error = time;
+ }
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
+ BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ host->dma_active = false;
+
+ if (host->data->error)
+ host->data->bytes_xfered = 0;
+
+ return false;
+}
+
+static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
+{
+ struct sh_mmcif_host *host = dev_id;
+ struct mmc_request *mrq = host->mrq;
+
+ cancel_delayed_work_sync(&host->timeout_work);
+
+ /*
+ * All handlers return true, if processing continues, and false, if the
+ * request has to be completed - successfully or not
+ */
+ switch (host->wait_for) {
+ case MMCIF_WAIT_FOR_REQUEST:
+ /* We're too late, the timeout has already kicked in */
+ return IRQ_HANDLED;
+ case MMCIF_WAIT_FOR_CMD:
+ if (sh_mmcif_end_cmd(host))
+ /* Wait for data */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_MREAD:
+ if (sh_mmcif_mread_block(host))
+ /* Wait for more data */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_READ:
+ if (sh_mmcif_read_block(host))
+ /* Wait for data end */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_MWRITE:
+ if (sh_mmcif_mwrite_block(host))
+ /* Wait data to write */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_WRITE:
+ if (sh_mmcif_write_block(host))
+ /* Wait for data end */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_STOP:
+ if (host->sd_error) {
+ mrq->stop->error = sh_mmcif_error_manage(host);
+ break;
+ }
+ sh_mmcif_get_cmd12response(host, mrq->stop);
+ mrq->stop->error = 0;
+ break;
+ case MMCIF_WAIT_FOR_READ_END:
+ case MMCIF_WAIT_FOR_WRITE_END:
+ if (host->sd_error)
+ mrq->data->error = sh_mmcif_error_manage(host);
+ break;
+ default:
+ BUG();
+ }
+
+ if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
+ host->data = NULL;
+
+ if (!mrq->cmd->error && mrq->data && !mrq->data->error)
+ mrq->data->bytes_xfered + mrq->data->blocks * mrq->data->blksz;
+
+ if (mrq->stop && !mrq->cmd->error && (!mrq->data || !mrq->data->error)) {
+ sh_mmcif_stop_cmd(host, mrq);
+ if (!mrq->stop->error)
+ return IRQ_HANDLED;
+ }
+ }
+
+ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
+ host->state = STATE_IDLE;
+ mmc_request_done(host->mmc, mrq);
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
{
struct sh_mmcif_host *host = dev_id;
@@ -980,14 +1171,58 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
host->sd_error = true;
dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
}
- if (state & ~(INT_CMD12RBE | INT_CMD12CRE))
- complete(&host->intr_wait);
- else
+ if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
+ if (!host->dma_active)
+ return IRQ_WAKE_THREAD;
+ else if (host->sd_error)
+ mmcif_dma_complete(host);
+ } else {
dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state);
+ }
return IRQ_HANDLED;
}
+static void mmcif_timeout_work(struct work_struct *work)
+{
+ struct delayed_work *d = container_of(work, struct delayed_work, work);
+ struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work);
+ struct mmc_request *mrq = host->mrq;
+
+ if (host->dying)
+ /* Don't run after mmc_remove_host() */
+ return;
+
+ /*
+ * Handle races with cancel_delayed_work(), unless
+ * cancel_delayed_work_sync() is used
+ */
+ switch (host->wait_for) {
+ case MMCIF_WAIT_FOR_CMD:
+ mrq->cmd->error = sh_mmcif_error_manage(host);
+ break;
+ case MMCIF_WAIT_FOR_STOP:
+ mrq->stop->error = sh_mmcif_error_manage(host);
+ break;
+ case MMCIF_WAIT_FOR_MREAD:
+ case MMCIF_WAIT_FOR_MWRITE:
+ case MMCIF_WAIT_FOR_READ:
+ case MMCIF_WAIT_FOR_WRITE:
+ case MMCIF_WAIT_FOR_READ_END:
+ case MMCIF_WAIT_FOR_WRITE_END:
+ host->data->error = sh_mmcif_error_manage(host);
+ break;
+ default:
+ BUG();
+ }
+
+ host->state = STATE_IDLE;
+ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
+ host->data = NULL;
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
+}
+
static int __devinit sh_mmcif_probe(struct platform_device *pdev)
{
int ret = 0, irq[2];
@@ -1041,7 +1276,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
host->clk = clk_get_rate(host->hclk);
host->pd = pdev;
- init_completion(&host->intr_wait);
spin_lock_init(&host->lock);
mmc->ops = &sh_mmcif_ops;
@@ -1078,18 +1312,20 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
- ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host);
+ ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
if (ret) {
dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
goto clean_up3;
}
- ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host);
+ ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
if (ret) {
free_irq(irq[0], host);
dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
goto clean_up3;
}
+ INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
+
mmc_detect_change(host->mmc, 0);
dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
@@ -1116,11 +1352,19 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
struct sh_mmcif_host *host = platform_get_drvdata(pdev);
int irq[2];
+ host->dying = true;
pm_runtime_get_sync(&pdev->dev);
mmc_remove_host(host->mmc);
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+ /*
+ * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the
+ * mmc_remove_host() call above. But swapping order doesn't help either
+ * (a query on the linux-mmc mailing list didn't bring any replies).
+ */
+ cancel_delayed_work_sync(&host->timeout_work);
+
if (host->addr)
iounmap(host->addr);
--
1.7.2.5
^ permalink raw reply related
* [PATCH 2/4 v2] mmc: sh_mmcif: cosmetic clean up
From: Guennadi Liakhovetski @ 2011-12-14 18:31 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-sh, Chris Ball, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1111301553330.22197@axis700.grange>
This patch doesn't introduce any functional changes, it only simplifies
some code fragments, removes superfluous parameters, fixes typos.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
drivers/mmc/host/sh_mmcif.c | 79 ++++++++++++++++++------------------------
1 files changed, 34 insertions(+), 45 deletions(-)
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 63559d6..d6a534c 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -123,6 +123,11 @@
#define MASK_MRBSYTO (1 << 1)
#define MASK_MRSPTO (1 << 0)
+#define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \
+ MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \
+ MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
+ MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
+
/* CE_HOST_STS1 */
#define STS1_CMDSEQ (1 << 31)
@@ -173,8 +178,8 @@ struct sh_mmcif_host {
long timeout;
void __iomem *addr;
struct completion intr_wait;
+ spinlock_t lock; /* protect sh_mmcif_host::state */
enum mmcif_state state;
- spinlock_t lock;
bool power;
bool card_present;
@@ -409,7 +414,7 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
{
u32 state1, state2;
- int ret, timeout = 10000000;
+ int ret, timeout;
host->sd_error = false;
@@ -421,31 +426,30 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
if (state1 & STS1_CMDSEQ) {
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK);
- while (1) {
- timeout--;
- if (timeout < 0) {
- dev_err(&host->pd->dev,
- "Forceed end of command sequence timeout err\n");
- return -EIO;
- }
+ for (timeout = 10000000; timeout; timeout--) {
if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
- & STS1_CMDSEQ))
+ & STS1_CMDSEQ))
break;
mdelay(1);
}
+ if (!timeout) {
+ dev_err(&host->pd->dev,
+ "Forced end of command sequence timeout err\n");
+ return -EIO;
+ }
sh_mmcif_sync_reset(host);
dev_dbg(&host->pd->dev, "Forced end of command sequence\n");
return -EIO;
}
if (state2 & STS2_CRC_ERR) {
- dev_dbg(&host->pd->dev, ": Happened CRC error\n");
+ dev_dbg(&host->pd->dev, ": CRC error\n");
ret = -EIO;
} else if (state2 & STS2_TIMEOUT_ERR) {
- dev_dbg(&host->pd->dev, ": Happened Timeout error\n");
+ dev_dbg(&host->pd->dev, ": Timeout\n");
ret = -ETIMEDOUT;
} else {
- dev_dbg(&host->pd->dev, ": Happened End/Index error\n");
+ dev_dbg(&host->pd->dev, ": End/Index error\n");
ret = -EIO;
}
return ret;
@@ -668,55 +672,44 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
struct mmc_request *mrq, u32 opc)
{
- int ret;
-
switch (opc) {
case MMC_READ_MULTIPLE_BLOCK:
- ret = sh_mmcif_multi_read(host, mrq);
- break;
+ return sh_mmcif_multi_read(host, mrq);
case MMC_WRITE_MULTIPLE_BLOCK:
- ret = sh_mmcif_multi_write(host, mrq);
- break;
+ return sh_mmcif_multi_write(host, mrq);
case MMC_WRITE_BLOCK:
- ret = sh_mmcif_single_write(host, mrq);
- break;
+ return sh_mmcif_single_write(host, mrq);
case MMC_READ_SINGLE_BLOCK:
case MMC_SEND_EXT_CSD:
- ret = sh_mmcif_single_read(host, mrq);
- break;
+ return sh_mmcif_single_read(host, mrq);
default:
dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
- return ret;
}
static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
- struct mmc_request *mrq, struct mmc_command *cmd)
+ struct mmc_request *mrq)
{
+ struct mmc_command *cmd = mrq->cmd;
long time;
- int ret = 0, mask = 0;
- u32 opc = cmd->opcode;
+ int ret = 0;
+ u32 mask, opc = cmd->opcode;
switch (opc) {
- /* respons busy check */
+ /* response busy check */
case MMC_SWITCH:
case MMC_STOP_TRANSMISSION:
case MMC_SET_WRITE_PROT:
case MMC_CLR_WRITE_PROT:
case MMC_ERASE:
case MMC_GEN_CMD:
- mask = MASK_MRBSYE;
+ mask = MASK_START_CMD | MASK_MRBSYE;
break;
default:
- mask = MASK_MCRSPE;
+ mask = MASK_START_CMD | MASK_MCRSPE;
break;
}
- mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
- MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
- MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
- MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
if (host->data) {
sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
@@ -784,8 +777,9 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
}
static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
- struct mmc_request *mrq, struct mmc_command *cmd)
+ struct mmc_request *mrq)
{
+ struct mmc_command *cmd = mrq->stop;
long time;
if (mrq->cmd->opcode = MMC_READ_MULTIPLE_BLOCK)
@@ -854,11 +848,11 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
sh_mmcif_start_dma_tx(host);
}
}
- sh_mmcif_start_cmd(host, mrq, mrq->cmd);
+ sh_mmcif_start_cmd(host, mrq);
host->data = NULL;
if (!mrq->cmd->error && mrq->stop)
- sh_mmcif_stop_cmd(host, mrq, mrq->stop);
+ sh_mmcif_stop_cmd(host, mrq);
host->state = STATE_IDLE;
mmc_request_done(mmc, mrq);
}
@@ -935,11 +929,6 @@ static struct mmc_host_ops sh_mmcif_ops = {
.get_cd = sh_mmcif_get_cd,
};
-static void sh_mmcif_detect(struct mmc_host *mmc)
-{
- mmc_detect_change(mmc, 0);
-}
-
static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
{
struct sh_mmcif_host *host = dev_id;
@@ -1101,7 +1090,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
goto clean_up3;
}
- sh_mmcif_detect(host->mmc);
+ mmc_detect_change(host->mmc, 0);
dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
dev_dbg(&pdev->dev, "chip ver H'%04x\n",
--
1.7.2.5
^ permalink raw reply related
* [PATCH 1/4] mmc: sh_mmcif: process error interrupts first
From: Guennadi Liakhovetski @ 2011-12-14 18:31 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-sh, Chris Ball, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1111301553330.22197@axis700.grange>
If an interrupt is coming with both error and data completion status bits
set, it has to be handled as an error interrupt, for which error interrupts
have to be processed first. The current version of the driver on the
contrary doesn't recognise such interrupts as an error event, which leads
to data corruption and breaks the error recovery.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
drivers/mmc/host/sh_mmcif.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 824fee5..63559d6 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -948,7 +948,12 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
- if (state & INT_RBSYE) {
+ if (state & INT_ERR_STS) {
+ /* error interrupts - process first */
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
+ sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
+ err = 1;
+ } else if (state & INT_RBSYE) {
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
~(INT_RBSYE | INT_CRSPE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
@@ -976,11 +981,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
~(INT_CMD12RBE | INT_CMD12CRE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
- } else if (state & INT_ERR_STS) {
- /* err interrupts */
- sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
- sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
- err = 1;
} else {
dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
--
1.7.2.5
^ permalink raw reply related
* [PATCH 0/4 v2] mmc_ sh_mmcif: process requests asynchronously
From: Guennadi Liakhovetski @ 2011-12-14 18:31 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-sh, Chris Ball, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1111301553330.22197@axis700.grange>
This used to be a single patch, which now has been split into 2, plus, two more
not directly related patches for the same driver have been included. Patch 1/4
is actually a fix and could be considered for 3.2, but I personally haven't
heard any bug-reports, that could be attributed to it, so, it doesn't seem to
be very critical. Also, on request from Magnus, a state machine description has
been added to the file header.
Guennadi Liakhovetski (4):
mmc: sh_mmcif: process error interrupts first
mmc: sh_mmcif: cosmetic clean up
mmc: sh_mmcif: process requests asynchronously
mmc: sh_mmcif: remove now superfluous sh_mmcif_host::data member
drivers/mmc/host/sh_mmcif.c | 709 +++++++++++++++++++++++++++++--------------
1 files changed, 474 insertions(+), 235 deletions(-)
--
1.7.2.5
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* Re: [PATCH v4 REPOST 3/5] omap4: Unconditionally require l2x0 L2
From: Dave Martin @ 2011-12-14 18:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111214181425.GB32251@atomide.com>
On Wed, Dec 14, 2011 at 10:14:25AM -0800, Tony Lindgren wrote:
> * Dave Martin <dave.martin@linaro.org> [111214 03:08]:
> > If running in the Normal World on a TrustZone-enabled SoC, Linux
> > does not have complete control over the L2 cache controller
> > configuration. The kernel cannot work reliably on such platforms
> > without the l2x0 cache support code built in.
>
> There are HS and GP omaps (High Security and General Purpose).
> GP omaps do have full control of the L2. Also HS omaps most likely
> provide control over enabling and disabling L2 depending how the
> secure code is implemented.
>
> BTW, the real problem is that because the secure code is implemented
> in various ways, we don't really have any handling for it in Linux.
>
> The SMI instruction numbers don't seem to be standardized at all,
> and can mean different things on different boards, even different
> board versions :(
>
> Sounds like devicetree is the only safe way to deal with the L2
> control options.
>
> Regards,
>
> Tony
>
>
> > This patch unconditionally enables l2x0 support for the OMAP4 SoCs.
> >
> > Thanks to Rob Herring for this suggestion. [1]
> >
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
> > ---
> > arch/arm/mach-omap2/Kconfig | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> > index bb1b670..94e568a 100644
> > --- a/arch/arm/mach-omap2/Kconfig
> > +++ b/arch/arm/mach-omap2/Kconfig
> > @@ -41,11 +41,11 @@ config ARCH_OMAP4
> > bool "TI OMAP4"
> > default y
> > depends on ARCH_OMAP2PLUS
> > + select CACHE_L2X0
> > select CPU_V7
> > select ARM_GIC
> > select HAVE_SMP
> > select LOCAL_TIMERS if SMP
> > - select MIGHT_HAVE_CACHE_L2X0
> > select PL310_ERRATA_588369
> > select PL310_ERRATA_727915
> > select ARM_ERRATA_720789
> > --
> > 1.7.4.1
> >
To clarify, are you suggesting we retain this patch, or not?
(If we only know what l2x0 support will be needed once the dts is
parsed at runtime, there could be an argument for keeping the
select CACHE_L2X0 here -- unless we have specific kconfigs for
the different security variants of omap.)
Cheers
---Dave
^ permalink raw reply
* Re: [PATCH v4 REPOST 2/5] ARM: SMP: Refactor Kconfig to be more
From: Tony Lindgren @ 2011-12-14 18:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-3-git-send-email-dave.martin@linaro.org>
* Dave Martin <dave.martin@linaro.org> [111214 03:08]:
> Making SMP depend on (huge list of MACH_ and ARCH_ configs) is
> bothersome to maintain and likely to lead to merge conflicts.
>
> This patch moves the knowledge of which platforms are SMP-capable
> to the individual machines. To enable this, a new HAVE_SMP config
> option is introduced to allow machines to indicate that they can
> run in a SMP configuration.
For omap:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply
* Re: [PATCH v4 REPOST 1/5] ARM: l2x0/pl310: Refactor Kconfig to be
From: Tony Lindgren @ 2011-12-14 18:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111214120314.GA9841@oksana.dev.rtsoft.ru>
* Anton Vorontsov <cbouatmailru@gmail.com> [111214 03:31]:
> On Wed, Dec 14, 2011 at 11:39:37AM +0000, Dave Martin wrote:
> > Making CACHE_L2X0 depend on (huge list of MACH_ and ARCH_ configs)
> > is bothersome to maintain and likely to lead to merge conflicts.
> >
> > This patch moves the knowledge of which platforms have a L2x0 or
> > PL310 cache controller to the individual machines. To enable this,
> > a new MIGHT_HAVE_CACHE_L2X0 config option is introduced to allow
> > machines to indicate that they may have such a cache controller
> > independently of each other.
> >
> > Boards/SoCs which cannot reliably operate without the L2 cache
> > controller support will need to select CACHE_L2X0 directly from
> > their own Kconfigs instead. This applies to some TrustZone-enabled
> > boards where Linux runs in the Normal World, for example.
> >
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
>
> For CNS3xxx bits:
>
> Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
For omap:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply
* Re: [PATCH v4 REPOST 3/5] omap4: Unconditionally require l2x0 L2
From: Tony Lindgren @ 2011-12-14 18:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-4-git-send-email-dave.martin@linaro.org>
* Dave Martin <dave.martin@linaro.org> [111214 03:08]:
> If running in the Normal World on a TrustZone-enabled SoC, Linux
> does not have complete control over the L2 cache controller
> configuration. The kernel cannot work reliably on such platforms
> without the l2x0 cache support code built in.
There are HS and GP omaps (High Security and General Purpose).
GP omaps do have full control of the L2. Also HS omaps most likely
provide control over enabling and disabling L2 depending how the
secure code is implemented.
BTW, the real problem is that because the secure code is implemented
in various ways, we don't really have any handling for it in Linux.
The SMI instruction numbers don't seem to be standardized at all,
and can mean different things on different boards, even different
board versions :(
Sounds like devicetree is the only safe way to deal with the L2
control options.
Regards,
Tony
> This patch unconditionally enables l2x0 support for the OMAP4 SoCs.
>
> Thanks to Rob Herring for this suggestion. [1]
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
> ---
> arch/arm/mach-omap2/Kconfig | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> index bb1b670..94e568a 100644
> --- a/arch/arm/mach-omap2/Kconfig
> +++ b/arch/arm/mach-omap2/Kconfig
> @@ -41,11 +41,11 @@ config ARCH_OMAP4
> bool "TI OMAP4"
> default y
> depends on ARCH_OMAP2PLUS
> + select CACHE_L2X0
> select CPU_V7
> select ARM_GIC
> select HAVE_SMP
> select LOCAL_TIMERS if SMP
> - select MIGHT_HAVE_CACHE_L2X0
> select PL310_ERRATA_588369
> select PL310_ERRATA_727915
> select ARM_ERRATA_720789
> --
> 1.7.4.1
>
^ permalink raw reply
* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is
From: Linus Walleij @ 2011-12-14 15:50 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Ulf Hansson, Guennadi Liakhovetski, linux-mmc@vger.kernel.org,
linux-pm@vger.kernel.org, Chris Ball, linux-sh@vger.kernel.org
In-Reply-To: <201112141128.56029.rjw@sisk.pl>
On Wed, Dec 14, 2011 at 11:28 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Wednesday, December 14, 2011, Linus Walleij wrote:
>> But this delta is dependent on a lot of stuff that only the platform
>> knows, like nominal CPU frequency, bus speed etc, so certainly the
>> platform must be able to modify that number.
>
> You seem to be confusing things. The exact meaning of this number is:
> "I may want to use the device 100 us from now (but not earlier), so please
> make it possible to do that". [It roughly means "don't put the device into
> a low-power state that takes more than 100 us to resume from", but it's a bit
> more complicated than that.] It doesn't mean "don't suspend the device for
> the next 100 us".
Yes you're right, I get it now!
Thanks for the explanation Rafael.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Thanks,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v4 REPOST 5/5] imx6q: Remove unconditional dependency on
From: Dave Martin @ 2011-12-14 15:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111214140500.GA1700@richard-laptop>
On Wed, Dec 14, 2011 at 10:05:04PM +0800, Richard Zhao wrote:
> On Wed, Dec 14, 2011 at 09:26:24PM +0800, Shawn Guo wrote:
> > Hi Dave,
> >
> > Sorry for that I did not look into previous post to point it out.
> >
> > On Wed, Dec 14, 2011 at 11:39:41AM +0000, Dave Martin wrote:
> > > The i.MX6 Quad SoC will work without the l2x0 L2 cache controller
> > > support built into the kernel, so this patch removes the dependency
> > > on CACHE_L2X0 and selects MIGHT_HAVE_CACHE_L2X0 instead.
> > >
> > > This makes the l2x0 support optional, so that it can be turned off
> > > when desired for debugging purposes etc.
> > >
> > > Thanks to Shawn Guo for this suggestion. [1]
> > >
> > > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > >
> > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074602.html
> > > ---
> > > arch/arm/mach-imx/Kconfig | 2 +-
> > > 1 files changed, 1 insertions(+), 1 deletions(-)
> > >
> > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > > index 29a3d61..1fb93f2 100644
> > > --- a/arch/arm/mach-imx/Kconfig
> > > +++ b/arch/arm/mach-imx/Kconfig
> > > @@ -609,13 +609,13 @@ comment "i.MX6 family:"
> > > config SOC_IMX6Q
> > > bool "i.MX6 Quad support"
> > > select ARM_GIC
> > > - select CACHE_L2X0
> > > select CPU_V7
> > > select HAVE_ARM_SCU
> > > select HAVE_IMX_GPC
> > > select HAVE_IMX_MMDC
> > > select HAVE_IMX_SRC
> > > select HAVE_SMP
> > > + select MIGHT_HAVE_CACHE_L2X0
> >
> > The option SOC_IMX6Q is only available when ARCH_IMX_V6_V7 is selected.
> > Since MIGHT_HAVE_CACHE_L2X0 has been selected by ARCH_IMX_V6_V7 in
> > patch #1, this line seems redundant here.
> Would it be better keep this one and remove patch #1 one? imx5 doesn't have
> l2x0.
Do you mean to remove MIGHT_HAVE_CACHE_L2X0 from ARCH_IMX_V6_V7, and select
it only from SOC_IMX6Q?
Cheers
---Dave
^ permalink raw reply
* Re: [PATCH v4 REPOST 5/5] imx6q: Remove unconditional dependency on
From: Richard Zhao @ 2011-12-14 14:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111214132622.GA1520@S2100-06.ap.freescale.net>
On Wed, Dec 14, 2011 at 09:26:24PM +0800, Shawn Guo wrote:
> Hi Dave,
>
> Sorry for that I did not look into previous post to point it out.
>
> On Wed, Dec 14, 2011 at 11:39:41AM +0000, Dave Martin wrote:
> > The i.MX6 Quad SoC will work without the l2x0 L2 cache controller
> > support built into the kernel, so this patch removes the dependency
> > on CACHE_L2X0 and selects MIGHT_HAVE_CACHE_L2X0 instead.
> >
> > This makes the l2x0 support optional, so that it can be turned off
> > when desired for debugging purposes etc.
> >
> > Thanks to Shawn Guo for this suggestion. [1]
> >
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074602.html
> > ---
> > arch/arm/mach-imx/Kconfig | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > index 29a3d61..1fb93f2 100644
> > --- a/arch/arm/mach-imx/Kconfig
> > +++ b/arch/arm/mach-imx/Kconfig
> > @@ -609,13 +609,13 @@ comment "i.MX6 family:"
> > config SOC_IMX6Q
> > bool "i.MX6 Quad support"
> > select ARM_GIC
> > - select CACHE_L2X0
> > select CPU_V7
> > select HAVE_ARM_SCU
> > select HAVE_IMX_GPC
> > select HAVE_IMX_MMDC
> > select HAVE_IMX_SRC
> > select HAVE_SMP
> > + select MIGHT_HAVE_CACHE_L2X0
>
> The option SOC_IMX6Q is only available when ARCH_IMX_V6_V7 is selected.
> Since MIGHT_HAVE_CACHE_L2X0 has been selected by ARCH_IMX_V6_V7 in
> patch #1, this line seems redundant here.
Would it be better keep this one and remove patch #1 one? imx5 doesn't have
l2x0.
Thanks
Richard
>
> Regards,
> Shawn
>
> > select USE_OF
> >
> > help
> > --
> > 1.7.4.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 REPOST 4/5] highbank: Unconditionally require l2x0 L2
From: Dave Martin @ 2011-12-14 13:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4EE8A69C.40304@gmail.com>
On Wed, Dec 14, 2011 at 07:37:32AM -0600, Rob Herring wrote:
>
> On 12/14/2011 05:39 AM, Dave Martin wrote:
> > If running in the Normal World on a TrustZone-enabled SoC, Linux
> > does not have complete control over the L2 cache controller
> > configuration. The kernel cannot work reliably on such platforms
> > without the l2x0 cache support code built in.
> >
> > This patch unconditionally enables l2x0 support for the Highbank
> > SoC.
> >
> > Thanks to Rob Herring for this suggestion. [1]
> >
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
>
> Doesn't this need to be above the SOB? Otherwise:
You may be right ... certainly I see no reason _not_ to change it.
So I'll change it.
>
> Acked-by: Rob Herring <rob.herring@calxeda.com>
Thanks
---Dave
^ permalink raw reply
* Re: [PATCH v4 REPOST 4/5] highbank: Unconditionally require l2x0
From: Rob Herring @ 2011-12-14 13:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-5-git-send-email-dave.martin@linaro.org>
On 12/14/2011 05:39 AM, Dave Martin wrote:
> If running in the Normal World on a TrustZone-enabled SoC, Linux
> does not have complete control over the L2 cache controller
> configuration. The kernel cannot work reliably on such platforms
> without the l2x0 cache support code built in.
>
> This patch unconditionally enables l2x0 support for the Highbank
> SoC.
>
> Thanks to Rob Herring for this suggestion. [1]
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
Doesn't this need to be above the SOB? Otherwise:
Acked-by: Rob Herring <rob.herring@calxeda.com>
> ---
> arch/arm/Kconfig | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index d33eb39..744296d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -340,12 +340,12 @@ config ARCH_HIGHBANK
> select ARM_AMBA
> select ARM_GIC
> select ARM_TIMER_SP804
> + select CACHE_L2X0
> select CLKDEV_LOOKUP
> select CPU_V7
> select GENERIC_CLOCKEVENTS
> select HAVE_ARM_SCU
> select HAVE_SMP
> - select MIGHT_HAVE_CACHE_L2X0
> select USE_OF
> help
> Support for the Calxeda Highbank SoC based boards.
^ permalink raw reply
* Re: [PATCH v4 REPOST 5/5] imx6q: Remove unconditional dependency on
From: Shawn Guo @ 2011-12-14 13:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-6-git-send-email-dave.martin@linaro.org>
Hi Dave,
Sorry for that I did not look into previous post to point it out.
On Wed, Dec 14, 2011 at 11:39:41AM +0000, Dave Martin wrote:
> The i.MX6 Quad SoC will work without the l2x0 L2 cache controller
> support built into the kernel, so this patch removes the dependency
> on CACHE_L2X0 and selects MIGHT_HAVE_CACHE_L2X0 instead.
>
> This makes the l2x0 support optional, so that it can be turned off
> when desired for debugging purposes etc.
>
> Thanks to Shawn Guo for this suggestion. [1]
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074602.html
> ---
> arch/arm/mach-imx/Kconfig | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 29a3d61..1fb93f2 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -609,13 +609,13 @@ comment "i.MX6 family:"
> config SOC_IMX6Q
> bool "i.MX6 Quad support"
> select ARM_GIC
> - select CACHE_L2X0
> select CPU_V7
> select HAVE_ARM_SCU
> select HAVE_IMX_GPC
> select HAVE_IMX_MMDC
> select HAVE_IMX_SRC
> select HAVE_SMP
> + select MIGHT_HAVE_CACHE_L2X0
The option SOC_IMX6Q is only available when ARCH_IMX_V6_V7 is selected.
Since MIGHT_HAVE_CACHE_L2X0 has been selected by ARCH_IMX_V6_V7 in
patch #1, this line seems redundant here.
Regards,
Shawn
> select USE_OF
>
> help
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* Re: [PATCH 02/57] fbdev: sh_mobile_lcdc: Mark init-only symbols with __devinit(const)
From: Laurent Pinchart @ 2011-12-14 12:30 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1323784972-24205-3-git-send-email-laurent.pinchart@ideasonboard.com>
Hi Guennadi,
On Wednesday 14 December 2011 12:07:26 Guennadi Liakhovetski wrote:
> On Wed, 14 Dec 2011, Laurent Pinchart wrote:
> > On Tuesday 13 December 2011 23:23:32 Guennadi Liakhovetski wrote:
> > > On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > > > default_720p and sh_mobile_lcdc_check_interface are used at device
> > > > initialization time only. Mark them as __devinitconst and __devinit
> > > > respectively.
> > > >
> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > > ---
> > > >
> > > > drivers/video/sh_mobile_lcdcfb.c | 5 +++--
> > > > 1 files changed, 3 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/video/sh_mobile_lcdcfb.c
> > > > b/drivers/video/sh_mobile_lcdcfb.c index 8b18360..a6bf4fb 100644
> > > > --- a/drivers/video/sh_mobile_lcdcfb.c
> > > > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > > > @@ -1459,7 +1459,7 @@ static int sh_mobile_lcdc_notify(struct
> > > > notifier_block *nb,
> > > >
> > > > * Probe/remove and driver init/exit
> > > > */
> > > >
> > > > -static const struct fb_videomode default_720p = {
> > > > +static const struct fb_videomode default_720p __devinitconst = {
> > > >
> > > > .name = "HDMI 720p",
> > > > .xres = 1280,
> > > > .yres = 720,
> > > >
> > > > @@ -1528,7 +1528,8 @@ static int sh_mobile_lcdc_remove(struct
> > > > platform_device *pdev)
> > > >
> > > > return 0;
> > > >
> > > > }
> > > >
> > > > -static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan
> > > > *ch) +static int __devinit
> > > > +sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
> > >
> > > Personally, I don't like this type of line splitting very much, I
> > > prefer the grep output to show the function type and all attributes,
> > > but this, certainly, would not be the reason to change this specific
> > > hunk:-) But this might be: the whole file so far has all function
> > > definitions at least up to and including the first parameter on one
> > > line, so, I find, this change would introduce an inconsistency in the
> > > file style. The line would __only__ be 83 characters long if you put
> > > it all on one line. I think, it would look better then:-)
> >
> > It's a matter of limits, as usual... I find 80 to be a nice limit,
> > although in some cases I'm fine with exceeding it (one example is a long
> > list of #defines with a small comment describing each macro, as in the
> > list of FOURCCs in linux/videodev2.h for instance). For code I try to
> > respect the 80 characters limit. Another reason is that it produces
> > checkpatch.pl warnings, which force me to manually look at all the
> > warnings to check which ones are acceptable.
> >
> > Regarding consistency, other patches in this series use the same style,
> > so that function won't feel alone anymore ;-)
> >
> > I can change this (and other instances of the same coding style) if you
> > insist. BTW, a possible improvement would be to shorten the
> > sh_mobile_lcdc_ prefix. I find it too long, and I was thinking about
> > reducing it to shm_lcdc_ (although shm reffers to shared memory, so that
> > might not be the best idea).
>
> How about sh_lcdc?
Sounds good to me. Does anyone have an objection ?
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v4 REPOST 1/5] ARM: l2x0/pl310: Refactor Kconfig to be
From: Anton Vorontsov @ 2011-12-14 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-2-git-send-email-dave.martin@linaro.org>
On Wed, Dec 14, 2011 at 11:39:37AM +0000, Dave Martin wrote:
> Making CACHE_L2X0 depend on (huge list of MACH_ and ARCH_ configs)
> is bothersome to maintain and likely to lead to merge conflicts.
>
> This patch moves the knowledge of which platforms have a L2x0 or
> PL310 cache controller to the individual machines. To enable this,
> a new MIGHT_HAVE_CACHE_L2X0 config option is introduced to allow
> machines to indicate that they may have such a cache controller
> independently of each other.
>
> Boards/SoCs which cannot reliably operate without the L2 cache
> controller support will need to select CACHE_L2X0 directly from
> their own Kconfigs instead. This applies to some TrustZone-enabled
> boards where Linux runs in the Normal World, for example.
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
For CNS3xxx bits:
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
Thanks!
^ permalink raw reply
* [PATCH v4 REPOST 5/5] imx6q: Remove unconditional dependency on l2x0 L2 cache support
From: Dave Martin @ 2011-12-14 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-1-git-send-email-dave.martin@linaro.org>
The i.MX6 Quad SoC will work without the l2x0 L2 cache controller
support built into the kernel, so this patch removes the dependency
on CACHE_L2X0 and selects MIGHT_HAVE_CACHE_L2X0 instead.
This makes the l2x0 support optional, so that it can be turned off
when desired for debugging purposes etc.
Thanks to Shawn Guo for this suggestion. [1]
Signed-off-by: Dave Martin <dave.martin@linaro.org>
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074602.html
---
arch/arm/mach-imx/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 29a3d61..1fb93f2 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -609,13 +609,13 @@ comment "i.MX6 family:"
config SOC_IMX6Q
bool "i.MX6 Quad support"
select ARM_GIC
- select CACHE_L2X0
select CPU_V7
select HAVE_ARM_SCU
select HAVE_IMX_GPC
select HAVE_IMX_MMDC
select HAVE_IMX_SRC
select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
select USE_OF
help
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 REPOST 4/5] highbank: Unconditionally require l2x0 L2 cache controller support
From: Dave Martin @ 2011-12-14 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-1-git-send-email-dave.martin@linaro.org>
If running in the Normal World on a TrustZone-enabled SoC, Linux
does not have complete control over the L2 cache controller
configuration. The kernel cannot work reliably on such platforms
without the l2x0 cache support code built in.
This patch unconditionally enables l2x0 support for the Highbank
SoC.
Thanks to Rob Herring for this suggestion. [1]
Signed-off-by: Dave Martin <dave.martin@linaro.org>
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
---
arch/arm/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d33eb39..744296d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -340,12 +340,12 @@ config ARCH_HIGHBANK
select ARM_AMBA
select ARM_GIC
select ARM_TIMER_SP804
+ select CACHE_L2X0
select CLKDEV_LOOKUP
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
select HAVE_SMP
- select MIGHT_HAVE_CACHE_L2X0
select USE_OF
help
Support for the Calxeda Highbank SoC based boards.
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 REPOST 3/5] omap4: Unconditionally require l2x0 L2 cache controller support
From: Dave Martin @ 2011-12-14 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-1-git-send-email-dave.martin@linaro.org>
If running in the Normal World on a TrustZone-enabled SoC, Linux
does not have complete control over the L2 cache controller
configuration. The kernel cannot work reliably on such platforms
without the l2x0 cache support code built in.
This patch unconditionally enables l2x0 support for the OMAP4 SoCs.
Thanks to Rob Herring for this suggestion. [1]
Signed-off-by: Dave Martin <dave.martin@linaro.org>
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html
---
arch/arm/mach-omap2/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index bb1b670..94e568a 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -41,11 +41,11 @@ config ARCH_OMAP4
bool "TI OMAP4"
default y
depends on ARCH_OMAP2PLUS
+ select CACHE_L2X0
select CPU_V7
select ARM_GIC
select HAVE_SMP
select LOCAL_TIMERS if SMP
- select MIGHT_HAVE_CACHE_L2X0
select PL310_ERRATA_588369
select PL310_ERRATA_727915
select ARM_ERRATA_720789
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 REPOST 2/5] ARM: SMP: Refactor Kconfig to be more maintainable
From: Dave Martin @ 2011-12-14 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-1-git-send-email-dave.martin@linaro.org>
Making SMP depend on (huge list of MACH_ and ARCH_ configs) is
bothersome to maintain and likely to lead to merge conflicts.
This patch moves the knowledge of which platforms are SMP-capable
to the individual machines. To enable this, a new HAVE_SMP config
option is introduced to allow machines to indicate that they can
run in a SMP configuration.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
arch/arm/Kconfig | 15 +++++++++++----
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-imx/Kconfig | 1 +
arch/arm/mach-msm/Kconfig | 1 +
arch/arm/mach-omap2/Kconfig | 1 +
arch/arm/mach-realview/Kconfig | 4 ++++
arch/arm/mach-vexpress/Kconfig | 1 +
7 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 16a4b9e..d33eb39 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -344,6 +344,7 @@ config ARCH_HIGHBANK
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select USE_OF
help
@@ -636,6 +637,7 @@ config ARCH_TEGRA
select GENERIC_GPIO
select HAVE_CLK
select HAVE_SCHED_CLOCK
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select ARCH_HAS_CPUFREQ
help
@@ -706,6 +708,7 @@ config ARCH_SHMOBILE
select HAVE_CLK
select CLKDEV_LOOKUP
select HAVE_MACH_CLKDEV
+ select HAVE_SMP
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_CACHE_L2X0
select NO_IOPORT
@@ -909,6 +912,7 @@ config ARCH_U8500
select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
help
Support for ST-Ericsson's Ux500 architecture
@@ -1430,14 +1434,17 @@ menu "Kernel Features"
source "kernel/time/Kconfig"
+config HAVE_SMP
+ bool
+ help
+ This option should be selected by machines which have an SMP-
+ capable CPU.
+
config SMP
bool "Symmetric Multi-Processing"
depends on CPU_V6K || CPU_V7
depends on GENERIC_CLOCKEVENTS
- depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
- MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
- ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
- ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK || SOC_IMX6Q
+ depends on HAVE_SMP
depends on MMU
select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 7f2347b..e1efbca 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -17,6 +17,7 @@ choice
config ARCH_EXYNOS4
bool "SAMSUNG EXYNOS4"
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
help
Samsung EXYNOS4 SoCs based systems
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 5f7f9c2..29a3d61 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -615,6 +615,7 @@ config SOC_IMX6Q
select HAVE_IMX_GPC
select HAVE_IMX_MMDC
select HAVE_IMX_SRC
+ select HAVE_SMP
select USE_OF
help
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index ebde97f..e6beaff 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -67,6 +67,7 @@ config MSM_SOC_REV_A
bool
config ARCH_MSM_SCORPIONMP
bool
+ select HAVE_SMP
config ARCH_MSM_ARM11
bool
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index c841578..bb1b670 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -43,6 +43,7 @@ config ARCH_OMAP4
depends on ARCH_OMAP2PLUS
select CPU_V7
select ARM_GIC
+ select HAVE_SMP
select LOCAL_TIMERS if SMP
select MIGHT_HAVE_CACHE_L2X0
select PL310_ERRATA_588369
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 3dd620f..c593be4 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -12,6 +12,7 @@ config REALVIEW_EB_A9MP
bool "Support Multicore Cortex-A9 Tile"
depends on MACH_REALVIEW_EB
select CPU_V7
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
help
Enable support for the Cortex-A9MPCore tile fitted to the
@@ -22,6 +23,7 @@ config REALVIEW_EB_ARM11MP
depends on MACH_REALVIEW_EB
select CPU_V6K
select ARCH_HAS_BARRIERS if SMP
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
help
Enable support for the ARM11MPCore tile fitted to the Realview(R)
@@ -41,6 +43,7 @@ config MACH_REALVIEW_PB11MP
select CPU_V6K
select ARM_GIC
select HAVE_PATA_PLATFORM
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select ARCH_HAS_BARRIERS if SMP
help
@@ -82,6 +85,7 @@ config MACH_REALVIEW_PBX
bool "Support RealView(R) Platform Baseboard Explore"
select ARM_GIC
select HAVE_PATA_PLATFORM
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
select ZONE_DMA if SPARSEMEM
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index a8aefc8..9b3d0fb 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -8,6 +8,7 @@ config ARCH_VEXPRESS_CA9X4
select ARM_ERRATA_720789
select ARM_ERRATA_751472
select ARM_ERRATA_753970
+ select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
endmenu
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 REPOST 1/5] ARM: l2x0/pl310: Refactor Kconfig to be more maintainable
From: Dave Martin @ 2011-12-14 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1323862781-3465-1-git-send-email-dave.martin@linaro.org>
Making CACHE_L2X0 depend on (huge list of MACH_ and ARCH_ configs)
is bothersome to maintain and likely to lead to merge conflicts.
This patch moves the knowledge of which platforms have a L2x0 or
PL310 cache controller to the individual machines. To enable this,
a new MIGHT_HAVE_CACHE_L2X0 config option is introduced to allow
machines to indicate that they may have such a cache controller
independently of each other.
Boards/SoCs which cannot reliably operate without the L2 cache
controller support will need to select CACHE_L2X0 directly from
their own Kconfigs instead. This applies to some TrustZone-enabled
boards where Linux runs in the Normal World, for example.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
arch/arm/Kconfig | 8 ++++++++
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-omap2/Kconfig | 1 +
arch/arm/mach-realview/Kconfig | 5 +++++
arch/arm/mach-vexpress/Kconfig | 1 +
arch/arm/mm/Kconfig | 15 ++++++++-------
arch/arm/plat-mxc/Kconfig | 1 +
7 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 44789ef..16a4b9e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -344,6 +344,7 @@ config ARCH_HIGHBANK
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
+ select MIGHT_HAVE_CACHE_L2X0
select USE_OF
help
Support for the Calxeda Highbank SoC based boards.
@@ -361,6 +362,7 @@ config ARCH_CNS3XXX
select CPU_V6K
select GENERIC_CLOCKEVENTS
select ARM_GIC
+ select MIGHT_HAVE_CACHE_L2X0
select MIGHT_HAVE_PCI
select PCI_DOMAINS if PCI
help
@@ -381,6 +383,7 @@ config ARCH_PRIMA2
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
select GENERIC_IRQ_CHIP
+ select MIGHT_HAVE_CACHE_L2X0
select USE_OF
select ZONE_DMA
help
@@ -633,6 +636,7 @@ config ARCH_TEGRA
select GENERIC_GPIO
select HAVE_CLK
select HAVE_SCHED_CLOCK
+ select MIGHT_HAVE_CACHE_L2X0
select ARCH_HAS_CPUFREQ
help
This enables support for NVIDIA Tegra based systems (Tegra APX,
@@ -703,6 +707,7 @@ config ARCH_SHMOBILE
select CLKDEV_LOOKUP
select HAVE_MACH_CLKDEV
select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_CACHE_L2X0
select NO_IOPORT
select SPARSE_IRQ
select MULTI_IRQ_HANDLER
@@ -904,6 +909,7 @@ config ARCH_U8500
select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
+ select MIGHT_HAVE_CACHE_L2X0
help
Support for ST-Ericsson's Ux500 architecture
@@ -914,6 +920,7 @@ config ARCH_NOMADIK
select CPU_ARM926T
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_CACHE_L2X0
select ARCH_REQUIRE_GPIOLIB
help
Support for the Nomadik platform by ST-Ericsson
@@ -973,6 +980,7 @@ config ARCH_ZYNQ
select ARM_GIC
select ARM_AMBA
select ICST
+ select MIGHT_HAVE_CACHE_L2X0
select USE_OF
help
Support for Xilinx Zynq ARM Cortex A9 Platform
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 724ec0f..7f2347b 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -17,6 +17,7 @@ choice
config ARCH_EXYNOS4
bool "SAMSUNG EXYNOS4"
+ select MIGHT_HAVE_CACHE_L2X0
help
Samsung EXYNOS4 SoCs based systems
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 5034147..c841578 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -44,6 +44,7 @@ config ARCH_OMAP4
select CPU_V7
select ARM_GIC
select LOCAL_TIMERS if SMP
+ select MIGHT_HAVE_CACHE_L2X0
select PL310_ERRATA_588369
select PL310_ERRATA_727915
select ARM_ERRATA_720789
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index dba6d0c..3dd620f 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -12,6 +12,7 @@ config REALVIEW_EB_A9MP
bool "Support Multicore Cortex-A9 Tile"
depends on MACH_REALVIEW_EB
select CPU_V7
+ select MIGHT_HAVE_CACHE_L2X0
help
Enable support for the Cortex-A9MPCore tile fitted to the
Realview(R) Emulation Baseboard platform.
@@ -21,6 +22,7 @@ config REALVIEW_EB_ARM11MP
depends on MACH_REALVIEW_EB
select CPU_V6K
select ARCH_HAS_BARRIERS if SMP
+ select MIGHT_HAVE_CACHE_L2X0
help
Enable support for the ARM11MPCore tile fitted to the Realview(R)
Emulation Baseboard platform.
@@ -39,6 +41,7 @@ config MACH_REALVIEW_PB11MP
select CPU_V6K
select ARM_GIC
select HAVE_PATA_PLATFORM
+ select MIGHT_HAVE_CACHE_L2X0
select ARCH_HAS_BARRIERS if SMP
help
Include support for the ARM(R) RealView(R) Platform Baseboard for
@@ -51,6 +54,7 @@ config MACH_REALVIEW_PB1176
select CPU_V6
select ARM_GIC
select HAVE_TCM
+ select MIGHT_HAVE_CACHE_L2X0
help
Include support for the ARM(R) RealView(R) Platform Baseboard for
ARM1176JZF-S.
@@ -78,6 +82,7 @@ config MACH_REALVIEW_PBX
bool "Support RealView(R) Platform Baseboard Explore"
select ARM_GIC
select HAVE_PATA_PLATFORM
+ select MIGHT_HAVE_CACHE_L2X0
select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
select ZONE_DMA if SPARSEMEM
help
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 9311484..a8aefc8 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -8,5 +8,6 @@ config ARCH_VEXPRESS_CA9X4
select ARM_ERRATA_720789
select ARM_ERRATA_751472
select ARM_ERRATA_753970
+ select MIGHT_HAVE_CACHE_L2X0
endmenu
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 67f75a0..d92aa3b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -816,14 +816,15 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
Say Y here to use the Feroceon L2 cache in writethrough mode.
Unless you specifically require this, say N for writeback mode.
+config MIGHT_HAVE_CACHE_L2X0
+ bool
+ help
+ This option should be selected by machines which have a L2x0
+ or PL310 cache controller.
+
config CACHE_L2X0
- bool "Enable the L2x0 outer cache controller"
- depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
- REALVIEW_EB_A9MP || ARCH_IMX_V6_V7 || MACH_REALVIEW_PBX || \
- ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
- ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \
- ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK
- default y
+ bool "Enable the L2x0 outer cache controller" if MIGHT_HAVE_CACHE_L2X0
+ default MIGHT_HAVE_CACHE_L2X0
select OUTER_CACHE
select OUTER_CACHE_SYNC
help
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index b3a1f2b..b30708e 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -20,6 +20,7 @@ config ARCH_IMX_V6_V7
bool "i.MX3, i.MX6"
select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
+ select MIGHT_HAVE_CACHE_L2X0
help
This enables support for systems based on the Freescale i.MX3 and i.MX6
family.
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 REPOST 0/5] Refactor common Kconfigs for easier maintenance
From: Dave Martin @ 2011-12-14 11:39 UTC (permalink / raw)
To: linux-arm-kernel
Common Kconfig options which depend on a long list of board- and
SoC- specific Kconfigs can be cumbersome to maintain, leading to
annoying merge conflicts (although rather trivial ones).
This series factors out the dependencies of CACHE_L2X0 and SMP so
that the knowledge about when these can be enabled is moved to the
relevant board/SoC Kconfig files instead. New
MIGHT_HAVE_CACHE_L2X0 and HAVE_SMP options are defined to mediate
the dependencies.
This series has been substantially reworked compared with the
previous post, and is now in two parts:
* The first two patches simply refactor the way the Kconfig
options for CACHE_L2X0 and SMP are implemented, without
making any other changes.
* The final three patches apply functional changes suggested by
the contributors to this series, to make the config
dependencies more correct for some specific boards.
Thanks to Rob Herring, Shawn Guo and Russell King for their
contributions to this series. Thanks also to David Brown for
pointing out the lack of a comprehensive CC list.
I have briefly build-tested on some of the affected boards, but any
further reviews or Tested-Bys would be much appreciated.
Dave Martin (5):
ARM: l2x0/pl310: Refactor Kconfig to be more maintainable
ARM: SMP: Refactor Kconfig to be more maintainable
omap4: Unconditionally require l2x0 L2 cache controller support
highbank: Unconditionally require l2x0 L2 cache controller support
imx6q: Remove unconditional dependency on l2x0 L2 cache support
arch/arm/Kconfig | 23 +++++++++++++++++++----
arch/arm/mach-exynos/Kconfig | 2 ++
arch/arm/mach-imx/Kconfig | 3 ++-
arch/arm/mach-msm/Kconfig | 1 +
arch/arm/mach-omap2/Kconfig | 2 ++
arch/arm/mach-realview/Kconfig | 9 +++++++++
arch/arm/mach-vexpress/Kconfig | 2 ++
arch/arm/mm/Kconfig | 15 ++++++++-------
arch/arm/plat-mxc/Kconfig | 1 +
9 files changed, 46 insertions(+), 12 deletions(-)
--
1.7.4.1
^ permalink raw reply
* Re: [PATCH 33/57] fbdev: sh_mobile_lcdc: Add sh_mobile_format_info() function
From: Laurent Pinchart @ 2011-12-14 11:30 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1323784972-24205-34-git-send-email-laurent.pinchart@ideasonboard.com>
Hi Damian,
On Wednesday 14 December 2011 04:04:52 Damian Hobson-Garcia wrote:
> On 2011/12/13 23:02, Laurent Pinchart wrote:
> > --- a/drivers/video/sh_mobile_lcdcfb.c
> > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > @@ -447,6 +447,75 @@ static int sh_mobile_lcdc_display_notify(struct
> > sh_mobile_lcdc_chan *ch,
> >
> > * Format helpers
> > */
> >
> > +struct sh_mobile_lcdc_format_info {
> > + u32 fourcc;
> > + unsigned int bpp;
> > + bool yuv;
> > + u32 lddfr;
> > +};
> > +
> > +static const struct sh_mobile_lcdc_format_info sh_mobile_format_infos[]
> > = { + {
> > + .fourcc = V4L2_PIX_FMT_RGB565,
> > + .bpp = 12,
>
> I think that this should be 16 instead of 12.
Oops, you're right. Thanks. I'll fix that.
> > @@ -665,37 +726,20 @@ static void __sh_mobile_lcdc_start(struct
> > sh_mobile_lcdc_priv *priv)
> >
> > /* Setup geometry, format, frame buffer memory and operation mode. */
> > for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
> >
> > + const struct sh_mobile_lcdc_format_info *format;
> > + u32 fourcc;
> > +
> >
> > ch = &priv->ch[k];
> > if (!ch->enabled)
> >
> > continue;
> >
> > sh_mobile_lcdc_geometry(ch);
> >
> > - switch (sh_mobile_format_fourcc(&ch->info->var)) {
> > - case V4L2_PIX_FMT_RGB565:
> > - tmp = LDDFR_PKF_RGB16;
> > - break;
> > - case V4L2_PIX_FMT_BGR24:
> > - tmp = LDDFR_PKF_RGB24;
> > - break;
> > - case V4L2_PIX_FMT_BGR32:
> > - tmp = LDDFR_PKF_ARGB32;
> > - break;
> > - case V4L2_PIX_FMT_NV12:
> > - case V4L2_PIX_FMT_NV21:
> > - tmp = LDDFR_CC | LDDFR_YF_420;
> > - break;
> > - case V4L2_PIX_FMT_NV16:
> > - case V4L2_PIX_FMT_NV61:
> > - tmp = LDDFR_CC | LDDFR_YF_422;
> > - break;
> > - case V4L2_PIX_FMT_NV24:
> > - case V4L2_PIX_FMT_NV42:
> > - tmp = LDDFR_CC | LDDFR_YF_444;
> > - break;
> > - }
> > + fourcc = sh_mobile_format_fourcc(&ch->info->var);
> > + format = sh_mobile_format_info(fourcc);
> > + tmp = format->lddfr;
>
> Do you need to check if format is NULL here?
The fourcc is validated in both sh_mobile_lcdc_channel_init() (for the value
passed to the driver through platform data) and sh_mobile_check_var() (for the
value requested by userspace). format should thus never be NULL here.
--
Regards,
Laurent Pinchart
^ permalink raw reply
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