* [PATCH v5 1/6] DMA: PL330: move filter function into driver
From: Thomas Abraham @ 2011-09-28 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317201925-25148-1-git-send-email-thomas.abraham@linaro.org>
The dma channel selection filter function is moved from plat-samsung
into the pl330 driver. In additon to that, a check is added in the
filter function to ensure that the channel on which the filter has
been invoked is pl330 channel instance (and avoid any incorrect
access of chan->private in a system with multiple types of DMA
drivers).
Suggested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/arm/plat-samsung/dma-ops.c | 6 ------
drivers/dma/pl330.c | 15 +++++++++++++++
include/linux/amba/pl330.h | 2 ++
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 6e3d9ab..8d18425 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -17,12 +17,6 @@
#include <mach/dma.h>
-static inline bool pl330_filter(struct dma_chan *chan, void *param)
-{
- struct dma_pl330_peri *peri = chan->private;
- return peri->peri_id == (unsigned)param;
-}
-
static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
struct samsung_dma_info *info)
{
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 621134f..5f1d24c 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -116,6 +116,9 @@ struct dma_pl330_desc {
struct dma_pl330_chan *pchan;
};
+/* forward declaration */
+static struct amba_driver pl330_driver;
+
static inline struct dma_pl330_chan *
to_pchan(struct dma_chan *ch)
{
@@ -267,6 +270,18 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
tasklet_schedule(&pch->task);
}
+bool pl330_filter(struct dma_chan *chan, void *param)
+{
+ struct dma_pl330_peri *peri;
+
+ if (chan->device->dev->driver != &pl330_driver.drv)
+ return false;
+
+ peri = chan->private;
+ return peri->peri_id == (unsigned)param;
+}
+EXPORT_SYMBOL(pl330_filter);
+
static int pl330_alloc_chan_resources(struct dma_chan *chan)
{
struct dma_pl330_chan *pch = to_pchan(chan);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index d12f077..6db72da 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -12,6 +12,7 @@
#ifndef __AMBA_PL330_H_
#define __AMBA_PL330_H_
+#include <linux/dmaengine.h>
#include <asm/hardware/pl330.h>
struct dma_pl330_peri {
@@ -38,4 +39,5 @@ struct dma_pl330_platdata {
unsigned mcbuf_sz;
};
+extern bool pl330_filter(struct dma_chan *chan, void *param);
#endif /* __AMBA_PL330_H_ */
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v5 2/6] DMA: PL330: Infer transfer direction from transfer request instead of platform data
From: Thomas Abraham @ 2011-09-28 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317201925-25148-1-git-send-email-thomas.abraham@linaro.org>
The transfer direction for a channel can be inferred from the transfer
request and the need for specifying transfer direction in platfrom data
can be eliminated. So the structure definition 'struct dma_pl330_peri'
is no longer required.
The channel's private data is set to point to a channel id specified in
the platform data (instead of an instance of type 'struct dma_pl330_peri').
The filter function is correspondingly modified to match the channel id.
With the 'struct dma_pl330_peri' removed from platform data, the dma
controller transfer capabilities cannot be inferred any more. Hence,
the dma controller capabilities is specified using platform data.
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/dma/pl330.c | 65 +++++++++++---------------------------------
include/linux/amba/pl330.h | 13 ++-------
2 files changed, 19 insertions(+), 59 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 5f1d24c..992bf82 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -272,13 +272,13 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
bool pl330_filter(struct dma_chan *chan, void *param)
{
- struct dma_pl330_peri *peri;
+ u8 *peri_id;
if (chan->device->dev->driver != &pl330_driver.drv)
return false;
- peri = chan->private;
- return peri->peri_id == (unsigned)param;
+ peri_id = chan->private;
+ return *peri_id == (unsigned)param;
}
EXPORT_SYMBOL(pl330_filter);
@@ -512,7 +512,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
{
struct dma_pl330_dmac *pdmac = pch->dmac;
- struct dma_pl330_peri *peri = pch->chan.private;
+ u8 *peri_id = pch->chan.private;
struct dma_pl330_desc *desc;
/* Pluck one desc from the pool of DMAC */
@@ -537,13 +537,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
desc->txd.cookie = 0;
async_tx_ack(&desc->txd);
- if (peri) {
- desc->req.rqtype = peri->rqtype;
- desc->req.peri = pch->chan.chan_id;
- } else {
- desc->req.rqtype = MEMTOMEM;
- desc->req.peri = 0;
- }
+ desc->req.peri = peri_id ? pch->chan.chan_id : 0;
dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
@@ -630,12 +624,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
case DMA_TO_DEVICE:
desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 0;
+ desc->req.rqtype = MEMTODEV;
src = dma_addr;
dst = pch->fifo_addr;
break;
case DMA_FROM_DEVICE:
desc->rqcfg.src_inc = 0;
desc->rqcfg.dst_inc = 1;
+ desc->req.rqtype = DEVTOMEM;
src = pch->fifo_addr;
dst = dma_addr;
break;
@@ -661,16 +657,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
{
struct dma_pl330_desc *desc;
struct dma_pl330_chan *pch = to_pchan(chan);
- struct dma_pl330_peri *peri = chan->private;
struct pl330_info *pi;
int burst;
if (unlikely(!pch || !len))
return NULL;
- if (peri && peri->rqtype != MEMTOMEM)
- return NULL;
-
pi = &pch->dmac->pif;
desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
@@ -679,6 +671,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 1;
+ desc->req.rqtype = MEMTOMEM;
/* Select max possible burst size */
burst = pi->pcfg.data_bus_width / 8;
@@ -707,24 +700,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
{
struct dma_pl330_desc *first, *desc = NULL;
struct dma_pl330_chan *pch = to_pchan(chan);
- struct dma_pl330_peri *peri = chan->private;
struct scatterlist *sg;
unsigned long flags;
int i;
dma_addr_t addr;
- if (unlikely(!pch || !sgl || !sg_len || !peri))
- return NULL;
-
- /* Make sure the direction is consistent */
- if ((direction == DMA_TO_DEVICE &&
- peri->rqtype != MEMTODEV) ||
- (direction == DMA_FROM_DEVICE &&
- peri->rqtype != DEVTOMEM)) {
- dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
- __func__, __LINE__);
+ if (unlikely(!pch || !sgl || !sg_len))
return NULL;
- }
addr = pch->fifo_addr;
@@ -765,11 +747,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if (direction == DMA_TO_DEVICE) {
desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 0;
+ desc->req.rqtype = MEMTODEV;
fill_px(&desc->px,
addr, sg_dma_address(sg), sg_dma_len(sg));
} else {
desc->rqcfg.src_inc = 0;
desc->rqcfg.dst_inc = 1;
+ desc->req.rqtype = DEVTOMEM;
fill_px(&desc->px,
sg_dma_address(sg), addr, sg_dma_len(sg));
}
@@ -876,28 +860,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
for (i = 0; i < num_chan; i++) {
pch = &pdmac->peripherals[i];
- if (pdat) {
- struct dma_pl330_peri *peri = &pdat->peri[i];
-
- switch (peri->rqtype) {
- case MEMTOMEM:
- dma_cap_set(DMA_MEMCPY, pd->cap_mask);
- break;
- case MEMTODEV:
- case DEVTOMEM:
- dma_cap_set(DMA_SLAVE, pd->cap_mask);
- dma_cap_set(DMA_CYCLIC, pd->cap_mask);
- break;
- default:
- dev_err(&adev->dev, "DEVTODEV Not Supported\n");
- continue;
- }
- pch->chan.private = peri;
- } else {
- dma_cap_set(DMA_MEMCPY, pd->cap_mask);
- pch->chan.private = NULL;
- }
-
+ pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
INIT_LIST_HEAD(&pch->work_list);
spin_lock_init(&pch->lock);
pch->pl330_chid = NULL;
@@ -911,6 +874,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
}
pd->dev = &adev->dev;
+ if (pdat)
+ pd->cap_mask = pdat->cap_mask;
+ else
+ dma_cap_set(DMA_MEMCPY, pd->cap_mask);
pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
pd->device_free_chan_resources = pl330_free_chan_resources;
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index 6db72da..12e023c 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -15,15 +15,6 @@
#include <linux/dmaengine.h>
#include <asm/hardware/pl330.h>
-struct dma_pl330_peri {
- /*
- * Peri_Req i/f of the DMAC that is
- * peripheral could be reached from.
- */
- u8 peri_id; /* specific dma id */
- enum pl330_reqtype rqtype;
-};
-
struct dma_pl330_platdata {
/*
* Number of valid peripherals connected to DMAC.
@@ -34,7 +25,9 @@ struct dma_pl330_platdata {
*/
u8 nr_valid_peri;
/* Array of valid peripherals */
- struct dma_pl330_peri *peri;
+ u8 *peri_id;
+ /* Operational capabilities */
+ dma_cap_mask_t cap_mask;
/* Bytes to allocate for MC buffer */
unsigned mcbuf_sz;
};
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v5 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver
From: Thomas Abraham @ 2011-09-28 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317201925-25148-1-git-send-email-thomas.abraham@linaro.org>
With the 'struct dma_pl330_peri' removed, the platfrom data for dma
driver can be simplified to a simple list of peripheral request ids.
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/arm/mach-exynos4/dma.c | 223 ++++++++++++-------------------------------
1 files changed, 62 insertions(+), 161 deletions(-)
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index 9667c61..c3c0d17 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -35,95 +35,40 @@
static u64 dma_dmamask = DMA_BIT_MASK(32);
-struct dma_pl330_peri pdma0_peri[28] = {
- {
- .peri_id = (u8)DMACH_PCM0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PCM0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PCM2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_MSM_REQ0,
- }, {
- .peri_id = (u8)DMACH_MSM_REQ2,
- }, {
- .peri_id = (u8)DMACH_SPI0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SPI0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SPI2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SPI2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S0S_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_I2S0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART4_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART4_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS4_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS4_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_AC97_MICIN,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_AC97_PCMIN,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_AC97_PCMOUT,
- .rqtype = MEMTODEV,
- },
+u8 pdma0_peri[] = {
+ DMACH_PCM0_RX,
+ DMACH_PCM0_TX,
+ DMACH_PCM2_RX,
+ DMACH_PCM2_TX,
+ DMACH_MSM_REQ0,
+ DMACH_MSM_REQ2,
+ DMACH_SPI0_RX,
+ DMACH_SPI0_TX,
+ DMACH_SPI2_RX,
+ DMACH_SPI2_TX,
+ DMACH_I2S0S_TX,
+ DMACH_I2S0_RX,
+ DMACH_I2S0_TX,
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART2_RX,
+ DMACH_UART2_TX,
+ DMACH_UART4_RX,
+ DMACH_UART4_TX,
+ DMACH_SLIMBUS0_RX,
+ DMACH_SLIMBUS0_TX,
+ DMACH_SLIMBUS2_RX,
+ DMACH_SLIMBUS2_TX,
+ DMACH_SLIMBUS4_RX,
+ DMACH_SLIMBUS4_TX,
+ DMACH_AC97_MICIN,
+ DMACH_AC97_PCMIN,
+ DMACH_AC97_PCMOUT,
};
struct dma_pl330_platdata exynos4_pdma0_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
- .peri = pdma0_peri,
+ .peri_id = pdma0_peri,
};
struct amba_device exynos4_device_pdma0 = {
@@ -142,86 +87,37 @@ struct amba_device exynos4_device_pdma0 = {
.periphid = 0x00041330,
};
-struct dma_pl330_peri pdma1_peri[25] = {
- {
- .peri_id = (u8)DMACH_PCM0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PCM0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PCM1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_MSM_REQ1,
- }, {
- .peri_id = (u8)DMACH_MSM_REQ3,
- }, {
- .peri_id = (u8)DMACH_SPI1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SPI1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S0S_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_I2S0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_I2S1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART3_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART3_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS3_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS3_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS5_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SLIMBUS5_TX,
- .rqtype = MEMTODEV,
- },
+u8 pdma1_peri[] = {
+ DMACH_PCM0_RX,
+ DMACH_PCM0_TX,
+ DMACH_PCM1_RX,
+ DMACH_PCM1_TX,
+ DMACH_MSM_REQ1,
+ DMACH_MSM_REQ3,
+ DMACH_SPI1_RX,
+ DMACH_SPI1_TX,
+ DMACH_I2S0S_TX,
+ DMACH_I2S0_RX,
+ DMACH_I2S0_TX,
+ DMACH_I2S1_RX,
+ DMACH_I2S1_TX,
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART1_RX,
+ DMACH_UART1_TX,
+ DMACH_UART3_RX,
+ DMACH_UART3_TX,
+ DMACH_SLIMBUS1_RX,
+ DMACH_SLIMBUS1_TX,
+ DMACH_SLIMBUS3_RX,
+ DMACH_SLIMBUS3_TX,
+ DMACH_SLIMBUS5_RX,
+ DMACH_SLIMBUS5_TX,
};
struct dma_pl330_platdata exynos4_pdma1_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
- .peri = pdma1_peri,
+ .peri_id = pdma1_peri,
};
struct amba_device exynos4_device_pdma1 = {
@@ -242,7 +138,12 @@ struct amba_device exynos4_device_pdma1 = {
static int __init exynos4_dma_init(void)
{
+ dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
+ dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+
+ dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
+ dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
amba_device_register(&exynos4_device_pdma1, &iomem_resource);
return 0;
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v5 4/6] DMA: PL330: Add device tree support
From: Thomas Abraham @ 2011-09-28 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317201925-25148-1-git-send-email-thomas.abraham@linaro.org>
For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.
Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
.../devicetree/bindings/dma/arm-pl330.txt | 30 ++++++++++++++++++
drivers/dma/pl330.c | 33 +++++++++++++++++--
2 files changed, 59 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..a4cd273
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,30 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+ - compatible: should include both "arm,pl330" and "arm,primecell".
+ - reg: physical base address of the controller and length of memory mapped
+ region.
+ - interrupts: interrupt number to the cpu.
+
+Example:
+
+ pdma0: pdma at 12680000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12680000 0x1000>;
+ interrupts = <99>;
+ };
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+ [property name] = <[phandle of the dma controller] [dma request id]>;
+
+ where 'dma request id' is the dma request number which is connected
+ to the client controller. The 'property name' is recommended to be
+ of the form <name>-dma-channel.
+
+ Example: tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 992bf82..7a4ebf1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
#include <linux/amba/pl330.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
+#include <linux/of.h>
#define NR_DEFAULT_DESC 16
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
if (chan->device->dev->driver != &pl330_driver.drv)
return false;
+#ifdef CONFIG_OF
+ if (chan->device->dev->of_node) {
+ const __be32 *prop_value;
+ phandle phandle;
+ struct device_node *node;
+
+ prop_value = ((struct property *)param)->value;
+ phandle = be32_to_cpup(prop_value++);
+ node = of_find_node_by_phandle(phandle);
+ return ((chan->private == node) &&
+ (chan->chan_id == be32_to_cpup(prop_value)));
+ }
+#endif
+
peri_id = chan->private;
return *peri_id == (unsigned)param;
}
@@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
INIT_LIST_HEAD(&pd->channels);
/* Initialize channel parameters */
- num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
+ num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
+ (u8)pi->pcfg.num_chan);
pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
for (i = 0; i < num_chan; i++) {
pch = &pdmac->peripherals[i];
- pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+ if (!adev->dev.of_node)
+ pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+ else
+ pch->chan.private = adev->dev.of_node;
+
INIT_LIST_HEAD(&pch->work_list);
spin_lock_init(&pch->lock);
pch->pl330_chid = NULL;
@@ -874,10 +894,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
}
pd->dev = &adev->dev;
- if (pdat)
+ if (pdat) {
pd->cap_mask = pdat->cap_mask;
- else
+ } else {
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+ if (pi->pcfg.num_peri) {
+ dma_cap_set(DMA_SLAVE, pd->cap_mask);
+ dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+ }
+ }
pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
pd->device_free_chan_resources = pl330_free_chan_resources;
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v5 5/6] ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
From: Thomas Abraham @ 2011-09-28 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317201925-25148-1-git-send-email-thomas.abraham@linaro.org>
A new dma request id 'DMACH_DT_PROP' is introduced for client drivers
requesting a dma channel. This request indicates that a device tree
node property represting the dma channel is available in
'struct samsung_dma_info'. The dma channel request wrapper uses the
node property value as the value for the filter parameter.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/arm/plat-samsung/dma-ops.c | 9 ++++++++-
arch/arm/plat-samsung/include/plat/dma-ops.h | 1 +
arch/arm/plat-samsung/include/plat/dma-pl330.h | 3 ++-
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 8d18425..b1135dd 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -23,11 +23,18 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
struct dma_chan *chan;
dma_cap_mask_t mask;
struct dma_slave_config slave_config;
+ void *filter_param;
dma_cap_zero(mask);
dma_cap_set(info->cap, mask);
- chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch);
+ /*
+ * If a dma channel property of a device node from device tree is
+ * specified, use that as the fliter parameter.
+ */
+ filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
+ (void *)dma_ch;
+ chan = dma_request_channel(mask, pl330_filter, filter_param);
if (info->direction == DMA_FROM_DEVICE) {
memset(&slave_config, 0, sizeof(struct dma_slave_config));
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 4c1a363..22eafc3 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -31,6 +31,7 @@ struct samsung_dma_info {
enum dma_slave_buswidth width;
dma_addr_t fifo;
struct s3c2410_dma_client *client;
+ struct property *dt_dmach_prop;
};
struct samsung_dma_ops {
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 2e55e59..c5eaad5 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -21,7 +21,8 @@
* use these just as IDs.
*/
enum dma_ch {
- DMACH_UART0_RX,
+ DMACH_DT_PROP = -1,
+ DMACH_UART0_RX = 0,
DMACH_UART0_TX,
DMACH_UART1_RX,
DMACH_UART1_TX,
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v5 6/6] ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build
From: Thomas Abraham @ 2011-09-28 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317201925-25148-1-git-send-email-thomas.abraham@linaro.org>
The pl330 device instances and associated platform data is required only
for non-device-tree builds. With device tree enabled, the data about the
platform is obtained from the device tree. For images that include both
dt and non-dt platforms, an addditional check is added to ensure that
static amba device registrations is applicable to only non-dt platforms.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/arm/mach-exynos4/Kconfig | 12 ++++++++++++
arch/arm/mach-exynos4/Makefile | 3 ++-
arch/arm/mach-exynos4/dma.c | 4 ++++
3 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 0c964b7..b013907 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -26,6 +26,11 @@ config EXYNOS4_MCT
help
Use MCT (Multi Core Timer) as kernel timers
+config EXYNOS4_DEV_DMA
+ bool
+ help
+ Compile in amba device definitions for DMA controller
+
config EXYNOS4_DEV_AHCI
bool
help
@@ -144,6 +149,7 @@ config MACH_SMDKV310
select EXYNOS4_DEV_PD
select SAMSUNG_DEV_PWM
select EXYNOS4_DEV_SYSMMU
+ select EXYNOS4_DEV_DMA
select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_KEYPAD
@@ -161,6 +167,7 @@ config MACH_ARMLEX4210
select S3C_DEV_HSMMC3
select EXYNOS4_DEV_AHCI
select EXYNOS4_DEV_SYSMMU
+ select EXYNOS4_DEV_DMA
select EXYNOS4_SETUP_SDHCI
help
Machine support for Samsung ARMLEX4210 based on EXYNOS4210
@@ -185,6 +192,7 @@ config MACH_UNIVERSAL_C210
select S5P_DEV_MFC
select S5P_DEV_ONENAND
select S5P_DEV_TV
+ select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_PD
select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
@@ -211,6 +219,7 @@ config MACH_NURI
select S3C_DEV_I2C5
select S5P_DEV_MFC
select S5P_DEV_USB_EHCI
+ select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_PD
select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
@@ -237,6 +246,7 @@ config MACH_ORIGEN
select S5P_DEV_I2C_HDMIPHY
select S5P_DEV_TV
select S5P_DEV_USB_EHCI
+ select EXYNOS4_DEV_DMA
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select EXYNOS4_SETUP_SDHCI
@@ -256,6 +266,7 @@ config MACH_SMDK4212
select S3C_DEV_I2C7
select S3C_DEV_RTC
select S3C_DEV_WDT
+ select EXYNOS4_DEV_DMA
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
@@ -271,6 +282,7 @@ config MACH_EXYNOS4_DT
bool "Samsung Exynos4 Machine using device tree"
select CPU_EXYNOS4210
select USE_OF
+ select ARM_AMBA
help
Machine support for Samsung Exynos4 machine with device tree enabled.
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 9e8b7e5..d0c5706 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -13,7 +13,7 @@ obj- :=
# Core support for EXYNOS4 system
obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o irq-eint.o dma.o pmu.o
+obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o irq-eint.o pmu.o
obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
obj-$(CONFIG_PM) += pm.o sleep.o
@@ -44,6 +44,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
+obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index c3c0d17..921d31d 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -24,6 +24,7 @@
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl330.h>
+#include <linux/of.h>
#include <asm/irq.h>
#include <plat/devs.h>
@@ -138,6 +139,9 @@ struct amba_device exynos4_device_pdma1 = {
static int __init exynos4_dma_init(void)
{
+ if (of_have_populated_dt())
+ return 0;
+
dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
amba_device_register(&exynos4_device_pdma0, &iomem_resource);
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH 4/8] ispvideo: Add support for G/S/ENUM_STD ioctl
From: Sakari Ailus @ 2011-09-28 9:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <19F8576C6E063C45BE387C64729E739404ECA54C58@dbde02.ent.ti.com>
Hi Hiremath,
Hiremath, Vaibhav wrote:
>> -----Original Message----- From: Laurent Pinchart
>> [mailto:laurent.pinchart at ideasonboard.com] Sent: Tuesday, September
>> 27, 2011 11:36 PM To: Hiremath, Vaibhav Cc: Ravi, Deepthy;
>> linux-media at vger.kernel.org; tony at atomide.com;
>> linux at arm.linux.org.uk; linux-omap at vger.kernel.org; linux-arm-
>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>> mchehab at infradead.org; g.liakhovetski at gmx.de Subject: Re: [PATCH
>> 4/8] ispvideo: Add support for G/S/ENUM_STD ioctl
>>
>> Hi Vaibhav,
>>
>> On Monday 19 September 2011 17:31:02 Hiremath, Vaibhav wrote:
>>> On Friday, September 16, 2011 6:36 PM Laurent Pinchart wrote:
>>>> On Friday 16 September 2011 15:00:53 Ravi, Deepthy wrote:
>>>>> On Thursday, September 08, 2011 10:51 PM Laurent Pinchart
>>>>> wrote:
>>>>>> On Thursday 08 September 2011 15:35:22 Deepthy Ravi wrote:
>>>>>>> From: Vaibhav Hiremath <hvaibhav@ti.com>
>>>>>>>
>>>>>>> In order to support TVP5146 (for that matter any video
>>>>>>> decoder), it is important to support G/S/ENUM_STD ioctl
>>>>>>> on /dev/videoX device node.
>>>>>>
>>>>>> Why so ? Shouldn't it be queried on the subdev output pad
>> directly ?
>>>>>
>>>>> Because standard v4l2 application for analog devices will
>>>>> call these std ioctls on the streaming device node. So it's
>>>>> done on /dev/video
>> to
>>>>> make the existing apllication work.
>>>>
>>>> Existing applications can't work with the OMAP3 ISP (and
>>>> similar
>> complex
>>>> embedded devices) without userspace support anyway, either in
>>>> the form
>> of
>>>> a GStreamer element or a libv4l plugin. I still believe that
>>>> analog
>> video
>>>> standard operations should be added to the subdev pad
>>>> operations and exposed through subdev device nodes, exactly as
>>>> done with formats.
>>>
>>> I completely agree with your point that, existing application
>>> will not
>> work
>>> without setting links properly. But I believe the assumption here
>>> is, media-controller should set the links (along with pad
>>> formants) and all existing application should work as is. Isn't
>>> it?
>>
>> The media controller is an API used (among other things) to set the
>> links. You still need to call it from userspace. That won't happen
>> magically. The userspace component that sets up the links and
>> configures the formats, be it a GStreamer element, a libv4l plugin,
>> or something else, can as well setup the standard on the TVP5146
>> subdev.
>>
> Please look at from analog device point of view which is interfaced
> to ISP.
>
> OMAP3 ISP => TVP5146 (video decoder)
>
> As a user I would want to expect the standard to be supported on
> streaming device node, since all standard streaming applications (for
> analog devices/interfaces) does this.
>
> Setting up the links and format is still something got added with MC
> framework, and I would consider it as a separate plug-in along with
> existing applications.
>
> Why do I need to write/use two different streaming application one
> for MC compatible device and another for non-MC?
You musn't need to.
This is something that will have to be handled by the libv4l plugin, as
the rest of controlling the device. Controls related ioctls will be
passed from the source to downstream once they apply, and I don't see
why the same shouldn't be done to the {G,S,ENUM}_STD.
Regards,
--
Sakari Ailus
sakari.ailus at iki.fi
^ permalink raw reply
* [PATCH V2 1/1] dmaengine/amba-pl08x: Add support for s3c64xx DMAC
From: Viresh Kumar @ 2011-09-28 9:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGOxZ53qZy+VUM65oK68W088QR=RgQ=cNxOCbO7_WESJesJaVQ@mail.gmail.com>
On 9/28/2011 2:20 PM, Alim Akhtar wrote:
> The main difference between Primecell PL080 and samsung variant is in
> LLI control register bit [0:11] is reserved in case of samsung pl080
> and one extra register is add to hold the transfer size at offset
> 0x10. The purpose of cctl1 is store the transfer_size.
So, actually you need to modify pl08x_fill_lli_for_desc() and
pl08x_cctl_bits() routines.
Updating cctl1 on the last lli will not solve your purpose,
and transfers needing more than one lli will fail.
BTW, did you try testing your patch for more than one LLI.
--
viresh
^ permalink raw reply
* [PATCH 4/8] ispvideo: Add support for G/S/ENUM_STD ioctl
From: Mauro Carvalho Chehab @ 2011-09-28 9:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E8252F1.9@mlbassoc.com>
Em 27-09-2011 19:49, Gary Thomas escreveu:
> On 2011-09-27 16:31, Mauro Carvalho Chehab wrote:
>> Em 19-09-2011 12:31, Hiremath, Vaibhav escreveu:
>>>
>>>> -----Original Message-----
>>>> From: Laurent Pinchart [mailto:laurent.pinchart at ideasonboard.com]
>>>> Sent: Friday, September 16, 2011 6:36 PM
>>>> To: Ravi, Deepthy
>>>> Cc: linux-media at vger.kernel.org; tony at atomide.com; linux at arm.linux.org.uk;
>>>> linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>>>> kernel at vger.kernel.org; mchehab at infradead.org; g.liakhovetski at gmx.de;
>>>> Hiremath, Vaibhav
>>>> Subject: Re: [PATCH 4/8] ispvideo: Add support for G/S/ENUM_STD ioctl
>>>>
>>>> Hi Deepthy,
>>>>
>>>> On Friday 16 September 2011 15:00:53 Ravi, Deepthy wrote:
>>>>> On Thursday, September 08, 2011 10:51 PM Laurent Pinchart wrote:
>>>>>> On Thursday 08 September 2011 15:35:22 Deepthy Ravi wrote:
>>>>>>> From: Vaibhav Hiremath<hvaibhav@ti.com>
>>>>>>>
>>>>>>> In order to support TVP5146 (for that matter any video decoder),
>>>>>>> it is important to support G/S/ENUM_STD ioctl on /dev/videoX
>>>>>>> device node.
>>>>>>
>>>>>> Why so ? Shouldn't it be queried on the subdev output pad directly ?
>>>>>
>>>>> Because standard v4l2 application for analog devices will call these std
>>>>> ioctls on the streaming device node. So it's done on /dev/video to make
>>>> the
>>>>> existing apllication work.
>>>>
>>>> Existing applications can't work with the OMAP3 ISP (and similar complex
>>>> embedded devices) without userspace support anyway, either in the form of
>>>> a
>>>> GStreamer element or a libv4l plugin. I still believe that analog video
>>>> standard operations should be added to the subdev pad operations and
>>>> exposed
>>>> through subdev device nodes, exactly as done with formats.
>>>>
>>> [Hiremath, Vaibhav] Laurent,
>>>
>>> I completely agree with your point that, existing application will not work without setting links properly.
>>> But I believe the assumption here is, media-controller should set the links (along with pad formants) and
>>> all existing application should work as is. Isn't it?
>>
>> Yes.
>>
>>> The way it is being done currently is, set the format at the pad level which is same as analog standard resolution and use existing application for streaming...
>>
>> Yes.
>>
>>> I am ok, if we add s/g/enum_std api support at sub-dev level but this should also be supported on streaming device node.
>>
>> Agreed. Standards selection should be done at device node, just like any other
>> device.
>
> So how do you handle a part like the TVP5150 that is standard agnostic?
> That device can sense the standard from the input signal and sets the
> result appropriately.
>
See the em28xx driver. It uses tvp5150 at the device node, and works properly.
It should be noticed, however, that the implementation at tvp5150 doesn't
implement standards detection properly, due to hardware limitation.
A proper implementation of standards detection is to get the standards mask from
userspace and let the driver detect between the standards that the userspace is
expecting.
So, userspace could, for example, do things like:
v4l2_std_id std = V4L2_STD_PAL_M | V4L2_STD_NTSC_M | V4L2_STD_PAL_DK;
ioctl (fd, VIDIOC_S_STD, &std);
msleep (100);
ioctl (fd, VIDIOC_G_STD, &std);
if (std & V4L2_STD_625_50)
height = 576;
else
height = 480;
The above code won't work with the current tvp5150 driver, due to two reasons:
1) The tvp5150 register 0x28 doesn't allow an arbitrary standards mask like the above.
The driver does support standards detection, if V4L2_STD_ALL is passed into it.
2) even if V4L2_STD_ALL is used, the driver currently doesn't implement a
vidioc_g_std callback. So, the driver cannot return back to userspace and to
the bridge driver what standard were detected. Without this information, userspace
might use the wrong number of lines when allocating the buffer, and this won't
work.
Of course, patches for fixing this are welcome.
Thanks,
Mauro
^ permalink raw reply
* [PATCH 0/8] S3C2416: Enable armdiv and armclk
From: Heiko Stübner @ 2011-09-28 10:17 UTC (permalink / raw)
To: linux-arm-kernel
To enable cpu frequency scaling on the S3C2416/2450 it is necessary
to define the arm-divider and armclock.
The layout of the clocks (i.e. msysclk -> armdiv -> armclk) is the
same on all three architectures (S3C2443/2416/2450) and only the
possible dividers for armdiv differ.
Therefore it is possible to move the armdiv and armclk to common
code with only the divider table definition remaining in the respective
clock.c-files.
The s3c2443_common_init_clocks method is modified to make it possible
to transmit the divider table to the common code.
As the armdiv is available in common code now, the fdiv function
pointer passed to s3c2443_common_init_clocks becomes obsolete and is
therefore removed as the fclk rate can be set by a clk_get_rate call.
It works as expected on S3C2416, is compile-tested on S3C2443
and checkpatch was happy.
Heiko Stuebner (8):
S3C2416: Add armdiv_mask constant.
S3C2443: Add infrastructure to transmit armdiv to common code
S3C2443: Move clk_arm and clk_armdiv to common code.
S3C2416: Add comment describing the armdiv/armclk.
S3C2443: Add get_rate operation for clk_armdiv
S3C2443: handle unset armdiv values gracefully.
S3C2443: Accommodate cpufreq frequency scheme in armdiv
S3C2443: use clk_get_rate to init fclk in common_setup_clocks
.../mach-s3c2410/include/mach/regs-s3c2443-clock.h | 1 +
arch/arm/mach-s3c2416/clock.c | 21 ++--
arch/arm/mach-s3c2443/clock.c | 98 +--------------
arch/arm/plat-s3c24xx/include/plat/s3c2443.h | 7 +-
arch/arm/plat-s3c24xx/s3c2443-clock.c | 134 +++++++++++++++++++-
5 files changed, 152 insertions(+), 109 deletions(-)
--
1.7.5.4
^ permalink raw reply
* [PATCH 1/8] S3C2416: Add armdiv_mask constant
From: Heiko Stübner @ 2011-09-28 10:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
The S3C2416/2450 has only 3 bits for the armdiv setting instead
of the 4 bits of the S3C2443.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
.../mach-s3c2410/include/mach/regs-s3c2443-clock.h | 1 +
arch/arm/mach-s3c2416/clock.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index df6434f..c3feff3 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -65,6 +65,7 @@
#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4)
#define S3C2443_CLKDIV0_PREDIV_SHIFT (4)
+#define S3C2416_CLKDIV0_ARMDIV_MASK (7 << 9)
#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9)
#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9)
#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9)
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 72b7c62..5569def 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -127,7 +127,7 @@ static struct clk hsmmc0_clk = {
static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
{
- clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+ clkcon0 &= S3C2416_CLKDIV0_ARMDIV_MASK;
return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/8] S3C2443: Add infrastructure to transmit armdiv to common code
From: Heiko Stübner @ 2011-09-28 10:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
This is needed for making the armdiv clock common to S3C2443 and
S3C2416/2450.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/mach-s3c2416/clock.c | 4 +++-
arch/arm/mach-s3c2443/clock.c | 4 +++-
arch/arm/plat-s3c24xx/include/plat/s3c2443.h | 4 +++-
arch/arm/plat-s3c24xx/s3c2443-clock.c | 12 +++++++++++-
4 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 5569def..3060796 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -158,7 +158,9 @@ void __init s3c2416_init_clocks(int xtal)
clk_epll.parent = &clk_epllref.clk;
- s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
+ s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div,
+ armdiv, ARRAY_SIZE(armdiv),
+ S3C2416_CLKDIV0_ARMDIV_MASK);
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_register_clksrc(clksrcs[ptr], 1);
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index cd51d04..88edc55 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -283,7 +283,9 @@ void __init s3c2443_init_clocks(int xtal)
clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
clk_epll.parent = &clk_epllref.clk;
- s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
+ s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div,
+ armdiv, ARRAY_SIZE(armdiv),
+ S3C2443_CLKDIV0_ARMDIV_MASK);
s3c2443_setup_clocks();
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index a19715f..7b824cb 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -40,7 +40,9 @@ typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
-extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv,
+ unsigned int *divs, int nr_divs,
+ int divmask);
extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 07a4c81..3f2117b 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -160,6 +160,10 @@ static struct clk clk_prediv = {
},
};
+static unsigned int *armdiv;
+static int nr_armdiv;
+static int armdivmask;
+
/* usbhost
*
* usb host bus-clock, usually 48MHz to provide USB bus clock timing
@@ -470,10 +474,16 @@ static struct clksrc_clk *clksrcs[] __initdata = {
};
void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
- fdiv_fn get_fdiv)
+ fdiv_fn get_fdiv,
+ unsigned int *divs, int nr_divs,
+ int divmask)
{
int ptr;
+ armdiv = divs;
+ nr_armdiv = nr_divs;
+ armdivmask = divmask;
+
/* s3c2443 parents h and p clocks from prediv */
clk_h.parent = &clk_prediv;
clk_p.parent = &clk_prediv;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 3/8] S3C2443: Move clk_arm and clk_armdiv to common code
From: Heiko Stübner @ 2011-09-28 10:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
The system-layout of the armdiv and armclk is common to
S3C2443/2416/2450 and only differs in the array of possible
dividers. Therefore it is possible to reuse the clock definitions
for all of these SoCs.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/mach-s3c2443/clock.c | 85 +-------------------------------
arch/arm/plat-s3c24xx/s3c2443-clock.c | 87 +++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 83 deletions(-)
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 88edc55..6fda4bf 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -61,10 +61,10 @@
*
* this clock is sourced from msysclk and can have a number of
* divider values applied to it to then be fed into armclk.
+ * The real clock definition is done in s3c2443-clock.c,
+ * only the armdiv divisor table must be defined here.
*/
-/* armdiv divisor table */
-
static unsigned int armdiv[16] = {
[S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
[S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
@@ -83,85 +83,6 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
}
-static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent = clk_get_rate(clk->parent);
- unsigned long calc;
- unsigned best = 256; /* bigger than any value */
- unsigned div;
- int ptr;
-
- for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
- div = armdiv[ptr];
- calc = parent / div;
- if (calc <= rate && div < best)
- best = div;
- }
-
- return parent / best;
-}
-
-static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent = clk_get_rate(clk->parent);
- unsigned long calc;
- unsigned div;
- unsigned best = 256; /* bigger than any value */
- int ptr;
- int val = -1;
-
- for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
- div = armdiv[ptr];
- calc = parent / div;
- if (calc <= rate && div < best) {
- best = div;
- val = ptr;
- }
- }
-
- if (val >= 0) {
- unsigned long clkcon0;
-
- clkcon0 = __raw_readl(S3C2443_CLKDIV0);
- clkcon0 &= ~S3C2443_CLKDIV0_ARMDIV_MASK;
- clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
- __raw_writel(clkcon0, S3C2443_CLKDIV0);
- }
-
- return (val == -1) ? -EINVAL : 0;
-}
-
-static struct clk clk_armdiv = {
- .name = "armdiv",
- .parent = &clk_msysclk.clk,
- .ops = &(struct clk_ops) {
- .round_rate = s3c2443_armclk_roundrate,
- .set_rate = s3c2443_armclk_setrate,
- },
-};
-
-/* armclk
- *
- * this is the clock fed into the ARM core itself, from armdiv or from hclk.
- */
-
-static struct clk *clk_arm_sources[] = {
- [0] = &clk_armdiv,
- [1] = &clk_h,
-};
-
-static struct clksrc_clk clk_arm = {
- .clk = {
- .name = "armclk",
- },
- .sources = &(struct clksrc_sources) {
- .sources = clk_arm_sources,
- .nr_sources = ARRAY_SIZE(clk_arm_sources),
- },
- .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
-};
-
/* hsspi
*
* high-speed spi clock, sourced from esysclk
@@ -260,14 +181,12 @@ static struct clk init_clocks[] = {
/* clocks to add straight away */
static struct clksrc_clk *clksrcs[] __initdata = {
- &clk_arm,
&clk_hsspi,
&clk_hsmmc_div,
};
static struct clk *clks[] __initdata = {
&clk_hsmmc,
- &clk_armdiv,
};
void __init_or_cpufreq s3c2443_setup_clocks(void)
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 3f2117b..f9c5b03 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -160,10 +160,95 @@ static struct clk clk_prediv = {
},
};
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+*/
+
static unsigned int *armdiv;
static int nr_armdiv;
static int armdivmask;
+static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ unsigned long calc;
+ unsigned best = 256; /* bigger than any value */
+ unsigned div;
+ int ptr;
+
+ for (ptr = 0; ptr < nr_armdiv; ptr++) {
+ div = armdiv[ptr];
+ calc = parent / div;
+ if (calc <= rate && div < best)
+ best = div;
+ }
+
+ return parent / best;
+}
+
+static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ unsigned long calc;
+ unsigned div;
+ unsigned best = 256; /* bigger than any value */
+ int ptr;
+ int val = -1;
+
+ for (ptr = 0; ptr < nr_armdiv; ptr++) {
+ div = armdiv[ptr];
+ calc = parent / div;
+ if (calc <= rate && div < best) {
+ best = div;
+ val = ptr;
+ }
+ }
+
+ if (val >= 0) {
+ unsigned long clkcon0;
+
+ clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+ clkcon0 &= ~armdivmask;
+ clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+ __raw_writel(clkcon0, S3C2443_CLKDIV0);
+ }
+
+ return (val == -1) ? -EINVAL : 0;
+}
+
+static struct clk clk_armdiv = {
+ .name = "armdiv",
+ .parent = &clk_msysclk.clk,
+ .ops = &(struct clk_ops) {
+ .round_rate = s3c2443_armclk_roundrate,
+ .set_rate = s3c2443_armclk_setrate,
+ },
+};
+
+/* armclk
+ *
+ * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+ */
+
+static struct clk *clk_arm_sources[] = {
+ [0] = &clk_armdiv,
+ [1] = &clk_h,
+};
+
+static struct clksrc_clk clk_arm = {
+ .clk = {
+ .name = "armclk",
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_arm_sources,
+ .nr_sources = ARRAY_SIZE(clk_arm_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+};
+
/* usbhost
*
* usb host bus-clock, usually 48MHz to provide USB bus clock timing
@@ -462,6 +547,7 @@ static struct clk *clks[] __initdata = {
&clk_ext,
&clk_epll,
&clk_usb_bus,
+ &clk_armdiv,
};
static struct clksrc_clk *clksrcs[] __initdata = {
@@ -471,6 +557,7 @@ static struct clksrc_clk *clksrcs[] __initdata = {
&clk_epllref,
&clk_esysclk,
&clk_msysclk,
+ &clk_arm,
};
void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
--
1.7.5.4
^ permalink raw reply related
* [PATCH 4/8] S3C2416: Add comment describing the armdiv/armclk
From: Heiko Stübner @ 2011-09-28 10:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/mach-s3c2416/clock.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 3060796..7aa0cfa 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -28,6 +28,14 @@
#include <mach/regs-clock.h>
#include <mach/regs-s3c2443-clock.h>
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+ * The real clock definition is done in s3c2443-clock.c,
+ * only the armdiv divisor table must be defined here.
+*/
+
static unsigned int armdiv[8] = {
[0] = 1,
[1] = 2,
--
1.7.5.4
^ permalink raw reply related
* [PATCH 5/8] S3C2443: Add get_rate operation for clk_armdiv
From: Heiko Stübner @ 2011-09-28 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/plat-s3c24xx/s3c2443-clock.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index f9c5b03..fea3d5c 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -189,6 +189,19 @@ static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
return parent / best;
}
+static unsigned long s3c2443_armclk_getrate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ unsigned long clkcon0;
+ int val;
+
+ clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+ clkcon0 &= armdivmask;
+ val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+ return rate / armdiv[val];
+}
+
static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
{
unsigned long parent = clk_get_rate(clk->parent);
@@ -224,6 +237,7 @@ static struct clk clk_armdiv = {
.parent = &clk_msysclk.clk,
.ops = &(struct clk_ops) {
.round_rate = s3c2443_armclk_roundrate,
+ .get_rate = s3c2443_armclk_getrate,
.set_rate = s3c2443_armclk_setrate,
},
};
--
1.7.5.4
^ permalink raw reply related
* [PATCH 6/8] S3C2443: handle unset armdiv values gracefully
From: Heiko Stübner @ 2011-09-28 10:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
The armdiv array may contain unset divider values. Check the
relevant value to prevent division by zero errors.
Also check for set nr_armdiv and armdivmask before
meddling with clkdiv0.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/plat-s3c24xx/s3c2443-clock.c | 27 ++++++++++++++++++++-------
1 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index fea3d5c..31f97f1 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -179,11 +179,16 @@ static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
unsigned div;
int ptr;
+ if (!nr_armdiv)
+ return -EINVAL;
+
for (ptr = 0; ptr < nr_armdiv; ptr++) {
div = armdiv[ptr];
- calc = parent / div;
- if (calc <= rate && div < best)
- best = div;
+ if (div) {
+ calc = parent / div;
+ if (calc <= rate && div < best)
+ best = div;
+ }
}
return parent / best;
@@ -195,6 +200,9 @@ static unsigned long s3c2443_armclk_getrate(struct clk *clk)
unsigned long clkcon0;
int val;
+ if (!nr_armdiv || !armdivmask)
+ return -EINVAL;
+
clkcon0 = __raw_readl(S3C2443_CLKDIV0);
clkcon0 &= armdivmask;
val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
@@ -211,12 +219,17 @@ static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
int ptr;
int val = -1;
+ if (!nr_armdiv || !armdivmask)
+ return -EINVAL;
+
for (ptr = 0; ptr < nr_armdiv; ptr++) {
div = armdiv[ptr];
- calc = parent / div;
- if (calc <= rate && div < best) {
- best = div;
- val = ptr;
+ if (div) {
+ calc = parent / div;
+ if (calc <= rate && div < best) {
+ best = div;
+ val = ptr;
+ }
}
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH 7/8] S3C2443: Accommodate cpufreq frequency scheme in armdiv
From: Heiko Stübner @ 2011-09-28 10:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
Cpufreq uses frequencies in kHz and not Hz, so set_rate and round_rate
would be called with a frequency of 266666000 instead of 266666666 but
the clock functions check for rates smaller or equal to the targetrate.
As the armdiv does not support steps this small we can accommodate
this by simply also setting the last 3 digits of the calculated rate
to zero.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/plat-s3c24xx/s3c2443-clock.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 31f97f1..40a8720 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -185,7 +185,8 @@ static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
for (ptr = 0; ptr < nr_armdiv; ptr++) {
div = armdiv[ptr];
if (div) {
- calc = parent / div;
+ /* cpufreq provides 266mhz as 266666000 not 266666666 */
+ calc = (parent / div / 1000) * 1000;
if (calc <= rate && div < best)
best = div;
}
@@ -225,7 +226,8 @@ static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
for (ptr = 0; ptr < nr_armdiv; ptr++) {
div = armdiv[ptr];
if (div) {
- calc = parent / div;
+ /* cpufreq provides 266mhz as 266666000 not 266666666 */
+ calc = (parent / div / 1000) * 1000;
if (calc <= rate && div < best) {
best = div;
val = ptr;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 8/8] S3C2443: use clk_get_rate to init fclk in common_setup_clocks
From: Heiko Stübner @ 2011-09-28 10:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109281217.33813.heiko@sntech.de>
Previously the fclk rate was calculated by dividing the pll through
the divider value of the armdiv. With a real armdiv clk in place it's
possible to simply read its value, which does essentially the same.
This change makes the whole fdiv_fn function pointers supplied to
s3c2443_common_init_clocks and s3c2443_common_setup_clocks
obsolete, so remove it too.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/mach-s3c2416/clock.c | 11 ++---------
arch/arm/mach-s3c2443/clock.c | 11 ++---------
arch/arm/plat-s3c24xx/include/plat/s3c2443.h | 5 ++---
arch/arm/plat-s3c24xx/s3c2443-clock.c | 8 +++-----
4 files changed, 9 insertions(+), 26 deletions(-)
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 7aa0cfa..afbbe8b 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -133,16 +133,9 @@ static struct clk hsmmc0_clk = {
.ctrlbit = S3C2416_HCLKCON_HSMMC0,
};
-static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
-{
- clkcon0 &= S3C2416_CLKDIV0_ARMDIV_MASK;
-
- return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
-}
-
void __init_or_cpufreq s3c2416_setup_clocks(void)
{
- s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
+ s3c2443_common_setup_clocks(s3c2416_get_pll);
}
@@ -166,7 +159,7 @@ void __init s3c2416_init_clocks(int xtal)
clk_epll.parent = &clk_epllref.clk;
- s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div,
+ s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
armdiv, ARRAY_SIZE(armdiv),
S3C2416_CLKDIV0_ARMDIV_MASK);
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 6fda4bf..b93cb96 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -76,13 +76,6 @@ static unsigned int armdiv[16] = {
[S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
};
-static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
-{
- clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
-
- return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
-}
-
/* hsspi
*
* high-speed spi clock, sourced from esysclk
@@ -191,7 +184,7 @@ static struct clk *clks[] __initdata = {
void __init_or_cpufreq s3c2443_setup_clocks(void)
{
- s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
+ s3c2443_common_setup_clocks(s3c2443_get_mpll);
}
void __init s3c2443_init_clocks(int xtal)
@@ -202,7 +195,7 @@ void __init s3c2443_init_clocks(int xtal)
clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
clk_epll.parent = &clk_epllref.clk;
- s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div,
+ s3c2443_common_init_clocks(xtal, s3c2443_get_mpll,
armdiv, ARRAY_SIZE(armdiv),
S3C2443_CLKDIV0_ARMDIV_MASK);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index 7b824cb..5496316 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -37,10 +37,9 @@ extern int s3c2443_baseclk_add(void);
struct clk; /* some files don't need clk.h otherwise */
typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
-typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
-extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
-extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv,
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
unsigned int *divs, int nr_divs,
int divmask);
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 40a8720..d3ebbee 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -520,8 +520,7 @@ static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
/* EPLLCON compatible enough to get on/off information */
-void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
- fdiv_fn get_fdiv)
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
{
unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
@@ -541,7 +540,7 @@ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
pll = get_mpll(mpllcon, xtal);
clk_msysclk.clk.rate = pll;
- fclk = pll / get_fdiv(clkdiv0);
+ fclk = clk_get_rate(&clk_armdiv);
hclk = s3c2443_prediv_getrate(&clk_prediv);
hclk /= s3c2443_get_hdiv(clkdiv0);
pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
@@ -590,7 +589,6 @@ static struct clksrc_clk *clksrcs[] __initdata = {
};
void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
- fdiv_fn get_fdiv,
unsigned int *divs, int nr_divs,
int divmask)
{
@@ -620,5 +618,5 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
- s3c2443_common_setup_clocks(get_mpll, get_fdiv);
+ s3c2443_common_setup_clocks(get_mpll);
}
--
1.7.5.4
^ permalink raw reply related
* [GIT PULL] DEBUG_LL platform updates for 3.2
From: Will Deacon @ 2011-09-28 10:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd,
Please pull these DEBUG_LL platform updates for 3.2. You can find the core
updates (actually all resident in arch/arm/Kconfig.debug) in Russell's
for-next branch.
I think Stephen Boyd was planning to move MSM to the new code as well, but
I've not seen any code yet so I guess that can go in later.
Thanks!
Will
The following changes since commit 589593ec8b1790c0d9ea227a3811f819eff4f977:
Stephen Boyd (1):
ARM: 7097/1: debug: Move DEBUG_ICEDCC into the DEBUG_LL choice
are available in the git repository at:
git://linux-arm.org/linux-2.6-wd.git for-arnd
Shawn Guo (1):
arm/imx: use Kconfig choice for low-level debug UART selection
Will Deacon (2):
ARM: plat-samsung: use Kconfig choice for debug UART selection
ARM: realview: use Kconfig choice for debug UART selection
arch/arm/Kconfig.debug | 117 ++++++++++++++++++--
arch/arm/mach-mxs/include/mach/debug-macro.S | 12 +--
arch/arm/mach-realview/include/mach/debug-macro.S | 17 +---
arch/arm/plat-mxc/include/mach/debug-macro.S | 38 +------
arch/arm/plat-samsung/Kconfig | 7 ++
5 files changed, 122 insertions(+), 69 deletions(-)
^ permalink raw reply
* [PATCHv2 00/10] VIC DT binding and MULTI_IRQ_HANDLER
From: Jamie Iles @ 2011-09-28 10:41 UTC (permalink / raw)
To: linux-arm-kernel
This patch series adds a device tree binding for the VIC and support for
a generic VIC MULTI_IRQ_HANDLER. The MULTI_IRQ_HANDLER is a step
towards a single image kernel, removing the need for mach specific entry
handlers for platforms using the VIC as the primary interrupt
controller.
This has dependencies on:
- of/irq: introduce of_irq_init
http://lists.infradead.org/pipermail/linux-arm-kernel/2011-September/066844.html
- irq: add declaration of irq_domain_simple_ops to irqdomain.h
https://lkml.org/lkml/2011/9/14/189
from Rob Herring, and
- ARM: Make global handler and CONFIG_MULTI_IRQ_HANDLER mutually
exclusive
http://www.spinics.net/lists/arm-kernel/msg141948.html
from Marc Zyngier.
Tested on picoxcell and build tested for all defconfigs.
Jamie Iles (10):
ARM: vic: device tree binding
ARM: vic: MULTI_IRQ_HANDLER handler
ARM: ep93xx: convert to MULTI_IRQ_HANDLER
ARM: netx: convert to MULTI_IRQ_HANDLER
ARM: nomadik: convert to MULTI_IRQ_HANDLER
ARM: s3c64xx: convert to MULTI_IRQ_HANDLER
ARM: spear: convert to MULTI_IRQ_HANDLER
ARM: u300: convert to MULTI_IRQ_HANDLER
ARM: versatile: convert to MULTI_IRQ_HANDLER
ARM: samsung: convert to MULTI_IRQ_HANDLER
Documentation/devicetree/bindings/arm/vic.txt | 29 ++++
arch/arm/Kconfig | 10 ++
arch/arm/common/Kconfig | 1 +
arch/arm/common/vic.c | 135 ++++++++++++++++----
arch/arm/include/asm/hardware/vic.h | 14 ++-
arch/arm/mach-ep93xx/adssphere.c | 2 +
arch/arm/mach-ep93xx/edb93xx.c | 9 ++
arch/arm/mach-ep93xx/gesbc9312.c | 2 +
arch/arm/mach-ep93xx/include/mach/entry-macro.S | 42 ------
arch/arm/mach-ep93xx/micro9.c | 5 +
arch/arm/mach-ep93xx/simone.c | 2 +
arch/arm/mach-ep93xx/snappercl15.c | 2 +
arch/arm/mach-ep93xx/ts72xx.c | 2 +
arch/arm/mach-netx/include/mach/entry-macro.S | 13 --
arch/arm/mach-netx/nxdb500.c | 2 +
arch/arm/mach-netx/nxdkn.c | 2 +
arch/arm/mach-netx/nxeb500hmi.c | 2 +
arch/arm/mach-nomadik/board-nhk8815.c | 2 +
arch/arm/mach-nomadik/include/mach/entry-macro.S | 30 -----
arch/arm/mach-s3c64xx/include/mach/entry-macro.S | 7 +-
arch/arm/mach-s3c64xx/mach-anw6410.c | 2 +
arch/arm/mach-s3c64xx/mach-crag6410.c | 2 +
arch/arm/mach-s3c64xx/mach-hmt.c | 2 +
arch/arm/mach-s3c64xx/mach-mini6410.c | 2 +
arch/arm/mach-s3c64xx/mach-ncp.c | 2 +
arch/arm/mach-s3c64xx/mach-real6410.c | 2 +
arch/arm/mach-s3c64xx/mach-smartq5.c | 2 +
arch/arm/mach-s3c64xx/mach-smartq7.c | 2 +
arch/arm/mach-s3c64xx/mach-smdk6400.c | 2 +
arch/arm/mach-s3c64xx/mach-smdk6410.c | 2 +
arch/arm/mach-s5p64x0/include/mach/entry-macro.S | 7 +-
arch/arm/mach-s5p64x0/mach-smdk6440.c | 2 +
arch/arm/mach-s5p64x0/mach-smdk6450.c | 2 +
arch/arm/mach-s5pc100/include/mach/entry-macro.S | 25 ----
arch/arm/mach-s5pc100/mach-smdkc100.c | 2 +
arch/arm/mach-s5pv210/include/mach/entry-macro.S | 37 ------
arch/arm/mach-s5pv210/mach-aquila.c | 2 +
arch/arm/mach-s5pv210/mach-goni.c | 2 +
arch/arm/mach-s5pv210/mach-smdkc110.c | 2 +
arch/arm/mach-s5pv210/mach-smdkv210.c | 2 +
arch/arm/mach-s5pv210/mach-torbreck.c | 2 +
arch/arm/mach-spear3xx/include/mach/entry-macro.S | 27 ----
arch/arm/mach-spear3xx/spear300_evb.c | 2 +
arch/arm/mach-spear3xx/spear310_evb.c | 2 +
arch/arm/mach-spear3xx/spear320_evb.c | 2 +
arch/arm/mach-spear6xx/include/mach/entry-macro.S | 36 -----
arch/arm/mach-spear6xx/spear600_evb.c | 2 +
arch/arm/mach-u300/include/mach/entry-macro.S | 24 ----
arch/arm/mach-u300/u300.c | 2 +
arch/arm/mach-versatile/include/mach/entry-macro.S | 30 -----
arch/arm/mach-versatile/versatile_ab.c | 2 +
arch/arm/mach-versatile/versatile_dt.c | 2 +
arch/arm/mach-versatile/versatile_pb.c | 2 +
53 files changed, 252 insertions(+), 299 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
--
1.7.4.1
^ permalink raw reply
* [PATCHv2 01/10] ARM: vic: device tree binding
From: Jamie Iles @ 2011-09-28 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317206507-18867-1-git-send-email-jamie@jamieiles.com>
This adds a device tree binding for the VIC based on the of_irq_init()
support. This adds an irqdomain to the vic and always registers all
vics in the static vic array rather than for pm only to keep track of
the irq domain. struct irq_data::hwirq is used where appropriate rather
than runtime masking.
v2: - use irq_domain_simple_ops
- remove stub implementation of vic_of_init for !CONFIG_OF
- Make VIC select IRQ_DOMAIN
Cc: Rob Herring <robherring2@gmail.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
Documentation/devicetree/bindings/arm/vic.txt | 29 +++++++
arch/arm/common/Kconfig | 1 +
arch/arm/common/vic.c | 106 ++++++++++++++++++-------
arch/arm/include/asm/hardware/vic.h | 10 ++-
4 files changed, 117 insertions(+), 29 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
new file mode 100644
index 0000000..266716b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vic.txt
@@ -0,0 +1,29 @@
+* ARM Vectored Interrupt Controller
+
+One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
+system for interrupt routing. For multiple controllers they can either be
+nested or have the outputs wire-OR'd together.
+
+Required properties:
+
+- compatible : should be one of
+ "arm,pl190-vic"
+ "arm,pl192-vic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
+ the VIC has no configuration options for interrupt sources. The cell is a u32
+ and defines the interrupt number.
+- reg : The register bank for the VIC.
+
+Optional properties:
+
+- interrupts : Interrupt source for parent controllers if the VIC is nested.
+
+Example:
+
+ vic0: interrupt-controller at 60000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x60000 0x1000>;
+ };
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 4b71766..43e9d1a 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -2,6 +2,7 @@ config ARM_GIC
bool
config ARM_VIC
+ select IRQ_DOMAIN
bool
config ARM_VIC_NR
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 7aa4262..3f9c8f2 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -22,6 +22,10 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <linux/syscore_ops.h>
#include <linux/device.h>
#include <linux/amba/bus.h>
@@ -29,7 +33,6 @@
#include <asm/mach/irq.h>
#include <asm/hardware/vic.h>
-#ifdef CONFIG_PM
/**
* struct vic_device - VIC PM device
* @irq: The IRQ number for the base of the VIC.
@@ -40,6 +43,7 @@
* @int_enable: Save for VIC_INT_ENABLE.
* @soft_int: Save for VIC_INT_SOFT.
* @protect: Save for VIC_PROTECT.
+ * @domain: The IRQ domain for the VIC.
*/
struct vic_device {
void __iomem *base;
@@ -50,13 +54,13 @@ struct vic_device {
u32 int_enable;
u32 soft_int;
u32 protect;
+ struct irq_domain domain;
};
/* we cannot allocate memory when VICs are initially registered */
static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
static int vic_id;
-#endif /* CONFIG_PM */
/**
* vic_init2 - common initialisation code
@@ -156,39 +160,50 @@ static int __init vic_pm_init(void)
return 0;
}
late_initcall(vic_pm_init);
+#endif /* CONFIG_PM */
/**
- * vic_pm_register - Register a VIC for later power management control
+ * vic_register() - Register a VIC.
* @base: The base address of the VIC.
* @irq: The base IRQ for the VIC.
* @resume_sources: bitmask of interrupts allowed for resume sources.
+ * @node: The device tree node associated with the VIC.
*
* Register the VIC with the system device tree so that it can be notified
* of suspend and resume requests and ensure that the correct actions are
* taken to re-instate the settings on resume.
+ *
+ * This also configures the IRQ domain for the VIC.
*/
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+static void __init vic_register(void __iomem *base, unsigned int irq,
+ u32 resume_sources, struct device_node *node)
{
struct vic_device *v;
- if (vic_id >= ARRAY_SIZE(vic_devices))
+ if (vic_id >= ARRAY_SIZE(vic_devices)) {
printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
- else {
- v = &vic_devices[vic_id];
- v->base = base;
- v->resume_sources = resume_sources;
- v->irq = irq;
- vic_id++;
+ return;
}
+
+ v = &vic_devices[vic_id];
+ v->base = base;
+ v->resume_sources = resume_sources;
+ v->irq = irq;
+ vic_id++;
+
+ v->domain.irq_base = irq;
+ v->domain.nr_irq = 32;
+#ifdef CONFIG_OF_IRQ
+ v->domain.of_node = of_node_get(node);
+ v->domain.ops = &irq_domain_simple_ops;
+#endif /* CONFIG_OF */
+ irq_domain_add(&v->domain);
}
-#else
-static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
-#endif /* CONFIG_PM */
static void vic_ack_irq(struct irq_data *d)
{
void __iomem *base = irq_data_get_irq_chip_data(d);
- unsigned int irq = d->irq & 31;
+ unsigned int irq = d->hwirq;
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
/* moreover, clear the soft-triggered, in case it was the reason */
writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
@@ -197,14 +212,14 @@ static void vic_ack_irq(struct irq_data *d)
static void vic_mask_irq(struct irq_data *d)
{
void __iomem *base = irq_data_get_irq_chip_data(d);
- unsigned int irq = d->irq & 31;
+ unsigned int irq = d->hwirq;
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
}
static void vic_unmask_irq(struct irq_data *d)
{
void __iomem *base = irq_data_get_irq_chip_data(d);
- unsigned int irq = d->irq & 31;
+ unsigned int irq = d->hwirq;
writel(1 << irq, base + VIC_INT_ENABLE);
}
@@ -226,7 +241,7 @@ static struct vic_device *vic_from_irq(unsigned int irq)
static int vic_set_wake(struct irq_data *d, unsigned int on)
{
struct vic_device *v = vic_from_irq(d->irq);
- unsigned int off = d->irq & 31;
+ unsigned int off = d->hwirq;
u32 bit = 1 << off;
if (!v)
@@ -331,15 +346,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
vic_set_irq_sources(base, irq_start, vic_sources);
}
-/**
- * vic_init - initialise a vectored interrupt controller
- * @base: iomem base address
- * @irq_start: starting interrupt number, must be muliple of 32
- * @vic_sources: bitmask of interrupt sources to allow
- * @resume_sources: bitmask of interrupt sources to allow for resume
- */
-void __init vic_init(void __iomem *base, unsigned int irq_start,
- u32 vic_sources, u32 resume_sources)
+static void __init __vic_init(void __iomem *base, unsigned int irq_start,
+ u32 vic_sources, u32 resume_sources,
+ struct device_node *node)
{
unsigned int i;
u32 cellid = 0;
@@ -375,5 +384,46 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
vic_set_irq_sources(base, irq_start, vic_sources);
- vic_pm_register(base, irq_start, resume_sources);
+ vic_register(base, irq_start, resume_sources, node);
+}
+
+/**
+ * vic_init() - initialise a vectored interrupt controller
+ * @base: iomem base address
+ * @irq_start: starting interrupt number, must be muliple of 32
+ * @vic_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
+ */
+void __init vic_init(void __iomem *base, unsigned int irq_start,
+ u32 vic_sources, u32 resume_sources)
+{
+ __vic_init(base, irq_start, vic_sources, resume_sources, NULL);
+}
+
+#ifdef CONFIG_OF
+int __init vic_of_init(struct device_node *node, struct device_node *parent)
+{
+ void __iomem *regs;
+ int irq_base;
+
+ if (WARN(parent, "non-root VICs are not supported"))
+ return -EINVAL;
+
+ regs = of_iomap(node, 0);
+ if (WARN_ON(!regs))
+ return -EIO;
+
+ irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
+ if (WARN_ON(irq_base < 0))
+ goto out_unmap;
+
+ __vic_init(regs, irq_base, ~0, ~0, node);
+
+ return 0;
+
+ out_unmap:
+ iounmap(regs);
+
+ return -EIO;
}
+#endif /* CONFIG OF */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index 5d72550..0135215 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -41,7 +41,15 @@
#define VIC_PL192_VECT_ADDR 0xF00
#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+struct device_node;
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
-#endif
+#ifdef CONFIG_OF
+int vic_of_init(struct device_node *node, struct device_node *parent);
+#endif /* CONFIG_OF */
+
+#endif /* __ASSEMBLY__ */
#endif
--
1.7.4.1
^ permalink raw reply related
* [PATCHv2 02/10] ARM: vic: MULTI_IRQ_HANDLER handler
From: Jamie Iles @ 2011-09-28 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317206507-18867-1-git-send-email-jamie@jamieiles.com>
Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
platforms. This can replace the ASM entry macros for platforms that use
the VIC.
v2: - allow the handler be used for !CONFIG_OF
- use irq_domain_to_irq()
Cc: Rob Herring <robherring2@gmail.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
arch/arm/common/vic.c | 29 +++++++++++++++++++++++++++++
arch/arm/include/asm/hardware/vic.h | 4 ++++
2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 3f9c8f2..71adced 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -427,3 +427,32 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
return -EIO;
}
#endif /* CONFIG OF */
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+ u32 stat, irq;
+ bool handled = false;
+
+ while (!handled) {
+ stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+ if (!stat)
+ break;
+
+ while (stat) {
+ irq = fls(stat) - 1;
+ handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+ stat &= ~(1 << irq);
+ handled = true;
+ }
+ }
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+ int i;
+
+ for (i = 0; i < vic_id; ++i)
+ vic_single_handle_irq(&vic_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index 0135215..c02fd6f 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -45,11 +45,15 @@
#include <linux/types.h>
struct device_node;
+struct pt_regs;
+
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
#ifdef CONFIG_OF
int vic_of_init(struct device_node *node, struct device_node *parent);
#endif /* CONFIG_OF */
+void vic_handle_irq(struct pt_regs *regs);
+
#endif /* __ASSEMBLY__ */
#endif
--
1.7.4.1
^ permalink raw reply related
* [PATCHv2 03/10] ARM: ep93xx: convert to MULTI_IRQ_HANDLER
From: Jamie Iles @ 2011-09-28 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317206507-18867-1-git-send-email-jamie@jamieiles.com>
Now that there is a generic IRQ handler for multiple VIC devices use it
for ep93xx to help building multi platform kernels.
Cc: Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ryan Mallon <rmallon@gmail.com>
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-ep93xx/adssphere.c | 2 +
arch/arm/mach-ep93xx/edb93xx.c | 9 +++++
arch/arm/mach-ep93xx/gesbc9312.c | 2 +
arch/arm/mach-ep93xx/include/mach/entry-macro.S | 42 -----------------------
arch/arm/mach-ep93xx/micro9.c | 5 +++
arch/arm/mach-ep93xx/simone.c | 2 +
arch/arm/mach-ep93xx/snappercl15.c | 2 +
arch/arm/mach-ep93xx/ts72xx.c | 2 +
9 files changed, 25 insertions(+), 42 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5ebc5d9..7facb7c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -377,6 +377,7 @@ config ARCH_EP93XX
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_USES_GETTIMEOFFSET
+ select MULTI_IRQ_HANDLER
help
This enables support for the Cirrus EP93xx series of CPUs.
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 61b98ce..1c09d24 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -16,6 +16,7 @@
#include <mach/hardware.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -36,6 +37,7 @@ MACHINE_START(ADSSPHERE, "ADS Sphere board")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = adssphere_init_machine,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 9969bb1..d2f0609 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -38,6 +38,7 @@
#include <mach/fb.h>
#include <mach/ep93xx_spi.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -243,6 +244,7 @@ MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -254,6 +256,7 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -265,6 +268,7 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -276,6 +280,7 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -287,6 +292,7 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -298,6 +304,7 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -309,6 +316,7 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
@@ -320,6 +328,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index 9bd3152..5e646b9 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -16,6 +16,7 @@
#include <mach/hardware.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -36,6 +37,7 @@ MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = gesbc9312_init_machine,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/include/mach/entry-macro.S b/arch/arm/mach-ep93xx/include/mach/entry-macro.S
index 96b85e2..9be6edc 100644
--- a/arch/arm/mach-ep93xx/include/mach/entry-macro.S
+++ b/arch/arm/mach-ep93xx/include/mach/entry-macro.S
@@ -9,51 +9,9 @@
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
-#include <mach/ep93xx-regs.h>
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
- .endm
-
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \base, =(EP93XX_AHB_VIRT_BASE)
- orr \base, \base, #0x000b0000
- mov \irqnr, #0
- ldr \irqstat, [\base] @ lower 32 interrupts
- cmp \irqstat, #0
- bne 1001f
-
- eor \base, \base, #0x00070000
- ldr \irqstat, [\base] @ upper 32 interrupts
- cmp \irqstat, #0
- beq 1002f
- mov \irqnr, #0x20
-
-1001:
- movs \tmp, \irqstat, lsl #16
- movne \irqstat, \tmp
- addeq \irqnr, \irqnr, #16
-
- movs \tmp, \irqstat, lsl #8
- movne \irqstat, \tmp
- addeq \irqnr, \irqnr, #8
-
- movs \tmp, \irqstat, lsl #4
- movne \irqstat, \tmp
- addeq \irqnr, \irqnr, #4
-
- movs \tmp, \irqstat, lsl #2
- movne \irqstat, \tmp
- addeq \irqnr, \irqnr, #2
-
- movs \tmp, \irqstat, lsl #1
- addeq \irqnr, \irqnr, #1
- orrs \base, \base, #1
-
-1002:
- .endm
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 7adea62..5b882b4 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -18,6 +18,7 @@
#include <mach/hardware.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -80,6 +81,7 @@ MACHINE_START(MICRO9, "Contec Micro9-High")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
MACHINE_END
@@ -91,6 +93,7 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid")
.boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
MACHINE_END
@@ -102,6 +105,7 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
MACHINE_END
@@ -113,6 +117,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim")
.boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index 8392e95..cd5a263 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -25,6 +25,7 @@
#include <mach/hardware.h>
#include <mach/fb.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -69,6 +70,7 @@ MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = simone_init_machine,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index 2e9c614..8959764 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -31,6 +31,7 @@
#include <mach/hardware.h>
#include <mach/fb.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -166,6 +167,7 @@ MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = snappercl15_init_machine,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index c2d2cf4..75e1249 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -23,6 +23,7 @@
#include <mach/hardware.h>
#include <mach/ts72xx.h>
+#include <asm/hardware/vic.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
@@ -260,6 +261,7 @@ MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ts72xx_map_io,
.init_irq = ep93xx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = ts72xx_init_machine,
MACHINE_END
--
1.7.4.1
^ permalink raw reply related
* [PATCHv2 04/10] ARM: netx: convert to MULTI_IRQ_HANDLER
From: Jamie Iles @ 2011-09-28 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317206507-18867-1-git-send-email-jamie@jamieiles.com>
Now that there is a generic IRQ handler for multiple VIC devices use it
for netx to help building multi platform kernels.
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-netx/include/mach/entry-macro.S | 13 -------------
arch/arm/mach-netx/nxdb500.c | 2 ++
arch/arm/mach-netx/nxdkn.c | 2 ++
arch/arm/mach-netx/nxeb500hmi.c | 2 ++
5 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7facb7c..b7cab06 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -416,6 +416,7 @@ config ARCH_NETX
select CPU_ARM926T
select ARM_VIC
select GENERIC_CLOCKEVENTS
+ select MULTI_IRQ_HANDLER
help
This enables support for systems based on the Hilscher NetX Soc
diff --git a/arch/arm/mach-netx/include/mach/entry-macro.S b/arch/arm/mach-netx/include/mach/entry-macro.S
index 844f1f9..6e9f1cb 100644
--- a/arch/arm/mach-netx/include/mach/entry-macro.S
+++ b/arch/arm/mach-netx/include/mach/entry-macro.S
@@ -18,22 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <mach/hardware.h>
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =io_p2v(0x001ff000)
- .endm
-
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \irqstat, [\base, #0]
- clz \irqnr, \irqstat
- rsb \irqnr, \irqnr, #31
- cmp \irqstat, #0
- .endm
-
diff --git a/arch/arm/mach-netx/nxdb500.c b/arch/arm/mach-netx/nxdb500.c
index ca8b203..e86aea8 100644
--- a/arch/arm/mach-netx/nxdb500.c
+++ b/arch/arm/mach-netx/nxdb500.c
@@ -28,6 +28,7 @@
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/hardware/vic.h>
#include <mach/netx-regs.h>
#include <mach/eth.h>
@@ -203,6 +204,7 @@ MACHINE_START(NXDB500, "Hilscher nxdb500")
.boot_params = 0x80000100,
.map_io = netx_map_io,
.init_irq = netx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &netx_timer,
.init_machine = nxdb500_init,
MACHINE_END
diff --git a/arch/arm/mach-netx/nxdkn.c b/arch/arm/mach-netx/nxdkn.c
index d775cbe..b3170da 100644
--- a/arch/arm/mach-netx/nxdkn.c
+++ b/arch/arm/mach-netx/nxdkn.c
@@ -28,6 +28,7 @@
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/hardware/vic.h>
#include <mach/netx-regs.h>
#include <mach/eth.h>
@@ -96,6 +97,7 @@ MACHINE_START(NXDKN, "Hilscher nxdkn")
.boot_params = 0x80000100,
.map_io = netx_map_io,
.init_irq = netx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &netx_timer,
.init_machine = nxdkn_init,
MACHINE_END
diff --git a/arch/arm/mach-netx/nxeb500hmi.c b/arch/arm/mach-netx/nxeb500hmi.c
index de369cd..dc6fa77 100644
--- a/arch/arm/mach-netx/nxeb500hmi.c
+++ b/arch/arm/mach-netx/nxeb500hmi.c
@@ -28,6 +28,7 @@
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/hardware/vic.h>
#include <mach/netx-regs.h>
#include <mach/eth.h>
@@ -180,6 +181,7 @@ MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi")
.boot_params = 0x80000100,
.map_io = netx_map_io,
.init_irq = netx_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &netx_timer,
.init_machine = nxeb500hmi_init,
MACHINE_END
--
1.7.4.1
^ permalink raw reply related
* [PATCHv2 05/10] ARM: nomadik: convert to MULTI_IRQ_HANDLER
From: Jamie Iles @ 2011-09-28 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317206507-18867-1-git-send-email-jamie@jamieiles.com>
Now that there is a generic IRQ handler for multiple VIC devices use it
for nomadik to help building multi platform kernels.
Cc: Alessandro Rubini <rubini@unipv.it>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: STEricsson <STEricsson_nomadik_linux@list.st.com>
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-nomadik/board-nhk8815.c | 2 +
arch/arm/mach-nomadik/include/mach/entry-macro.S | 30 ----------------------
3 files changed, 3 insertions(+), 30 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b7cab06..8d131a2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -859,6 +859,7 @@ config ARCH_NOMADIK
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
+ select MULTI_IRQ_HANDLER
help
Support for the Nomadik platform by ST-Ericsson
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index 1399303..46d9dce 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -21,6 +21,7 @@
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
+#include <asm/hardware/vic.h>
#include <asm/sizes.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -279,6 +280,7 @@ MACHINE_START(NOMADIK, "NHK8815")
.boot_params = 0x100,
.map_io = cpu8815_map_io,
.init_irq = cpu8815_init_irq,
+ .handle_irq = vic_handle_irq,
.timer = &nomadik_timer,
.init_machine = nhk8815_platform_init,
MACHINE_END
diff --git a/arch/arm/mach-nomadik/include/mach/entry-macro.S b/arch/arm/mach-nomadik/include/mach/entry-macro.S
index 49f1aa3..98ea1c1 100644
--- a/arch/arm/mach-nomadik/include/mach/entry-macro.S
+++ b/arch/arm/mach-nomadik/include/mach/entry-macro.S
@@ -6,38 +6,8 @@
* warranty of any kind, whether express or implied.
*/
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =IO_ADDRESS(NOMADIK_IC_BASE)
- .endm
-
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-
- /* This stanza gets the irq mask from one of two status registers */
- mov \irqnr, #0
- ldr \irqstat, [\base, #VIC_REG_IRQSR0] @ get masked status
- cmp \irqstat, #0
- bne 1001f
- add \irqnr, \irqnr, #32
- ldr \irqstat, [\base, #VIC_REG_IRQSR1] @ get masked status
-
-1001: tst \irqstat, #15
- bne 1002f
- add \irqnr, \irqnr, #4
- movs \irqstat, \irqstat, lsr #4
- bne 1001b
-1002: tst \irqstat, #1
- bne 1003f
- add \irqnr, \irqnr, #1
- movs \irqstat, \irqstat, lsr #1
- bne 1002b
-1003: /* EQ will be set if no irqs pending */
- .endm
--
1.7.4.1
^ 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