Device tree conversions for samsung and tegra

Both platforms had some initial device tree support, but this adds
 much more to actually make it usable.
 
 This is where the really nasty conflicts in the samsung platform
 start, due to some files getting moved around and combined in the
 'restart' branch that has already gone into mainline through
 Russell's tree.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIVAwUATwtUpWCrR//JCVInAQI7bhAA1Q8MXyQ3EwLKMWX2p0vmbb29Nugoq0Y3
 u9pBlCqiz0zw/jccPWASCgVgMVYguZLuhvMRCO8Q1D4l3ljcTt7qhtN6lBAESz2N
 OTTaNU2T84Um2Watm7VAQrnLcJMhxd/wFV06lmE62SgxwIVzyqxo4sr3KB3S5Qyj
 W3q5wRLuc5pC293HkWSNpLj3nfcKFF2oHOFpEAC5AS/C5S38Eu/T9y4FSUGvoTq4
 u7xlZT11uZUTRfvkRQUTOXkh9I0Fk0JuwUpUkqhgvM4jD0Ehs60/702CX4mPAoVd
 +BFUI23QNSof6O04rUxEzOSt1ZNg4Le+pQZ3vUcOvi539Npq+VgzDU+yo7uzNtYv
 c22VJihvS9GY2s7ynmmCE6Rgw17B3VOMMy1cBbQEET2V2GwgU9lQLx2eR/bUrOGq
 ewcTCqgFFWVugsGsn0wM0BiPZAJ+FddXon3w3X09BM0v5a6O6q0aUAQiJnGqDgUE
 ZLHhYRoL87r2TU6J+3iutK3sDHQrvHkGAZdXX3H5hVWdfLWqnwGgLjT/NpBeUaWc
 g6nut7pFgVDCD4q4JUCa99XykgKGWRtSHAuHmJQsdZ24PzpXmse3etVZTCYwr7t6
 BM3zrozoecQbGTRwZKGb9poOKd7g7xJ7125770GqYgTeX+BnBcA2lIEDAkEKsLBR
 GaxJggw32Q0=
 =XY2N
 -----END PGP SIGNATURE-----

Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Device tree conversions for samsung and tegra

Both platforms had some initial device tree support, but this adds
much more to actually make it usable.

* tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (45 commits)
  ARM: dts: Add intial dts file for EXYNOS4210 SoC, SMDKV310 and ORIGEN
  ARM: EXYNOS: Add Exynos4 device tree enabled board file
  rtc: rtc-s3c: Add device tree support
  input: samsung-keypad: Add device tree support
  ARM: S5PV210: Modify platform data for pl330 driver
  ARM: S5PC100: Modify platform data for pl330 driver
  ARM: S5P64x0: Modify platform data for pl330 driver
  ARM: EXYNOS: Add a alias for pdma clocks
  ARM: EXYNOS: Limit usage of pl330 device instance to non-dt build
  ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
  DMA: PL330: Add device tree support
  ARM: EXYNOS: Modify platform data for pl330 driver
  DMA: PL330: Infer transfer direction from transfer request instead of platform data
  DMA: PL330: move filter function into driver
  serial: samsung: Fix build for non-Exynos4210 devices
  serial: samsung: add device tree support
  serial: samsung: merge probe() function from all SoC specific extensions
  serial: samsung: merge all SoC specific port reset functions
  ARM: SAMSUNG: register uart clocks to clock lookup list
  serial: samsung: remove all uses of get_clksrc and set_clksrc
  ...

Fix up fairly trivial conflicts in arch/arm/mach-s3c2440/clock.c and
drivers/tty/serial/Kconfig both due to just adding code close to
changes.
This commit is contained in:
Linus Torvalds 2012-01-09 14:28:38 -08:00
commit dfc1ebe766
74 changed files with 3015 additions and 2247 deletions

View file

@ -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
@ -116,6 +117,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 +271,32 @@ 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)
{
u8 *peri_id;
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;
}
EXPORT_SYMBOL(pl330_filter);
static int pl330_alloc_chan_resources(struct dma_chan *chan)
{
struct dma_pl330_chan *pch = to_pchan(chan);
@ -497,7 +527,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 */
@ -522,13 +552,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);
@ -615,12 +639,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;
@ -646,16 +672,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);
@ -664,6 +686,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;
@ -692,25 +715,14 @@ 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))
if (unlikely(!pch || !sgl || !sg_len))
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__);
return NULL;
}
addr = pch->fifo_addr;
first = NULL;
@ -750,11 +762,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));
}
@ -856,32 +870,16 @@ 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];
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;
}
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);
@ -894,6 +892,15 @@ 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);
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;