From cecd87da83869ad4157295b87a2e51e38c3e03bf Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 Mar 2010 14:31:47 +0100 Subject: DMAENGINE: COH 901 318 rename confusing vars This fixes up the code with a lot of comments that make it readable, rename things with opaque names like "data" into something more appropriate, and remove some very confusing BUG() statements. Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/coh901318.c | 103 ++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 38 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 1656fdcdb6c2..20889c98e9b0 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -37,7 +37,7 @@ struct coh901318_desc { struct list_head node; struct scatterlist *sg; unsigned int sg_len; - struct coh901318_lli *data; + struct coh901318_lli *lli; enum dma_data_direction dir; unsigned long flags; }; @@ -283,7 +283,7 @@ static int coh901318_start(struct coh901318_chan *cohc) } static int coh901318_prep_linked_list(struct coh901318_chan *cohc, - struct coh901318_lli *data) + struct coh901318_lli *lli) { int channel = cohc->id; void __iomem *virtbase = cohc->base->virtbase; @@ -292,18 +292,18 @@ static int coh901318_prep_linked_list(struct coh901318_chan *cohc, COH901318_CX_STAT_SPACING*channel) & COH901318_CX_STAT_ACTIVE); - writel(data->src_addr, + writel(lli->src_addr, virtbase + COH901318_CX_SRC_ADDR + COH901318_CX_SRC_ADDR_SPACING * channel); - writel(data->dst_addr, virtbase + + writel(lli->dst_addr, virtbase + COH901318_CX_DST_ADDR + COH901318_CX_DST_ADDR_SPACING * channel); - writel(data->link_addr, virtbase + COH901318_CX_LNK_ADDR + + writel(lli->link_addr, virtbase + COH901318_CX_LNK_ADDR + COH901318_CX_LNK_ADDR_SPACING * channel); - writel(data->control, virtbase + COH901318_CX_CTRL + + writel(lli->control, virtbase + COH901318_CX_CTRL + COH901318_CX_CTRL_SPACING * channel); return 0; @@ -565,29 +565,30 @@ static int coh901318_config(struct coh901318_chan *cohc, */ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc) { - struct coh901318_desc *cohd_que; + struct coh901318_desc *cohd; - /* start queued jobs, if any + /* + * start queued jobs, if any * TODO: transmit all queued jobs in one go */ - cohd_que = coh901318_first_queued(cohc); + cohd = coh901318_first_queued(cohc); - if (cohd_que != NULL) { + if (cohd != NULL) { /* Remove from queue */ - coh901318_desc_remove(cohd_que); + coh901318_desc_remove(cohd); /* initiate DMA job */ cohc->busy = 1; - coh901318_desc_submit(cohc, cohd_que); + coh901318_desc_submit(cohc, cohd); - coh901318_prep_linked_list(cohc, cohd_que->data); + coh901318_prep_linked_list(cohc, cohd->lli); - /* start dma job */ + /* start dma job on this channel */ coh901318_start(cohc); } - return cohd_que; + return cohd; } /* @@ -622,7 +623,7 @@ static void dma_tasklet(unsigned long data) cohc->completed = cohd_fin->desc.cookie; /* release the lli allocation and remove the descriptor */ - coh901318_lli_free(&cohc->base->pool, &cohd_fin->data); + coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli); /* return desc to free-list */ coh901318_desc_remove(cohd_fin); @@ -666,23 +667,44 @@ static void dma_tasklet(unsigned long data) /* called from interrupt context */ static void dma_tc_handle(struct coh901318_chan *cohc) { - BUG_ON(!cohc->allocated && (list_empty(&cohc->active) || - list_empty(&cohc->queue))); - - if (!cohc->allocated) + /* + * If the channel is not allocated, then we shouldn't have + * any TC interrupts on it. + */ + if (!cohc->allocated) { + dev_err(COHC_2_DEV(cohc), "spurious interrupt from " + "unallocated channel\n"); return; + } spin_lock(&cohc->lock); + /* + * When we reach this point, at least one queue item + * should have been moved over from cohc->queue to + * cohc->active and run to completion, that is why we're + * getting a terminal count interrupt is it not? + * If you get this BUG() the most probable cause is that + * the individual nodes in the lli chain have IRQ enabled, + * so check your platform config for lli chain ctrl. + */ + BUG_ON(list_empty(&cohc->active)); + cohc->nbr_active_done++; + /* + * This attempt to take a job from cohc->queue, put it + * into cohc->active and start it. + */ if (coh901318_queue_start(cohc) == NULL) cohc->busy = 0; - BUG_ON(list_empty(&cohc->active)); - spin_unlock(&cohc->lock); + /* + * This tasklet will remove items from cohc->active + * and thus terminates them. + */ if (cohc_chan_conf(cohc)->priority_high) tasklet_hi_schedule(&cohc->tasklet); else @@ -870,7 +892,7 @@ static struct dma_async_tx_descriptor * coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, size_t size, unsigned long flags) { - struct coh901318_lli *data; + struct coh901318_lli *lli; struct coh901318_desc *cohd; unsigned long flg; struct coh901318_chan *cohc = to_coh901318_chan(chan); @@ -892,23 +914,23 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, if ((lli_len << MAX_DMA_PACKET_SIZE_SHIFT) < size) lli_len++; - data = coh901318_lli_alloc(&cohc->base->pool, lli_len); + lli = coh901318_lli_alloc(&cohc->base->pool, lli_len); - if (data == NULL) + if (lli == NULL) goto err; ret = coh901318_lli_fill_memcpy( - &cohc->base->pool, data, src, size, dest, + &cohc->base->pool, lli, src, size, dest, cohc_chan_param(cohc)->ctrl_lli_chained, ctrl_last); if (ret) goto err; - COH_DBG(coh901318_list_print(cohc, data)); + COH_DBG(coh901318_list_print(cohc, lli)); /* Pick a descriptor to handle this transfer */ cohd = coh901318_desc_get(cohc); - cohd->data = data; + cohd->lli = lli; cohd->flags = flags; cohd->desc.tx_submit = coh901318_tx_submit; @@ -926,7 +948,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned long flags) { struct coh901318_chan *cohc = to_coh901318_chan(chan); - struct coh901318_lli *data; + struct coh901318_lli *lli; struct coh901318_desc *cohd; const struct coh901318_params *params; struct scatterlist *sg; @@ -999,13 +1021,13 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } pr_debug("Allocate %d lli:s for this transfer\n", len); - data = coh901318_lli_alloc(&cohc->base->pool, len); + lli = coh901318_lli_alloc(&cohc->base->pool, len); - if (data == NULL) + if (lli == NULL) goto err_dma_alloc; - /* initiate allocated data list */ - ret = coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len, + /* initiate allocated lli list */ + ret = coh901318_lli_fill_sg(&cohc->base->pool, lli, sgl, sg_len, cohc_dev_addr(cohc), ctrl_chained, ctrl, @@ -1014,14 +1036,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (ret) goto err_lli_fill; - COH_DBG(coh901318_list_print(cohc, data)); + COH_DBG(coh901318_list_print(cohc, lli)); /* Pick a descriptor to handle this transfer */ cohd = coh901318_desc_get(cohc); cohd->dir = direction; cohd->flags = flags; cohd->desc.tx_submit = coh901318_tx_submit; - cohd->data = data; + cohd->lli = lli; spin_unlock_irqrestore(&cohc->lock, flg); @@ -1065,7 +1087,12 @@ coh901318_issue_pending(struct dma_chan *chan) spin_lock_irqsave(&cohc->lock, flags); - /* Busy means that pending jobs are already being processed */ + /* + * Busy means that pending jobs are already being processed, + * and then there is no point in starting the queue: the + * terminal count interrupt on the channel will take the next + * job on the queue and execute it anyway. + */ if (!cohc->busy) coh901318_queue_start(cohc); @@ -1099,7 +1126,7 @@ coh901318_terminate_all(struct dma_chan *chan) while ((cohd = coh901318_first_active_get(cohc))) { /* release the lli allocation*/ - coh901318_lli_free(&cohc->base->pool, &cohd->data); + coh901318_lli_free(&cohc->base->pool, &cohd->lli); /* return desc to free-list */ coh901318_desc_remove(cohd); @@ -1108,7 +1135,7 @@ coh901318_terminate_all(struct dma_chan *chan) while ((cohd = coh901318_first_queued(cohc))) { /* release the lli allocation*/ - coh901318_lli_free(&cohc->base->pool, &cohd->data); + coh901318_lli_free(&cohc->base->pool, &cohd->lli); /* return desc to free-list */ coh901318_desc_remove(cohd); -- cgit v1.2.3 From 84c8447c544bc7579097649273bc3f4e1b5de6af Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 Mar 2010 14:40:30 +0100 Subject: DMAENGINE: COH 901 318 fix bytesleft This makes the function to get the number of bytes left in the ongoing DMA transaction actually work: the old code did not take neither lli:s nor queued jobs into account. Also fix a missing spinlock while we're at it. Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/coh901318.c | 96 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 8 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 20889c98e9b0..f636c4a87c7f 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -408,25 +408,100 @@ coh901318_first_queued(struct coh901318_chan *cohc) return d; } +static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) +{ + struct coh901318_lli *lli = in_lli; + u32 bytes = 0; + + while (lli) { + bytes += lli->control & COH901318_CX_CTRL_TC_VALUE_MASK; + lli = lli->virt_link_addr; + } + return bytes; +} + /* - * DMA start/stop controls + * Get the number of bytes left to transfer on this channel, + * it is unwise to call this before stopping the channel for + * absolute measures, but for a rough guess you can still call + * it. */ u32 coh901318_get_bytes_left(struct dma_chan *chan) { - unsigned long flags; - u32 ret; struct coh901318_chan *cohc = to_coh901318_chan(chan); + struct coh901318_desc *cohd; + struct list_head *pos; + unsigned long flags; + u32 left = 0; + int i = 0; spin_lock_irqsave(&cohc->lock, flags); - /* Read transfer count value */ - ret = readl(cohc->base->virtbase + - COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING * - cohc->id) & COH901318_CX_CTRL_TC_VALUE_MASK; + /* + * If there are many queued jobs, we iterate and add the + * size of them all. We take a special look on the first + * job though, since it is probably active. + */ + list_for_each(pos, &cohc->active) { + /* + * The first job in the list will be working on the + * hardware. The job can be stopped but still active, + * so that the transfer counter is somewhere inside + * the buffer. + */ + cohd = list_entry(pos, struct coh901318_desc, node); + + if (i == 0) { + struct coh901318_lli *lli; + dma_addr_t ladd; + + /* Read current transfer count value */ + left = readl(cohc->base->virtbase + + COH901318_CX_CTRL + + COH901318_CX_CTRL_SPACING * cohc->id) & + COH901318_CX_CTRL_TC_VALUE_MASK; + + /* See if the transfer is linked... */ + ladd = readl(cohc->base->virtbase + + COH901318_CX_LNK_ADDR + + COH901318_CX_LNK_ADDR_SPACING * + cohc->id) & + ~COH901318_CX_LNK_LINK_IMMEDIATE; + /* Single transaction */ + if (!ladd) + continue; + + /* + * Linked transaction, follow the lli, find the + * currently processing lli, and proceed to the next + */ + lli = cohd->lli; + while (lli && lli->link_addr != ladd) + lli = lli->virt_link_addr; + + if (lli) + lli = lli->virt_link_addr; + + /* + * Follow remaining lli links around to count the total + * number of bytes left + */ + left += coh901318_get_bytes_in_lli(lli); + } else { + left += coh901318_get_bytes_in_lli(cohd->lli); + } + i++; + } + + /* Also count bytes in the queued jobs */ + list_for_each(pos, &cohc->queue) { + cohd = list_entry(pos, struct coh901318_desc, node); + left += coh901318_get_bytes_in_lli(cohd->lli); + } spin_unlock_irqrestore(&cohc->lock, flags); - return ret; + return left; } EXPORT_SYMBOL(coh901318_get_bytes_left); @@ -831,6 +906,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) static int coh901318_alloc_chan_resources(struct dma_chan *chan) { struct coh901318_chan *cohc = to_coh901318_chan(chan); + unsigned long flags; dev_vdbg(COHC_2_DEV(cohc), "[%s] DMA channel %d\n", __func__, cohc->id); @@ -838,11 +914,15 @@ static int coh901318_alloc_chan_resources(struct dma_chan *chan) if (chan->client_count > 1) return -EBUSY; + spin_lock_irqsave(&cohc->lock, flags); + coh901318_config(cohc, NULL); cohc->allocated = 1; cohc->completed = chan->cookie = 1; + spin_unlock_irqrestore(&cohc->lock, flags); + return 1; } -- cgit v1.2.3 From de5d4453c5b224eefd02b6a141ed411a76d458af Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Thu, 25 Mar 2010 19:44:21 +0100 Subject: dma: Add timb-dma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the support for the DMA engine withing the timberdale FPGA. The DMA channels are strict device to host, or host to device and can not be used for generic memcpy. Signed-off-by: Richard Röjfors Signed-off-by: Dan Williams --- drivers/dma/Kconfig | 7 + drivers/dma/Makefile | 1 + drivers/dma/timb_dma.c | 853 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/timb_dma.h | 55 +++ 4 files changed, 916 insertions(+) create mode 100644 drivers/dma/timb_dma.c create mode 100644 include/linux/timb_dma.h (limited to 'drivers/dma') diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index c27f80e5d531..a2fcb2ead892 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -149,6 +149,13 @@ config AMCC_PPC440SPE_ADMA help Enable support for the AMCC PPC440SPe RAID engines. +config TIMB_DMA + tristate "Timberdale FPGA DMA support" + depends on MFD_TIMBERDALE || HAS_IOMEM + select DMA_ENGINE + help + Enable support for the Timberdale FPGA DMA engine. + config ARCH_HAS_ASYNC_TX_FIND_CHANNEL bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 22bba3d5e2b6..40c627d8f73b 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ +obj-$(CONFIG_TIMB_DMA) += timb_dma.o diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c new file mode 100644 index 000000000000..4dd710246c79 --- /dev/null +++ b/drivers/dma/timb_dma.c @@ -0,0 +1,853 @@ +/* + * timb_dma.c timberdale FPGA DMA driver + * Copyright (c) 2010 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Supports: + * Timberdale FPGA DMA engine + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "timb-dma" + +/* Global DMA registers */ +#define TIMBDMA_ACR 0x34 +#define TIMBDMA_32BIT_ADDR 0x01 + +#define TIMBDMA_ISR 0x080000 +#define TIMBDMA_IPR 0x080004 +#define TIMBDMA_IER 0x080008 + +/* Channel specific registers */ +/* RX instances base addresses are 0x00, 0x40, 0x80 ... + * TX instances base addresses are 0x18, 0x58, 0x98 ... + */ +#define TIMBDMA_INSTANCE_OFFSET 0x40 +#define TIMBDMA_INSTANCE_TX_OFFSET 0x18 + +/* RX registers, relative the instance base */ +#define TIMBDMA_OFFS_RX_DHAR 0x00 +#define TIMBDMA_OFFS_RX_DLAR 0x04 +#define TIMBDMA_OFFS_RX_LR 0x0C +#define TIMBDMA_OFFS_RX_BLR 0x10 +#define TIMBDMA_OFFS_RX_ER 0x14 +#define TIMBDMA_RX_EN 0x01 +/* bytes per Row, video specific register + * which is placed after the TX registers... + */ +#define TIMBDMA_OFFS_RX_BPRR 0x30 + +/* TX registers, relative the instance base */ +#define TIMBDMA_OFFS_TX_DHAR 0x00 +#define TIMBDMA_OFFS_TX_DLAR 0x04 +#define TIMBDMA_OFFS_TX_BLR 0x0C +#define TIMBDMA_OFFS_TX_LR 0x14 + + +#define TIMB_DMA_DESC_SIZE 8 + +struct timb_dma_desc { + struct list_head desc_node; + struct dma_async_tx_descriptor txd; + u8 *desc_list; + unsigned int desc_list_len; + bool interrupt; +}; + +struct timb_dma_chan { + struct dma_chan chan; + void __iomem *membase; + spinlock_t lock; /* Used for mutual exclusion */ + dma_cookie_t last_completed_cookie; + bool ongoing; + struct list_head active_list; + struct list_head queue; + struct list_head free_list; + unsigned int bytes_per_line; + enum dma_data_direction direction; + unsigned int descs; /* Descriptors to allocate */ + unsigned int desc_elems; /* number of elems per descriptor */ +}; + +struct timb_dma { + struct dma_device dma; + void __iomem *membase; + struct tasklet_struct tasklet; + struct timb_dma_chan channels[0]; +}; + +static struct device *chan2dev(struct dma_chan *chan) +{ + return &chan->dev->device; +} +static struct device *chan2dmadev(struct dma_chan *chan) +{ + return chan2dev(chan)->parent->parent; +} + +static struct timb_dma *tdchantotd(struct timb_dma_chan *td_chan) +{ + int id = td_chan->chan.chan_id; + return (struct timb_dma *)((u8 *)td_chan - + id * sizeof(struct timb_dma_chan) - sizeof(struct timb_dma)); +} + +/* Must be called with the spinlock held */ +static void __td_enable_chan_irq(struct timb_dma_chan *td_chan) +{ + int id = td_chan->chan.chan_id; + struct timb_dma *td = tdchantotd(td_chan); + u32 ier; + + /* enable interrupt for this channel */ + ier = ioread32(td->membase + TIMBDMA_IER); + ier |= 1 << id; + dev_dbg(chan2dev(&td_chan->chan), "Enabling irq: %d, IER: 0x%x\n", id, + ier); + iowrite32(ier, td->membase + TIMBDMA_IER); +} + +/* Should be called with the spinlock held */ +static bool __td_dma_done_ack(struct timb_dma_chan *td_chan) +{ + int id = td_chan->chan.chan_id; + struct timb_dma *td = (struct timb_dma *)((u8 *)td_chan - + id * sizeof(struct timb_dma_chan) - sizeof(struct timb_dma)); + u32 isr; + bool done = false; + + dev_dbg(chan2dev(&td_chan->chan), "Checking irq: %d, td: %p\n", id, td); + + isr = ioread32(td->membase + TIMBDMA_ISR) & (1 << id); + if (isr) { + iowrite32(isr, td->membase + TIMBDMA_ISR); + done = true; + } + + return done; +} + +static void __td_unmap_desc(struct timb_dma_chan *td_chan, const u8 *dma_desc, + bool single) +{ + dma_addr_t addr; + int len; + + addr = (dma_desc[7] << 24) | (dma_desc[6] << 16) | (dma_desc[5] << 8) | + dma_desc[4]; + + len = (dma_desc[3] << 8) | dma_desc[2]; + + if (single) + dma_unmap_single(chan2dev(&td_chan->chan), addr, len, + td_chan->direction); + else + dma_unmap_page(chan2dev(&td_chan->chan), addr, len, + td_chan->direction); +} + +static void __td_unmap_descs(struct timb_dma_desc *td_desc, bool single) +{ + struct timb_dma_chan *td_chan = container_of(td_desc->txd.chan, + struct timb_dma_chan, chan); + u8 *descs; + + for (descs = td_desc->desc_list; ; descs += TIMB_DMA_DESC_SIZE) { + __td_unmap_desc(td_chan, descs, single); + if (descs[0] & 0x02) + break; + } +} + +static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, + struct scatterlist *sg, bool last) +{ + if (sg_dma_len(sg) > USHORT_MAX) { + dev_err(chan2dev(&td_chan->chan), "Too big sg element\n"); + return -EINVAL; + } + + /* length must be word aligned */ + if (sg_dma_len(sg) % sizeof(u32)) { + dev_err(chan2dev(&td_chan->chan), "Incorrect length: %d\n", + sg_dma_len(sg)); + return -EINVAL; + } + + dev_dbg(chan2dev(&td_chan->chan), "desc: %p, addr: %p\n", + dma_desc, (void *)(int)sg_dma_address(sg)); + + dma_desc[7] = (sg_dma_address(sg) >> 24) & 0xff; + dma_desc[6] = (sg_dma_address(sg) >> 16) & 0xff; + dma_desc[5] = (sg_dma_address(sg) >> 8) & 0xff; + dma_desc[4] = (sg_dma_address(sg) >> 0) & 0xff; + + dma_desc[3] = (sg_dma_len(sg) >> 8) & 0xff; + dma_desc[2] = (sg_dma_len(sg) >> 0) & 0xff; + + dma_desc[1] = 0x00; + dma_desc[0] = 0x21 | (last ? 0x02 : 0); /* tran, valid */ + + return 0; +} + +/* Must be called with the spinlock held */ +static void __td_start_dma(struct timb_dma_chan *td_chan) +{ + struct timb_dma_desc *td_desc; + + if (td_chan->ongoing) { + dev_err(chan2dev(&td_chan->chan), + "Transfer already ongoing\n"); + return; + } + + td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc, + desc_node); + + dev_dbg(chan2dev(&td_chan->chan), + "td_chan: %p, chan: %d, membase: %p\n", + td_chan, td_chan->chan.chan_id, td_chan->membase); + + if (td_chan->direction == DMA_FROM_DEVICE) { + + /* descriptor address */ + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_RX_DHAR); + iowrite32(td_desc->txd.phys, td_chan->membase + + TIMBDMA_OFFS_RX_DLAR); + /* Bytes per line */ + iowrite32(td_chan->bytes_per_line, td_chan->membase + + TIMBDMA_OFFS_RX_BPRR); + /* enable RX */ + iowrite32(TIMBDMA_RX_EN, td_chan->membase + TIMBDMA_OFFS_RX_ER); + } else { + /* address high */ + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DHAR); + iowrite32(td_desc->txd.phys, td_chan->membase + + TIMBDMA_OFFS_TX_DLAR); + } + + td_chan->ongoing = true; + + if (td_desc->interrupt) + __td_enable_chan_irq(td_chan); +} + +static void __td_finish(struct timb_dma_chan *td_chan) +{ + dma_async_tx_callback callback; + void *param; + struct dma_async_tx_descriptor *txd; + struct timb_dma_desc *td_desc; + + /* can happen if the descriptor is canceled */ + if (list_empty(&td_chan->active_list)) + return; + + td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc, + desc_node); + txd = &td_desc->txd; + + dev_dbg(chan2dev(&td_chan->chan), "descriptor %u complete\n", + txd->cookie); + + /* make sure to stop the transfer */ + if (td_chan->direction == DMA_FROM_DEVICE) + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_RX_ER); +/* Currently no support for stopping DMA transfers + else + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR); +*/ + td_chan->last_completed_cookie = txd->cookie; + td_chan->ongoing = false; + + callback = txd->callback; + param = txd->callback_param; + + list_move(&td_desc->desc_node, &td_chan->free_list); + + if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) + __td_unmap_descs(td_desc, + txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE); + + /* + * The API requires that no submissions are done from a + * callback, so we don't need to drop the lock here + */ + if (callback) + callback(param); +} + +static u32 __td_ier_mask(struct timb_dma *td) +{ + int i; + u32 ret = 0; + + for (i = 0; i < td->dma.chancnt; i++) { + struct timb_dma_chan *td_chan = td->channels + i; + if (td_chan->ongoing) { + struct timb_dma_desc *td_desc = + list_entry(td_chan->active_list.next, + struct timb_dma_desc, desc_node); + if (td_desc->interrupt) + ret |= 1 << i; + } + } + + return ret; +} + +static void __td_start_next(struct timb_dma_chan *td_chan) +{ + struct timb_dma_desc *td_desc; + + BUG_ON(list_empty(&td_chan->queue)); + BUG_ON(td_chan->ongoing); + + td_desc = list_entry(td_chan->queue.next, struct timb_dma_desc, + desc_node); + + dev_dbg(chan2dev(&td_chan->chan), "%s: started %u\n", + __func__, td_desc->txd.cookie); + + list_move(&td_desc->desc_node, &td_chan->active_list); + __td_start_dma(td_chan); +} + +static dma_cookie_t td_tx_submit(struct dma_async_tx_descriptor *txd) +{ + struct timb_dma_desc *td_desc = container_of(txd, struct timb_dma_desc, + txd); + struct timb_dma_chan *td_chan = container_of(txd->chan, + struct timb_dma_chan, chan); + dma_cookie_t cookie; + + spin_lock_bh(&td_chan->lock); + + cookie = txd->chan->cookie; + if (++cookie < 0) + cookie = 1; + txd->chan->cookie = cookie; + txd->cookie = cookie; + + if (list_empty(&td_chan->active_list)) { + dev_dbg(chan2dev(txd->chan), "%s: started %u\n", __func__, + txd->cookie); + list_add_tail(&td_desc->desc_node, &td_chan->active_list); + __td_start_dma(td_chan); + } else { + dev_dbg(chan2dev(txd->chan), "tx_submit: queued %u\n", + txd->cookie); + + list_add_tail(&td_desc->desc_node, &td_chan->queue); + } + + spin_unlock_bh(&td_chan->lock); + + return cookie; +} + +static struct timb_dma_desc *td_alloc_init_desc(struct timb_dma_chan *td_chan) +{ + struct dma_chan *chan = &td_chan->chan; + struct timb_dma_desc *td_desc; + int err; + + td_desc = kzalloc(sizeof(struct timb_dma_desc), GFP_KERNEL); + if (!td_desc) { + dev_err(chan2dev(chan), "Failed to alloc descriptor\n"); + goto err; + } + + td_desc->desc_list_len = td_chan->desc_elems * TIMB_DMA_DESC_SIZE; + + td_desc->desc_list = kzalloc(td_desc->desc_list_len, GFP_KERNEL); + if (!td_desc->desc_list) { + dev_err(chan2dev(chan), "Failed to alloc descriptor\n"); + goto err; + } + + dma_async_tx_descriptor_init(&td_desc->txd, chan); + td_desc->txd.tx_submit = td_tx_submit; + td_desc->txd.flags = DMA_CTRL_ACK; + + td_desc->txd.phys = dma_map_single(chan2dmadev(chan), + td_desc->desc_list, td_desc->desc_list_len, DMA_TO_DEVICE); + + err = dma_mapping_error(chan2dmadev(chan), td_desc->txd.phys); + if (err) { + dev_err(chan2dev(chan), "DMA mapping error: %d\n", err); + goto err; + } + + return td_desc; +err: + kfree(td_desc->desc_list); + kfree(td_desc); + + return NULL; + +} + +static void td_free_desc(struct timb_dma_desc *td_desc) +{ + dev_dbg(chan2dev(td_desc->txd.chan), "Freeing desc: %p\n", td_desc); + dma_unmap_single(chan2dmadev(td_desc->txd.chan), td_desc->txd.phys, + td_desc->desc_list_len, DMA_TO_DEVICE); + + kfree(td_desc->desc_list); + kfree(td_desc); +} + +static void td_desc_put(struct timb_dma_chan *td_chan, + struct timb_dma_desc *td_desc) +{ + dev_dbg(chan2dev(&td_chan->chan), "Putting desc: %p\n", td_desc); + + spin_lock_bh(&td_chan->lock); + list_add(&td_desc->desc_node, &td_chan->free_list); + spin_unlock_bh(&td_chan->lock); +} + +static struct timb_dma_desc *td_desc_get(struct timb_dma_chan *td_chan) +{ + struct timb_dma_desc *td_desc, *_td_desc; + struct timb_dma_desc *ret = NULL; + + spin_lock_bh(&td_chan->lock); + list_for_each_entry_safe(td_desc, _td_desc, &td_chan->free_list, + desc_node) { + if (async_tx_test_ack(&td_desc->txd)) { + list_del(&td_desc->desc_node); + ret = td_desc; + break; + } + dev_dbg(chan2dev(&td_chan->chan), "desc %p not ACKed\n", + td_desc); + } + spin_unlock_bh(&td_chan->lock); + + return ret; +} + +static int td_alloc_chan_resources(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + int i; + + dev_dbg(chan2dev(chan), "%s: entry\n", __func__); + + BUG_ON(!list_empty(&td_chan->free_list)); + for (i = 0; i < td_chan->descs; i++) { + struct timb_dma_desc *td_desc = td_alloc_init_desc(td_chan); + if (!td_desc) { + if (i) + break; + else { + dev_err(chan2dev(chan), + "Couldnt allocate any descriptors\n"); + return -ENOMEM; + } + } + + td_desc_put(td_chan, td_desc); + } + + spin_lock_bh(&td_chan->lock); + td_chan->last_completed_cookie = 1; + chan->cookie = 1; + spin_unlock_bh(&td_chan->lock); + + return 0; +} + +static void td_free_chan_resources(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + struct timb_dma_desc *td_desc, *_td_desc; + LIST_HEAD(list); + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + + /* check that all descriptors are free */ + BUG_ON(!list_empty(&td_chan->active_list)); + BUG_ON(!list_empty(&td_chan->queue)); + + spin_lock_bh(&td_chan->lock); + list_splice_init(&td_chan->free_list, &list); + spin_unlock_bh(&td_chan->lock); + + list_for_each_entry_safe(td_desc, _td_desc, &list, desc_node) { + dev_dbg(chan2dev(chan), "%s: Freeing desc: %p\n", __func__, + td_desc); + td_free_desc(td_desc); + } +} + +static enum dma_status td_is_tx_complete(struct dma_chan *chan, + dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + int ret; + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + + last_complete = td_chan->last_completed_cookie; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + + if (done) + *done = last_complete; + if (used) + *used = last_used; + + dev_dbg(chan2dev(chan), + "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", + __func__, ret, last_complete, last_used); + + return ret; +} + +static void td_issue_pending(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + spin_lock_bh(&td_chan->lock); + + if (!list_empty(&td_chan->active_list)) + /* transfer ongoing */ + if (__td_dma_done_ack(td_chan)) + __td_finish(td_chan); + + if (list_empty(&td_chan->active_list) && !list_empty(&td_chan->queue)) + __td_start_next(td_chan); + + spin_unlock_bh(&td_chan->lock); +} + +static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, + struct scatterlist *sgl, unsigned int sg_len, + enum dma_data_direction direction, unsigned long flags) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + struct timb_dma_desc *td_desc; + struct scatterlist *sg; + unsigned int i; + unsigned int desc_usage = 0; + + if (!sgl || !sg_len) { + dev_err(chan2dev(chan), "%s: No SG list\n", __func__); + return NULL; + } + + /* even channels are for RX, odd for TX */ + if (td_chan->direction != direction) { + dev_err(chan2dev(chan), + "Requesting channel in wrong direction\n"); + return NULL; + } + + td_desc = td_desc_get(td_chan); + if (!td_desc) { + dev_err(chan2dev(chan), "Not enough descriptors available\n"); + return NULL; + } + + td_desc->interrupt = (flags & DMA_PREP_INTERRUPT) != 0; + + for_each_sg(sgl, sg, sg_len, i) { + int err; + if (desc_usage > td_desc->desc_list_len) { + dev_err(chan2dev(chan), "No descriptor space\n"); + return NULL; + } + + err = td_fill_desc(td_chan, td_desc->desc_list + desc_usage, sg, + i == (sg_len - 1)); + if (err) { + dev_err(chan2dev(chan), "Failed to update desc: %d\n", + err); + td_desc_put(td_chan, td_desc); + return NULL; + } + desc_usage += TIMB_DMA_DESC_SIZE; + } + + dma_sync_single_for_device(chan2dmadev(chan), td_desc->txd.phys, + td_desc->desc_list_len, DMA_TO_DEVICE); + + return &td_desc->txd; +} + +static void td_terminate_all(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + struct timb_dma_desc *td_desc, *_td_desc; + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + + /* first the easy part, put the queue into the free list */ + spin_lock_bh(&td_chan->lock); + list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue, + desc_node) + list_move(&td_desc->desc_node, &td_chan->free_list); + + /* now tear down the runnning */ + __td_finish(td_chan); + spin_unlock_bh(&td_chan->lock); +} + +static void td_tasklet(unsigned long data) +{ + struct timb_dma *td = (struct timb_dma *)data; + u32 isr; + u32 ipr; + u32 ier; + int i; + + isr = ioread32(td->membase + TIMBDMA_ISR); + ipr = isr & __td_ier_mask(td); + + /* ack the interrupts */ + iowrite32(ipr, td->membase + TIMBDMA_ISR); + + for (i = 0; i < td->dma.chancnt; i++) + if (ipr & (1 << i)) { + struct timb_dma_chan *td_chan = td->channels + i; + spin_lock(&td_chan->lock); + __td_finish(td_chan); + if (!list_empty(&td_chan->queue)) + __td_start_next(td_chan); + spin_unlock(&td_chan->lock); + } + + ier = __td_ier_mask(td); + iowrite32(ier, td->membase + TIMBDMA_IER); +} + + +static irqreturn_t td_irq(int irq, void *devid) +{ + struct timb_dma *td = devid; + u32 ipr = ioread32(td->membase + TIMBDMA_IPR); + + if (ipr) { + /* disable interrupts, will be re-enabled in tasklet */ + iowrite32(0, td->membase + TIMBDMA_IER); + + tasklet_schedule(&td->tasklet); + + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + + +static int __devinit td_probe(struct platform_device *pdev) +{ + struct timb_dma_platform_data *pdata = pdev->dev.platform_data; + struct timb_dma *td; + struct resource *iomem; + int irq; + int err; + int i; + + if (!pdata) { + dev_err(&pdev->dev, "No platform data\n"); + return -EINVAL; + } + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) + return -EINVAL; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + if (!request_mem_region(iomem->start, resource_size(iomem), + DRIVER_NAME)) + return -EBUSY; + + td = kzalloc(sizeof(struct timb_dma) + + sizeof(struct timb_dma_chan) * pdata->nr_channels, GFP_KERNEL); + if (!td) { + err = -ENOMEM; + goto err_release_region; + } + + dev_dbg(&pdev->dev, "Allocated TD: %p\n", td); + + td->membase = ioremap(iomem->start, resource_size(iomem)); + if (!td->membase) { + dev_err(&pdev->dev, "Failed to remap I/O memory\n"); + err = -ENOMEM; + goto err_free_mem; + } + + /* 32bit addressing */ + iowrite32(TIMBDMA_32BIT_ADDR, td->membase + TIMBDMA_ACR); + + /* disable and clear any interrupts */ + iowrite32(0x0, td->membase + TIMBDMA_IER); + iowrite32(0xFFFFFFFF, td->membase + TIMBDMA_ISR); + + tasklet_init(&td->tasklet, td_tasklet, (unsigned long)td); + + err = request_irq(irq, td_irq, IRQF_SHARED, DRIVER_NAME, td); + if (err) { + dev_err(&pdev->dev, "Failed to request IRQ\n"); + goto err_tasklet_kill; + } + + td->dma.device_alloc_chan_resources = td_alloc_chan_resources; + td->dma.device_free_chan_resources = td_free_chan_resources; + td->dma.device_is_tx_complete = td_is_tx_complete; + td->dma.device_issue_pending = td_issue_pending; + + dma_cap_set(DMA_SLAVE, td->dma.cap_mask); + dma_cap_set(DMA_PRIVATE, td->dma.cap_mask); + td->dma.device_prep_slave_sg = td_prep_slave_sg; + td->dma.device_terminate_all = td_terminate_all; + + td->dma.dev = &pdev->dev; + + INIT_LIST_HEAD(&td->dma.channels); + + for (i = 0; i < pdata->nr_channels; i++, td->dma.chancnt++) { + struct timb_dma_chan *td_chan = &td->channels[i]; + struct timb_dma_platform_data_channel *pchan = + pdata->channels + i; + + /* even channels are RX, odd are TX */ + if (((i % 2) && pchan->rx) || (!(i % 2) && !pchan->rx)) { + dev_err(&pdev->dev, "Wrong channel configuration\n"); + err = -EINVAL; + goto err_tasklet_kill; + } + + td_chan->chan.device = &td->dma; + td_chan->chan.cookie = 1; + td_chan->chan.chan_id = i; + spin_lock_init(&td_chan->lock); + INIT_LIST_HEAD(&td_chan->active_list); + INIT_LIST_HEAD(&td_chan->queue); + INIT_LIST_HEAD(&td_chan->free_list); + + td_chan->descs = pchan->descriptors; + td_chan->desc_elems = pchan->descriptor_elements; + td_chan->bytes_per_line = pchan->bytes_per_line; + td_chan->direction = pchan->rx ? DMA_FROM_DEVICE : + DMA_TO_DEVICE; + + td_chan->membase = td->membase + + (i / 2) * TIMBDMA_INSTANCE_OFFSET + + (pchan->rx ? 0 : TIMBDMA_INSTANCE_TX_OFFSET); + + dev_dbg(&pdev->dev, "Chan: %d, membase: %p\n", + i, td_chan->membase); + + list_add_tail(&td_chan->chan.device_node, &td->dma.channels); + } + + err = dma_async_device_register(&td->dma); + if (err) { + dev_err(&pdev->dev, "Failed to register async device\n"); + goto err_free_irq; + } + + platform_set_drvdata(pdev, td); + + dev_dbg(&pdev->dev, "Probe result: %d\n", err); + return err; + +err_free_irq: + free_irq(irq, td); +err_tasklet_kill: + tasklet_kill(&td->tasklet); + iounmap(td->membase); +err_free_mem: + kfree(td); +err_release_region: + release_mem_region(iomem->start, resource_size(iomem)); + + return err; + +} + +static int __devexit td_remove(struct platform_device *pdev) +{ + struct timb_dma *td = platform_get_drvdata(pdev); + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int irq = platform_get_irq(pdev, 0); + + dma_async_device_unregister(&td->dma); + free_irq(irq, td); + tasklet_kill(&td->tasklet); + iounmap(td->membase); + kfree(td); + release_mem_region(iomem->start, resource_size(iomem)); + + platform_set_drvdata(pdev, NULL); + + dev_dbg(&pdev->dev, "Removed...\n"); + return 0; +} + +static struct platform_driver td_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = td_probe, + .remove = __exit_p(td_remove), +}; + +static int __init td_init(void) +{ + return platform_driver_register(&td_driver); +} +module_init(td_init); + +static void __exit td_exit(void) +{ + platform_driver_unregister(&td_driver); +} +module_exit(td_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Timberdale DMA controller driver"); +MODULE_AUTHOR("Pelagicore AB "); +MODULE_ALIAS("platform:"DRIVER_NAME); diff --git a/include/linux/timb_dma.h b/include/linux/timb_dma.h new file mode 100644 index 000000000000..bb043e970b96 --- /dev/null +++ b/include/linux/timb_dma.h @@ -0,0 +1,55 @@ +/* + * timb_dma.h timberdale FPGA DMA driver defines + * Copyright (c) 2010 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Supports: + * Timberdale FPGA DMA engine + */ + +#ifndef _LINUX_TIMB_DMA_H +#define _LINUX_TIMB_DMA_H + +/** + * struct timb_dma_platform_data_channel - Description of each individual + * DMA channel for the timberdale DMA driver + * @rx: true if this channel handles data in the direction to + * the CPU. + * @bytes_per_line: Number of bytes per line, this is specific for channels + * handling video data. For other channels this shall be left to 0. + * @descriptors: Number of descriptors to allocate for this channel. + * @descriptor_elements: Number of elements in each descriptor. + * + */ +struct timb_dma_platform_data_channel { + bool rx; + unsigned int bytes_per_line; + unsigned int descriptors; + unsigned int descriptor_elements; +}; + +/** + * struct timb_dma_platform_data - Platform data of the timberdale DMA driver + * @nr_channels: Number of defined channels in the channels array. + * @channels: Definition of the each channel. + * + */ +struct timb_dma_platform_data { + unsigned nr_channels; + struct timb_dma_platform_data_channel channels[32]; +}; + +#endif -- cgit v1.2.3 From 0f65169b1bf44220308e1ce1f6666ad03ddc27af Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Fri, 26 Mar 2010 08:23:58 +0100 Subject: dma: timb-dma: Update comment and fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An incremental patch which clarifies what the spinlock is used for and fixes a compiler warning. Signed-off-by: Richard Röjfors Signed-off-by: Dan Williams --- drivers/dma/timb_dma.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 4dd710246c79..145f1c23408f 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -79,7 +79,10 @@ struct timb_dma_desc { struct timb_dma_chan { struct dma_chan chan; void __iomem *membase; - spinlock_t lock; /* Used for mutual exclusion */ + spinlock_t lock; /* Used to protect data structures, + especially the lists and descriptors, + from races between the tasklet and calls + from above */ dma_cookie_t last_completed_cookie; bool ongoing; struct list_head active_list; @@ -197,7 +200,7 @@ static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, } dev_dbg(chan2dev(&td_chan->chan), "desc: %p, addr: %p\n", - dma_desc, (void *)(int)sg_dma_address(sg)); + dma_desc, (void *)sg_dma_address(sg)); dma_desc[7] = (sg_dma_address(sg) >> 24) & 0xff; dma_desc[6] = (sg_dma_address(sg) >> 16) & 0xff; -- cgit v1.2.3 From c3635c78e500a52c9fcd55de381a72928d9e054d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 26 Mar 2010 16:44:01 -0700 Subject: DMAENGINE: generic slave control v2 Convert the device_terminate_all() operation on the DMA engine to a generic device_control() operation which can now optionally support also pausing and resuming DMA on a certain channel. Implemented for the COH 901 318 DMAC as an example. [dan.j.williams@intel.com: update for timberdale] Signed-off-by: Linus Walleij Acked-by: Mark Brown Cc: Maciej Sosnowski Cc: Nicolas Ferre Cc: Pavel Machek Cc: Li Yang Cc: Guennadi Liakhovetski Cc: Paul Mundt Cc: Ralf Baechle Cc: Haavard Skinnemoen Cc: Magnus Damm Cc: Liam Girdwood Cc: Joe Perches Cc: Roland Dreier Signed-off-by: Dan Williams --- arch/arm/mach-u300/include/mach/coh901318.h | 14 ---------- drivers/dma/at_hdmac.c | 10 +++++-- drivers/dma/coh901318.c | 42 +++++++++++++++++++---------- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw_dmac.c | 10 +++++-- drivers/dma/fsldma.c | 13 ++++++--- drivers/dma/ipu/ipu_idmac.c | 21 ++++++++++----- drivers/dma/shdma.c | 12 ++++++--- drivers/dma/timb_dma.c | 9 +++++-- drivers/dma/txx9dmac.c | 10 +++++-- drivers/mmc/host/atmel-mci.c | 2 +- drivers/serial/sh-sci.c | 2 +- drivers/video/mx3fb.c | 3 ++- include/linux/dmaengine.h | 18 +++++++++++-- sound/soc/txx9/txx9aclc.c | 6 ++--- 15 files changed, 117 insertions(+), 57 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index b8155b4e5ffa..43ec040e765b 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -109,20 +109,6 @@ struct coh901318_platform { */ u32 coh901318_get_bytes_left(struct dma_chan *chan); -/** - * coh901318_stop() - Stops dma transfer - * @chan: dma channel handle - * return 0 on success otherwise negative value - */ -void coh901318_stop(struct dma_chan *chan); - -/** - * coh901318_continue() - Resumes a stopped dma transfer - * @chan: dma channel handle - * return 0 on success otherwise negative value - */ -void coh901318_continue(struct dma_chan *chan); - /** * coh901318_filter_id() - DMA channel filter function * @chan: dma channel handle diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index efc1a61ca231..f9143cf9e50a 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -759,13 +759,17 @@ err_desc_get: return NULL; } -static void atc_terminate_all(struct dma_chan *chan) +static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); struct at_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* * This is only called when something went wrong elsewhere, so * we don't really care about the data. Just disable the @@ -789,6 +793,8 @@ static void atc_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) atc_chain_complete(atchan, desc); + + return 0; } /** @@ -1091,7 +1097,7 @@ static int __init at_dma_probe(struct platform_device *pdev) if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) { atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; - atdma->dma_common.device_terminate_all = atc_terminate_all; + atdma->dma_common.device_control = atc_control; } dma_writel(atdma, EN, AT_DMA_ENABLE); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index f636c4a87c7f..53c54e034aa3 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -506,10 +506,11 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) EXPORT_SYMBOL(coh901318_get_bytes_left); -/* Stops a transfer without losing data. Enables power save. - Use this function in conjunction with coh901318_continue(..) -*/ -void coh901318_stop(struct dma_chan *chan) +/* + * Pauses a transfer without losing data. Enables power save. + * Use this function in conjunction with coh901318_resume. + */ +static void coh901318_pause(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -550,12 +551,11 @@ void coh901318_stop(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -EXPORT_SYMBOL(coh901318_stop); -/* Continues a transfer that has been stopped via 300_dma_stop(..). +/* Resumes a transfer that has been stopped via 300_dma_stop(..). Power save is handled. */ -void coh901318_continue(struct dma_chan *chan) +static void coh901318_resume(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -581,7 +581,6 @@ void coh901318_continue(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -EXPORT_SYMBOL(coh901318_continue); bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) { @@ -945,7 +944,7 @@ coh901318_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); } @@ -1179,16 +1178,29 @@ coh901318_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -static void -coh901318_terminate_all(struct dma_chan *chan) +static int +coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { unsigned long flags; struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_desc *cohd; void __iomem *virtbase = cohc->base->virtbase; - coh901318_stop(chan); + if (cmd == DMA_PAUSE) { + coh901318_pause(chan); + return 0; + } + + if (cmd == DMA_RESUME) { + coh901318_resume(chan); + return 0; + } + + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* The remainder of this function terminates the transfer */ + coh901318_pause(chan); spin_lock_irqsave(&cohc->lock, flags); /* Clear any pending BE or TC interrupt */ @@ -1227,6 +1239,8 @@ coh901318_terminate_all(struct dma_chan *chan) cohc->busy = 0; spin_unlock_irqrestore(&cohc->lock, flags); + + return 0; } void coh901318_base_init(struct dma_device *dma, const int *pick_chans, struct coh901318_base *base) @@ -1344,7 +1358,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; base->dma_slave.device_issue_pending = coh901318_issue_pending; - base->dma_slave.device_terminate_all = coh901318_terminate_all; + base->dma_slave.device_control = coh901318_control; base->dma_slave.dev = &pdev->dev; err = dma_async_device_register(&base->dma_slave); @@ -1364,7 +1378,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; base->dma_memcpy.device_issue_pending = coh901318_issue_pending; - base->dma_memcpy.device_terminate_all = coh901318_terminate_all; + base->dma_memcpy.device_control = coh901318_control; base->dma_memcpy.dev = &pdev->dev; /* * This controller can only access address at even 32bit boundaries, diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 87399cafce37..ffc4ee9c5e21 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -694,7 +694,7 @@ int dma_async_device_register(struct dma_device *device) BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && !device->device_prep_slave_sg); BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && - !device->device_terminate_all); + !device->device_control); BUG_ON(!device->device_alloc_chan_resources); BUG_ON(!device->device_free_chan_resources); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index d28369f7afd2..8a6b85f61176 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -781,13 +781,17 @@ err_desc_get: return NULL; } -static void dwc_terminate_all(struct dma_chan *chan) +static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma *dw = to_dw_dma(chan->device); struct dw_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* * This is only called when something went wrong elsewhere, so * we don't really care about the data. Just disable the @@ -810,6 +814,8 @@ static void dwc_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) dwc_descriptor_complete(dwc, desc); + + return 0; } static enum dma_status @@ -1338,7 +1344,7 @@ static int __init dw_probe(struct platform_device *pdev) dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy; dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; - dw->dma.device_terminate_all = dwc_terminate_all; + dw->dma.device_control = dwc_control; dw->dma.device_is_tx_complete = dwc_is_tx_complete; dw->dma.device_issue_pending = dwc_issue_pending; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index bbb4be5a3ff4..714fc46e7695 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -774,13 +774,18 @@ fail: return NULL; } -static void fsl_dma_device_terminate_all(struct dma_chan *dchan) +static int fsl_dma_device_control(struct dma_chan *dchan, + enum dma_ctrl_cmd cmd) { struct fsldma_chan *chan; unsigned long flags; + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + if (!dchan) - return; + return -EINVAL; chan = to_fsl_chan(dchan); @@ -794,6 +799,8 @@ static void fsl_dma_device_terminate_all(struct dma_chan *dchan) fsldma_free_desc_list(chan, &chan->ld_running); spin_unlock_irqrestore(&chan->desc_lock, flags); + + return 0; } /** @@ -1332,7 +1339,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, fdev->common.device_is_tx_complete = fsl_dma_is_complete; fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; - fdev->common.device_terminate_all = fsl_dma_device_terminate_all; + fdev->common.device_control = fsl_dma_device_control; fdev->common.dev = &op->dev; dev_set_drvdata(&op->dev, fdev); diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 2a446397c884..39e7fb2a90e3 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1472,13 +1472,17 @@ static void idmac_issue_pending(struct dma_chan *chan) */ } -static void __idmac_terminate_all(struct dma_chan *chan) +static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct idmac_channel *ichan = to_idmac_chan(chan); struct idmac *idmac = to_idmac(chan->device); unsigned long flags; int i; + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + ipu_disable_channel(idmac, ichan, ichan->status >= IPU_CHANNEL_ENABLED); @@ -1505,17 +1509,22 @@ static void __idmac_terminate_all(struct dma_chan *chan) tasklet_enable(&to_ipu(idmac)->tasklet); ichan->status = IPU_CHANNEL_INITIALIZED; + + return 0; } -static void idmac_terminate_all(struct dma_chan *chan) +static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct idmac_channel *ichan = to_idmac_chan(chan); + int ret; mutex_lock(&ichan->chan_mutex); - __idmac_terminate_all(chan); + ret = __idmac_control(chan, cmd); mutex_unlock(&ichan->chan_mutex); + + return ret; } #ifdef DEBUG @@ -1607,7 +1616,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan) mutex_lock(&ichan->chan_mutex); - __idmac_terminate_all(chan); + __idmac_control(chan, DMA_TERMINATE_ALL); if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG @@ -1669,7 +1678,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) /* Compulsory for DMA_SLAVE fields */ dma->device_prep_slave_sg = idmac_prep_slave_sg; - dma->device_terminate_all = idmac_terminate_all; + dma->device_control = idmac_control; INIT_LIST_HEAD(&dma->channels); for (i = 0; i < IPU_CHANNELS_NUM; i++) { @@ -1703,7 +1712,7 @@ static void __exit ipu_idmac_exit(struct ipu *ipu) for (i = 0; i < IPU_CHANNELS_NUM; i++) { struct idmac_channel *ichan = ipu->channel + i; - idmac_terminate_all(&ichan->dma_chan); + idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL); idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 5d17e09cb625..ce28c1e22825 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -580,12 +580,16 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( direction, flags); } -static void sh_dmae_terminate_all(struct dma_chan *chan) +static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + if (!chan) - return; + return -EINVAL; dmae_halt(sh_chan); @@ -601,6 +605,8 @@ static void sh_dmae_terminate_all(struct dma_chan *chan) spin_unlock_bh(&sh_chan->desc_lock); sh_dmae_chan_ld_cleanup(sh_chan, true); + + return 0; } static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) @@ -1029,7 +1035,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) /* Compulsory for DMA_SLAVE fields */ shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg; - shdev->common.device_terminate_all = sh_dmae_terminate_all; + shdev->common.device_control = sh_dmae_control; shdev->common.dev = &pdev->dev; /* Default transfer size of 32 bytes requires 32-byte alignment */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 145f1c23408f..7c06471ef863 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -613,7 +613,7 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, return &td_desc->txd; } -static void td_terminate_all(struct dma_chan *chan) +static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); @@ -621,6 +621,9 @@ static void td_terminate_all(struct dma_chan *chan) dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* first the easy part, put the queue into the free list */ spin_lock_bh(&td_chan->lock); list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue, @@ -630,6 +633,8 @@ static void td_terminate_all(struct dma_chan *chan) /* now tear down the runnning */ __td_finish(td_chan); spin_unlock_bh(&td_chan->lock); + + return 0; } static void td_tasklet(unsigned long data) @@ -743,7 +748,7 @@ static int __devinit td_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, td->dma.cap_mask); dma_cap_set(DMA_PRIVATE, td->dma.cap_mask); td->dma.device_prep_slave_sg = td_prep_slave_sg; - td->dma.device_terminate_all = td_terminate_all; + td->dma.device_control = td_control; td->dma.dev = &pdev->dev; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 3ebc61067e54..e528e15f44ab 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -938,12 +938,16 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return &first->txd; } -static void txx9dmac_terminate_all(struct dma_chan *chan) +static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); struct txx9dmac_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -EINVAL; + dev_vdbg(chan2dev(chan), "terminate_all\n"); spin_lock_bh(&dc->lock); @@ -958,6 +962,8 @@ static void txx9dmac_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) txx9dmac_descriptor_complete(dc, desc); + + return 0; } static enum dma_status @@ -1153,7 +1159,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) dc->dma.dev = &pdev->dev; dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; - dc->dma.device_terminate_all = txx9dmac_terminate_all; + dc->dma.device_control = txx9dmac_control; dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; dc->dma.device_issue_pending = txx9dmac_issue_pending; if (pdata && pdata->memcpy_chan == ch) { diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8072128e933b..ae6d24ba4f08 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -578,7 +578,7 @@ static void atmci_stop_dma(struct atmel_mci *host) struct dma_chan *chan = host->data_chan; if (chan) { - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); atmci_dma_cleanup(host); } else { /* Data transfer was stopped by the interrupt handler */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f7b9aff88f4a..690988237971 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1087,7 +1087,7 @@ static void work_fn_rx(struct work_struct *work) unsigned long flags; int count; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); dev_dbg(port->dev, "Read %u bytes with cookie %d\n", sh_desc->partial, sh_desc->cookie); diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 772ba3f45e6f..3aa50bc276eb 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -387,7 +387,8 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_unlock_irqrestore(&mx3fb->lock, flags); - mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); + mx3_fbi->txd->chan->device->device_control(mx3_fbi->txd->chan, + DMA_TERMINATE_ALL); mx3_fbi->txd = NULL; mx3_fbi->cookie = -EINVAL; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 20ea12c86fd0..0731802f876f 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -106,6 +106,19 @@ enum dma_ctrl_flags { DMA_PREP_FENCE = (1 << 9), }; +/** + * enum dma_ctrl_cmd - DMA operations that can optionally be exercised + * on a running channel. + * @DMA_TERMINATE_ALL: terminate all ongoing transfers + * @DMA_PAUSE: pause ongoing transfers + * @DMA_RESUME: resume paused transfer + */ +enum dma_ctrl_cmd { + DMA_TERMINATE_ALL, + DMA_PAUSE, + DMA_RESUME, +}; + /** * enum sum_check_bits - bit position of pq_check_flags */ @@ -261,7 +274,8 @@ struct dma_async_tx_descriptor { * @device_prep_dma_memset: prepares a memset operation * @device_prep_dma_interrupt: prepares an end of chain interrupt operation * @device_prep_slave_sg: prepares a slave dma operation - * @device_terminate_all: terminate all pending operations + * @device_control: manipulate all pending operations on a channel, returns + * zero or error code * @device_is_tx_complete: poll for transaction completion * @device_issue_pending: push pending transactions to hardware */ @@ -313,7 +327,7 @@ struct dma_device { struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); - void (*device_terminate_all)(struct dma_chan *chan); + int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index efed64b8b026..b35d00706c0e 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -159,7 +159,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -267,7 +267,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); return 0; } @@ -396,7 +396,7 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; -- cgit v1.2.3 From 0793448187643b50af89d36b08470baf45a3cab4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 26 Mar 2010 16:50:49 -0700 Subject: DMAENGINE: generic channel status v2 Convert the device_is_tx_complete() operation on the DMA engine to a generic device_tx_status()operation which can return three states, DMA_TX_RUNNING, DMA_TX_COMPLETE, DMA_TX_PAUSED. [dan.j.williams@intel.com: update for timberdale] Signed-off-by: Linus Walleij Acked-by: Mark Brown Cc: Maciej Sosnowski Cc: Nicolas Ferre Cc: Pavel Machek Cc: Li Yang Cc: Guennadi Liakhovetski Cc: Paul Mundt Cc: Ralf Baechle Cc: Haavard Skinnemoen Cc: Magnus Damm Cc: Liam Girdwood Cc: Joe Perches Cc: Roland Dreier Signed-off-by: Dan Williams --- arch/arm/mach-u300/include/mach/coh901318.h | 7 ----- drivers/dma/at_hdmac.c | 29 ++++++++++--------- drivers/dma/coh901318.c | 25 ++++++++-------- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw_dmac.c | 17 +++++------ drivers/dma/fsldma.c | 19 ++++++------- drivers/dma/ioat/dma.c | 12 ++++---- drivers/dma/ioat/dma.h | 22 +++++++-------- drivers/dma/ioat/dma_v2.c | 2 +- drivers/dma/ioat/dma_v3.c | 20 ++++++------- drivers/dma/iop-adma.c | 44 +++++++++++++++-------------- drivers/dma/ipu/ipu_idmac.c | 15 +++++----- drivers/dma/mpc512x_dma.c | 16 +++++------ drivers/dma/mv_xor.c | 32 +++++++++++---------- drivers/dma/ppc4xx/adma.c | 27 ++++++++++-------- drivers/dma/shdma.c | 17 ++++++----- drivers/dma/timb_dma.c | 15 +++++----- drivers/dma/txx9dmac.c | 16 +++++------ include/linux/dmaengine.h | 38 +++++++++++++++++++++---- 19 files changed, 203 insertions(+), 172 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 43ec040e765b..193da2df732c 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -102,13 +102,6 @@ struct coh901318_platform { const int max_channels; }; -/** - * coh901318_get_bytes_left() - Get number of bytes left on a current transfer - * @chan: dma channel handle - * return number of bytes left, or negative on error - */ -u32 coh901318_get_bytes_left(struct dma_chan *chan); - /** * coh901318_filter_id() - DMA channel filter function * @chan: dma channel handle diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index f9143cf9e50a..ff75cf18d32e 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -798,29 +798,25 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } /** - * atc_is_tx_complete - poll for transaction completion + * atc_tx_status - poll for transaction completion * @chan: DMA channel * @cookie: transaction identifier to check status of - * @done: if not %NULL, updated with last completed transaction - * @used: if not %NULL, updated with last used transaction + * @txstate: if not %NULL updated with transaction state * - * If @done and @used are passed in, upon return they reflect the driver + * If @txstate is passed in, upon return it reflect the driver * internal state and can be used with dma_async_is_complete() to check * the status of multiple cookies without re-checking hardware state. */ static enum dma_status -atc_is_tx_complete(struct dma_chan *chan, +atc_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) + struct dma_tx_state *txstate) { struct at_dma_chan *atchan = to_at_dma_chan(chan); dma_cookie_t last_used; dma_cookie_t last_complete; enum dma_status ret; - dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", - cookie, done ? *done : 0, used ? *used : 0); - spin_lock_bh(&atchan->lock); last_complete = atchan->completed_cookie; @@ -838,10 +834,15 @@ atc_is_tx_complete(struct dma_chan *chan, spin_unlock_bh(&atchan->lock); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } + + dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", + cookie, last_complete ? last_complete : 0, + last_used ? last_used : 0); return ret; } @@ -1087,7 +1088,7 @@ static int __init at_dma_probe(struct platform_device *pdev) /* set base routines */ atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources; atdma->dma_common.device_free_chan_resources = atc_free_chan_resources; - atdma->dma_common.device_is_tx_complete = atc_is_tx_complete; + atdma->dma_common.device_tx_status = atc_tx_status; atdma->dma_common.device_issue_pending = atc_issue_pending; atdma->dma_common.dev = &pdev->dev; diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 53c54e034aa3..309db3beef16 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -426,7 +426,7 @@ static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) * absolute measures, but for a rough guess you can still call * it. */ -u32 coh901318_get_bytes_left(struct dma_chan *chan) +static u32 coh901318_get_bytes_left(struct dma_chan *chan) { struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_desc *cohd; @@ -503,8 +503,6 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) return left; } -EXPORT_SYMBOL(coh901318_get_bytes_left); - /* * Pauses a transfer without losing data. Enables power save. @@ -1136,9 +1134,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } static enum dma_status -coh901318_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, - dma_cookie_t *used) +coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct coh901318_chan *cohc = to_coh901318_chan(chan); dma_cookie_t last_used; @@ -1150,10 +1147,14 @@ coh901318_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = coh901318_get_bytes_left(chan); + } + + if (ret == DMA_IN_PROGRESS && cohc->stopped) + ret = DMA_PAUSED; return ret; } @@ -1356,7 +1357,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; - base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_slave.device_tx_status = coh901318_tx_status; base->dma_slave.device_issue_pending = coh901318_issue_pending; base->dma_slave.device_control = coh901318_control; base->dma_slave.dev = &pdev->dev; @@ -1376,7 +1377,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; - base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_memcpy.device_tx_status = coh901318_tx_status; base->dma_memcpy.device_issue_pending = coh901318_issue_pending; base->dma_memcpy.device_control = coh901318_control; base->dma_memcpy.dev = &pdev->dev; diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ffc4ee9c5e21..790caeeb4ccd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -698,7 +698,7 @@ int dma_async_device_register(struct dma_device *device) BUG_ON(!device->device_alloc_chan_resources); BUG_ON(!device->device_free_chan_resources); - BUG_ON(!device->device_is_tx_complete); + BUG_ON(!device->device_tx_status); BUG_ON(!device->device_issue_pending); BUG_ON(!device->dev); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 8a6b85f61176..263b70ee8562 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -819,9 +819,9 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } static enum dma_status -dwc_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +dwc_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); dma_cookie_t last_used; @@ -841,10 +841,11 @@ dwc_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return ret; } @@ -1346,7 +1347,7 @@ static int __init dw_probe(struct platform_device *pdev) dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; dw->dma.device_control = dwc_control; - dw->dma.device_is_tx_complete = dwc_is_tx_complete; + dw->dma.device_tx_status = dwc_tx_status; dw->dma.device_issue_pending = dwc_issue_pending; dma_writel(dw, CFG, DW_CFG_DMA_EN); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 714fc46e7695..ca5e8a3dce72 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -971,13 +971,12 @@ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan) } /** - * fsl_dma_is_complete - Determine the DMA status + * fsl_tx_status - Determine the DMA status * @chan : Freescale DMA channel */ -static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, +static enum dma_status fsl_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct fsldma_chan *chan = to_fsl_chan(dchan); dma_cookie_t last_used; @@ -988,11 +987,11 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, last_used = dchan->cookie; last_complete = chan->completed_cookie; - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -1336,7 +1335,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources; fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt; fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy; - fdev->common.device_is_tx_complete = fsl_dma_is_complete; + fdev->common.device_tx_status = fsl_tx_status; fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; fdev->common.device_control = fsl_dma_device_control; diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 0099340b9616..59cebbfc89ec 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -726,18 +726,18 @@ static void ioat1_timer_event(unsigned long data) } enum dma_status -ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat_chan_common *chan = to_chan_common(c); struct ioatdma_device *device = chan->device; - if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) + if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) return DMA_SUCCESS; device->cleanup_fn((unsigned long) c); - return ioat_is_complete(c, cookie, done, used); + return ioat_tx_status(c, cookie, txstate); } static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat) @@ -857,7 +857,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); if (tmo == 0 || - dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) + dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test copy timed out, disabling\n"); err = -ENODEV; @@ -1198,7 +1198,7 @@ int __devinit ioat1_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat1_dma_memcpy_issue_pending; dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources; dma->device_free_chan_resources = ioat1_dma_free_chan_resources; - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_dma_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 86b97ac8774e..23399672239e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -142,15 +142,14 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c) } /** - * ioat_is_complete - poll the status of an ioat transaction + * ioat_tx_status - poll the status of an ioat transaction * @c: channel handle * @cookie: transaction identifier - * @done: if set, updated with last completed transaction - * @used: if set, updated with last used transaction + * @txstate: if set, updated with the transaction state */ static inline enum dma_status -ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat_chan_common *chan = to_chan_common(c); dma_cookie_t last_used; @@ -159,10 +158,11 @@ ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, last_used = c->cookie; last_complete = chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -338,8 +338,8 @@ struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx); -enum dma_status ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used); +enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate); void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, size_t len, struct ioat_dma_descriptor *hw); bool ioat_cleanup_preamble(struct ioat_chan_common *chan, diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 1ed5d66d7dca..f540e0be7f31 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -854,7 +854,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat2_issue_pending; dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; dma->device_free_chan_resources = ioat2_free_chan_resources; - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 26febc56dab1..d1adbf35268c 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -438,17 +438,17 @@ static void ioat3_timer_event(unsigned long data) } static enum dma_status -ioat3_is_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat3_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat2_dma_chan *ioat = to_ioat2_chan(c); - if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) + if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) return DMA_SUCCESS; ioat3_cleanup_poll(ioat); - return ioat_is_complete(c, cookie, done, used); + return ioat_tx_status(c, cookie, txstate); } static struct dma_async_tx_descriptor * @@ -976,7 +976,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test xor timed out\n"); err = -ENODEV; goto free_resources; @@ -1030,7 +1030,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test validate timed out\n"); err = -ENODEV; goto free_resources; @@ -1071,7 +1071,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test memset timed out\n"); err = -ENODEV; goto free_resources; @@ -1114,7 +1114,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test 2nd validate timed out\n"); err = -ENODEV; goto free_resources; @@ -1258,11 +1258,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (is_raid_device) { - dma->device_is_tx_complete = ioat3_is_complete; + dma->device_tx_status = ioat3_tx_status; device->cleanup_fn = ioat3_cleanup_event; device->timer_fn = ioat3_timer_event; } else { - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_dma_tx_status; device->cleanup_fn = ioat2_cleanup_event; device->timer_fn = ioat2_timer_event; } diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ca6e6a0cb793..ee40dbba1879 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -893,14 +893,14 @@ static void iop_adma_free_chan_resources(struct dma_chan *chan) } /** - * iop_adma_is_complete - poll the status of an ADMA transaction + * iop_adma_status - poll the status of an ADMA transaction * @chan: ADMA channel handle * @cookie: ADMA transaction identifier + * @txstate: a holder for the current state of the channel or NULL */ -static enum dma_status iop_adma_is_complete(struct dma_chan *chan, +static enum dma_status iop_adma_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); dma_cookie_t last_used; @@ -910,10 +910,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -924,10 +925,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -1042,7 +1044,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(1); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test copy timed out, disabling\n"); @@ -1142,7 +1144,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test xor timed out, disabling\n"); @@ -1189,7 +1191,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test zero sum timed out, disabling\n"); err = -ENODEV; @@ -1213,7 +1215,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test memset timed out, disabling\n"); err = -ENODEV; @@ -1245,7 +1247,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test non-zero sum timed out, disabling\n"); err = -ENODEV; @@ -1340,7 +1342,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test pq timed out, disabling\n"); err = -ENODEV; @@ -1377,7 +1379,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test pq-zero-sum timed out, disabling\n"); err = -ENODEV; @@ -1409,7 +1411,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test !pq-zero-sum timed out, disabling\n"); err = -ENODEV; @@ -1507,7 +1509,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) /* set base routines */ dma_dev->device_alloc_chan_resources = iop_adma_alloc_chan_resources; dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; - dma_dev->device_is_tx_complete = iop_adma_is_complete; + dma_dev->device_tx_status = iop_adma_status; dma_dev->device_issue_pending = iop_adma_issue_pending; dma_dev->dev = &pdev->dev; diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 39e7fb2a90e3..b9cef8b1701c 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1646,15 +1646,16 @@ static void idmac_free_chan_resources(struct dma_chan *chan) tasklet_schedule(&to_ipu(idmac)->tasklet); } -static enum dma_status idmac_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status idmac_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) { struct idmac_channel *ichan = to_idmac_chan(chan); - if (done) - *done = ichan->completed; - if (used) - *used = chan->cookie; + if (txstate) { + txstate->last = ichan->completed; + txstate->used = chan->cookie; + txstate->residue = 0; + } if (cookie != chan->cookie) return DMA_ERROR; return DMA_SUCCESS; @@ -1673,7 +1674,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) dma->dev = ipu->dev; dma->device_alloc_chan_resources = idmac_alloc_chan_resources; dma->device_free_chan_resources = idmac_free_chan_resources; - dma->device_is_tx_complete = idmac_is_tx_complete; + dma->device_tx_status = idmac_tx_status; dma->device_issue_pending = idmac_issue_pending; /* Compulsory for DMA_SLAVE fields */ diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 3fdf1f46bd63..cb3a8e94ea48 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -540,8 +540,8 @@ static void mpc_dma_issue_pending(struct dma_chan *chan) /* Check request completion status */ static enum dma_status -mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); unsigned long flags; @@ -553,11 +553,11 @@ mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, last_complete = mchan->completed_cookie; spin_unlock_irqrestore(&mchan->lock, flags); - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -693,7 +693,7 @@ static int __devinit mpc_dma_probe(struct of_device *op, dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; dma->device_free_chan_resources = mpc_dma_free_chan_resources; dma->device_issue_pending = mpc_dma_issue_pending; - dma->device_is_tx_complete = mpc_dma_is_tx_complete; + dma->device_tx_status = mpc_dma_tx_status; dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy; INIT_LIST_HEAD(&dma->channels); diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 466ab10c1ff1..79fb1dea691b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -809,14 +809,14 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) } /** - * mv_xor_is_complete - poll the status of an XOR transaction + * mv_xor_status - poll the status of an XOR transaction * @chan: XOR channel handle * @cookie: XOR transaction identifier + * @txstate: XOR transactions state holder (or NULL) */ -static enum dma_status mv_xor_is_complete(struct dma_chan *chan, +static enum dma_status mv_xor_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); dma_cookie_t last_used; @@ -826,10 +826,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; mv_chan->is_complete_cookie = cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) { @@ -841,10 +842,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -974,7 +976,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) async_tx_ack(tx); msleep(1); - if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test copy timed out, disabling\n"); @@ -1072,7 +1074,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) async_tx_ack(tx); msleep(8); - if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test xor timed out, disabling\n"); @@ -1167,7 +1169,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) /* set base routines */ dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources; dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; - dma_dev->device_is_tx_complete = mv_xor_is_complete; + dma_dev->device_tx_status = mv_xor_status; dma_dev->device_issue_pending = mv_xor_issue_pending; dma_dev->dev = &pdev->dev; diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index e69d87f24a25..d9a54c018652 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -3934,12 +3934,13 @@ static void ppc440spe_adma_free_chan_resources(struct dma_chan *chan) } /** - * ppc440spe_adma_is_complete - poll the status of an ADMA transaction + * ppc440spe_adma_tx_status - poll the status of an ADMA transaction * @chan: ADMA channel handle * @cookie: ADMA transaction identifier + * @txstate: a holder for the current state of the channel */ -static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) { struct ppc440spe_adma_chan *ppc440spe_chan; dma_cookie_t last_used; @@ -3950,10 +3951,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -3964,10 +3966,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -4179,7 +4182,7 @@ static void ppc440spe_adma_init_capabilities(struct ppc440spe_adma_device *adev) ppc440spe_adma_alloc_chan_resources; adev->common.device_free_chan_resources = ppc440spe_adma_free_chan_resources; - adev->common.device_is_tx_complete = ppc440spe_adma_is_complete; + adev->common.device_tx_status = ppc440spe_adma_tx_status; adev->common.device_issue_pending = ppc440spe_adma_issue_pending; /* Set prep routines based on capability */ diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index ce28c1e22825..8aeda9ceb225 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -738,10 +738,9 @@ static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) sh_chan_xfer_ld_queue(sh_chan); } -static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, +static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); dma_cookie_t last_used; @@ -754,11 +753,11 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, last_complete = sh_chan->completed_cookie; BUG_ON(last_complete < 0); - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } spin_lock_bh(&sh_chan->desc_lock); @@ -1030,7 +1029,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) = sh_dmae_alloc_chan_resources; shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; - shdev->common.device_is_tx_complete = sh_dmae_is_complete; + shdev->common.device_tx_status = sh_dmae_tx_status; shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; /* Compulsory for DMA_SLAVE fields */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 7c06471ef863..8fc28814561a 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -511,8 +511,8 @@ static void td_free_chan_resources(struct dma_chan *chan) } } -static enum dma_status td_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); @@ -527,10 +527,11 @@ static enum dma_status td_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } dev_dbg(chan2dev(chan), "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", @@ -742,7 +743,7 @@ static int __devinit td_probe(struct platform_device *pdev) td->dma.device_alloc_chan_resources = td_alloc_chan_resources; td->dma.device_free_chan_resources = td_free_chan_resources; - td->dma.device_is_tx_complete = td_is_tx_complete; + td->dma.device_tx_status = td_tx_status; td->dma.device_issue_pending = td_issue_pending; dma_cap_set(DMA_SLAVE, td->dma.cap_mask); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index e528e15f44ab..a44e422cbc27 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -967,9 +967,8 @@ static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } static enum dma_status -txx9dmac_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); dma_cookie_t last_used; @@ -991,10 +990,11 @@ txx9dmac_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return ret; } @@ -1160,7 +1160,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; dc->dma.device_control = txx9dmac_control; - dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; + dc->dma.device_tx_status = txx9dmac_tx_status; dc->dma.device_issue_pending = txx9dmac_issue_pending; if (pdata && pdata->memcpy_chan == ch) { dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy; diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 0731802f876f..55b08e84ac8d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -40,11 +40,13 @@ typedef s32 dma_cookie_t; * enum dma_status - DMA transaction status * @DMA_SUCCESS: transaction completed successfully * @DMA_IN_PROGRESS: transaction not yet processed + * @DMA_PAUSED: transaction is paused * @DMA_ERROR: transaction failed */ enum dma_status { DMA_SUCCESS, DMA_IN_PROGRESS, + DMA_PAUSED, DMA_ERROR, }; @@ -248,6 +250,21 @@ struct dma_async_tx_descriptor { spinlock_t lock; }; +/** + * struct dma_tx_state - filled in to report the status of + * a transfer. + * @last: last completed DMA cookie + * @used: last issued DMA cookie (i.e. the one in progress) + * @residue: the remaining number of bytes left to transmit + * on the selected transfer for states DMA_IN_PROGRESS and + * DMA_PAUSED if this is implemented in the driver, else 0 + */ +struct dma_tx_state { + dma_cookie_t last; + dma_cookie_t used; + u32 residue; +}; + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported @@ -276,7 +293,10 @@ struct dma_async_tx_descriptor { * @device_prep_slave_sg: prepares a slave dma operation * @device_control: manipulate all pending operations on a channel, returns * zero or error code - * @device_is_tx_complete: poll for transaction completion + * @device_tx_status: poll for transaction completion, the optional + * txstate parameter can be supplied with a pointer to get a + * struct with auxilary transfer status information, otherwise the call + * will just return a simple status code * @device_issue_pending: push pending transactions to hardware */ struct dma_device { @@ -329,9 +349,9 @@ struct dma_device { unsigned long flags); int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); - enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *last, - dma_cookie_t *used); + enum dma_status (*device_tx_status)(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); }; @@ -572,7 +592,15 @@ static inline void dma_async_issue_pending(struct dma_chan *chan) static inline enum dma_status dma_async_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used) { - return chan->device->device_is_tx_complete(chan, cookie, last, used); + struct dma_tx_state state; + enum dma_status status; + + status = chan->device->device_tx_status(chan, cookie, &state); + if (last) + *last = state.last; + if (used) + *used = state.used; + return status; } #define dma_async_memcpy_complete(chan, cookie, last, used)\ -- cgit v1.2.3 From bca3469205402d9fb14060d255d8786ae2256640 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 26 Mar 2010 16:52:10 -0700 Subject: dmaengine: provide helper for setting txstate Simple conditional struct filler to cut out some duplicated code. Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 7 +------ drivers/dma/coh901318.c | 8 ++------ drivers/dma/dw_dmac.c | 6 +----- drivers/dma/fsldma.c | 6 +----- drivers/dma/ioat/dma.h | 6 +----- drivers/dma/iop-adma.c | 15 ++------------- drivers/dma/ipu/ipu_idmac.c | 6 +----- drivers/dma/mpc512x_dma.c | 7 +------ drivers/dma/mv_xor.c | 13 ++----------- drivers/dma/ppc4xx/adma.c | 12 ++---------- drivers/dma/shdma.c | 7 +------ drivers/dma/timb_dma.c | 6 +----- drivers/dma/txx9dmac.c | 6 +----- include/linux/dmaengine.h | 10 ++++++++++ 14 files changed, 27 insertions(+), 88 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index ff75cf18d32e..93ed99c84cf1 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -834,12 +834,7 @@ atc_tx_status(struct dma_chan *chan, spin_unlock_bh(&atchan->lock); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", cookie, last_complete ? last_complete : 0, last_used ? last_used : 0); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 309db3beef16..4233440741a2 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -1147,12 +1147,8 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = coh901318_get_bytes_left(chan); - } - + dma_set_tx_state(txstate, last_complete, last_used, + coh901318_get_bytes_left(chan)); if (ret == DMA_IN_PROGRESS && cohc->stopped) ret = DMA_PAUSED; diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 263b70ee8562..18fb5b41cedf 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -841,11 +841,7 @@ dwc_tx_status(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return ret; } diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index ca5e8a3dce72..cb1924f46c9e 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -987,11 +987,7 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan, last_used = dchan->cookie; last_complete = chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 23399672239e..26f48ef94c5c 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -158,11 +158,7 @@ ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, last_used = c->cookie; last_complete = chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ee40dbba1879..e5d4b97b7fd5 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -909,13 +909,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) return ret; @@ -924,12 +918,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index b9cef8b1701c..246a6143e4a7 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1651,11 +1651,7 @@ static enum dma_status idmac_tx_status(struct dma_chan *chan, { struct idmac_channel *ichan = to_idmac_chan(chan); - if (txstate) { - txstate->last = ichan->completed; - txstate->used = chan->cookie; - txstate->residue = 0; - } + dma_set_tx_state(txstate, ichan->completed, chan->cookie, 0); if (cookie != chan->cookie) return DMA_ERROR; return DMA_SUCCESS; diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index cb3a8e94ea48..7a750b95303c 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -553,12 +553,7 @@ mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, last_complete = mchan->completed_cookie; spin_unlock_irqrestore(&mchan->lock, flags); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 79fb1dea691b..4b8c1fcc834d 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -826,11 +826,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; mv_chan->is_complete_cookie = cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) { @@ -842,12 +838,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index d9a54c018652..5558419876e8 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -3951,11 +3951,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -3966,11 +3962,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 8aeda9ceb225..98f82cdb404c 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -752,12 +752,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = sh_chan->completed_cookie; BUG_ON(last_complete < 0); - - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); spin_lock_bh(&sh_chan->desc_lock); diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 8fc28814561a..e20d5c1fa213 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -527,11 +527,7 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); dev_dbg(chan2dev(chan), "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index a44e422cbc27..e523737639aa 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -990,11 +990,7 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return ret; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 55b08e84ac8d..50b7b3e0d572 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -628,6 +628,16 @@ static inline enum dma_status dma_async_is_complete(dma_cookie_t cookie, return DMA_IN_PROGRESS; } +static inline void +dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used, u32 residue) +{ + if (st) { + st->last = last; + st->used = used; + st->residue = residue; + } +} + enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); -- cgit v1.2.3 From 6a3cd3ea48584d14f60dce0b3c4e9e4428beb0fe Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 29 Mar 2010 15:54:40 +1100 Subject: async_tx: use of kzalloc/kfree requires the include of slab.h Signed-off-by: Stephen Rothwell Signed-off-by: Dan Williams --- drivers/dma/timb_dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/dma') diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index e20d5c1fa213..44b346d8d319 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -27,6 +27,7 @@ #include #include #include +#include #include -- cgit v1.2.3 From 8d318a50b3d72e3daf94131f91e1ab799a8d5ad4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Mar 2010 15:33:42 +0200 Subject: DMAENGINE: Support for ST-Ericssons DMA40 block v3 This is a straightforward driver for the ST-Ericsson DMA40 DMA controller found in U8500, implemented akin to the existing COH 901 318 driver. Signed-off-by: Linus Walleij Acked-by: Srinidh Kasagar Cc: STEricsson_nomadik_linux@list.st.com Cc: Alessandro Rubini Signed-off-by: Andrew Morton Signed-off-by: Dan Williams --- arch/arm/plat-nomadik/include/plat/ste_dma40.h | 239 +++ drivers/dma/Kconfig | 7 + drivers/dma/Makefile | 1 + drivers/dma/ste_dma40.c | 2596 ++++++++++++++++++++++++ drivers/dma/ste_dma40_ll.c | 454 +++++ drivers/dma/ste_dma40_ll.h | 354 ++++ 6 files changed, 3651 insertions(+) create mode 100644 arch/arm/plat-nomadik/include/plat/ste_dma40.h create mode 100644 drivers/dma/ste_dma40.c create mode 100644 drivers/dma/ste_dma40_ll.c create mode 100644 drivers/dma/ste_dma40_ll.h (limited to 'drivers/dma') diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h new file mode 100644 index 000000000000..4d12ea4ca361 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -0,0 +1,239 @@ +/* + * arch/arm/plat-nomadik/include/plat/ste_dma40.h + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ + + +#ifndef STE_DMA40_H +#define STE_DMA40_H + +#include +#include +#include +#include + +/* dev types for memcpy */ +#define STEDMA40_DEV_DST_MEMORY (-1) +#define STEDMA40_DEV_SRC_MEMORY (-1) + +/* + * Description of bitfields of channel_type variable is available in + * the info structure. + */ + +/* Priority */ +#define STEDMA40_INFO_PRIO_TYPE_POS 2 +#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS) +#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS) + +/* Mode */ +#define STEDMA40_INFO_CH_MODE_TYPE_POS 6 +#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS) +#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS) +#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS) + +/* Mode options */ +#define STEDMA40_INFO_CH_MODE_OPT_POS 8 +#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS) + +/* Interrupt */ +#define STEDMA40_INFO_TIM_POS 10 +#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS) +#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS) + +/* End of channel_type configuration */ + +#define STEDMA40_ESIZE_8_BIT 0x0 +#define STEDMA40_ESIZE_16_BIT 0x1 +#define STEDMA40_ESIZE_32_BIT 0x2 +#define STEDMA40_ESIZE_64_BIT 0x3 + +/* The value 4 indicates that PEN-reg shall be set to 0 */ +#define STEDMA40_PSIZE_PHY_1 0x4 +#define STEDMA40_PSIZE_PHY_2 0x0 +#define STEDMA40_PSIZE_PHY_4 0x1 +#define STEDMA40_PSIZE_PHY_8 0x2 +#define STEDMA40_PSIZE_PHY_16 0x3 + +/* + * The number of elements differ in logical and + * physical mode + */ +#define STEDMA40_PSIZE_LOG_1 STEDMA40_PSIZE_PHY_2 +#define STEDMA40_PSIZE_LOG_4 STEDMA40_PSIZE_PHY_4 +#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8 +#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16 + +enum stedma40_flow_ctrl { + STEDMA40_NO_FLOW_CTRL, + STEDMA40_FLOW_CTRL, +}; + +enum stedma40_endianess { + STEDMA40_LITTLE_ENDIAN, + STEDMA40_BIG_ENDIAN +}; + +enum stedma40_periph_data_width { + STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, + STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, + STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, + STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT +}; + +struct stedma40_half_channel_info { + enum stedma40_endianess endianess; + enum stedma40_periph_data_width data_width; + int psize; + enum stedma40_flow_ctrl flow_ctrl; +}; + +enum stedma40_xfer_dir { + STEDMA40_MEM_TO_MEM, + STEDMA40_MEM_TO_PERIPH, + STEDMA40_PERIPH_TO_MEM, + STEDMA40_PERIPH_TO_PERIPH +}; + + +/** + * struct stedma40_chan_cfg - Structure to be filled by client drivers. + * + * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH + * @channel_type: priority, mode, mode options and interrupt configuration. + * @src_dev_type: Src device type + * @dst_dev_type: Dst device type + * @src_info: Parameters for dst half channel + * @dst_info: Parameters for dst half channel + * @pre_transfer_data: Data to be passed on to the pre_transfer() function. + * @pre_transfer: Callback used if needed before preparation of transfer. + * Only called if device is set. size of bytes to transfer + * (in case of multiple element transfer size is size of the first element). + * + * + * This structure has to be filled by the client drivers. + * It is recommended to do all dma configurations for clients in the machine. + * + */ +struct stedma40_chan_cfg { + enum stedma40_xfer_dir dir; + unsigned int channel_type; + int src_dev_type; + int dst_dev_type; + struct stedma40_half_channel_info src_info; + struct stedma40_half_channel_info dst_info; + void *pre_transfer_data; + int (*pre_transfer) (struct dma_chan *chan, + void *data, + int size); +}; + +/** + * struct stedma40_platform_data - Configuration struct for the dma device. + * + * @dev_len: length of dev_tx and dev_rx + * @dev_tx: mapping between destination event line and io address + * @dev_rx: mapping between source event line and io address + * @memcpy: list of memcpy event lines + * @memcpy_len: length of memcpy + * @memcpy_conf_phy: default configuration of physical channel memcpy + * @memcpy_conf_log: default configuration of logical channel memcpy + * @llis_per_log: number of max linked list items per logical channel + * + */ +struct stedma40_platform_data { + u32 dev_len; + const dma_addr_t *dev_tx; + const dma_addr_t *dev_rx; + int *memcpy; + u32 memcpy_len; + struct stedma40_chan_cfg *memcpy_conf_phy; + struct stedma40_chan_cfg *memcpy_conf_log; + unsigned int llis_per_log; +}; + +/** + * setdma40_set_psize() - Used for changing the package size of an + * already configured dma channel. + * + * @chan: dmaengine handle + * @src_psize: new package side for src. (STEDMA40_PSIZE*) + * @src_psize: new package side for dst. (STEDMA40_PSIZE*) + * + * returns 0 on ok, otherwise negative error number. + */ +int stedma40_set_psize(struct dma_chan *chan, + int src_psize, + int dst_psize); + +/** + * stedma40_filter() - Provides stedma40_chan_cfg to the + * ste_dma40 dma driver via the dmaengine framework. + * does some checking of what's provided. + * + * Never directly called by client. It used by dmaengine. + * @chan: dmaengine handle. + * @data: Must be of type: struct stedma40_chan_cfg and is + * the configuration of the framework. + * + * + */ + +bool stedma40_filter(struct dma_chan *chan, void *data); + +/** + * stedma40_memcpy_sg() - extension of the dma framework, memcpy to/from + * scattergatter lists. + * + * @chan: dmaengine handle + * @sgl_dst: Destination scatter list + * @sgl_src: Source scatter list + * @sgl_len: The length of each scatterlist. Both lists must be of equal length + * and each element must match the corresponding element in the other scatter + * list. + * @flags: is actually enum dma_ctrl_flags. See dmaengine.h + */ + +struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan, + struct scatterlist *sgl_dst, + struct scatterlist *sgl_src, + unsigned int sgl_len, + unsigned long flags); + +/** + * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave + * (=device) + * + * @chan: dmaengine handle + * @addr: source or destination physicall address. + * @size: bytes to transfer + * @direction: direction of transfer + * @flags: is actually enum dma_ctrl_flags. See dmaengine.h + */ + +static inline struct +dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, + dma_addr_t addr, + unsigned int size, + enum dma_data_direction direction, + unsigned long flags) +{ + struct scatterlist sg; + sg_init_table(&sg, 1); + sg.dma_address = addr; + sg.length = size; + + return chan->device->device_prep_slave_sg(chan, &sg, 1, + direction, flags); +} + +#endif diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a2fcb2ead892..1b8877922fb0 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -141,6 +141,13 @@ config COH901318 help Enable support for ST-Ericsson COH 901 318 DMA. +config STE_DMA40 + bool "ST-Ericsson DMA40 support" + depends on ARCH_U8500 + select DMA_ENGINE + help + Support for ST-Ericsson DMA40 controller + config AMCC_PPC440SPE_ADMA tristate "AMCC PPC440SPe ADMA support" depends on 440SPe || 440SP diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 40c627d8f73b..20881426c1ac 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ obj-$(CONFIG_TIMB_DMA) += timb_dma.o +obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c new file mode 100644 index 000000000000..e4295a27672b --- /dev/null +++ b/drivers/dma/ste_dma40.c @@ -0,0 +1,2596 @@ +/* + * driver/dma/ste_dma40.c + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "ste_dma40_ll.h" + +#define D40_NAME "dma40" + +#define D40_PHY_CHAN -1 + +/* For masking out/in 2 bit channel positions */ +#define D40_CHAN_POS(chan) (2 * (chan / 2)) +#define D40_CHAN_POS_MASK(chan) (0x3 << D40_CHAN_POS(chan)) + +/* Maximum iterations taken before giving up suspending a channel */ +#define D40_SUSPEND_MAX_IT 500 + +#define D40_ALLOC_FREE (1 << 31) +#define D40_ALLOC_PHY (1 << 30) +#define D40_ALLOC_LOG_FREE 0 + +/* The number of free d40_desc to keep in memory before starting + * to kfree() them */ +#define D40_DESC_CACHE_SIZE 50 + +/* Hardware designer of the block */ +#define D40_PERIPHID2_DESIGNER 0x8 + +/** + * enum 40_command - The different commands and/or statuses. + * + * @D40_DMA_STOP: DMA channel command STOP or status STOPPED, + * @D40_DMA_RUN: The DMA channel is RUNNING of the command RUN. + * @D40_DMA_SUSPEND_REQ: Request the DMA to SUSPEND as soon as possible. + * @D40_DMA_SUSPENDED: The DMA channel is SUSPENDED. + */ +enum d40_command { + D40_DMA_STOP = 0, + D40_DMA_RUN = 1, + D40_DMA_SUSPEND_REQ = 2, + D40_DMA_SUSPENDED = 3 +}; + +/** + * struct d40_lli_pool - Structure for keeping LLIs in memory + * + * @base: Pointer to memory area when the pre_alloc_lli's are not large + * enough, IE bigger than the most common case, 1 dst and 1 src. NULL if + * pre_alloc_lli is used. + * @size: The size in bytes of the memory at base or the size of pre_alloc_lli. + * @pre_alloc_lli: Pre allocated area for the most common case of transfers, + * one buffer to one buffer. + */ +struct d40_lli_pool { + void *base; + int size; + /* Space for dst and src, plus an extra for padding */ + u8 pre_alloc_lli[3 * sizeof(struct d40_phy_lli)]; +}; + +/** + * struct d40_desc - A descriptor is one DMA job. + * + * @lli_phy: LLI settings for physical channel. Both src and dst= + * points into the lli_pool, to base if lli_len > 1 or to pre_alloc_lli if + * lli_len equals one. + * @lli_log: Same as above but for logical channels. + * @lli_pool: The pool with two entries pre-allocated. + * @lli_len: Number of LLI's in lli_pool + * @lli_tcount: Number of LLIs processed in the transfer. When equals lli_len + * then this transfer job is done. + * @txd: DMA engine struct. Used for among other things for communication + * during a transfer. + * @node: List entry. + * @dir: The transfer direction of this job. + * @is_in_client_list: true if the client owns this descriptor. + * + * This descriptor is used for both logical and physical transfers. + */ + +struct d40_desc { + /* LLI physical */ + struct d40_phy_lli_bidir lli_phy; + /* LLI logical */ + struct d40_log_lli_bidir lli_log; + + struct d40_lli_pool lli_pool; + u32 lli_len; + u32 lli_tcount; + + struct dma_async_tx_descriptor txd; + struct list_head node; + + enum dma_data_direction dir; + bool is_in_client_list; +}; + +/** + * struct d40_lcla_pool - LCLA pool settings and data. + * + * @base: The virtual address of LCLA. + * @phy: Physical base address of LCLA. + * @base_size: size of lcla. + * @lock: Lock to protect the content in this struct. + * @alloc_map: Mapping between physical channel and LCLA entries. + * @num_blocks: The number of entries of alloc_map. Equals to the + * number of physical channels. + */ +struct d40_lcla_pool { + void *base; + dma_addr_t phy; + resource_size_t base_size; + spinlock_t lock; + u32 *alloc_map; + int num_blocks; +}; + +/** + * struct d40_phy_res - struct for handling eventlines mapped to physical + * channels. + * + * @lock: A lock protection this entity. + * @num: The physical channel number of this entity. + * @allocated_src: Bit mapped to show which src event line's are mapped to + * this physical channel. Can also be free or physically allocated. + * @allocated_dst: Same as for src but is dst. + * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as + * event line number. Both allocated_src and allocated_dst can not be + * allocated to a physical channel, since the interrupt handler has then + * no way of figure out which one the interrupt belongs to. + */ +struct d40_phy_res { + spinlock_t lock; + int num; + u32 allocated_src; + u32 allocated_dst; +}; + +struct d40_base; + +/** + * struct d40_chan - Struct that describes a channel. + * + * @lock: A spinlock to protect this struct. + * @log_num: The logical number, if any of this channel. + * @completed: Starts with 1, after first interrupt it is set to dma engine's + * current cookie. + * @pending_tx: The number of pending transfers. Used between interrupt handler + * and tasklet. + * @busy: Set to true when transfer is ongoing on this channel. + * @phy_chan: Pointer to physical channel which this instance runs on. + * @chan: DMA engine handle. + * @tasklet: Tasklet that gets scheduled from interrupt context to complete a + * transfer and call client callback. + * @client: Cliented owned descriptor list. + * @active: Active descriptor. + * @queue: Queued jobs. + * @free: List of free descripts, ready to be reused. + * @free_len: Number of descriptors in the free list. + * @dma_cfg: The client configuration of this dma channel. + * @base: Pointer to the device instance struct. + * @src_def_cfg: Default cfg register setting for src. + * @dst_def_cfg: Default cfg register setting for dst. + * @log_def: Default logical channel settings. + * @lcla: Space for one dst src pair for logical channel transfers. + * @lcpa: Pointer to dst and src lcpa settings. + * + * This struct can either "be" a logical or a physical channel. + */ +struct d40_chan { + spinlock_t lock; + int log_num; + /* ID of the most recent completed transfer */ + int completed; + int pending_tx; + bool busy; + struct d40_phy_res *phy_chan; + struct dma_chan chan; + struct tasklet_struct tasklet; + struct list_head client; + struct list_head active; + struct list_head queue; + struct list_head free; + int free_len; + struct stedma40_chan_cfg dma_cfg; + struct d40_base *base; + /* Default register configurations */ + u32 src_def_cfg; + u32 dst_def_cfg; + struct d40_def_lcsp log_def; + struct d40_lcla_elem lcla; + struct d40_log_lli_full *lcpa; +}; + +/** + * struct d40_base - The big global struct, one for each probe'd instance. + * + * @interrupt_lock: Lock used to make sure one interrupt is handle a time. + * @execmd_lock: Lock for execute command usage since several channels share + * the same physical register. + * @dev: The device structure. + * @virtbase: The virtual base address of the DMA's register. + * @clk: Pointer to the DMA clock structure. + * @phy_start: Physical memory start of the DMA registers. + * @phy_size: Size of the DMA register map. + * @irq: The IRQ number. + * @num_phy_chans: The number of physical channels. Read from HW. This + * is the number of available channels for this driver, not counting "Secure + * mode" allocated physical channels. + * @num_log_chans: The number of logical channels. Calculated from + * num_phy_chans. + * @dma_both: dma_device channels that can do both memcpy and slave transfers. + * @dma_slave: dma_device channels that can do only do slave transfers. + * @dma_memcpy: dma_device channels that can do only do memcpy transfers. + * @phy_chans: Room for all possible physical channels in system. + * @log_chans: Room for all possible logical channels in system. + * @lookup_log_chans: Used to map interrupt number to logical channel. Points + * to log_chans entries. + * @lookup_phy_chans: Used to map interrupt number to physical channel. Points + * to phy_chans entries. + * @plat_data: Pointer to provided platform_data which is the driver + * configuration. + * @phy_res: Vector containing all physical channels. + * @lcla_pool: lcla pool settings and data. + * @lcpa_base: The virtual mapped address of LCPA. + * @phy_lcpa: The physical address of the LCPA. + * @lcpa_size: The size of the LCPA area. + */ +struct d40_base { + spinlock_t interrupt_lock; + spinlock_t execmd_lock; + struct device *dev; + void __iomem *virtbase; + struct clk *clk; + phys_addr_t phy_start; + resource_size_t phy_size; + int irq; + int num_phy_chans; + int num_log_chans; + struct dma_device dma_both; + struct dma_device dma_slave; + struct dma_device dma_memcpy; + struct d40_chan *phy_chans; + struct d40_chan *log_chans; + struct d40_chan **lookup_log_chans; + struct d40_chan **lookup_phy_chans; + struct stedma40_platform_data *plat_data; + /* Physical half channels */ + struct d40_phy_res *phy_res; + struct d40_lcla_pool lcla_pool; + void *lcpa_base; + dma_addr_t phy_lcpa; + resource_size_t lcpa_size; +}; + +/** + * struct d40_interrupt_lookup - lookup table for interrupt handler + * + * @src: Interrupt mask register. + * @clr: Interrupt clear register. + * @is_error: true if this is an error interrupt. + * @offset: start delta in the lookup_log_chans in d40_base. If equals to + * D40_PHY_CHAN, the lookup_phy_chans shall be used instead. + */ +struct d40_interrupt_lookup { + u32 src; + u32 clr; + bool is_error; + int offset; +}; + +/** + * struct d40_reg_val - simple lookup struct + * + * @reg: The register. + * @val: The value that belongs to the register in reg. + */ +struct d40_reg_val { + unsigned int reg; + unsigned int val; +}; + +static int d40_pool_lli_alloc(struct d40_desc *d40d, + int lli_len, bool is_log) +{ + u32 align; + void *base; + + if (is_log) + align = sizeof(struct d40_log_lli); + else + align = sizeof(struct d40_phy_lli); + + if (lli_len == 1) { + base = d40d->lli_pool.pre_alloc_lli; + d40d->lli_pool.size = sizeof(d40d->lli_pool.pre_alloc_lli); + d40d->lli_pool.base = NULL; + } else { + d40d->lli_pool.size = ALIGN(lli_len * 2 * align, align); + + base = kmalloc(d40d->lli_pool.size + align, GFP_NOWAIT); + d40d->lli_pool.base = base; + + if (d40d->lli_pool.base == NULL) + return -ENOMEM; + } + + if (is_log) { + d40d->lli_log.src = PTR_ALIGN((struct d40_log_lli *) base, + align); + d40d->lli_log.dst = PTR_ALIGN(d40d->lli_log.src + lli_len, + align); + } else { + d40d->lli_phy.src = PTR_ALIGN((struct d40_phy_lli *)base, + align); + d40d->lli_phy.dst = PTR_ALIGN(d40d->lli_phy.src + lli_len, + align); + + d40d->lli_phy.src_addr = virt_to_phys(d40d->lli_phy.src); + d40d->lli_phy.dst_addr = virt_to_phys(d40d->lli_phy.dst); + } + + return 0; +} + +static void d40_pool_lli_free(struct d40_desc *d40d) +{ + kfree(d40d->lli_pool.base); + d40d->lli_pool.base = NULL; + d40d->lli_pool.size = 0; + d40d->lli_log.src = NULL; + d40d->lli_log.dst = NULL; + d40d->lli_phy.src = NULL; + d40d->lli_phy.dst = NULL; + d40d->lli_phy.src_addr = 0; + d40d->lli_phy.dst_addr = 0; +} + +static dma_cookie_t d40_assign_cookie(struct d40_chan *d40c, + struct d40_desc *desc) +{ + dma_cookie_t cookie = d40c->chan.cookie; + + if (++cookie < 0) + cookie = 1; + + d40c->chan.cookie = cookie; + desc->txd.cookie = cookie; + + return cookie; +} + +static void d40_desc_reset(struct d40_desc *d40d) +{ + d40d->lli_tcount = 0; +} + +static void d40_desc_remove(struct d40_desc *d40d) +{ + list_del(&d40d->node); +} + +static struct d40_desc *d40_desc_get(struct d40_chan *d40c) +{ + struct d40_desc *desc; + struct d40_desc *d; + struct d40_desc *_d; + + if (!list_empty(&d40c->client)) { + list_for_each_entry_safe(d, _d, &d40c->client, node) + if (async_tx_test_ack(&d->txd)) { + d40_pool_lli_free(d); + d40_desc_remove(d); + desc = d; + goto out; + } + } + + if (list_empty(&d40c->free)) { + /* Alloc new desc because we're out of used ones */ + desc = kzalloc(sizeof(struct d40_desc), GFP_NOWAIT); + if (desc == NULL) + goto out; + INIT_LIST_HEAD(&desc->node); + } else { + /* Reuse an old desc. */ + desc = list_first_entry(&d40c->free, + struct d40_desc, + node); + list_del(&desc->node); + d40c->free_len--; + } +out: + return desc; +} + +static void d40_desc_free(struct d40_chan *d40c, struct d40_desc *d40d) +{ + if (d40c->free_len < D40_DESC_CACHE_SIZE) { + list_add_tail(&d40d->node, &d40c->free); + d40c->free_len++; + } else + kfree(d40d); +} + +static void d40_desc_submit(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->active); +} + +static struct d40_desc *d40_first_active_get(struct d40_chan *d40c) +{ + struct d40_desc *d; + + if (list_empty(&d40c->active)) + return NULL; + + d = list_first_entry(&d40c->active, + struct d40_desc, + node); + return d; +} + +static void d40_desc_queue(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->queue); +} + +static struct d40_desc *d40_first_queued(struct d40_chan *d40c) +{ + struct d40_desc *d; + + if (list_empty(&d40c->queue)) + return NULL; + + d = list_first_entry(&d40c->queue, + struct d40_desc, + node); + return d; +} + +/* Support functions for logical channels */ + +static int d40_lcla_id_get(struct d40_chan *d40c, + struct d40_lcla_pool *pool) +{ + int src_id = 0; + int dst_id = 0; + struct d40_log_lli *lcla_lidx_base = + pool->base + d40c->phy_chan->num * 1024; + int i; + int lli_per_log = d40c->base->plat_data->llis_per_log; + + if (d40c->lcla.src_id >= 0 && d40c->lcla.dst_id >= 0) + return 0; + + if (pool->num_blocks > 32) + return -EINVAL; + + spin_lock(&pool->lock); + + for (i = 0; i < pool->num_blocks; i++) { + if (!(pool->alloc_map[d40c->phy_chan->num] & (0x1 << i))) { + pool->alloc_map[d40c->phy_chan->num] |= (0x1 << i); + break; + } + } + src_id = i; + if (src_id >= pool->num_blocks) + goto err; + + for (; i < pool->num_blocks; i++) { + if (!(pool->alloc_map[d40c->phy_chan->num] & (0x1 << i))) { + pool->alloc_map[d40c->phy_chan->num] |= (0x1 << i); + break; + } + } + + dst_id = i; + if (dst_id == src_id) + goto err; + + d40c->lcla.src_id = src_id; + d40c->lcla.dst_id = dst_id; + d40c->lcla.dst = lcla_lidx_base + dst_id * lli_per_log + 1; + d40c->lcla.src = lcla_lidx_base + src_id * lli_per_log + 1; + + + spin_unlock(&pool->lock); + return 0; +err: + spin_unlock(&pool->lock); + return -EINVAL; +} + +static void d40_lcla_id_put(struct d40_chan *d40c, + struct d40_lcla_pool *pool, + int id) +{ + if (id < 0) + return; + + d40c->lcla.src_id = -1; + d40c->lcla.dst_id = -1; + + spin_lock(&pool->lock); + pool->alloc_map[d40c->phy_chan->num] &= (~(0x1 << id)); + spin_unlock(&pool->lock); +} + +static int d40_channel_execute_command(struct d40_chan *d40c, + enum d40_command command) +{ + int status, i; + void __iomem *active_reg; + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&d40c->base->execmd_lock, flags); + + if (d40c->phy_chan->num % 2 == 0) + active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; + else + active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + if (command == D40_DMA_SUSPEND_REQ) { + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + + if (status == D40_DMA_SUSPENDED || status == D40_DMA_STOP) + goto done; + } + + writel(command << D40_CHAN_POS(d40c->phy_chan->num), active_reg); + + if (command == D40_DMA_SUSPEND_REQ) { + + for (i = 0 ; i < D40_SUSPEND_MAX_IT; i++) { + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + + cpu_relax(); + /* + * Reduce the number of bus accesses while + * waiting for the DMA to suspend. + */ + udelay(3); + + if (status == D40_DMA_STOP || + status == D40_DMA_SUSPENDED) + break; + } + + if (i == D40_SUSPEND_MAX_IT) { + dev_err(&d40c->chan.dev->device, + "[%s]: unable to suspend the chl %d (log: %d) status %x\n", + __func__, d40c->phy_chan->num, d40c->log_num, + status); + dump_stack(); + ret = -EBUSY; + } + + } +done: + spin_unlock_irqrestore(&d40c->base->execmd_lock, flags); + return ret; +} + +static void d40_term_all(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + struct d40_desc *d; + struct d40_desc *_d; + + /* Release active descriptors */ + while ((d40d = d40_first_active_get(d40c))) { + d40_desc_remove(d40d); + + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + /* Release queued descriptors waiting for transfer */ + while ((d40d = d40_first_queued(d40c))) { + d40_desc_remove(d40d); + + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + /* Release client owned descriptors */ + if (!list_empty(&d40c->client)) + list_for_each_entry_safe(d, _d, &d40c->client, node) { + d40_pool_lli_free(d); + d40_desc_remove(d); + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + d40_lcla_id_put(d40c, &d40c->base->lcla_pool, + d40c->lcla.src_id); + d40_lcla_id_put(d40c, &d40c->base->lcla_pool, + d40c->lcla.dst_id); + + d40c->pending_tx = 0; + d40c->busy = false; +} + +static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) +{ + u32 val; + unsigned long flags; + + if (do_enable) + val = D40_ACTIVATE_EVENTLINE; + else + val = D40_DEACTIVATE_EVENTLINE; + + spin_lock_irqsave(&d40c->phy_chan->lock, flags); + + /* Enable event line connected to device (or memcpy) */ + if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + + writel((val << D40_EVENTLINE_POS(event)) | + ~D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSLNK); + } + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + + writel((val << D40_EVENTLINE_POS(event)) | + ~D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK); + } + + spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); +} + +static bool d40_chan_has_events(struct d40_chan *d40c) +{ + u32 val = 0; + + /* If SSLNK or SDLNK is zero all events are disabled */ + if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + val = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSLNK); + + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) + val = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK); + return (bool) val; +} + +static void d40_config_enable_lidx(struct d40_chan *d40c) +{ + /* Set LIDX for lcla */ + writel((d40c->phy_chan->num << D40_SREG_ELEM_LOG_LIDX_POS) & + D40_SREG_ELEM_LOG_LIDX_MASK, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SDELT); + + writel((d40c->phy_chan->num << D40_SREG_ELEM_LOG_LIDX_POS) & + D40_SREG_ELEM_LOG_LIDX_MASK, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SSELT); +} + +static int d40_config_write(struct d40_chan *d40c) +{ + u32 addr_base; + u32 var; + int res; + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) + return res; + + /* Odd addresses are even addresses + 4 */ + addr_base = (d40c->phy_chan->num % 2) * 4; + /* Setup channel mode to logical or physical */ + var = ((u32)(d40c->log_num != D40_PHY_CHAN) + 1) << + D40_CHAN_POS(d40c->phy_chan->num); + writel(var, d40c->base->virtbase + D40_DREG_PRMSE + addr_base); + + /* Setup operational mode option register */ + var = ((d40c->dma_cfg.channel_type >> STEDMA40_INFO_CH_MODE_OPT_POS) & + 0x3) << D40_CHAN_POS(d40c->phy_chan->num); + + writel(var, d40c->base->virtbase + D40_DREG_PRMOE + addr_base); + + if (d40c->log_num != D40_PHY_CHAN) { + /* Set default config for CFG reg */ + writel(d40c->src_def_cfg, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSCFG); + writel(d40c->dst_def_cfg, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDCFG); + + d40_config_enable_lidx(d40c); + } + return res; +} + +static void d40_desc_load(struct d40_chan *d40c, struct d40_desc *d40d) +{ + + if (d40d->lli_phy.dst && d40d->lli_phy.src) { + d40_phy_lli_write(d40c->base->virtbase, + d40c->phy_chan->num, + d40d->lli_phy.dst, + d40d->lli_phy.src); + d40d->lli_tcount = d40d->lli_len; + } else if (d40d->lli_log.dst && d40d->lli_log.src) { + u32 lli_len; + struct d40_log_lli *src = d40d->lli_log.src; + struct d40_log_lli *dst = d40d->lli_log.dst; + + src += d40d->lli_tcount; + dst += d40d->lli_tcount; + + if (d40d->lli_len <= d40c->base->plat_data->llis_per_log) + lli_len = d40d->lli_len; + else + lli_len = d40c->base->plat_data->llis_per_log; + d40d->lli_tcount += lli_len; + d40_log_lli_write(d40c->lcpa, d40c->lcla.src, + d40c->lcla.dst, + dst, src, + d40c->base->plat_data->llis_per_log); + } +} + +static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct d40_chan *d40c = container_of(tx->chan, + struct d40_chan, + chan); + struct d40_desc *d40d = container_of(tx, struct d40_desc, txd); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + tx->cookie = d40_assign_cookie(d40c, d40d); + + d40_desc_queue(d40c, d40d); + + spin_unlock_irqrestore(&d40c->lock, flags); + + return tx->cookie; +} + +static int d40_start(struct d40_chan *d40c) +{ + int err; + + if (d40c->log_num != D40_PHY_CHAN) { + err = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (err) + return err; + d40_config_set_event(d40c, true); + } + + err = d40_channel_execute_command(d40c, D40_DMA_RUN); + + return err; +} + +static struct d40_desc *d40_queue_start(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + int err; + + /* Start queued jobs, if any */ + d40d = d40_first_queued(d40c); + + if (d40d != NULL) { + d40c->busy = true; + + /* Remove from queue */ + d40_desc_remove(d40d); + + /* Add to active queue */ + d40_desc_submit(d40c, d40d); + + /* Initiate DMA job */ + d40_desc_load(d40c, d40d); + + /* Start dma job */ + err = d40_start(d40c); + + if (err) + return NULL; + } + + return d40d; +} + +/* called from interrupt context */ +static void dma_tc_handle(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + + if (!d40c->phy_chan) + return; + + /* Get first active entry from list */ + d40d = d40_first_active_get(d40c); + + if (d40d == NULL) + return; + + if (d40d->lli_tcount < d40d->lli_len) { + + d40_desc_load(d40c, d40d); + /* Start dma job */ + (void) d40_start(d40c); + return; + } + + if (d40_queue_start(d40c) == NULL) + d40c->busy = false; + + d40c->pending_tx++; + tasklet_schedule(&d40c->tasklet); + +} + +static void dma_tasklet(unsigned long data) +{ + struct d40_chan *d40c = (struct d40_chan *) data; + struct d40_desc *d40d_fin; + unsigned long flags; + dma_async_tx_callback callback; + void *callback_param; + + spin_lock_irqsave(&d40c->lock, flags); + + /* Get first active entry from list */ + d40d_fin = d40_first_active_get(d40c); + + if (d40d_fin == NULL) + goto err; + + d40c->completed = d40d_fin->txd.cookie; + + /* + * If terminating a channel pending_tx is set to zero. + * This prevents any finished active jobs to return to the client. + */ + if (d40c->pending_tx == 0) { + spin_unlock_irqrestore(&d40c->lock, flags); + return; + } + + /* Callback to client */ + callback = d40d_fin->txd.callback; + callback_param = d40d_fin->txd.callback_param; + + if (async_tx_test_ack(&d40d_fin->txd)) { + d40_pool_lli_free(d40d_fin); + d40_desc_remove(d40d_fin); + /* Return desc to free-list */ + d40_desc_free(d40c, d40d_fin); + } else { + d40_desc_reset(d40d_fin); + if (!d40d_fin->is_in_client_list) { + d40_desc_remove(d40d_fin); + list_add_tail(&d40d_fin->node, &d40c->client); + d40d_fin->is_in_client_list = true; + } + } + + d40c->pending_tx--; + + if (d40c->pending_tx) + tasklet_schedule(&d40c->tasklet); + + spin_unlock_irqrestore(&d40c->lock, flags); + + if (callback) + callback(callback_param); + + return; + + err: + /* Rescue manouver if receiving double interrupts */ + if (d40c->pending_tx > 0) + d40c->pending_tx--; + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static irqreturn_t d40_handle_interrupt(int irq, void *data) +{ + static const struct d40_interrupt_lookup il[] = { + {D40_DREG_LCTIS0, D40_DREG_LCICR0, false, 0}, + {D40_DREG_LCTIS1, D40_DREG_LCICR1, false, 32}, + {D40_DREG_LCTIS2, D40_DREG_LCICR2, false, 64}, + {D40_DREG_LCTIS3, D40_DREG_LCICR3, false, 96}, + {D40_DREG_LCEIS0, D40_DREG_LCICR0, true, 0}, + {D40_DREG_LCEIS1, D40_DREG_LCICR1, true, 32}, + {D40_DREG_LCEIS2, D40_DREG_LCICR2, true, 64}, + {D40_DREG_LCEIS3, D40_DREG_LCICR3, true, 96}, + {D40_DREG_PCTIS, D40_DREG_PCICR, false, D40_PHY_CHAN}, + {D40_DREG_PCEIS, D40_DREG_PCICR, true, D40_PHY_CHAN}, + }; + + int i; + u32 regs[ARRAY_SIZE(il)]; + u32 tmp; + u32 idx; + u32 row; + long chan = -1; + struct d40_chan *d40c; + unsigned long flags; + struct d40_base *base = data; + + spin_lock_irqsave(&base->interrupt_lock, flags); + + /* Read interrupt status of both logical and physical channels */ + for (i = 0; i < ARRAY_SIZE(il); i++) + regs[i] = readl(base->virtbase + il[i].src); + + for (;;) { + + chan = find_next_bit((unsigned long *)regs, + BITS_PER_LONG * ARRAY_SIZE(il), chan + 1); + + /* No more set bits found? */ + if (chan == BITS_PER_LONG * ARRAY_SIZE(il)) + break; + + row = chan / BITS_PER_LONG; + idx = chan & (BITS_PER_LONG - 1); + + /* ACK interrupt */ + tmp = readl(base->virtbase + il[row].clr); + tmp |= 1 << idx; + writel(tmp, base->virtbase + il[row].clr); + + if (il[row].offset == D40_PHY_CHAN) + d40c = base->lookup_phy_chans[idx]; + else + d40c = base->lookup_log_chans[il[row].offset + idx]; + spin_lock(&d40c->lock); + + if (!il[row].is_error) + dma_tc_handle(d40c); + else + dev_err(base->dev, "[%s] IRQ chan: %ld offset %d idx %d\n", + __func__, chan, il[row].offset, idx); + + spin_unlock(&d40c->lock); + } + + spin_unlock_irqrestore(&base->interrupt_lock, flags); + + return IRQ_HANDLED; +} + + +static int d40_validate_conf(struct d40_chan *d40c, + struct stedma40_chan_cfg *conf) +{ + int res = 0; + u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type); + u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type); + bool is_log = (conf->channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) + == STEDMA40_CHANNEL_IN_LOG_MODE; + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH && + dst_event_group == STEDMA40_DEV_DST_MEMORY) { + dev_err(&d40c->chan.dev->device, "[%s] Invalid dst\n", + __func__); + res = -EINVAL; + } + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM && + src_event_group == STEDMA40_DEV_SRC_MEMORY) { + dev_err(&d40c->chan.dev->device, "[%s] Invalid src\n", + __func__); + res = -EINVAL; + } + + if (src_event_group == STEDMA40_DEV_SRC_MEMORY && + dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) { + dev_err(&d40c->chan.dev->device, + "[%s] No event line\n", __func__); + res = -EINVAL; + } + + if (conf->dir == STEDMA40_PERIPH_TO_PERIPH && + (src_event_group != dst_event_group)) { + dev_err(&d40c->chan.dev->device, + "[%s] Invalid event group\n", __func__); + res = -EINVAL; + } + + if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { + /* + * DMAC HW supports it. Will be added to this driver, + * in case any dma client requires it. + */ + dev_err(&d40c->chan.dev->device, + "[%s] periph to periph not supported\n", + __func__); + res = -EINVAL; + } + + return res; +} + +static bool d40_alloc_mask_set(struct d40_phy_res *phy, bool is_src, + int log_event_line) +{ + unsigned long flags; + spin_lock_irqsave(&phy->lock, flags); + if (!log_event_line) { + /* Physical interrupts are masked per physical full channel */ + if (phy->allocated_src == D40_ALLOC_FREE && + phy->allocated_dst == D40_ALLOC_FREE) { + phy->allocated_dst = D40_ALLOC_PHY; + phy->allocated_src = D40_ALLOC_PHY; + goto found; + } else + goto not_found; + } + + /* Logical channel */ + if (is_src) { + if (phy->allocated_src == D40_ALLOC_PHY) + goto not_found; + + if (phy->allocated_src == D40_ALLOC_FREE) + phy->allocated_src = D40_ALLOC_LOG_FREE; + + if (!(phy->allocated_src & (1 << log_event_line))) { + phy->allocated_src |= 1 << log_event_line; + goto found; + } else + goto not_found; + } else { + if (phy->allocated_dst == D40_ALLOC_PHY) + goto not_found; + + if (phy->allocated_dst == D40_ALLOC_FREE) + phy->allocated_dst = D40_ALLOC_LOG_FREE; + + if (!(phy->allocated_dst & (1 << log_event_line))) { + phy->allocated_dst |= 1 << log_event_line; + goto found; + } else + goto not_found; + } + +not_found: + spin_unlock_irqrestore(&phy->lock, flags); + return false; +found: + spin_unlock_irqrestore(&phy->lock, flags); + return true; +} + +static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src, + int log_event_line) +{ + unsigned long flags; + bool is_free = false; + + spin_lock_irqsave(&phy->lock, flags); + if (!log_event_line) { + /* Physical interrupts are masked per physical full channel */ + phy->allocated_dst = D40_ALLOC_FREE; + phy->allocated_src = D40_ALLOC_FREE; + is_free = true; + goto out; + } + + /* Logical channel */ + if (is_src) { + phy->allocated_src &= ~(1 << log_event_line); + if (phy->allocated_src == D40_ALLOC_LOG_FREE) + phy->allocated_src = D40_ALLOC_FREE; + } else { + phy->allocated_dst &= ~(1 << log_event_line); + if (phy->allocated_dst == D40_ALLOC_LOG_FREE) + phy->allocated_dst = D40_ALLOC_FREE; + } + + is_free = ((phy->allocated_src | phy->allocated_dst) == + D40_ALLOC_FREE); + +out: + spin_unlock_irqrestore(&phy->lock, flags); + + return is_free; +} + +static int d40_allocate_channel(struct d40_chan *d40c) +{ + int dev_type; + int event_group; + int event_line; + struct d40_phy_res *phys; + int i; + int j; + int log_num; + bool is_src; + bool is_log = (d40c->dma_cfg.channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) + == STEDMA40_CHANNEL_IN_LOG_MODE; + + + phys = d40c->base->phy_res; + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + dev_type = d40c->dma_cfg.src_dev_type; + log_num = 2 * dev_type; + is_src = true; + } else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + /* dst event lines are used for logical memcpy */ + dev_type = d40c->dma_cfg.dst_dev_type; + log_num = 2 * dev_type + 1; + is_src = false; + } else + return -EINVAL; + + event_group = D40_TYPE_TO_GROUP(dev_type); + event_line = D40_TYPE_TO_EVENT(dev_type); + + if (!is_log) { + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + /* Find physical half channel */ + for (i = 0; i < d40c->base->num_phy_chans; i++) { + + if (d40_alloc_mask_set(&phys[i], is_src, 0)) + goto found_phy; + } + } else + for (j = 0; j < d40c->base->num_phy_chans; j += 8) { + int phy_num = j + event_group * 2; + for (i = phy_num; i < phy_num + 2; i++) { + if (d40_alloc_mask_set(&phys[i], + is_src, 0)) + goto found_phy; + } + } + return -EINVAL; +found_phy: + d40c->phy_chan = &phys[i]; + d40c->log_num = D40_PHY_CHAN; + goto out; + } + if (dev_type == -1) + return -EINVAL; + + /* Find logical channel */ + for (j = 0; j < d40c->base->num_phy_chans; j += 8) { + int phy_num = j + event_group * 2; + /* + * Spread logical channels across all available physical rather + * than pack every logical channel at the first available phy + * channels. + */ + if (is_src) { + for (i = phy_num; i < phy_num + 2; i++) { + if (d40_alloc_mask_set(&phys[i], is_src, + event_line)) + goto found_log; + } + } else { + for (i = phy_num + 1; i >= phy_num; i--) { + if (d40_alloc_mask_set(&phys[i], is_src, + event_line)) + goto found_log; + } + } + } + return -EINVAL; + +found_log: + d40c->phy_chan = &phys[i]; + d40c->log_num = log_num; +out: + + if (is_log) + d40c->base->lookup_log_chans[d40c->log_num] = d40c; + else + d40c->base->lookup_phy_chans[d40c->phy_chan->num] = d40c; + + return 0; + +} + +static int d40_config_chan(struct d40_chan *d40c, + struct stedma40_chan_cfg *info) +{ + + /* Fill in basic CFG register values */ + d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg, + &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN); + + if (d40c->log_num != D40_PHY_CHAN) { + d40_log_cfg(&d40c->dma_cfg, + &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.src_dev_type * 32; + else + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.dst_dev_type * 32 + 16; + } + + /* Write channel configuration to the DMA */ + return d40_config_write(d40c); +} + +static int d40_config_memcpy(struct d40_chan *d40c) +{ + dma_cap_mask_t cap = d40c->chan.device->cap_mask; + + if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) { + d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log; + d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY; + d40c->dma_cfg.dst_dev_type = d40c->base->plat_data-> + memcpy[d40c->chan.chan_id]; + + } else if (dma_has_cap(DMA_MEMCPY, cap) && + dma_has_cap(DMA_SLAVE, cap)) { + d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy; + } else { + dev_err(&d40c->chan.dev->device, "[%s] No memcpy\n", + __func__); + return -EINVAL; + } + + return 0; +} + + +static int d40_free_dma(struct d40_chan *d40c) +{ + + int res = 0; + u32 event, dir; + struct d40_phy_res *phy = d40c->phy_chan; + bool is_src; + + /* Terminate all queued and active transfers */ + d40_term_all(d40c); + + if (phy == NULL) { + dev_err(&d40c->chan.dev->device, "[%s] phy == null\n", + __func__); + return -EINVAL; + } + + if (phy->allocated_src == D40_ALLOC_FREE && + phy->allocated_dst == D40_ALLOC_FREE) { + dev_err(&d40c->chan.dev->device, "[%s] channel already free\n", + __func__); + return -EINVAL; + } + + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) { + dev_err(&d40c->chan.dev->device, "[%s] suspend\n", + __func__); + return res; + } + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + dir = D40_CHAN_REG_SDLNK; + is_src = false; + } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + dir = D40_CHAN_REG_SSLNK; + is_src = true; + } else { + dev_err(&d40c->chan.dev->device, + "[%s] Unknown direction\n", __func__); + return -EINVAL; + } + + if (d40c->log_num != D40_PHY_CHAN) { + /* + * Release logical channel, deactivate the event line during + * the time physical res is suspended. + */ + writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) & + D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + phy->num * D40_DREG_PCDELTA + dir); + + d40c->base->lookup_log_chans[d40c->log_num] = NULL; + + /* + * Check if there are more logical allocation + * on this phy channel. + */ + if (!d40_alloc_mask_free(phy, is_src, event)) { + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + if (res) { + dev_err(&d40c->chan.dev->device, + "[%s] Executing RUN command\n", + __func__); + return res; + } + } + return 0; + } + } else + d40_alloc_mask_free(phy, is_src, 0); + + /* Release physical channel */ + res = d40_channel_execute_command(d40c, D40_DMA_STOP); + if (res) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to stop channel\n", __func__); + return res; + } + d40c->phy_chan = NULL; + /* Invalidate channel type */ + d40c->dma_cfg.channel_type = 0; + d40c->base->lookup_phy_chans[phy->num] = NULL; + + return 0; + + +} + +static int d40_pause(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int res; + + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res == 0) { + if (d40c->log_num != D40_PHY_CHAN) { + d40_config_set_event(d40c, false); + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + } + } + + spin_unlock_irqrestore(&d40c->lock, flags); + return res; +} + +static bool d40_tx_is_linked(struct d40_chan *d40c) +{ + bool is_link; + + if (d40c->log_num != D40_PHY_CHAN) + is_link = readl(&d40c->lcpa->lcsp3) & D40_MEM_LCSP3_DLOS_MASK; + else + is_link = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK) & + D40_SREG_LNK_PHYS_LNK_MASK; + return is_link; +} + +static u32 d40_residue(struct d40_chan *d40c) +{ + u32 num_elt; + + if (d40c->log_num != D40_PHY_CHAN) + num_elt = (readl(&d40c->lcpa->lcsp2) & D40_MEM_LCSP2_ECNT_MASK) + >> D40_MEM_LCSP2_ECNT_POS; + else + num_elt = (readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDELT) & + D40_SREG_ELEM_PHY_ECNT_MASK) >> D40_SREG_ELEM_PHY_ECNT_POS; + return num_elt * (1 << d40c->dma_cfg.dst_info.data_width); +} + +static int d40_resume(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int res = 0; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num != D40_PHY_CHAN) { + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) + goto out; + + /* If bytes left to transfer or linked tx resume job */ + if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { + d40_config_set_event(d40c, true); + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + } + } else if (d40_residue(d40c) || d40_tx_is_linked(d40c)) + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + +out: + spin_unlock_irqrestore(&d40c->lock, flags); + return res; +} + +static u32 stedma40_residue(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + u32 bytes_left; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + bytes_left = d40_residue(d40c); + spin_unlock_irqrestore(&d40c->lock, flags); + + return bytes_left; +} + +/* Public DMA functions in addition to the DMA engine framework */ + +int stedma40_set_psize(struct dma_chan *chan, + int src_psize, + int dst_psize) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num != D40_PHY_CHAN) { + d40c->log_def.lcsp1 &= ~D40_MEM_LCSP1_SCFG_PSIZE_MASK; + d40c->log_def.lcsp3 &= ~D40_MEM_LCSP1_SCFG_PSIZE_MASK; + d40c->log_def.lcsp1 |= src_psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + d40c->log_def.lcsp3 |= dst_psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + goto out; + } + + if (src_psize == STEDMA40_PSIZE_PHY_1) + d40c->src_def_cfg &= ~(1 << D40_SREG_CFG_PHY_PEN_POS); + else { + d40c->src_def_cfg |= 1 << D40_SREG_CFG_PHY_PEN_POS; + d40c->src_def_cfg &= ~(STEDMA40_PSIZE_PHY_16 << + D40_SREG_CFG_PSIZE_POS); + d40c->src_def_cfg |= src_psize << D40_SREG_CFG_PSIZE_POS; + } + + if (dst_psize == STEDMA40_PSIZE_PHY_1) + d40c->dst_def_cfg &= ~(1 << D40_SREG_CFG_PHY_PEN_POS); + else { + d40c->dst_def_cfg |= 1 << D40_SREG_CFG_PHY_PEN_POS; + d40c->dst_def_cfg &= ~(STEDMA40_PSIZE_PHY_16 << + D40_SREG_CFG_PSIZE_POS); + d40c->dst_def_cfg |= dst_psize << D40_SREG_CFG_PSIZE_POS; + } +out: + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; +} +EXPORT_SYMBOL(stedma40_set_psize); + +struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan, + struct scatterlist *sgl_dst, + struct scatterlist *sgl_src, + unsigned int sgl_len, + unsigned long flags) +{ + int res; + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int lli_max = d40c->base->plat_data->llis_per_log; + + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + + if (d40d == NULL) + goto err; + + memset(d40d, 0, sizeof(struct d40_desc)); + d40d->lli_len = sgl_len; + + d40d->txd.flags = flags; + + if (d40c->log_num != D40_PHY_CHAN) { + if (sgl_len > 1) + /* + * Check if there is space available in lcla. If not, + * split list into 1-length and run only in lcpa + * space. + */ + if (d40_lcla_id_get(d40c, + &d40c->base->lcla_pool) != 0) + lli_max = 1; + + if (d40_pool_lli_alloc(d40d, sgl_len, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + (void) d40_log_sg_to_lli(d40c->lcla.src_id, + sgl_src, + sgl_len, + d40d->lli_log.src, + d40c->log_def.lcsp1, + d40c->dma_cfg.src_info.data_width, + flags & DMA_PREP_INTERRUPT, lli_max, + d40c->base->plat_data->llis_per_log); + + (void) d40_log_sg_to_lli(d40c->lcla.dst_id, + sgl_dst, + sgl_len, + d40d->lli_log.dst, + d40c->log_def.lcsp3, + d40c->dma_cfg.dst_info.data_width, + flags & DMA_PREP_INTERRUPT, lli_max, + d40c->base->plat_data->llis_per_log); + + + } else { + if (d40_pool_lli_alloc(d40d, sgl_len, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + res = d40_phy_sg_to_lli(sgl_src, + sgl_len, + 0, + d40d->lli_phy.src, + d40d->lli_phy.src_addr, + d40c->src_def_cfg, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.src_info.psize, + true); + + if (res < 0) + goto err; + + res = d40_phy_sg_to_lli(sgl_dst, + sgl_len, + 0, + d40d->lli_phy.dst, + d40d->lli_phy.dst_addr, + d40c->dst_def_cfg, + d40c->dma_cfg.dst_info.data_width, + d40c->dma_cfg.dst_info.psize, + true); + + if (res < 0) + goto err; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + } + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + spin_unlock_irqrestore(&d40c->lock, flg); + + return &d40d->txd; +err: + spin_unlock_irqrestore(&d40c->lock, flg); + return NULL; +} +EXPORT_SYMBOL(stedma40_memcpy_sg); + +bool stedma40_filter(struct dma_chan *chan, void *data) +{ + struct stedma40_chan_cfg *info = data; + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int err; + + if (data) { + err = d40_validate_conf(d40c, info); + if (!err) + d40c->dma_cfg = *info; + } else + err = d40_config_memcpy(d40c); + + return err == 0; +} +EXPORT_SYMBOL(stedma40_filter); + +/* DMA ENGINE functions */ +static int d40_alloc_chan_resources(struct dma_chan *chan) +{ + int err; + unsigned long flags; + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + + spin_lock_irqsave(&d40c->lock, flags); + + d40c->completed = chan->cookie = 1; + + /* + * If no dma configuration is set (channel_type == 0) + * use default configuration + */ + if (d40c->dma_cfg.channel_type == 0) { + err = d40_config_memcpy(d40c); + if (err) + goto err_alloc; + } + + err = d40_allocate_channel(d40c); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to allocate channel\n", __func__); + goto err_alloc; + } + + err = d40_config_chan(d40c, &d40c->dma_cfg); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to configure channel\n", + __func__); + goto err_config; + } + + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; + + err_config: + (void) d40_free_dma(d40c); + err_alloc: + spin_unlock_irqrestore(&d40c->lock, flags); + dev_err(&d40c->chan.dev->device, + "[%s] Channel allocation failed\n", __func__); + return -EINVAL; +} + +static void d40_free_chan_resources(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int err; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + err = d40_free_dma(d40c); + + if (err) + dev_err(&d40c->chan.dev->device, + "[%s] Failed to free channel\n", __func__); + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static struct dma_async_tx_descriptor *d40_prep_memcpy(struct dma_chan *chan, + dma_addr_t dst, + dma_addr_t src, + size_t size, + unsigned long flags) +{ + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int err = 0; + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + + if (d40d == NULL) { + dev_err(&d40c->chan.dev->device, + "[%s] Descriptor is NULL\n", __func__); + goto err; + } + + memset(d40d, 0, sizeof(struct d40_desc)); + + d40d->txd.flags = flags; + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + if (d40c->log_num != D40_PHY_CHAN) { + + if (d40_pool_lli_alloc(d40d, 1, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + d40d->lli_len = 1; + + d40_log_fill_lli(d40d->lli_log.src, + src, + size, + 0, + d40c->log_def.lcsp1, + d40c->dma_cfg.src_info.data_width, + true, true); + + d40_log_fill_lli(d40d->lli_log.dst, + dst, + size, + 0, + d40c->log_def.lcsp3, + d40c->dma_cfg.dst_info.data_width, + true, true); + + } else { + + if (d40_pool_lli_alloc(d40d, 1, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + err = d40_phy_fill_lli(d40d->lli_phy.src, + src, + size, + d40c->dma_cfg.src_info.psize, + 0, + d40c->src_def_cfg, + true, + d40c->dma_cfg.src_info.data_width, + false); + if (err) + goto err_fill_lli; + + err = d40_phy_fill_lli(d40d->lli_phy.dst, + dst, + size, + d40c->dma_cfg.dst_info.psize, + 0, + d40c->dst_def_cfg, + true, + d40c->dma_cfg.dst_info.data_width, + false); + + if (err) + goto err_fill_lli; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + } + + spin_unlock_irqrestore(&d40c->lock, flg); + return &d40d->txd; + +err_fill_lli: + dev_err(&d40c->chan.dev->device, + "[%s] Failed filling in PHY LLI\n", __func__); + d40_pool_lli_free(d40d); +err: + spin_unlock_irqrestore(&d40c->lock, flg); + return NULL; +} + +static int d40_prep_slave_sg_log(struct d40_desc *d40d, + struct d40_chan *d40c, + struct scatterlist *sgl, + unsigned int sg_len, + enum dma_data_direction direction, + unsigned long flags) +{ + dma_addr_t dev_addr = 0; + int total_size; + int lli_max = d40c->base->plat_data->llis_per_log; + + if (d40_pool_lli_alloc(d40d, sg_len, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + return -ENOMEM; + } + + d40d->lli_len = sg_len; + d40d->lli_tcount = 0; + + if (sg_len > 1) + /* + * Check if there is space available in lcla. + * If not, split list into 1-length and run only + * in lcpa space. + */ + if (d40_lcla_id_get(d40c, &d40c->base->lcla_pool) != 0) + lli_max = 1; + + if (direction == DMA_FROM_DEVICE) { + dev_addr = d40c->base->plat_data->dev_rx[d40c->dma_cfg.src_dev_type]; + total_size = d40_log_sg_to_dev(&d40c->lcla, + sgl, sg_len, + &d40d->lli_log, + &d40c->log_def, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.dst_info.data_width, + direction, + flags & DMA_PREP_INTERRUPT, + dev_addr, lli_max, + d40c->base->plat_data->llis_per_log); + } else if (direction == DMA_TO_DEVICE) { + dev_addr = d40c->base->plat_data->dev_tx[d40c->dma_cfg.dst_dev_type]; + total_size = d40_log_sg_to_dev(&d40c->lcla, + sgl, sg_len, + &d40d->lli_log, + &d40c->log_def, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.dst_info.data_width, + direction, + flags & DMA_PREP_INTERRUPT, + dev_addr, lli_max, + d40c->base->plat_data->llis_per_log); + } else + return -EINVAL; + if (total_size < 0) + return -EINVAL; + + return 0; +} + +static int d40_prep_slave_sg_phy(struct d40_desc *d40d, + struct d40_chan *d40c, + struct scatterlist *sgl, + unsigned int sgl_len, + enum dma_data_direction direction, + unsigned long flags) +{ + dma_addr_t src_dev_addr; + dma_addr_t dst_dev_addr; + int res; + + if (d40_pool_lli_alloc(d40d, sgl_len, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + return -ENOMEM; + } + + d40d->lli_len = sgl_len; + d40d->lli_tcount = 0; + + if (direction == DMA_FROM_DEVICE) { + dst_dev_addr = 0; + src_dev_addr = d40c->base->plat_data->dev_rx[d40c->dma_cfg.src_dev_type]; + } else if (direction == DMA_TO_DEVICE) { + dst_dev_addr = d40c->base->plat_data->dev_tx[d40c->dma_cfg.dst_dev_type]; + src_dev_addr = 0; + } else + return -EINVAL; + + res = d40_phy_sg_to_lli(sgl, + sgl_len, + src_dev_addr, + d40d->lli_phy.src, + d40d->lli_phy.src_addr, + d40c->src_def_cfg, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.src_info.psize, + true); + if (res < 0) + return res; + + res = d40_phy_sg_to_lli(sgl, + sgl_len, + dst_dev_addr, + d40d->lli_phy.dst, + d40d->lli_phy.dst_addr, + d40c->dst_def_cfg, + d40c->dma_cfg.dst_info.data_width, + d40c->dma_cfg.dst_info.psize, + true); + if (res < 0) + return res; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + return 0; +} + +static struct dma_async_tx_descriptor *d40_prep_slave_sg(struct dma_chan *chan, + struct scatterlist *sgl, + unsigned int sg_len, + enum dma_data_direction direction, + unsigned long flags) +{ + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int err; + + if (d40c->dma_cfg.pre_transfer) + d40c->dma_cfg.pre_transfer(chan, + d40c->dma_cfg.pre_transfer_data, + sg_dma_len(sgl)); + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + spin_unlock_irqrestore(&d40c->lock, flg); + + if (d40d == NULL) + return NULL; + + memset(d40d, 0, sizeof(struct d40_desc)); + + if (d40c->log_num != D40_PHY_CHAN) + err = d40_prep_slave_sg_log(d40d, d40c, sgl, sg_len, + direction, flags); + else + err = d40_prep_slave_sg_phy(d40d, d40c, sgl, sg_len, + direction, flags); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to prepare %s slave sg job: %d\n", + __func__, + d40c->log_num != D40_PHY_CHAN ? "log" : "phy", err); + return NULL; + } + + d40d->txd.flags = flags; + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + return &d40d->txd; +} + +static enum dma_status d40_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + int ret; + + last_complete = d40c->completed; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = stedma40_residue(chan); + } + + return ret; +} + +static void d40_issue_pending(struct dma_chan *chan) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + /* Busy means that pending jobs are already being processed */ + if (!d40c->busy) + (void) d40_queue_start(d40c); + + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +{ + unsigned long flags; + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(&d40c->lock, flags); + d40_term_all(d40c); + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; + case DMA_PAUSE: + return d40_pause(chan); + case DMA_RESUME: + return d40_resume(chan); + } + + /* Other commands are unimplemented */ + return -ENXIO; +} + +/* Initialization functions */ + +static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma, + struct d40_chan *chans, int offset, + int num_chans) +{ + int i = 0; + struct d40_chan *d40c; + + INIT_LIST_HEAD(&dma->channels); + + for (i = offset; i < offset + num_chans; i++) { + d40c = &chans[i]; + d40c->base = base; + d40c->chan.device = dma; + + /* Invalidate lcla element */ + d40c->lcla.src_id = -1; + d40c->lcla.dst_id = -1; + + spin_lock_init(&d40c->lock); + + d40c->log_num = D40_PHY_CHAN; + + INIT_LIST_HEAD(&d40c->free); + INIT_LIST_HEAD(&d40c->active); + INIT_LIST_HEAD(&d40c->queue); + INIT_LIST_HEAD(&d40c->client); + + d40c->free_len = 0; + + tasklet_init(&d40c->tasklet, dma_tasklet, + (unsigned long) d40c); + + list_add_tail(&d40c->chan.device_node, + &dma->channels); + } +} + +static int __init d40_dmaengine_init(struct d40_base *base, + int num_reserved_chans) +{ + int err ; + + d40_chan_init(base, &base->dma_slave, base->log_chans, + 0, base->num_log_chans); + + dma_cap_zero(base->dma_slave.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask); + + base->dma_slave.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_slave.device_free_chan_resources = d40_free_chan_resources; + base->dma_slave.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_slave.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_slave.device_tx_status = d40_tx_status; + base->dma_slave.device_issue_pending = d40_issue_pending; + base->dma_slave.device_control = d40_control; + base->dma_slave.dev = base->dev; + + err = dma_async_device_register(&base->dma_slave); + + if (err) { + dev_err(base->dev, + "[%s] Failed to register slave channels\n", + __func__); + goto failure1; + } + + d40_chan_init(base, &base->dma_memcpy, base->log_chans, + base->num_log_chans, base->plat_data->memcpy_len); + + dma_cap_zero(base->dma_memcpy.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); + + base->dma_memcpy.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_memcpy.device_free_chan_resources = d40_free_chan_resources; + base->dma_memcpy.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_memcpy.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_memcpy.device_tx_status = d40_tx_status; + base->dma_memcpy.device_issue_pending = d40_issue_pending; + base->dma_memcpy.device_control = d40_control; + base->dma_memcpy.dev = base->dev; + /* + * This controller can only access address at even + * 32bit boundaries, i.e. 2^2 + */ + base->dma_memcpy.copy_align = 2; + + err = dma_async_device_register(&base->dma_memcpy); + + if (err) { + dev_err(base->dev, + "[%s] Failed to regsiter memcpy only channels\n", + __func__); + goto failure2; + } + + d40_chan_init(base, &base->dma_both, base->phy_chans, + 0, num_reserved_chans); + + dma_cap_zero(base->dma_both.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_both.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_both.cap_mask); + + base->dma_both.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_both.device_free_chan_resources = d40_free_chan_resources; + base->dma_both.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_both.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_both.device_tx_status = d40_tx_status; + base->dma_both.device_issue_pending = d40_issue_pending; + base->dma_both.device_control = d40_control; + base->dma_both.dev = base->dev; + base->dma_both.copy_align = 2; + err = dma_async_device_register(&base->dma_both); + + if (err) { + dev_err(base->dev, + "[%s] Failed to register logical and physical capable channels\n", + __func__); + goto failure3; + } + return 0; +failure3: + dma_async_device_unregister(&base->dma_memcpy); +failure2: + dma_async_device_unregister(&base->dma_slave); +failure1: + return err; +} + +/* Initialization functions. */ + +static int __init d40_phy_res_init(struct d40_base *base) +{ + int i; + int num_phy_chans_avail = 0; + u32 val[2]; + int odd_even_bit = -2; + + val[0] = readl(base->virtbase + D40_DREG_PRSME); + val[1] = readl(base->virtbase + D40_DREG_PRSMO); + + for (i = 0; i < base->num_phy_chans; i++) { + base->phy_res[i].num = i; + odd_even_bit += 2 * ((i % 2) == 0); + if (((val[i % 2] >> odd_even_bit) & 3) == 1) { + /* Mark security only channels as occupied */ + base->phy_res[i].allocated_src = D40_ALLOC_PHY; + base->phy_res[i].allocated_dst = D40_ALLOC_PHY; + } else { + base->phy_res[i].allocated_src = D40_ALLOC_FREE; + base->phy_res[i].allocated_dst = D40_ALLOC_FREE; + num_phy_chans_avail++; + } + spin_lock_init(&base->phy_res[i].lock); + } + dev_info(base->dev, "%d of %d physical DMA channels available\n", + num_phy_chans_avail, base->num_phy_chans); + + /* Verify settings extended vs standard */ + val[0] = readl(base->virtbase + D40_DREG_PRTYP); + + for (i = 0; i < base->num_phy_chans; i++) { + + if (base->phy_res[i].allocated_src == D40_ALLOC_FREE && + (val[0] & 0x3) != 1) + dev_info(base->dev, + "[%s] INFO: channel %d is misconfigured (%d)\n", + __func__, i, val[0] & 0x3); + + val[0] = val[0] >> 2; + } + + return num_phy_chans_avail; +} + +static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) +{ + static const struct d40_reg_val dma_id_regs[] = { + /* Peripheral Id */ + { .reg = D40_DREG_PERIPHID0, .val = 0x0040}, + { .reg = D40_DREG_PERIPHID1, .val = 0x0000}, + /* + * D40_DREG_PERIPHID2 Depends on HW revision: + * MOP500/HREF ED has 0x0008, + * ? has 0x0018, + * HREF V1 has 0x0028 + */ + { .reg = D40_DREG_PERIPHID3, .val = 0x0000}, + + /* PCell Id */ + { .reg = D40_DREG_CELLID0, .val = 0x000d}, + { .reg = D40_DREG_CELLID1, .val = 0x00f0}, + { .reg = D40_DREG_CELLID2, .val = 0x0005}, + { .reg = D40_DREG_CELLID3, .val = 0x00b1} + }; + struct stedma40_platform_data *plat_data; + struct clk *clk = NULL; + void __iomem *virtbase = NULL; + struct resource *res = NULL; + struct d40_base *base = NULL; + int num_log_chans = 0; + int num_phy_chans; + int i; + + clk = clk_get(&pdev->dev, NULL); + + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "[%s] No matching clock found\n", + __func__); + goto failure; + } + + clk_enable(clk); + + /* Get IO for DMAC base address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); + if (!res) + goto failure; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O base") == NULL) + goto failure; + + virtbase = ioremap(res->start, resource_size(res)); + if (!virtbase) + goto failure; + + /* HW version check */ + for (i = 0; i < ARRAY_SIZE(dma_id_regs); i++) { + if (dma_id_regs[i].val != + readl(virtbase + dma_id_regs[i].reg)) { + dev_err(&pdev->dev, + "[%s] Unknown hardware! Expected 0x%x at 0x%x but got 0x%x\n", + __func__, + dma_id_regs[i].val, + dma_id_regs[i].reg, + readl(virtbase + dma_id_regs[i].reg)); + goto failure; + } + } + + i = readl(virtbase + D40_DREG_PERIPHID2); + + if ((i & 0xf) != D40_PERIPHID2_DESIGNER) { + dev_err(&pdev->dev, + "[%s] Unknown designer! Got %x wanted %x\n", + __func__, i & 0xf, D40_PERIPHID2_DESIGNER); + goto failure; + } + + /* The number of physical channels on this HW */ + num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + + dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n", + (i >> 4) & 0xf, res->start); + + plat_data = pdev->dev.platform_data; + + /* Count the number of logical channels in use */ + for (i = 0; i < plat_data->dev_len; i++) + if (plat_data->dev_rx[i] != 0) + num_log_chans++; + + for (i = 0; i < plat_data->dev_len; i++) + if (plat_data->dev_tx[i] != 0) + num_log_chans++; + + base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + + (num_phy_chans + num_log_chans + plat_data->memcpy_len) * + sizeof(struct d40_chan), GFP_KERNEL); + + if (base == NULL) { + dev_err(&pdev->dev, "[%s] Out of memory\n", __func__); + goto failure; + } + + base->clk = clk; + base->num_phy_chans = num_phy_chans; + base->num_log_chans = num_log_chans; + base->phy_start = res->start; + base->phy_size = resource_size(res); + base->virtbase = virtbase; + base->plat_data = plat_data; + base->dev = &pdev->dev; + base->phy_chans = ((void *)base) + ALIGN(sizeof(struct d40_base), 4); + base->log_chans = &base->phy_chans[num_phy_chans]; + + base->phy_res = kzalloc(num_phy_chans * sizeof(struct d40_phy_res), + GFP_KERNEL); + if (!base->phy_res) + goto failure; + + base->lookup_phy_chans = kzalloc(num_phy_chans * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_phy_chans) + goto failure; + + if (num_log_chans + plat_data->memcpy_len) { + /* + * The max number of logical channels are event lines for all + * src devices and dst devices + */ + base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_log_chans) + goto failure; + } + base->lcla_pool.alloc_map = kzalloc(num_phy_chans * sizeof(u32), + GFP_KERNEL); + if (!base->lcla_pool.alloc_map) + goto failure; + + return base; + +failure: + if (clk) { + clk_disable(clk); + clk_put(clk); + } + if (virtbase) + iounmap(virtbase); + if (res) + release_mem_region(res->start, + resource_size(res)); + if (virtbase) + iounmap(virtbase); + + if (base) { + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); + } + + return NULL; +} + +static void __init d40_hw_init(struct d40_base *base) +{ + + static const struct d40_reg_val dma_init_reg[] = { + /* Clock every part of the DMA block from start */ + { .reg = D40_DREG_GCC, .val = 0x0000ff01}, + + /* Interrupts on all logical channels */ + { .reg = D40_DREG_LCMIS0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS3, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR3, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS3, .val = 0xFFFFFFFF} + }; + int i; + u32 prmseo[2] = {0, 0}; + u32 activeo[2] = {0xFFFFFFFF, 0xFFFFFFFF}; + u32 pcmis = 0; + u32 pcicr = 0; + + for (i = 0; i < ARRAY_SIZE(dma_init_reg); i++) + writel(dma_init_reg[i].val, + base->virtbase + dma_init_reg[i].reg); + + /* Configure all our dma channels to default settings */ + for (i = 0; i < base->num_phy_chans; i++) { + + activeo[i % 2] = activeo[i % 2] << 2; + + if (base->phy_res[base->num_phy_chans - i - 1].allocated_src + == D40_ALLOC_PHY) { + activeo[i % 2] |= 3; + continue; + } + + /* Enable interrupt # */ + pcmis = (pcmis << 1) | 1; + + /* Clear interrupt # */ + pcicr = (pcicr << 1) | 1; + + /* Set channel to physical mode */ + prmseo[i % 2] = prmseo[i % 2] << 2; + prmseo[i % 2] |= 1; + + } + + writel(prmseo[1], base->virtbase + D40_DREG_PRMSE); + writel(prmseo[0], base->virtbase + D40_DREG_PRMSO); + writel(activeo[1], base->virtbase + D40_DREG_ACTIVE); + writel(activeo[0], base->virtbase + D40_DREG_ACTIVO); + + /* Write which interrupt to enable */ + writel(pcmis, base->virtbase + D40_DREG_PCMIS); + + /* Write which interrupt to clear */ + writel(pcicr, base->virtbase + D40_DREG_PCICR); + +} + +static int __init d40_probe(struct platform_device *pdev) +{ + int err; + int ret = -ENOENT; + struct d40_base *base; + struct resource *res = NULL; + int num_reserved_chans; + u32 val; + + base = d40_hw_detect_init(pdev); + + if (!base) + goto failure; + + num_reserved_chans = d40_phy_res_init(base); + + platform_set_drvdata(pdev, base); + + spin_lock_init(&base->interrupt_lock); + spin_lock_init(&base->execmd_lock); + + /* Get IO for logical channel parameter address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcpa"); + if (!res) { + ret = -ENOENT; + dev_err(&pdev->dev, + "[%s] No \"lcpa\" memory resource\n", + __func__); + goto failure; + } + base->lcpa_size = resource_size(res); + base->phy_lcpa = res->start; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O lcpa") == NULL) { + ret = -EBUSY; + dev_err(&pdev->dev, + "[%s] Failed to request LCPA region 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + + /* We make use of ESRAM memory for this. */ + val = readl(base->virtbase + D40_DREG_LCPA); + if (res->start != val && val != 0) { + dev_warn(&pdev->dev, + "[%s] Mismatch LCPA dma 0x%x, def 0x%x\n", + __func__, val, res->start); + } else + writel(res->start, base->virtbase + D40_DREG_LCPA); + + base->lcpa_base = ioremap(res->start, resource_size(res)); + if (!base->lcpa_base) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "[%s] Failed to ioremap LCPA region\n", + __func__); + goto failure; + } + /* Get IO for logical channel link address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcla"); + if (!res) { + ret = -ENOENT; + dev_err(&pdev->dev, + "[%s] No \"lcla\" resource defined\n", + __func__); + goto failure; + } + + base->lcla_pool.base_size = resource_size(res); + base->lcla_pool.phy = res->start; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O lcla") == NULL) { + ret = -EBUSY; + dev_err(&pdev->dev, + "[%s] Failed to request LCLA region 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + val = readl(base->virtbase + D40_DREG_LCLA); + if (res->start != val && val != 0) { + dev_warn(&pdev->dev, + "[%s] Mismatch LCLA dma 0x%x, def 0x%x\n", + __func__, val, res->start); + } else + writel(res->start, base->virtbase + D40_DREG_LCLA); + + base->lcla_pool.base = ioremap(res->start, resource_size(res)); + if (!base->lcla_pool.base) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "[%s] Failed to ioremap LCLA 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + + spin_lock_init(&base->lcla_pool.lock); + + base->lcla_pool.num_blocks = base->num_phy_chans; + + base->irq = platform_get_irq(pdev, 0); + + ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); + + if (ret) { + dev_err(&pdev->dev, "[%s] No IRQ defined\n", __func__); + goto failure; + } + + err = d40_dmaengine_init(base, num_reserved_chans); + if (err) + goto failure; + + d40_hw_init(base); + + dev_info(base->dev, "initialized\n"); + return 0; + +failure: + if (base) { + if (base->virtbase) + iounmap(base->virtbase); + if (base->lcla_pool.phy) + release_mem_region(base->lcla_pool.phy, + base->lcla_pool.base_size); + if (base->phy_lcpa) + release_mem_region(base->phy_lcpa, + base->lcpa_size); + if (base->phy_start) + release_mem_region(base->phy_start, + base->phy_size); + if (base->clk) { + clk_disable(base->clk); + clk_put(base->clk); + } + + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); + } + + dev_err(&pdev->dev, "[%s] probe failed\n", __func__); + return ret; +} + +static struct platform_driver d40_driver = { + .driver = { + .owner = THIS_MODULE, + .name = D40_NAME, + }, +}; + +int __init stedma40_init(void) +{ + return platform_driver_probe(&d40_driver, d40_probe); +} +arch_initcall(stedma40_init); diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c new file mode 100644 index 000000000000..561fdd8a80c1 --- /dev/null +++ b/drivers/dma/ste_dma40_ll.c @@ -0,0 +1,454 @@ +/* + * driver/dma/ste_dma40_ll.c + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ + +#include +#include + +#include "ste_dma40_ll.h" + +/* Sets up proper LCSP1 and LCSP3 register for a logical channel */ +void d40_log_cfg(struct stedma40_chan_cfg *cfg, + u32 *lcsp1, u32 *lcsp3) +{ + u32 l3 = 0; /* dst */ + u32 l1 = 0; /* src */ + + /* src is mem? -> increase address pos */ + if (cfg->dir == STEDMA40_MEM_TO_PERIPH || + cfg->dir == STEDMA40_MEM_TO_MEM) + l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; + + /* dst is mem? -> increase address pos */ + if (cfg->dir == STEDMA40_PERIPH_TO_MEM || + cfg->dir == STEDMA40_MEM_TO_MEM) + l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; + + /* src is hw? -> master port 1 */ + if (cfg->dir == STEDMA40_PERIPH_TO_MEM || + cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; + + /* dst is hw? -> master port 1 */ + if (cfg->dir == STEDMA40_MEM_TO_PERIPH || + cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; + + l3 |= 1 << D40_MEM_LCSP3_DCFG_TIM_POS; + l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; + l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; + l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; + l3 |= 1 << D40_MEM_LCSP3_DTCP_POS; + + l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; + l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; + l1 |= 1 << D40_MEM_LCSP1_STCP_POS; + + *lcsp1 = l1; + *lcsp3 = l3; + +} + +/* Sets up SRC and DST CFG register for both logical and physical channels */ +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, + u32 *src_cfg, u32 *dst_cfg, bool is_log) +{ + u32 src = 0; + u32 dst = 0; + + if (!is_log) { + /* Physical channel */ + if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + src |= 1 << D40_SREG_CFG_MST_POS; + src |= D40_TYPE_TO_EVENT(cfg->src_dev_type); + + if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + src |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + src |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + dst |= 1 << D40_SREG_CFG_MST_POS; + dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type); + + if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + dst |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + dst |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + /* Interrupt on end of transfer for destination */ + dst |= 1 << D40_SREG_CFG_TIM_POS; + + /* Generate interrupt on error */ + src |= 1 << D40_SREG_CFG_EIM_POS; + dst |= 1 << D40_SREG_CFG_EIM_POS; + + /* PSIZE */ + if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { + src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; + } + if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { + dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; + dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; + } + + /* Element size */ + src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; + dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + + } else { + /* Logical channel */ + dst |= 1 << D40_SREG_CFG_LOG_GIM_POS; + src |= 1 << D40_SREG_CFG_LOG_GIM_POS; + } + + if (cfg->channel_type & STEDMA40_HIGH_PRIORITY_CHANNEL) { + src |= 1 << D40_SREG_CFG_PRI_POS; + dst |= 1 << D40_SREG_CFG_PRI_POS; + } + + src |= cfg->src_info.endianess << D40_SREG_CFG_LBE_POS; + dst |= cfg->dst_info.endianess << D40_SREG_CFG_LBE_POS; + + *src_cfg = src; + *dst_cfg = dst; +} + +int d40_phy_fill_lli(struct d40_phy_lli *lli, + dma_addr_t data, + u32 data_size, + int psize, + dma_addr_t next_lli, + u32 reg_cfg, + bool term_int, + u32 data_width, + bool is_device) +{ + int num_elems; + + if (psize == STEDMA40_PSIZE_PHY_1) + num_elems = 1; + else + num_elems = 2 << psize; + + /* + * Size is 16bit. data_width is 8, 16, 32 or 64 bit + * Block large than 64 KiB must be split. + */ + if (data_size > (0xffff << data_width)) + return -EINVAL; + + /* Must be aligned */ + if (!IS_ALIGNED(data, 0x1 << data_width)) + return -EINVAL; + + /* Transfer size can't be smaller than (num_elms * elem_size) */ + if (data_size < num_elems * (0x1 << data_width)) + return -EINVAL; + + /* The number of elements. IE now many chunks */ + lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; + + /* + * Distance to next element sized entry. + * Usually the size of the element unless you want gaps. + */ + if (!is_device) + lli->reg_elt |= (0x1 << data_width) << + D40_SREG_ELEM_PHY_EIDX_POS; + + /* Where the data is */ + lli->reg_ptr = data; + lli->reg_cfg = reg_cfg; + + /* If this scatter list entry is the last one, no next link */ + if (next_lli == 0) + lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; + else + lli->reg_lnk = next_lli; + + /* Set/clear interrupt generation on this link item.*/ + if (term_int) + lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; + else + lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); + + /* Post link */ + lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; + + return 0; +} + +int d40_phy_sg_to_lli(struct scatterlist *sg, + int sg_len, + dma_addr_t target, + struct d40_phy_lli *lli, + dma_addr_t lli_phys, + u32 reg_cfg, + u32 data_width, + int psize, + bool term_int) +{ + int total_size = 0; + int i; + struct scatterlist *current_sg = sg; + dma_addr_t next_lli_phys; + dma_addr_t dst; + int err = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + + total_size += sg_dma_len(current_sg); + + /* If this scatter list entry is the last one, no next link */ + if (sg_len - 1 == i) + next_lli_phys = 0; + else + next_lli_phys = ALIGN(lli_phys + (i + 1) * + sizeof(struct d40_phy_lli), + D40_LLI_ALIGN); + + if (target) + dst = target; + else + dst = sg_phys(current_sg); + + err = d40_phy_fill_lli(&lli[i], + dst, + sg_dma_len(current_sg), + psize, + next_lli_phys, + reg_cfg, + !next_lli_phys, + data_width, + target == dst); + if (err) + goto err; + } + + return total_size; + err: + return err; +} + + +void d40_phy_lli_write(void __iomem *virtbase, + u32 phy_chan_num, + struct d40_phy_lli *lli_dst, + struct d40_phy_lli *lli_src) +{ + + writel(lli_src->reg_cfg, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSCFG); + writel(lli_src->reg_elt, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSELT); + writel(lli_src->reg_ptr, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSPTR); + writel(lli_src->reg_lnk, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSLNK); + + writel(lli_dst->reg_cfg, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDCFG); + writel(lli_dst->reg_elt, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDELT); + writel(lli_dst->reg_ptr, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDPTR); + writel(lli_dst->reg_lnk, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDLNK); + +} + +/* DMA logical lli operations */ + +void d40_log_fill_lli(struct d40_log_lli *lli, + dma_addr_t data, u32 data_size, + u32 lli_next_off, u32 reg_cfg, + u32 data_width, + bool term_int, bool addr_inc) +{ + lli->lcsp13 = reg_cfg; + + /* The number of elements to transfer */ + lli->lcsp02 = ((data_size >> data_width) << + D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; + /* 16 LSBs address of the current element */ + lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; + /* 16 MSBs address of the current element */ + lli->lcsp13 |= data & D40_MEM_LCSP1_SPTR_MASK; + + if (addr_inc) + lli->lcsp13 |= D40_MEM_LCSP1_SCFG_INCR_MASK; + + lli->lcsp13 |= D40_MEM_LCSP3_DTCP_MASK; + /* If this scatter list entry is the last one, no next link */ + lli->lcsp13 |= (lli_next_off << D40_MEM_LCSP1_SLOS_POS) & + D40_MEM_LCSP1_SLOS_MASK; + + if (term_int) + lli->lcsp13 |= D40_MEM_LCSP1_SCFG_TIM_MASK; + else + lli->lcsp13 &= ~D40_MEM_LCSP1_SCFG_TIM_MASK; +} + +int d40_log_sg_to_dev(struct d40_lcla_elem *lcla, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli_bidir *lli, + struct d40_def_lcsp *lcsp, + u32 src_data_width, + u32 dst_data_width, + enum dma_data_direction direction, + bool term_int, dma_addr_t dev_addr, int max_len, + int llis_per_log) +{ + int total_size = 0; + struct scatterlist *current_sg = sg; + int i; + u32 next_lli_off_dst; + u32 next_lli_off_src; + + next_lli_off_src = 0; + next_lli_off_dst = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + total_size += sg_dma_len(current_sg); + + /* + * If this scatter list entry is the last one or + * max length, terminate link. + */ + if (sg_len - 1 == i || ((i+1) % max_len == 0)) { + next_lli_off_src = 0; + next_lli_off_dst = 0; + } else { + if (next_lli_off_dst == 0 && + next_lli_off_src == 0) { + /* The first lli will be at next_lli_off */ + next_lli_off_dst = (lcla->dst_id * + llis_per_log + 1); + next_lli_off_src = (lcla->src_id * + llis_per_log + 1); + } else { + next_lli_off_dst++; + next_lli_off_src++; + } + } + + if (direction == DMA_TO_DEVICE) { + d40_log_fill_lli(&lli->src[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off_src, + lcsp->lcsp1, src_data_width, + term_int && !next_lli_off_src, + true); + d40_log_fill_lli(&lli->dst[i], + dev_addr, + sg_dma_len(current_sg), + next_lli_off_dst, + lcsp->lcsp3, dst_data_width, + /* No next == terminal interrupt */ + term_int && !next_lli_off_dst, + false); + } else { + d40_log_fill_lli(&lli->dst[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off_dst, + lcsp->lcsp3, dst_data_width, + /* No next == terminal interrupt */ + term_int && !next_lli_off_dst, + true); + d40_log_fill_lli(&lli->src[i], + dev_addr, + sg_dma_len(current_sg), + next_lli_off_src, + lcsp->lcsp1, src_data_width, + term_int && !next_lli_off_src, + false); + } + } + return total_size; +} + +int d40_log_sg_to_lli(int lcla_id, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli *lli_sg, + u32 lcsp13, /* src or dst*/ + u32 data_width, + bool term_int, int max_len, int llis_per_log) +{ + int total_size = 0; + struct scatterlist *current_sg = sg; + int i; + u32 next_lli_off = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + total_size += sg_dma_len(current_sg); + + /* + * If this scatter list entry is the last one or + * max length, terminate link. + */ + if (sg_len - 1 == i || ((i+1) % max_len == 0)) + next_lli_off = 0; + else { + if (next_lli_off == 0) + /* The first lli will be at next_lli_off */ + next_lli_off = lcla_id * llis_per_log + 1; + else + next_lli_off++; + } + + d40_log_fill_lli(&lli_sg[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off, + lcsp13, data_width, + term_int && !next_lli_off, + true); + } + return total_size; +} + +void d40_log_lli_write(struct d40_log_lli_full *lcpa, + struct d40_log_lli *lcla_src, + struct d40_log_lli *lcla_dst, + struct d40_log_lli *lli_dst, + struct d40_log_lli *lli_src, + int llis_per_log) +{ + u32 slos = 0; + u32 dlos = 0; + int i; + + lcpa->lcsp0 = lli_src->lcsp02; + lcpa->lcsp1 = lli_src->lcsp13; + lcpa->lcsp2 = lli_dst->lcsp02; + lcpa->lcsp3 = lli_dst->lcsp13; + + slos = lli_src->lcsp13 & D40_MEM_LCSP1_SLOS_MASK; + dlos = lli_dst->lcsp13 & D40_MEM_LCSP3_DLOS_MASK; + + for (i = 0; (i < llis_per_log) && slos && dlos; i++) { + writel(lli_src[i+1].lcsp02, &lcla_src[i].lcsp02); + writel(lli_src[i+1].lcsp13, &lcla_src[i].lcsp13); + writel(lli_dst[i+1].lcsp02, &lcla_dst[i].lcsp02); + writel(lli_dst[i+1].lcsp13, &lcla_dst[i].lcsp13); + + slos = lli_src[i+1].lcsp13 & D40_MEM_LCSP1_SLOS_MASK; + dlos = lli_dst[i+1].lcsp13 & D40_MEM_LCSP3_DLOS_MASK; + } +} diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h new file mode 100644 index 000000000000..2029280cb332 --- /dev/null +++ b/drivers/dma/ste_dma40_ll.h @@ -0,0 +1,354 @@ +/* + * driver/dma/ste_dma40_ll.h + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ +#ifndef STE_DMA40_LL_H +#define STE_DMA40_LL_H + +#define D40_DREG_PCBASE 0x400 +#define D40_DREG_PCDELTA (8 * 4) +#define D40_LLI_ALIGN 16 /* LLI alignment must be 16 bytes. */ + +#define D40_TYPE_TO_GROUP(type) (type / 16) +#define D40_TYPE_TO_EVENT(type) (type % 16) + +/* Most bits of the CFG register are the same in log as in phy mode */ +#define D40_SREG_CFG_MST_POS 15 +#define D40_SREG_CFG_TIM_POS 14 +#define D40_SREG_CFG_EIM_POS 13 +#define D40_SREG_CFG_LOG_INCR_POS 12 +#define D40_SREG_CFG_PHY_PEN_POS 12 +#define D40_SREG_CFG_PSIZE_POS 10 +#define D40_SREG_CFG_ESIZE_POS 8 +#define D40_SREG_CFG_PRI_POS 7 +#define D40_SREG_CFG_LBE_POS 6 +#define D40_SREG_CFG_LOG_GIM_POS 5 +#define D40_SREG_CFG_LOG_MFU_POS 4 +#define D40_SREG_CFG_PHY_TM_POS 4 +#define D40_SREG_CFG_PHY_EVTL_POS 0 + + +/* Standard channel parameters - basic mode (element register) */ +#define D40_SREG_ELEM_PHY_ECNT_POS 16 +#define D40_SREG_ELEM_PHY_EIDX_POS 0 + +#define D40_SREG_ELEM_PHY_ECNT_MASK (0xFFFF << D40_SREG_ELEM_PHY_ECNT_POS) + +/* Standard channel parameters - basic mode (Link register) */ +#define D40_SREG_LNK_PHY_TCP_POS 0 +#define D40_SREG_LNK_PHY_LMP_POS 1 +#define D40_SREG_LNK_PHY_PRE_POS 2 +/* + * Source destination link address. Contains the + * 29-bit byte word aligned address of the reload area. + */ +#define D40_SREG_LNK_PHYS_LNK_MASK 0xFFFFFFF8UL + +/* Standard basic channel logical mode */ + +/* Element register */ +#define D40_SREG_ELEM_LOG_ECNT_POS 16 +#define D40_SREG_ELEM_LOG_LIDX_POS 8 +#define D40_SREG_ELEM_LOG_LOS_POS 1 +#define D40_SREG_ELEM_LOG_TCP_POS 0 + +#define D40_SREG_ELEM_LOG_LIDX_MASK (0xFF << D40_SREG_ELEM_LOG_LIDX_POS) + +/* Link register */ +#define D40_DEACTIVATE_EVENTLINE 0x0 +#define D40_ACTIVATE_EVENTLINE 0x1 +#define D40_EVENTLINE_POS(i) (2 * i) +#define D40_EVENTLINE_MASK(i) (0x3 << D40_EVENTLINE_POS(i)) + +/* Standard basic channel logical params in memory */ + +/* LCSP0 */ +#define D40_MEM_LCSP0_ECNT_POS 16 +#define D40_MEM_LCSP0_SPTR_POS 0 + +#define D40_MEM_LCSP0_ECNT_MASK (0xFFFF << D40_MEM_LCSP0_ECNT_POS) +#define D40_MEM_LCSP0_SPTR_MASK (0xFFFF << D40_MEM_LCSP0_SPTR_POS) + +/* LCSP1 */ +#define D40_MEM_LCSP1_SPTR_POS 16 +#define D40_MEM_LCSP1_SCFG_MST_POS 15 +#define D40_MEM_LCSP1_SCFG_TIM_POS 14 +#define D40_MEM_LCSP1_SCFG_EIM_POS 13 +#define D40_MEM_LCSP1_SCFG_INCR_POS 12 +#define D40_MEM_LCSP1_SCFG_PSIZE_POS 10 +#define D40_MEM_LCSP1_SCFG_ESIZE_POS 8 +#define D40_MEM_LCSP1_SLOS_POS 1 +#define D40_MEM_LCSP1_STCP_POS 0 + +#define D40_MEM_LCSP1_SPTR_MASK (0xFFFF << D40_MEM_LCSP1_SPTR_POS) +#define D40_MEM_LCSP1_SCFG_TIM_MASK (0x1 << D40_MEM_LCSP1_SCFG_TIM_POS) +#define D40_MEM_LCSP1_SCFG_INCR_MASK (0x1 << D40_MEM_LCSP1_SCFG_INCR_POS) +#define D40_MEM_LCSP1_SCFG_PSIZE_MASK (0x3 << D40_MEM_LCSP1_SCFG_PSIZE_POS) +#define D40_MEM_LCSP1_SLOS_MASK (0x7F << D40_MEM_LCSP1_SLOS_POS) +#define D40_MEM_LCSP1_STCP_MASK (0x1 << D40_MEM_LCSP1_STCP_POS) + +/* LCSP2 */ +#define D40_MEM_LCSP2_ECNT_POS 16 + +#define D40_MEM_LCSP2_ECNT_MASK (0xFFFF << D40_MEM_LCSP2_ECNT_POS) + +/* LCSP3 */ +#define D40_MEM_LCSP3_DCFG_MST_POS 15 +#define D40_MEM_LCSP3_DCFG_TIM_POS 14 +#define D40_MEM_LCSP3_DCFG_EIM_POS 13 +#define D40_MEM_LCSP3_DCFG_INCR_POS 12 +#define D40_MEM_LCSP3_DCFG_PSIZE_POS 10 +#define D40_MEM_LCSP3_DCFG_ESIZE_POS 8 +#define D40_MEM_LCSP3_DLOS_POS 1 +#define D40_MEM_LCSP3_DTCP_POS 0 + +#define D40_MEM_LCSP3_DLOS_MASK (0x7F << D40_MEM_LCSP3_DLOS_POS) +#define D40_MEM_LCSP3_DTCP_MASK (0x1 << D40_MEM_LCSP3_DTCP_POS) + + +/* Standard channel parameter register offsets */ +#define D40_CHAN_REG_SSCFG 0x00 +#define D40_CHAN_REG_SSELT 0x04 +#define D40_CHAN_REG_SSPTR 0x08 +#define D40_CHAN_REG_SSLNK 0x0C +#define D40_CHAN_REG_SDCFG 0x10 +#define D40_CHAN_REG_SDELT 0x14 +#define D40_CHAN_REG_SDPTR 0x18 +#define D40_CHAN_REG_SDLNK 0x1C + +/* DMA Register Offsets */ +#define D40_DREG_GCC 0x000 +#define D40_DREG_PRTYP 0x004 +#define D40_DREG_PRSME 0x008 +#define D40_DREG_PRSMO 0x00C +#define D40_DREG_PRMSE 0x010 +#define D40_DREG_PRMSO 0x014 +#define D40_DREG_PRMOE 0x018 +#define D40_DREG_PRMOO 0x01C +#define D40_DREG_LCPA 0x020 +#define D40_DREG_LCLA 0x024 +#define D40_DREG_ACTIVE 0x050 +#define D40_DREG_ACTIVO 0x054 +#define D40_DREG_FSEB1 0x058 +#define D40_DREG_FSEB2 0x05C +#define D40_DREG_PCMIS 0x060 +#define D40_DREG_PCICR 0x064 +#define D40_DREG_PCTIS 0x068 +#define D40_DREG_PCEIS 0x06C +#define D40_DREG_LCMIS0 0x080 +#define D40_DREG_LCMIS1 0x084 +#define D40_DREG_LCMIS2 0x088 +#define D40_DREG_LCMIS3 0x08C +#define D40_DREG_LCICR0 0x090 +#define D40_DREG_LCICR1 0x094 +#define D40_DREG_LCICR2 0x098 +#define D40_DREG_LCICR3 0x09C +#define D40_DREG_LCTIS0 0x0A0 +#define D40_DREG_LCTIS1 0x0A4 +#define D40_DREG_LCTIS2 0x0A8 +#define D40_DREG_LCTIS3 0x0AC +#define D40_DREG_LCEIS0 0x0B0 +#define D40_DREG_LCEIS1 0x0B4 +#define D40_DREG_LCEIS2 0x0B8 +#define D40_DREG_LCEIS3 0x0BC +#define D40_DREG_STFU 0xFC8 +#define D40_DREG_ICFG 0xFCC +#define D40_DREG_PERIPHID0 0xFE0 +#define D40_DREG_PERIPHID1 0xFE4 +#define D40_DREG_PERIPHID2 0xFE8 +#define D40_DREG_PERIPHID3 0xFEC +#define D40_DREG_CELLID0 0xFF0 +#define D40_DREG_CELLID1 0xFF4 +#define D40_DREG_CELLID2 0xFF8 +#define D40_DREG_CELLID3 0xFFC + +/* LLI related structures */ + +/** + * struct d40_phy_lli - The basic configration register for each physical + * channel. + * + * @reg_cfg: The configuration register. + * @reg_elt: The element register. + * @reg_ptr: The pointer register. + * @reg_lnk: The link register. + * + * These registers are set up for both physical and logical transfers + * Note that the bit in each register means differently in logical and + * physical(standard) mode. + * + * This struct must be 16 bytes aligned, and only contain physical registers + * since it will be directly accessed by the DMA. + */ +struct d40_phy_lli { + u32 reg_cfg; + u32 reg_elt; + u32 reg_ptr; + u32 reg_lnk; +}; + +/** + * struct d40_phy_lli_bidir - struct for a transfer. + * + * @src: Register settings for src channel. + * @dst: Register settings for dst channel. + * @dst_addr: Physical destination address. + * @src_addr: Physical source address. + * + * All DMA transfers have a source and a destination. + */ + +struct d40_phy_lli_bidir { + struct d40_phy_lli *src; + struct d40_phy_lli *dst; + dma_addr_t dst_addr; + dma_addr_t src_addr; +}; + + +/** + * struct d40_log_lli - logical lli configuration + * + * @lcsp02: Either maps to register lcsp0 if src or lcsp2 if dst. + * @lcsp13: Either maps to register lcsp1 if src or lcsp3 if dst. + * + * This struct must be 8 bytes aligned since it will be accessed directy by + * the DMA. Never add any none hw mapped registers to this struct. + */ + +struct d40_log_lli { + u32 lcsp02; + u32 lcsp13; +}; + +/** + * struct d40_log_lli_bidir - For both src and dst + * + * @src: pointer to src lli configuration. + * @dst: pointer to dst lli configuration. + * + * You always have a src and a dst when doing DMA transfers. + */ + +struct d40_log_lli_bidir { + struct d40_log_lli *src; + struct d40_log_lli *dst; +}; + +/** + * struct d40_log_lli_full - LCPA layout + * + * @lcsp0: Logical Channel Standard Param 0 - Src. + * @lcsp1: Logical Channel Standard Param 1 - Src. + * @lcsp2: Logical Channel Standard Param 2 - Dst. + * @lcsp3: Logical Channel Standard Param 3 - Dst. + * + * This struct maps to LCPA physical memory layout. Must map to + * the hw. + */ +struct d40_log_lli_full { + u32 lcsp0; + u32 lcsp1; + u32 lcsp2; + u32 lcsp3; +}; + +/** + * struct d40_def_lcsp - Default LCSP1 and LCSP3 settings + * + * @lcsp3: The default configuration for dst. + * @lcsp1: The default configuration for src. + */ +struct d40_def_lcsp { + u32 lcsp3; + u32 lcsp1; +}; + +/** + * struct d40_lcla_elem - Info for one LCA element. + * + * @src_id: logical channel src id + * @dst_id: logical channel dst id + * @src: LCPA formated src parameters + * @dst: LCPA formated dst parameters + * + */ +struct d40_lcla_elem { + int src_id; + int dst_id; + struct d40_log_lli *src; + struct d40_log_lli *dst; +}; + +/* Physical channels */ + +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, + u32 *src_cfg, u32 *dst_cfg, bool is_log); + +void d40_log_cfg(struct stedma40_chan_cfg *cfg, + u32 *lcsp1, u32 *lcsp2); + +int d40_phy_sg_to_lli(struct scatterlist *sg, + int sg_len, + dma_addr_t target, + struct d40_phy_lli *lli, + dma_addr_t lli_phys, + u32 reg_cfg, + u32 data_width, + int psize, + bool term_int); + +int d40_phy_fill_lli(struct d40_phy_lli *lli, + dma_addr_t data, + u32 data_size, + int psize, + dma_addr_t next_lli, + u32 reg_cfg, + bool term_int, + u32 data_width, + bool is_device); + +void d40_phy_lli_write(void __iomem *virtbase, + u32 phy_chan_num, + struct d40_phy_lli *lli_dst, + struct d40_phy_lli *lli_src); + +/* Logical channels */ + +void d40_log_fill_lli(struct d40_log_lli *lli, + dma_addr_t data, u32 data_size, + u32 lli_next_off, u32 reg_cfg, + u32 data_width, + bool term_int, bool addr_inc); + +int d40_log_sg_to_dev(struct d40_lcla_elem *lcla, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli_bidir *lli, + struct d40_def_lcsp *lcsp, + u32 src_data_width, + u32 dst_data_width, + enum dma_data_direction direction, + bool term_int, dma_addr_t dev_addr, int max_len, + int llis_per_log); + +void d40_log_lli_write(struct d40_log_lli_full *lcpa, + struct d40_log_lli *lcla_src, + struct d40_log_lli *lcla_dst, + struct d40_log_lli *lli_dst, + struct d40_log_lli *lli_src, + int llis_per_log); + +int d40_log_sg_to_lli(int lcla_id, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli *lli_sg, + u32 lcsp13, /* src or dst*/ + u32 data_width, + bool term_int, int max_len, int llis_per_log); + +#endif /* STE_DMA40_LLI_H */ -- cgit v1.2.3 From abb12dfd50c7580d7dcbd581cf6265ba4d01ea7e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 15:22:54 -0700 Subject: ioat: convert to circ_buf Use the common power-of-2 circular buffer macros. Signed-off-by: Dan Williams --- drivers/dma/ioat/dma_v2.c | 2 +- drivers/dma/ioat/dma_v2.h | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index b5ae56c211e6..b6699a350989 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -553,7 +553,7 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order) */ struct ioat_chan_common *chan = &ioat->base; struct dma_chan *c = &chan->common; - const u16 curr_size = ioat2_ring_mask(ioat) + 1; + const u16 curr_size = ioat2_ring_size(ioat); const u16 active = ioat2_ring_active(ioat); const u16 new_size = 1 << order; struct ioat_ring_ent **ring; diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h index ef2871fd7868..d7b64f188f78 100644 --- a/drivers/dma/ioat/dma_v2.h +++ b/drivers/dma/ioat/dma_v2.h @@ -22,6 +22,7 @@ #define IOATDMA_V2_H #include +#include #include "dma.h" #include "hw.h" @@ -71,31 +72,26 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) return container_of(chan, struct ioat2_dma_chan, base); } -static inline u16 ioat2_ring_mask(struct ioat2_dma_chan *ioat) +static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat) { - return (1 << ioat->alloc_order) - 1; + return 1 << ioat->alloc_order; } /* count of descriptors in flight with the engine */ static inline u16 ioat2_ring_active(struct ioat2_dma_chan *ioat) { - return (ioat->head - ioat->tail) & ioat2_ring_mask(ioat); + return CIRC_CNT(ioat->head, ioat->tail, ioat2_ring_size(ioat)); } /* count of descriptors pending submission to hardware */ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat) { - return (ioat->head - ioat->issued) & ioat2_ring_mask(ioat); + return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat)); } static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) { - u16 num_descs = ioat2_ring_mask(ioat) + 1; - u16 active = ioat2_ring_active(ioat); - - BUG_ON(active > num_descs); - - return num_descs - active; + return ioat2_ring_size(ioat) - ioat2_ring_active(ioat); } /* assumes caller already checked space */ @@ -151,7 +147,7 @@ struct ioat_ring_ent { static inline struct ioat_ring_ent * ioat2_get_ring_ent(struct ioat2_dma_chan *ioat, u16 idx) { - return ioat->ring[idx & ioat2_ring_mask(ioat)]; + return ioat->ring[idx & (ioat2_ring_size(ioat) - 1)]; } static inline void ioat2_set_chainaddr(struct ioat2_dma_chan *ioat, u64 addr) -- cgit v1.2.3 From 074cc47679f8b0931d7d5384e95822d82768f149 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 15:22:55 -0700 Subject: ioat2,3: convert to producer/consumer locking Use separate locks for the descriptor prep (producer) and descriptor cleanup (consumer) paths. Allows the producer path to run concurrently with the cleanup path. Inspired by Documentation/circular-buffer.txt. Cc: David Howells Cc: Paul E. McKenney Cc: Maciej Sosnowski Signed-off-by: Dan Williams --- drivers/dma/ioat/dma.h | 1 + drivers/dma/ioat/dma_v2.c | 182 +++++++++++++++++++++++----------------------- drivers/dma/ioat/dma_v2.h | 15 ++-- drivers/dma/ioat/dma_v3.c | 117 +++++++++-------------------- 4 files changed, 134 insertions(+), 181 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 86b97ac8774e..0c76578e9911 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -96,6 +96,7 @@ struct ioat_chan_common { #define IOAT_COMPLETION_ACK 1 #define IOAT_RESET_PENDING 2 #define IOAT_KOBJ_INIT_FAIL 3 + #define IOAT_RESHAPE_PENDING 4 struct timer_list timer; #define COMPLETION_TIMEOUT msecs_to_jiffies(100) #define IDLE_TIMEOUT msecs_to_jiffies(2000) diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index b6699a350989..e75d0299bb82 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -56,8 +56,6 @@ void __ioat2_issue_pending(struct ioat2_dma_chan *ioat) ioat->dmacount += ioat2_ring_pending(ioat); ioat->issued = ioat->head; - /* make descriptor updates globally visible before notifying channel */ - wmb(); writew(ioat->dmacount, chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET); dev_dbg(to_dev(chan), "%s: head: %#x tail: %#x issued: %#x count: %#x\n", @@ -69,9 +67,9 @@ void ioat2_issue_pending(struct dma_chan *c) struct ioat2_dma_chan *ioat = to_ioat2_chan(c); if (ioat2_ring_pending(ioat)) { - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&ioat->prep_lock); __ioat2_issue_pending(ioat); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); } } @@ -80,7 +78,7 @@ void ioat2_issue_pending(struct dma_chan *c) * @ioat: ioat2+ channel * * Check if the number of unsubmitted descriptors has exceeded the - * watermark. Called with ring_lock held + * watermark. Called with prep_lock held */ static void ioat2_update_pending(struct ioat2_dma_chan *ioat) { @@ -92,7 +90,6 @@ static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat) { struct ioat_ring_ent *desc; struct ioat_dma_descriptor *hw; - int idx; if (ioat2_ring_space(ioat) < 1) { dev_err(to_dev(&ioat->base), @@ -102,8 +99,7 @@ static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat) dev_dbg(to_dev(&ioat->base), "%s: head: %#x tail: %#x issued: %#x\n", __func__, ioat->head, ioat->tail, ioat->issued); - idx = ioat2_desc_alloc(ioat, 1); - desc = ioat2_get_ring_ent(ioat, idx); + desc = ioat2_get_ring_ent(ioat, ioat->head); hw = desc->hw; hw->ctl = 0; @@ -117,14 +113,16 @@ static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat) async_tx_ack(&desc->txd); ioat2_set_chainaddr(ioat, desc->txd.phys); dump_desc_dbg(ioat, desc); + wmb(); + ioat->head += 1; __ioat2_issue_pending(ioat); } static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat) { - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&ioat->prep_lock); __ioat2_start_null_desc(ioat); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); } static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) @@ -134,15 +132,16 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) struct ioat_ring_ent *desc; bool seen_current = false; u16 active; - int i; + int idx = ioat->tail, i; dev_dbg(to_dev(chan), "%s: head: %#x tail: %#x issued: %#x\n", __func__, ioat->head, ioat->tail, ioat->issued); active = ioat2_ring_active(ioat); for (i = 0; i < active && !seen_current; i++) { - prefetch(ioat2_get_ring_ent(ioat, ioat->tail + i + 1)); - desc = ioat2_get_ring_ent(ioat, ioat->tail + i); + smp_read_barrier_depends(); + prefetch(ioat2_get_ring_ent(ioat, idx + i + 1)); + desc = ioat2_get_ring_ent(ioat, idx + i); tx = &desc->txd; dump_desc_dbg(ioat, desc); if (tx->cookie) { @@ -158,11 +157,12 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) if (tx->phys == phys_complete) seen_current = true; } - ioat->tail += i; + smp_mb(); /* finish all descriptor reads before incrementing tail */ + ioat->tail = idx + i; BUG_ON(active && !seen_current); /* no active descs have written a completion? */ chan->last_completion = phys_complete; - if (ioat->head == ioat->tail) { + if (active - i == 0) { dev_dbg(to_dev(chan), "%s: cancel completion timeout\n", __func__); clear_bit(IOAT_COMPLETION_PENDING, &chan->state); @@ -179,24 +179,9 @@ static void ioat2_cleanup(struct ioat2_dma_chan *ioat) struct ioat_chan_common *chan = &ioat->base; unsigned long phys_complete; - prefetch(chan->completion); - - if (!spin_trylock_bh(&chan->cleanup_lock)) - return; - - if (!ioat_cleanup_preamble(chan, &phys_complete)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - if (!spin_trylock_bh(&ioat->ring_lock)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - __cleanup(ioat, phys_complete); - - spin_unlock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) + __cleanup(ioat, phys_complete); spin_unlock_bh(&chan->cleanup_lock); } @@ -287,12 +272,10 @@ void ioat2_timer_event(unsigned long data) struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); struct ioat_chan_common *chan = &ioat->base; - spin_lock_bh(&chan->cleanup_lock); if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { unsigned long phys_complete; u64 status; - spin_lock_bh(&ioat->ring_lock); status = ioat_chansts(chan); /* when halted due to errors check for channel @@ -311,26 +294,31 @@ void ioat2_timer_event(unsigned long data) * acknowledged a pending completion once, then be more * forceful with a restart */ - if (ioat_cleanup_preamble(chan, &phys_complete)) + spin_lock_bh(&chan->cleanup_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) { __cleanup(ioat, phys_complete); - else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) + } else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) { + spin_lock_bh(&ioat->prep_lock); ioat2_restart_channel(ioat); - else { + spin_unlock_bh(&ioat->prep_lock); + } else { set_bit(IOAT_COMPLETION_ACK, &chan->state); mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); } - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&chan->cleanup_lock); } else { u16 active; /* if the ring is idle, empty, and oversized try to step * down the size */ - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); active = ioat2_ring_active(ioat); if (active == 0 && ioat->alloc_order > ioat_get_alloc_order()) reshape_ring(ioat, ioat->alloc_order-1); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); /* keep shrinking until we get back to our minimum * default size @@ -338,7 +326,6 @@ void ioat2_timer_event(unsigned long data) if (ioat->alloc_order > ioat_get_alloc_order()) mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT); } - spin_unlock_bh(&chan->cleanup_lock); } static int ioat2_reset_hw(struct ioat_chan_common *chan) @@ -392,7 +379,7 @@ int ioat2_enumerate_channels(struct ioatdma_device *device) ioat_init_channel(device, &ioat->base, i); ioat->xfercap_log = xfercap_log; - spin_lock_init(&ioat->ring_lock); + spin_lock_init(&ioat->prep_lock); if (device->reset_hw(&ioat->base)) { i = 0; break; @@ -418,8 +405,17 @@ static dma_cookie_t ioat2_tx_submit_unlock(struct dma_async_tx_descriptor *tx) if (!test_and_set_bit(IOAT_COMPLETION_PENDING, &chan->state)) mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); + + /* make descriptor updates visible before advancing ioat->head, + * this is purposefully not smp_wmb() since we are also + * publishing the descriptor updates to a dma device + */ + wmb(); + + ioat->head += ioat->produce; + ioat2_update_pending(ioat); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); return cookie; } @@ -531,13 +527,15 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) if (!ring) return -ENOMEM; - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); ioat->ring = ring; ioat->head = 0; ioat->issued = 0; ioat->tail = 0; ioat->alloc_order = order; - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); tasklet_enable(&chan->cleanup_task); ioat2_start_null_desc(ioat); @@ -653,54 +651,61 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order) } /** - * ioat2_alloc_and_lock - common descriptor alloc boilerplate for ioat2,3 ops - * @idx: gets starting descriptor index on successful allocation + * ioat2_check_space_lock - verify space and grab ring producer lock * @ioat: ioat2,3 channel (ring) to operate on * @num_descs: allocation length */ -int ioat2_alloc_and_lock(u16 *idx, struct ioat2_dma_chan *ioat, int num_descs) +int ioat2_check_space_lock(struct ioat2_dma_chan *ioat, int num_descs) { struct ioat_chan_common *chan = &ioat->base; + bool retry; - spin_lock_bh(&ioat->ring_lock); + retry: + spin_lock_bh(&ioat->prep_lock); /* never allow the last descriptor to be consumed, we need at * least one free at all times to allow for on-the-fly ring * resizing. */ - while (unlikely(ioat2_ring_space(ioat) <= num_descs)) { - if (reshape_ring(ioat, ioat->alloc_order + 1) && - ioat2_ring_space(ioat) > num_descs) - break; - - if (printk_ratelimit()) - dev_dbg(to_dev(chan), - "%s: ring full! num_descs: %d (%x:%x:%x)\n", - __func__, num_descs, ioat->head, ioat->tail, - ioat->issued); - spin_unlock_bh(&ioat->ring_lock); - - /* progress reclaim in the allocation failure case we - * may be called under bh_disabled so we need to trigger - * the timer event directly - */ - spin_lock_bh(&chan->cleanup_lock); - if (jiffies > chan->timer.expires && - timer_pending(&chan->timer)) { - struct ioatdma_device *device = chan->device; - - mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); - spin_unlock_bh(&chan->cleanup_lock); - device->timer_fn((unsigned long) &chan->common); - } else - spin_unlock_bh(&chan->cleanup_lock); - return -ENOMEM; + if (likely(ioat2_ring_space(ioat) > num_descs)) { + dev_dbg(to_dev(chan), "%s: num_descs: %d (%x:%x:%x)\n", + __func__, num_descs, ioat->head, ioat->tail, ioat->issued); + ioat->produce = num_descs; + return 0; /* with ioat->prep_lock held */ } + retry = test_and_set_bit(IOAT_RESHAPE_PENDING, &chan->state); + spin_unlock_bh(&ioat->prep_lock); - dev_dbg(to_dev(chan), "%s: num_descs: %d (%x:%x:%x)\n", - __func__, num_descs, ioat->head, ioat->tail, ioat->issued); + /* is another cpu already trying to expand the ring? */ + if (retry) + goto retry; - *idx = ioat2_desc_alloc(ioat, num_descs); - return 0; /* with ioat->ring_lock held */ + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); + retry = reshape_ring(ioat, ioat->alloc_order + 1); + clear_bit(IOAT_RESHAPE_PENDING, &chan->state); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); + + /* if we were able to expand the ring retry the allocation */ + if (retry) + goto retry; + + if (printk_ratelimit()) + dev_dbg(to_dev(chan), "%s: ring full! num_descs: %d (%x:%x:%x)\n", + __func__, num_descs, ioat->head, ioat->tail, ioat->issued); + + /* progress reclaim in the allocation failure case we may be + * called under bh_disabled so we need to trigger the timer + * event directly + */ + if (jiffies > chan->timer.expires && timer_pending(&chan->timer)) { + struct ioatdma_device *device = chan->device; + + mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); + device->timer_fn((unsigned long) &chan->common); + } + + return -ENOMEM; } struct dma_async_tx_descriptor * @@ -713,14 +718,11 @@ ioat2_dma_prep_memcpy_lock(struct dma_chan *c, dma_addr_t dma_dest, dma_addr_t dst = dma_dest; dma_addr_t src = dma_src; size_t total_len = len; - int num_descs; - u16 idx; - int i; + int num_descs, idx, i; num_descs = ioat2_xferlen_to_descs(ioat, len); - if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs) == 0) - /* pass */; + if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -777,7 +779,8 @@ void ioat2_free_chan_resources(struct dma_chan *c) device->cleanup_fn((unsigned long) c); device->reset_hw(chan); - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); descs = ioat2_ring_space(ioat); dev_dbg(to_dev(chan), "freeing %d idle descriptors\n", descs); for (i = 0; i < descs; i++) { @@ -800,7 +803,8 @@ void ioat2_free_chan_resources(struct dma_chan *c) ioat->alloc_order = 0; pci_pool_free(device->completion_pool, chan->completion, chan->completion_dma); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); chan->last_completion = 0; chan->completion_dma = 0; diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h index d7b64f188f78..a2c413b2b8d8 100644 --- a/drivers/dma/ioat/dma_v2.h +++ b/drivers/dma/ioat/dma_v2.h @@ -50,8 +50,9 @@ extern int ioat_ring_alloc_order; * @tail: cleanup index * @dmacount: identical to 'head' except for occasionally resetting to zero * @alloc_order: log2 of the number of allocated descriptors + * @produce: number of descriptors to produce at submit time * @ring: software ring buffer implementation of hardware ring - * @ring_lock: protects ring attributes + * @prep_lock: serializes descriptor preparation (producers) */ struct ioat2_dma_chan { struct ioat_chan_common base; @@ -61,8 +62,9 @@ struct ioat2_dma_chan { u16 tail; u16 dmacount; u16 alloc_order; + u16 produce; struct ioat_ring_ent **ring; - spinlock_t ring_lock; + spinlock_t prep_lock; }; static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) @@ -94,13 +96,6 @@ static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) return ioat2_ring_size(ioat) - ioat2_ring_active(ioat); } -/* assumes caller already checked space */ -static inline u16 ioat2_desc_alloc(struct ioat2_dma_chan *ioat, u16 len) -{ - ioat->head += len; - return ioat->head - len; -} - static inline u16 ioat2_xferlen_to_descs(struct ioat2_dma_chan *ioat, size_t len) { u16 num_descs = len >> ioat->xfercap_log; @@ -164,7 +159,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *dev, int dca); int __devinit ioat3_dma_probe(struct ioatdma_device *dev, int dca); struct dca_provider * __devinit ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase); struct dca_provider * __devinit ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase); -int ioat2_alloc_and_lock(u16 *idx, struct ioat2_dma_chan *ioat, int num_descs); +int ioat2_check_space_lock(struct ioat2_dma_chan *ioat, int num_descs); int ioat2_enumerate_channels(struct ioatdma_device *device); struct dma_async_tx_descriptor * ioat2_dma_prep_memcpy_lock(struct dma_chan *c, dma_addr_t dma_dest, diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 6740e319c9cf..8b573fac2a25 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -260,8 +260,8 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) struct ioat_chan_common *chan = &ioat->base; struct ioat_ring_ent *desc; bool seen_current = false; + int idx = ioat->tail, i; u16 active; - int i; dev_dbg(to_dev(chan), "%s: head: %#x tail: %#x issued: %#x\n", __func__, ioat->head, ioat->tail, ioat->issued); @@ -270,13 +270,14 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) for (i = 0; i < active && !seen_current; i++) { struct dma_async_tx_descriptor *tx; - prefetch(ioat2_get_ring_ent(ioat, ioat->tail + i + 1)); - desc = ioat2_get_ring_ent(ioat, ioat->tail + i); + smp_read_barrier_depends(); + prefetch(ioat2_get_ring_ent(ioat, idx + i + 1)); + desc = ioat2_get_ring_ent(ioat, idx + i); dump_desc_dbg(ioat, desc); tx = &desc->txd; if (tx->cookie) { chan->completed_cookie = tx->cookie; - ioat3_dma_unmap(ioat, desc, ioat->tail + i); + ioat3_dma_unmap(ioat, desc, idx + i); tx->cookie = 0; if (tx->callback) { tx->callback(tx->callback_param); @@ -293,69 +294,30 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) i++; } } - ioat->tail += i; + smp_mb(); /* finish all descriptor reads before incrementing tail */ + ioat->tail = idx + i; BUG_ON(active && !seen_current); /* no active descs have written a completion? */ chan->last_completion = phys_complete; - active = ioat2_ring_active(ioat); - if (active == 0) { + if (active - i == 0) { dev_dbg(to_dev(chan), "%s: cancel completion timeout\n", __func__); clear_bit(IOAT_COMPLETION_PENDING, &chan->state); mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT); } /* 5 microsecond delay per pending descriptor */ - writew(min((5 * active), IOAT_INTRDELAY_MASK), + writew(min((5 * (active - i)), IOAT_INTRDELAY_MASK), chan->device->reg_base + IOAT_INTRDELAY_OFFSET); } -/* try to cleanup, but yield (via spin_trylock) to incoming submissions - * with the expectation that we will immediately poll again shortly - */ -static void ioat3_cleanup_poll(struct ioat2_dma_chan *ioat) +static void ioat3_cleanup(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; unsigned long phys_complete; - prefetch(chan->completion); - - if (!spin_trylock_bh(&chan->cleanup_lock)) - return; - - if (!ioat_cleanup_preamble(chan, &phys_complete)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - if (!spin_trylock_bh(&ioat->ring_lock)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - __cleanup(ioat, phys_complete); - - spin_unlock_bh(&ioat->ring_lock); - spin_unlock_bh(&chan->cleanup_lock); -} - -/* run cleanup now because we already delayed the interrupt via INTRDELAY */ -static void ioat3_cleanup_sync(struct ioat2_dma_chan *ioat) -{ - struct ioat_chan_common *chan = &ioat->base; - unsigned long phys_complete; - - prefetch(chan->completion); - spin_lock_bh(&chan->cleanup_lock); - if (!ioat_cleanup_preamble(chan, &phys_complete)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - spin_lock_bh(&ioat->ring_lock); - - __cleanup(ioat, phys_complete); - - spin_unlock_bh(&ioat->ring_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) + __cleanup(ioat, phys_complete); spin_unlock_bh(&chan->cleanup_lock); } @@ -363,7 +325,7 @@ static void ioat3_cleanup_event(unsigned long data) { struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); - ioat3_cleanup_sync(ioat); + ioat3_cleanup(ioat); writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); } @@ -384,12 +346,10 @@ static void ioat3_timer_event(unsigned long data) struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); struct ioat_chan_common *chan = &ioat->base; - spin_lock_bh(&chan->cleanup_lock); if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { unsigned long phys_complete; u64 status; - spin_lock_bh(&ioat->ring_lock); status = ioat_chansts(chan); /* when halted due to errors check for channel @@ -408,26 +368,31 @@ static void ioat3_timer_event(unsigned long data) * acknowledged a pending completion once, then be more * forceful with a restart */ + spin_lock_bh(&chan->cleanup_lock); if (ioat_cleanup_preamble(chan, &phys_complete)) __cleanup(ioat, phys_complete); - else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) + else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) { + spin_lock_bh(&ioat->prep_lock); ioat3_restart_channel(ioat); - else { + spin_unlock_bh(&ioat->prep_lock); + } else { set_bit(IOAT_COMPLETION_ACK, &chan->state); mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); } - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&chan->cleanup_lock); } else { u16 active; /* if the ring is idle, empty, and oversized try to step * down the size */ - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); active = ioat2_ring_active(ioat); if (active == 0 && ioat->alloc_order > ioat_get_alloc_order()) reshape_ring(ioat, ioat->alloc_order-1); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); /* keep shrinking until we get back to our minimum * default size @@ -435,7 +400,6 @@ static void ioat3_timer_event(unsigned long data) if (ioat->alloc_order > ioat_get_alloc_order()) mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT); } - spin_unlock_bh(&chan->cleanup_lock); } static enum dma_status @@ -447,7 +411,7 @@ ioat3_is_complete(struct dma_chan *c, dma_cookie_t cookie, if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) return DMA_SUCCESS; - ioat3_cleanup_poll(ioat); + ioat3_cleanup(ioat); return ioat_is_complete(c, cookie, done, used); } @@ -460,15 +424,12 @@ ioat3_prep_memset_lock(struct dma_chan *c, dma_addr_t dest, int value, struct ioat_ring_ent *desc; size_t total_len = len; struct ioat_fill_descriptor *fill; - int num_descs; u64 src_data = (0x0101010101010101ULL) * (value & 0xff); - u16 idx; - int i; + int num_descs, idx, i; num_descs = ioat2_xferlen_to_descs(ioat, len); - if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs) == 0) - /* pass */; + if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -513,11 +474,8 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result, struct ioat_xor_descriptor *xor; struct ioat_xor_ext_descriptor *xor_ex = NULL; struct ioat_dma_descriptor *hw; + int num_descs, with_ext, idx, i; u32 offset = 0; - int num_descs; - int with_ext; - int i; - u16 idx; u8 op = result ? IOAT_OP_XOR_VAL : IOAT_OP_XOR; BUG_ON(src_cnt < 2); @@ -537,9 +495,8 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result, * (legacy) descriptor to ensure all completion writes arrive in * order. */ - if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs+1) == 0) - /* pass */; + if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs+1) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -657,11 +614,8 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, struct ioat_pq_ext_descriptor *pq_ex = NULL; struct ioat_dma_descriptor *hw; u32 offset = 0; - int num_descs; - int with_ext; - int i, s; - u16 idx; u8 op = result ? IOAT_OP_PQ_VAL : IOAT_OP_PQ; + int i, s, idx, with_ext, num_descs; dev_dbg(to_dev(chan), "%s\n", __func__); /* the engine requires at least two sources (we provide @@ -687,8 +641,8 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, * order. */ if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs+1) == 0) - /* pass */; + ioat2_check_space_lock(ioat, num_descs+1) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -851,10 +805,9 @@ ioat3_prep_interrupt_lock(struct dma_chan *c, unsigned long flags) struct ioat2_dma_chan *ioat = to_ioat2_chan(c); struct ioat_ring_ent *desc; struct ioat_dma_descriptor *hw; - u16 idx; - if (ioat2_alloc_and_lock(&idx, ioat, 1) == 0) - desc = ioat2_get_ring_ent(ioat, idx); + if (ioat2_check_space_lock(ioat, 1) == 0) + desc = ioat2_get_ring_ent(ioat, ioat->head); else return NULL; -- cgit v1.2.3 From 2adfc550b6d9646301c810643bc309fa49375987 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 15:22:56 -0700 Subject: ioat3: disable cacheline-unaligned transfers for raid operations There are cases where cacheline-unaligned raid operations can hang the dma channel. Simply disable these operations by increasing the alignment constraints published to async_tx. The raid456 driver always issues page aligned requests, so the only in-kernel user of the ioatdma driver that is affected by this change is dmatest. Signed-off-by: Dan Williams --- drivers/dma/ioat/dma_v3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 8b573fac2a25..e2a23952172d 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -1175,7 +1175,7 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (cap & IOAT_CAP_XOR) { is_raid_device = true; dma->max_xor = 8; - dma->xor_align = 2; + dma->xor_align = 6; dma_cap_set(DMA_XOR, dma->cap_mask); dma->device_prep_dma_xor = ioat3_prep_xor; @@ -1186,7 +1186,7 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (cap & IOAT_CAP_PQ) { is_raid_device = true; dma_set_maxpq(dma, 8, 0); - dma->pq_align = 2; + dma->pq_align = 6; dma_cap_set(DMA_PQ, dma->cap_mask); dma->device_prep_dma_pq = ioat3_prep_pq; @@ -1196,7 +1196,7 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (!(cap & IOAT_CAP_XOR)) { dma->max_xor = 8; - dma->xor_align = 2; + dma->xor_align = 6; dma_cap_set(DMA_XOR, dma->cap_mask); dma->device_prep_dma_xor = ioat3_prep_pqxor; -- cgit v1.2.3 From c86e1401c9f2ba8d989fa1c4b33d0f0ec3ba8aaf Mon Sep 17 00:00:00 2001 From: Minskey Guo Date: Sun, 2 May 2010 12:52:35 -0700 Subject: ioat: Remove duplicated devm_kzalloc() calls for ioatdma_device The memory for ioatdma_device structure is being allocated in alloc_ioatdma() Signed-off-by: Minskey Guo Signed-off-by: Dan Williams --- drivers/dma/ioat/pci.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c index 99ec26725bae..fab37d1cf48d 100644 --- a/drivers/dma/ioat/pci.c +++ b/drivers/dma/ioat/pci.c @@ -138,15 +138,10 @@ static int __devinit ioat_pci_probe(struct pci_dev *pdev, const struct pci_devic if (err) return err; - device = devm_kzalloc(dev, sizeof(*device), GFP_KERNEL); - if (!device) - return -ENOMEM; - - pci_set_master(pdev); - device = alloc_ioatdma(pdev, iomap[IOAT_MMIO_BAR]); if (!device) return -ENOMEM; + pci_set_master(pdev); pci_set_drvdata(pdev, device); device->version = readb(device->reg_base + IOAT_VER_OFFSET); -- cgit v1.2.3 From cc05ea0cd63437da2033b3ce6e033b1f1aaaf640 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 4 May 2010 18:22:15 +0900 Subject: DMA ENGINE: Do not reset 'private' of channel The member 'private' of 'struct dma_chan' is meant for passing data between client and the controller driver. The DMA client driver may point it to platform specific stuff after acquiring the channel. So, it is the responsiblity of the same code to reset it, if it must. The DMA engine doesn't set it and hence, shouldn't reset it either. This reseting of private by DMA Engine comes in the way of implementing default channel settings during DMAC probe. That capability is useful for not having the clients to always provide platform specific data, like Rx/Tx FIFO addresses, which usually doesn't change across channel requests. Signed-off-by: Jassi Brar Signed-off-by: Dan Williams --- drivers/dma/dmaengine.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 790caeeb4ccd..21eb896f4dfd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -514,7 +514,6 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v break; if (--device->privatecnt == 0) dma_cap_clear(DMA_PRIVATE, device->cap_mask); - chan->private = NULL; chan = NULL; } } @@ -536,7 +535,6 @@ void dma_release_channel(struct dma_chan *chan) /* drop PRIVATE cap enabled by __dma_request_channel() */ if (--chan->device->privatecnt == 0) dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask); - chan->private = NULL; mutex_unlock(&dma_list_mutex); } EXPORT_SYMBOL_GPL(dma_release_channel); -- cgit v1.2.3 From 8381fc35244dbdf58cfc49e04e0d7c3498c8aa03 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 6 May 2010 11:58:55 +0200 Subject: dmaengine: mpc512x: Use resource_size Use the resource_size function instead of manually calculating the resource size. This reduces the chance of introducing off-by-one errors. Signed-off-by: Tobias Klauser Signed-off-by: Dan Williams --- drivers/dma/mpc512x_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 7a750b95303c..e41fb8b671d3 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -657,7 +657,7 @@ static int __devinit mpc_dma_probe(struct of_device *op, } regs_start = res.start; - regs_size = res.end - res.start + 1; + regs_size = resource_size(&res); if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) { dev_err(dev, "Error requesting memory region!\n"); -- cgit v1.2.3 From a5ebca4769f28ceade28ff59fcbffb8e184e599c Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Tue, 18 May 2010 00:41:09 +0200 Subject: DMAENGINE: DMA40 support paused channel status Support determining whether a channel is paused or not using the status function. Signed-off-by: Jonas Aaberg Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/ste_dma40.c | 75 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 8 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index e4295a27672b..16a7d2b605ed 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -659,7 +659,7 @@ static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); } -static bool d40_chan_has_events(struct d40_chan *d40c) +static u32 d40_chan_has_events(struct d40_chan *d40c) { u32 val = 0; @@ -674,7 +674,7 @@ static bool d40_chan_has_events(struct d40_chan *d40c) val = readl(d40c->base->virtbase + D40_DREG_PCBASE + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SDLNK); - return (bool) val; + return val; } static void d40_config_enable_lidx(struct d40_chan *d40c) @@ -1389,6 +1389,65 @@ static int d40_pause(struct dma_chan *chan) return res; } +static bool d40_is_paused(struct d40_chan *d40c) +{ + bool is_paused = false; + unsigned long flags; + void __iomem *active_reg; + u32 status; + u32 event; + int res; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num == D40_PHY_CHAN) { + if (d40c->phy_chan->num % 2 == 0) + active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; + else + active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + if (status == D40_DMA_SUSPENDED || status == D40_DMA_STOP) + is_paused = true; + + goto _exit; + } + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res != 0) + goto _exit; + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + else { + dev_err(&d40c->chan.dev->device, + "[%s] Unknown direction\n", __func__); + goto _exit; + } + status = d40_chan_has_events(d40c); + status = (status & D40_EVENTLINE_MASK(event)) >> + D40_EVENTLINE_POS(event); + + if (status != D40_DMA_RUN) + is_paused = true; + + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + +_exit: + spin_unlock_irqrestore(&d40c->lock, flags); + return is_paused; + +} + + static bool d40_tx_is_linked(struct d40_chan *d40c) { bool is_link; @@ -1980,13 +2039,13 @@ static enum dma_status d40_tx_status(struct dma_chan *chan, last_complete = d40c->completed; last_used = chan->cookie; - ret = dma_async_is_complete(cookie, last_complete, last_used); + if (d40_is_paused(d40c)) + ret = DMA_PAUSED; + else + ret = dma_async_is_complete(cookie, last_complete, last_used); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = stedma40_residue(chan); - } + dma_set_tx_state(txstate, last_complete, last_used, + stedma40_residue(chan)); return ret; } -- cgit v1.2.3 From 4aed79b2818e7330b5d00143e4c20bc6555df91f Mon Sep 17 00:00:00 2001 From: Marcin Mielczarczyk Date: Tue, 18 May 2010 00:41:21 +0200 Subject: DMAENGINE: DMA40 fix for allocation of logical channel 0 Fix for allocation failure of logical channel when event line happens to be number 0. Signed-off-by: Marcin Mielczarczyk Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/ste_dma40.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 16a7d2b605ed..81fec95312b6 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1039,11 +1039,11 @@ static int d40_validate_conf(struct d40_chan *d40c, } static bool d40_alloc_mask_set(struct d40_phy_res *phy, bool is_src, - int log_event_line) + int log_event_line, bool is_log) { unsigned long flags; spin_lock_irqsave(&phy->lock, flags); - if (!log_event_line) { + if (!is_log) { /* Physical interrupts are masked per physical full channel */ if (phy->allocated_src == D40_ALLOC_FREE && phy->allocated_dst == D40_ALLOC_FREE) { @@ -1161,15 +1161,16 @@ static int d40_allocate_channel(struct d40_chan *d40c) /* Find physical half channel */ for (i = 0; i < d40c->base->num_phy_chans; i++) { - if (d40_alloc_mask_set(&phys[i], is_src, 0)) + if (d40_alloc_mask_set(&phys[i], is_src, + 0, is_log)) goto found_phy; } } else for (j = 0; j < d40c->base->num_phy_chans; j += 8) { int phy_num = j + event_group * 2; for (i = phy_num; i < phy_num + 2; i++) { - if (d40_alloc_mask_set(&phys[i], - is_src, 0)) + if (d40_alloc_mask_set(&phys[i], is_src, + 0, is_log)) goto found_phy; } } @@ -1193,13 +1194,13 @@ found_phy: if (is_src) { for (i = phy_num; i < phy_num + 2; i++) { if (d40_alloc_mask_set(&phys[i], is_src, - event_line)) + event_line, is_log)) goto found_log; } } else { for (i = phy_num + 1; i >= phy_num; i--) { if (d40_alloc_mask_set(&phys[i], is_src, - event_line)) + event_line, is_log)) goto found_log; } } -- cgit v1.2.3 From caa20d974c86af496b419eef70010e63b7fab7ac Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 17 May 2010 16:24:16 -0700 Subject: async_tx: trim dma_async_tx_descriptor in 'no channel switch' case Saves 24 bytes per descriptor (64-bit) when the channel-switching capabilities of async_tx are not required. Signed-off-by: Dan Williams --- crypto/async_tx/async_tx.c | 46 +++++++++++++++-------------------- drivers/dma/dmaengine.c | 16 +++++++------ include/linux/dmaengine.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 34 deletions(-) (limited to 'drivers/dma') diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c index f9cdf04fe7c0..7f2c00a45205 100644 --- a/crypto/async_tx/async_tx.c +++ b/crypto/async_tx/async_tx.c @@ -81,18 +81,13 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx, struct dma_device *device = chan->device; struct dma_async_tx_descriptor *intr_tx = (void *) ~0; - #ifdef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH - BUG(); - #endif - /* first check to see if we can still append to depend_tx */ - spin_lock_bh(&depend_tx->lock); - if (depend_tx->parent && depend_tx->chan == tx->chan) { - tx->parent = depend_tx; - depend_tx->next = tx; + txd_lock(depend_tx); + if (txd_parent(depend_tx) && depend_tx->chan == tx->chan) { + txd_chain(depend_tx, tx); intr_tx = NULL; } - spin_unlock_bh(&depend_tx->lock); + txd_unlock(depend_tx); /* attached dependency, flush the parent channel */ if (!intr_tx) { @@ -111,24 +106,22 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx, if (intr_tx) { intr_tx->callback = NULL; intr_tx->callback_param = NULL; - tx->parent = intr_tx; - /* safe to set ->next outside the lock since we know we are + /* safe to chain outside the lock since we know we are * not submitted yet */ - intr_tx->next = tx; + txd_chain(intr_tx, tx); /* check if we need to append */ - spin_lock_bh(&depend_tx->lock); - if (depend_tx->parent) { - intr_tx->parent = depend_tx; - depend_tx->next = intr_tx; + txd_lock(depend_tx); + if (txd_parent(depend_tx)) { + txd_chain(depend_tx, intr_tx); async_tx_ack(intr_tx); intr_tx = NULL; } - spin_unlock_bh(&depend_tx->lock); + txd_unlock(depend_tx); if (intr_tx) { - intr_tx->parent = NULL; + txd_clear_parent(intr_tx); intr_tx->tx_submit(intr_tx); async_tx_ack(intr_tx); } @@ -176,21 +169,20 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, * 2/ dependencies are 1:1 i.e. two transactions can * not depend on the same parent */ - BUG_ON(async_tx_test_ack(depend_tx) || depend_tx->next || - tx->parent); + BUG_ON(async_tx_test_ack(depend_tx) || txd_next(depend_tx) || + txd_parent(tx)); /* the lock prevents async_tx_run_dependencies from missing * the setting of ->next when ->parent != NULL */ - spin_lock_bh(&depend_tx->lock); - if (depend_tx->parent) { + txd_lock(depend_tx); + if (txd_parent(depend_tx)) { /* we have a parent so we can not submit directly * if we are staying on the same channel: append * else: channel switch */ if (depend_tx->chan == chan) { - tx->parent = depend_tx; - depend_tx->next = tx; + txd_chain(depend_tx, tx); s = ASYNC_TX_SUBMITTED; } else s = ASYNC_TX_CHANNEL_SWITCH; @@ -203,7 +195,7 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, else s = ASYNC_TX_CHANNEL_SWITCH; } - spin_unlock_bh(&depend_tx->lock); + txd_unlock(depend_tx); switch (s) { case ASYNC_TX_SUBMITTED: @@ -212,12 +204,12 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, async_tx_channel_switch(depend_tx, tx); break; case ASYNC_TX_DIRECT_SUBMIT: - tx->parent = NULL; + txd_clear_parent(tx); tx->tx_submit(tx); break; } } else { - tx->parent = NULL; + txd_clear_parent(tx); tx->tx_submit(tx); } diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index d18b5d069d7e..fcfe1a62ffa5 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -978,7 +978,9 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx, struct dma_chan *chan) { tx->chan = chan; + #ifndef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH spin_lock_init(&tx->lock); + #endif } EXPORT_SYMBOL(dma_async_tx_descriptor_init); @@ -1011,7 +1013,7 @@ EXPORT_SYMBOL_GPL(dma_wait_for_async_tx); */ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) { - struct dma_async_tx_descriptor *dep = tx->next; + struct dma_async_tx_descriptor *dep = txd_next(tx); struct dma_async_tx_descriptor *dep_next; struct dma_chan *chan; @@ -1019,7 +1021,7 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) return; /* we'll submit tx->next now, so clear the link */ - tx->next = NULL; + txd_clear_next(tx); chan = dep->chan; /* keep submitting up until a channel switch is detected @@ -1027,14 +1029,14 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) * processing the interrupt from async_tx_channel_switch */ for (; dep; dep = dep_next) { - spin_lock_bh(&dep->lock); - dep->parent = NULL; - dep_next = dep->next; + txd_lock(dep); + txd_clear_parent(dep); + dep_next = txd_next(dep); if (dep_next && dep_next->chan == chan) - dep->next = NULL; /* ->next will be submitted */ + txd_clear_next(dep); /* ->next will be submitted */ else dep_next = NULL; /* submit current dep and terminate */ - spin_unlock_bh(&dep->lock); + txd_unlock(dep); dep->tx_submit(dep); } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 20ea12c86fd0..cb234979fc6b 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -230,11 +230,71 @@ struct dma_async_tx_descriptor { dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx); dma_async_tx_callback callback; void *callback_param; +#ifndef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH struct dma_async_tx_descriptor *next; struct dma_async_tx_descriptor *parent; spinlock_t lock; +#endif }; +#ifdef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH +static inline void txd_lock(struct dma_async_tx_descriptor *txd) +{ +} +static inline void txd_unlock(struct dma_async_tx_descriptor *txd) +{ +} +static inline void txd_chain(struct dma_async_tx_descriptor *txd, struct dma_async_tx_descriptor *next) +{ + BUG(); +} +static inline void txd_clear_parent(struct dma_async_tx_descriptor *txd) +{ +} +static inline void txd_clear_next(struct dma_async_tx_descriptor *txd) +{ +} +static inline struct dma_async_tx_descriptor *txd_next(struct dma_async_tx_descriptor *txd) +{ + return NULL; +} +static inline struct dma_async_tx_descriptor *txd_parent(struct dma_async_tx_descriptor *txd) +{ + return NULL; +} + +#else +static inline void txd_lock(struct dma_async_tx_descriptor *txd) +{ + spin_lock_bh(&txd->lock); +} +static inline void txd_unlock(struct dma_async_tx_descriptor *txd) +{ + spin_unlock_bh(&txd->lock); +} +static inline void txd_chain(struct dma_async_tx_descriptor *txd, struct dma_async_tx_descriptor *next) +{ + txd->next = next; + next->parent = txd; +} +static inline void txd_clear_parent(struct dma_async_tx_descriptor *txd) +{ + txd->parent = NULL; +} +static inline void txd_clear_next(struct dma_async_tx_descriptor *txd) +{ + txd->next = NULL; +} +static inline struct dma_async_tx_descriptor *txd_parent(struct dma_async_tx_descriptor *txd) +{ + return txd->parent; +} +static inline struct dma_async_tx_descriptor *txd_next(struct dma_async_tx_descriptor *txd) +{ + return txd->next; +} +#endif + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported -- cgit v1.2.3 From 058276303dbc4ed089c1f7dad0871810b1f5ddf1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 17 May 2010 16:30:42 -0700 Subject: DMAENGINE: extend the control command to include an arg This adds an argument to the DMAengine control function, so that we can later provide control commands that need some external data passed in through an argument akin to the ioctl() operation prototype. [dan.j.williams@intel.com: fix up some missed conversions] Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 3 ++- drivers/dma/coh901318.c | 5 +++-- drivers/dma/dw_dmac.c | 3 ++- drivers/dma/fsldma.c | 2 +- drivers/dma/ipu/ipu_idmac.c | 12 +++++++----- drivers/dma/shdma.c | 3 ++- drivers/dma/ste_dma40.c | 3 ++- drivers/dma/timb_dma.c | 3 ++- drivers/dma/txx9dmac.c | 3 ++- drivers/mmc/host/atmel-mci.c | 2 +- drivers/serial/sh-sci.c | 2 +- drivers/video/mx3fb.c | 2 +- include/linux/dmaengine.h | 3 ++- sound/soc/txx9/txx9aclc.c | 7 ++++--- 14 files changed, 32 insertions(+), 21 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 93ed99c84cf1..ee805a43f879 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -759,7 +759,8 @@ err_desc_get: return NULL; } -static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 4233440741a2..a724e6be1b4d 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -942,7 +942,7 @@ coh901318_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); } @@ -1176,7 +1176,8 @@ coh901318_issue_pending(struct dma_chan *chan) } static int -coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { unsigned long flags; struct coh901318_chan *cohc = to_coh901318_chan(chan); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 18fb5b41cedf..a3991ab0d67e 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -781,7 +781,8 @@ err_desc_get: return NULL; } -static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma *dw = to_dw_dma(chan->device); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index cb1924f46c9e..005329d496bd 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -775,7 +775,7 @@ fail: } static int fsl_dma_device_control(struct dma_chan *dchan, - enum dma_ctrl_cmd cmd) + enum dma_ctrl_cmd cmd, unsigned long arg) { struct fsldma_chan *chan; unsigned long flags; diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 246a6143e4a7..cb26ee9773d6 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1472,7 +1472,8 @@ static void idmac_issue_pending(struct dma_chan *chan) */ } -static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct idmac_channel *ichan = to_idmac_chan(chan); struct idmac *idmac = to_idmac(chan->device); @@ -1513,14 +1514,15 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) return 0; } -static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct idmac_channel *ichan = to_idmac_chan(chan); int ret; mutex_lock(&ichan->chan_mutex); - ret = __idmac_control(chan, cmd); + ret = __idmac_control(chan, cmd, arg); mutex_unlock(&ichan->chan_mutex); @@ -1616,7 +1618,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan) mutex_lock(&ichan->chan_mutex); - __idmac_control(chan, DMA_TERMINATE_ALL); + __idmac_control(chan, DMA_TERMINATE_ALL, 0); if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG @@ -1709,7 +1711,7 @@ static void __exit ipu_idmac_exit(struct ipu *ipu) for (i = 0; i < IPU_CHANNELS_NUM; i++) { struct idmac_channel *ichan = ipu->channel + i; - idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL); + idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0); idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 98f82cdb404c..e9de1d35c20d 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -580,7 +580,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( direction, flags); } -static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 81fec95312b6..c426829f6ab8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2065,7 +2065,8 @@ static void d40_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&d40c->lock, flags); } -static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { unsigned long flags; struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 44b346d8d319..0172fa3c7a2b 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -611,7 +611,8 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, return &td_desc->txd; } -static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index e523737639aa..d02edb05910e 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -938,7 +938,8 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return &first->txd; } -static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); struct txx9dmac_desc *desc, *_desc; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index ae6d24ba4f08..fd2d24f81478 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -578,7 +578,7 @@ static void atmci_stop_dma(struct atmel_mci *host) struct dma_chan *chan = host->data_chan; if (chan) { - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); atmci_dma_cleanup(host); } else { /* Data transfer was stopped by the interrupt handler */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 690988237971..882f3d5ed028 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1087,7 +1087,7 @@ static void work_fn_rx(struct work_struct *work) unsigned long flags; int count; - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); dev_dbg(port->dev, "Read %u bytes with cookie %d\n", sh_desc->partial, sh_desc->cookie); diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 3aa50bc276eb..7cfc170bce19 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -388,7 +388,7 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_unlock_irqrestore(&mx3fb->lock, flags); mx3_fbi->txd->chan->device->device_control(mx3_fbi->txd->chan, - DMA_TERMINATE_ALL); + DMA_TERMINATE_ALL, 0); mx3_fbi->txd = NULL; mx3_fbi->cookie = -EINVAL; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 50b7b3e0d572..17456571ff7a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -347,7 +347,8 @@ struct dma_device { struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); - int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); + int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg); enum dma_status (*device_tx_status)(struct dma_chan *chan, dma_cookie_t cookie, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index b35d00706c0e..9398f507f77f 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -159,7 +159,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -267,7 +267,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); return 0; } @@ -396,7 +396,8 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, + DMA_TERMINATE_ALL, 0); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; -- cgit v1.2.3 From 61c7a080a5a061c976988fd4b844dfb468dda255 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:29 -0700 Subject: of: Always use 'struct device.of_node' to get device node pointer. The following structure elements duplicate the information in 'struct device.of_node' and so are being eliminated. This patch makes all readers of these elements use device.of_node instead. (struct of_device *)->node (struct dev_archdata *)->prom_node (sparc) (struct dev_archdata *)->of_node (powerpc & microblaze) Signed-off-by: Grant Likely --- arch/microblaze/kernel/of_device.c | 8 +++---- arch/microblaze/kernel/of_platform.c | 4 ++-- arch/powerpc/include/asm/macio.h | 2 +- arch/powerpc/kernel/ibmebus.c | 4 ++-- arch/powerpc/kernel/of_device.c | 8 +++---- arch/powerpc/kernel/of_platform.c | 16 +++++++------- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 4 ++-- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 16 +++++++------- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 6 +++--- arch/powerpc/platforms/82xx/ep8248e.c | 6 +++--- arch/powerpc/platforms/83xx/suspend.c | 2 +- arch/powerpc/platforms/cell/axon_msi.c | 2 +- arch/powerpc/platforms/pasemi/gpio_mdio.c | 2 +- arch/powerpc/sysdev/axonram.c | 6 +++--- arch/powerpc/sysdev/bestcomm/bestcomm.c | 8 +++---- arch/powerpc/sysdev/fsl_msi.c | 14 ++++++------- arch/powerpc/sysdev/fsl_pmc.c | 2 +- arch/powerpc/sysdev/fsl_rio.c | 30 +++++++++++++-------------- arch/powerpc/sysdev/pmi.c | 2 +- arch/sparc/include/asm/fb.h | 2 +- arch/sparc/include/asm/floppy_64.h | 4 ++-- arch/sparc/include/asm/parport.h | 2 +- arch/sparc/kernel/auxio_64.c | 2 +- arch/sparc/kernel/central.c | 4 ++-- arch/sparc/kernel/chmc.c | 10 ++++----- arch/sparc/kernel/ioport.c | 2 +- arch/sparc/kernel/of_device_32.c | 14 ++++++------- arch/sparc/kernel/of_device_64.c | 26 +++++++++++------------ arch/sparc/kernel/of_device_common.c | 4 ++-- arch/sparc/kernel/pci.c | 12 +++++------ arch/sparc/kernel/pci_common.c | 9 ++++---- arch/sparc/kernel/pci_fire.c | 4 ++-- arch/sparc/kernel/pci_msi.c | 18 ++++++++-------- arch/sparc/kernel/pci_psycho.c | 4 ++-- arch/sparc/kernel/pci_sabre.c | 4 ++-- arch/sparc/kernel/pci_schizo.c | 14 ++++++------- arch/sparc/kernel/pci_sun4v.c | 8 +++---- arch/sparc/kernel/power.c | 4 ++-- arch/sparc/kernel/psycho_common.c | 2 +- arch/sparc/kernel/sbus.c | 16 +++++++------- arch/sparc/kernel/time_32.c | 2 +- arch/sparc/kernel/time_64.c | 6 +++--- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_mpc52xx.c | 10 ++++----- drivers/ata/pata_of_platform.c | 2 +- drivers/ata/sata_fsl.c | 4 ++-- drivers/atm/fore200e.c | 16 +++++++------- drivers/block/swim3.c | 2 +- drivers/block/xsysace.c | 8 +++---- drivers/cdrom/viocd.c | 2 +- drivers/char/hw_random/n2-drv.c | 2 +- drivers/char/hw_random/pasemi-rng.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 4 ++-- drivers/char/viotape.c | 2 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 6 +++--- drivers/crypto/talitos.c | 2 +- drivers/dma/fsldma.c | 6 +++--- drivers/gpio/pca953x.c | 2 +- drivers/i2c/busses/i2c-cpm.c | 20 +++++++++--------- drivers/i2c/busses/i2c-ibm_iic.c | 4 ++-- drivers/i2c/busses/i2c-mpc.c | 17 ++++++++------- drivers/ide/pmac.c | 10 ++++----- drivers/infiniband/hw/ehca/ehca_main.c | 11 +++++----- drivers/input/serio/i8042-sparcio.h | 2 +- drivers/input/serio/xilinx_ps2.c | 8 +++---- drivers/leds/leds-gpio.c | 2 +- drivers/macintosh/macio_asic.c | 16 +++++++------- drivers/macintosh/macio_sysfs.c | 6 +++--- drivers/macintosh/mediabay.c | 2 +- drivers/macintosh/rack-meter.c | 4 ++-- drivers/macintosh/therm_pm72.c | 2 +- drivers/mmc/host/of_mmc_spi.c | 4 ++-- drivers/mmc/host/sdhci-of-core.c | 2 +- drivers/mtd/maps/physmap_of.c | 6 +++--- drivers/mtd/maps/sun_uflash.c | 2 +- drivers/mtd/nand/fsl_elbc_nand.c | 6 +++--- drivers/mtd/nand/ndfc.c | 10 ++++----- drivers/mtd/nand/pasemi_nand.c | 2 +- drivers/net/can/sja1000/sja1000_of_platform.c | 4 ++-- drivers/net/ehea/ehea_main.c | 14 ++++++------- drivers/net/fec_mpc52xx.c | 12 +++++------ drivers/net/fec_mpc52xx_phy.c | 4 ++-- drivers/net/fs_enet/fs_enet-main.c | 8 +++---- drivers/net/fs_enet/mac-fcc.c | 8 +++---- drivers/net/fs_enet/mac-fec.c | 4 ++-- drivers/net/fs_enet/mac-scc.c | 6 +++--- drivers/net/fs_enet/mii-fec.c | 6 +++--- drivers/net/fsl_pq_mdio.c | 2 +- drivers/net/gianfar.c | 6 +++--- drivers/net/greth.c | 3 ++- drivers/net/ibm_newemac/core.c | 13 ++++++------ drivers/net/ibm_newemac/debug.c | 9 ++++---- drivers/net/ibm_newemac/debug.h | 4 ++-- drivers/net/ibm_newemac/mal.c | 28 ++++++++++++------------- drivers/net/ibm_newemac/rgmii.c | 12 +++++------ drivers/net/ibm_newemac/tah.c | 7 ++++--- drivers/net/ibm_newemac/zmii.c | 9 ++++---- drivers/net/ll_temac_main.c | 10 ++++----- drivers/net/myri_sbus.c | 2 +- drivers/net/niu.c | 10 ++++----- drivers/net/phy/mdio-gpio.c | 6 +++--- drivers/net/sunbmac.c | 6 +++--- drivers/net/sunhme.c | 8 +++---- drivers/net/sunlance.c | 6 +++--- drivers/net/sunqe.c | 6 +++--- drivers/net/ucc_geth.c | 2 +- drivers/net/xilinx_emaclite.c | 10 ++++----- drivers/of/device.c | 20 +++++++++--------- drivers/of/of_i2c.c | 2 +- drivers/of/of_mdio.c | 4 ++-- drivers/pcmcia/electra_cf.c | 2 +- drivers/sbus/char/bbc_envctrl.c | 4 ++-- drivers/sbus/char/bbc_i2c.c | 4 ++-- drivers/sbus/char/display7seg.c | 2 +- drivers/sbus/char/envctrl.c | 2 +- drivers/sbus/char/flash.c | 4 ++-- drivers/sbus/char/uctrl.c | 2 +- drivers/scsi/ibmvscsi/ibmvfc.c | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- drivers/scsi/qlogicpti.c | 10 ++++----- drivers/scsi/sun_esp.c | 16 +++++++------- drivers/serial/apbuart.c | 2 +- drivers/serial/cpm_uart/cpm_uart_core.c | 2 +- drivers/serial/mpc52xx_uart.c | 8 +++---- drivers/serial/nwpserial.c | 2 +- drivers/serial/of_serial.c | 4 ++-- drivers/serial/pmac_zilog.c | 2 +- drivers/serial/sunhv.c | 2 +- drivers/serial/sunsab.c | 6 +++--- drivers/serial/sunsu.c | 6 +++--- drivers/serial/sunzilog.c | 8 +++---- drivers/serial/uartlite.c | 6 +++--- drivers/serial/ucc_uart.c | 2 +- drivers/spi/mpc52xx_psc_spi.c | 11 +++++----- drivers/spi/mpc52xx_spi.c | 14 ++++++------- drivers/spi/spi_mpc8xxx.c | 8 +++---- drivers/usb/host/ehci-ppc-of.c | 2 +- drivers/usb/host/fhci-hcd.c | 4 ++-- drivers/usb/host/isp1760-if.c | 2 +- drivers/usb/host/ohci-ppc-of.c | 2 +- drivers/video/cg6.c | 2 +- drivers/video/ffb.c | 2 +- drivers/video/fsl-diu-fb.c | 2 +- drivers/video/platinumfb.c | 2 +- drivers/video/sunxvr1000.c | 2 +- drivers/video/xilinxfb.c | 18 ++++++++-------- drivers/watchdog/cpwd.c | 2 +- sound/aoa/fabrics/layout.c | 2 +- sound/aoa/soundbus/core.c | 8 +++---- sound/aoa/soundbus/i2sbus/control.c | 2 +- sound/aoa/soundbus/i2sbus/core.c | 4 ++-- sound/aoa/soundbus/sysfs.c | 4 ++-- sound/soc/fsl/mpc5200_dma.c | 6 +++--- sound/soc/fsl/mpc5200_psc_i2s.c | 2 +- sound/soc/fsl/mpc8610_hpcd.c | 2 +- sound/sparc/cs4231.c | 6 +++--- sound/sparc/dbri.c | 2 +- 157 files changed, 497 insertions(+), 488 deletions(-) (limited to 'drivers/dma') diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index f6c521898ebf..90d2246e15c0 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -12,7 +12,7 @@ void of_device_make_bus_id(struct of_device *dev) { static atomic_t bus_no_reg_magic; - struct device_node *node = dev->node; + struct device_node *node = dev->dev.of_node; const u32 *reg; u64 addr; int magic; @@ -76,17 +76,17 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ofdev = to_of_device(dev); - if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) return -ENOMEM; - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index 0dc755286d38..46a1e105a6bd 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -166,7 +166,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } struct of_device *of_find_device_by_node(struct device_node *np) @@ -184,7 +184,7 @@ EXPORT_SYMBOL(of_find_device_by_node); static int of_dev_phandle_match(struct device *dev, void *data) { phandle *ph = data; - return to_of_device(dev)->node->phandle == *ph; + return to_of_device(dev)->dev.of_node->phandle == *ph; } struct of_device *of_find_device_by_phandle(phandle ph) diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index a062c57696d0..19a661b4cb98 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h @@ -108,7 +108,7 @@ static inline void* macio_get_drvdata(struct macio_dev *dev) static inline struct device_node *macio_get_of_node(struct macio_dev *mdev) { - return mdev->ofdev.node; + return mdev->ofdev.dev.of_node; } #ifdef CONFIG_PCI diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 71cf280da184..a9f31631a293 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -140,14 +140,14 @@ static struct dma_map_ops ibmebus_dma_ops = { static int ibmebus_match_path(struct device *dev, void *data) { - struct device_node *dn = to_of_device(dev)->node; + struct device_node *dn = to_of_device(dev)->dev.of_node; return (dn->full_name && (strcasecmp((char *)data, dn->full_name) == 0)); } static int ibmebus_match_node(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } static int ibmebus_create_device(struct device_node *dn) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 9577e6f4e3bf..285c8490c547 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -13,7 +13,7 @@ static void of_device_make_bus_id(struct of_device *dev) { static atomic_t bus_no_reg_magic; - struct device_node *node = dev->node; + struct device_node *node = dev->dev.of_node; const u32 *reg; u64 addr; int magic; @@ -96,17 +96,17 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ofdev = to_of_device(dev); - if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) return -ENOMEM; - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 6c1dfc3ff8bc..1c747c474415 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -195,7 +195,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } struct of_device *of_find_device_by_node(struct device_node *np) @@ -213,7 +213,7 @@ EXPORT_SYMBOL(of_find_device_by_node); static int of_dev_phandle_match(struct device *dev, void *data) { phandle *ph = data; - return to_of_device(dev)->node->phandle == *ph; + return to_of_device(dev)->dev.of_node->phandle == *ph; } struct of_device *of_find_device_by_phandle(phandle ph) @@ -246,10 +246,10 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, if (ppc_md.pci_setup_phb == NULL) return -ENODEV; - printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name); + pr_info("Setting up PCI bus %s\n", dev->dev.of_node->full_name); /* Alloc and setup PHB data structure */ - phb = pcibios_alloc_controller(dev->node); + phb = pcibios_alloc_controller(dev->dev.of_node); if (!phb) return -ENODEV; @@ -263,19 +263,19 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, } /* Process "ranges" property */ - pci_process_bridge_OF_ranges(phb, dev->node, 0); + pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0); /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); /* Register devices with EEH */ #ifdef CONFIG_EEH - if (dev->node->child) - eeh_add_device_tree_early(dev->node); + if (dev->dev.of_node->child) + eeh_add_device_tree_early(dev->dev.of_node); #endif /* CONFIG_EEH */ /* Scan the bus */ - pcibios_scan_phb(phb, dev->node); + pcibios_scan_phb(phb, dev->dev.of_node); if (phb->bus == NULL) return -ENXIO; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index fda7c2a18282..576669fc4fbf 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -168,7 +168,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_wkup_gpio_get; ofchip->gc.set = mpc52xx_wkup_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; @@ -329,7 +329,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_simple_gpio_get; ofchip->gc.set = mpc52xx_simple_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index a60ee39d3b78..42c507f9c35b 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -734,8 +734,8 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, spin_lock_init(&gpt->lock); gpt->dev = &ofdev->dev; - gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->node); - gpt->regs = of_iomap(ofdev->node, 0); + gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); + gpt->regs = of_iomap(ofdev->dev.of_node, 0); if (!gpt->regs) { kfree(gpt); return -ENOMEM; @@ -743,21 +743,21 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, gpt); - mpc52xx_gpt_gpio_setup(gpt, ofdev->node); - mpc52xx_gpt_irq_setup(gpt, ofdev->node); + mpc52xx_gpt_gpio_setup(gpt, ofdev->dev.of_node); + mpc52xx_gpt_irq_setup(gpt, ofdev->dev.of_node); mutex_lock(&mpc52xx_gpt_list_mutex); list_add(&gpt->list, &mpc52xx_gpt_list); mutex_unlock(&mpc52xx_gpt_list_mutex); /* check if this device could be a watchdog */ - if (of_get_property(ofdev->node, "fsl,has-wdt", NULL) || - of_get_property(ofdev->node, "has-wdt", NULL)) { + if (of_get_property(ofdev->dev.of_node, "fsl,has-wdt", NULL) || + of_get_property(ofdev->dev.of_node, "has-wdt", NULL)) { const u32 *on_boot_wdt; gpt->wdt_mode = MPC52xx_GPT_CAN_WDT; - on_boot_wdt = of_get_property(ofdev->node, "fsl,wdt-on-boot", - NULL); + on_boot_wdt = of_get_property(ofdev->dev.of_node, + "fsl,wdt-on-boot", NULL); if (on_boot_wdt) { dev_info(gpt->dev, "used as watchdog\n"); gpt->wdt_mode |= MPC52xx_GPT_IS_WDT; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index d4f8be307cd5..17b99ba7a8cc 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -445,14 +445,14 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) if (lpbfifo.dev != NULL) return -ENOSPC; - lpbfifo.irq = irq_of_parse_and_map(op->node, 0); + lpbfifo.irq = irq_of_parse_and_map(op->dev.of_node, 0); if (!lpbfifo.irq) return -ENODEV; - if (of_address_to_resource(op->node, 0, &res)) + if (of_address_to_resource(op->dev.of_node, 0, &res)) return -ENODEV; lpbfifo.regs_phys = res.start; - lpbfifo.regs = of_iomap(op->node, 0); + lpbfifo.regs = of_iomap(op->dev.of_node, 0); if (!lpbfifo.regs) return -ENOMEM; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index f21555d3395a..0176ae8249d5 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -119,12 +119,12 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, struct device_node *node; int ret; - node = of_get_parent(ofdev->node); + node = of_get_parent(ofdev->dev.of_node); of_node_put(node); if (node != ep8248e_bcsr_node) return -ENODEV; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) return ret; @@ -142,7 +142,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); - ret = of_mdiobus_register(bus, ofdev->node); + ret = of_mdiobus_register(bus, ofdev->dev.of_node); if (ret) goto err_free_irq; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 43805348b81e..aa0b764b1cc4 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -321,7 +321,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type = match->data; int ret = 0; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 8efe48192f3f..177a4f1369b4 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -345,7 +345,7 @@ static int axon_msi_shutdown(struct of_device *device) static int axon_msi_probe(struct of_device *device, const struct of_device_id *device_id) { - struct device_node *dn = device->node; + struct device_node *dn = device->dev.of_node; struct axon_msic *msic; unsigned int virq; int dcr_base, dcr_len; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 0f881f64583e..c44e1b3b91db 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -220,7 +220,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mii_bus *new_bus; struct gpio_priv *priv; const unsigned int *prop; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88f4ae787832..88b21fccf0c9 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -185,7 +185,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) axon_ram_bank_id++; dev_info(&device->dev, "Found memory controller on %s\n", - device->node->full_name); + device->dev.of_node->full_name); bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); if (bank == NULL) { @@ -198,7 +198,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) bank->device = device; - if (of_address_to_resource(device->node, 0, &resource) != 0) { + if (of_address_to_resource(device->dev.of_node, 0, &resource) != 0) { dev_err(&device->dev, "Cannot access device tree\n"); rc = -EFAULT; goto failed; @@ -253,7 +253,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); add_disk(bank->disk); - bank->irq_id = irq_of_parse_and_map(device->node, 0); + bank->irq_id = irq_of_parse_and_map(device->dev.of_node, 0); if (bank->irq_id == NO_IRQ) { dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); rc = -EFAULT; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 378ebd9aac18..d32d5389b67a 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -377,7 +377,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) printk(KERN_INFO "DMA: MPC52xx BestComm driver\n"); /* Get the bestcomm node */ - of_node_get(op->node); + of_node_get(op->dev.of_node); /* Prepare SRAM */ ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids); @@ -406,10 +406,10 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) } /* Save the node */ - bcom_eng->ofnode = op->node; + bcom_eng->ofnode = op->dev.of_node; /* Get, reserve & map io */ - if (of_address_to_resource(op->node, 0, &res_bcom)) { + if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) { printk(KERN_ERR DRIVER_NAME ": " "Can't get resource\n"); rv = -EINVAL; @@ -453,7 +453,7 @@ error_sramclean: kfree(bcom_eng); bcom_sram_cleanup(); error_ofput: - of_node_put(op->node); + of_node_put(op->dev.of_node); printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n"); diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 3482e3fd89c0..569dae8ea1ce 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -249,7 +249,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR, + msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, NR_MSI_IRQS, &fsl_msi_host_ops, 0); if (msi->irqhost == NULL) { @@ -259,10 +259,10 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, } /* Get the MSI reg base */ - err = of_address_to_resource(dev->node, 0, &res); + err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { dev_err(&dev->dev, "%s resource error!\n", - dev->node->full_name); + dev->dev.of_node->full_name); goto error_out; } @@ -285,16 +285,16 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - p = of_get_property(dev->node, "interrupts", &count); + p = of_get_property(dev->dev.of_node, "interrupts", &count); if (!p) { dev_err(&dev->dev, "no interrupts property found on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -ENODEV; goto error_out; } if (count % 8 != 0) { dev_err(&dev->dev, "Malformed interrupts property on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -EINVAL; goto error_out; } @@ -303,7 +303,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, for (i = 0; i < count / 2; i++) { if (i > NR_MSI_REG) break; - virt_msir = irq_of_parse_and_map(dev->node, i); + virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); if (virt_msir != NO_IRQ) { set_irq_data(virt_msir, (void *)i); set_irq_chained_handler(virt_msir, fsl_msi_cascade); diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index a7635a993dca..2ebe817ca72f 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -60,7 +60,7 @@ static struct platform_suspend_ops pmc_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) { - pmc_regs = of_iomap(ofdev->node, 0); + pmc_regs = of_iomap(ofdev->dev.of_node, 0); if (!pmc_regs) return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 71fba88f50db..a98d51639243 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1015,41 +1015,41 @@ int fsl_rio_setup(struct of_device *dev) u64 law_start, law_size; int paw, aw, sw; - if (!dev->node) { + if (!dev->dev.of_node) { dev_err(&dev->dev, "Device OF-Node is NULL"); return -EFAULT; } - rc = of_address_to_resource(dev->node, 0, ®s); + rc = of_address_to_resource(dev->dev.of_node, 0, ®s); if (rc) { dev_err(&dev->dev, "Can't get %s property 'reg'\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EFAULT; } - dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name); + dev_info(&dev->dev, "Of-device full name %s\n", dev->dev.of_node->full_name); dev_info(&dev->dev, "Regs: %pR\n", ®s); - dt_range = of_get_property(dev->node, "ranges", &rlen); + dt_range = of_get_property(dev->dev.of_node, "ranges", &rlen); if (!dt_range) { dev_err(&dev->dev, "Can't get %s property 'ranges'\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EFAULT; } /* Get node address wide */ - cell = of_get_property(dev->node, "#address-cells", NULL); + cell = of_get_property(dev->dev.of_node, "#address-cells", NULL); if (cell) aw = *cell; else - aw = of_n_addr_cells(dev->node); + aw = of_n_addr_cells(dev->dev.of_node); /* Get node size wide */ - cell = of_get_property(dev->node, "#size-cells", NULL); + cell = of_get_property(dev->dev.of_node, "#size-cells", NULL); if (cell) sw = *cell; else - sw = of_n_size_cells(dev->node); + sw = of_n_size_cells(dev->dev.of_node); /* Get parent address wide wide */ - paw = of_n_addr_cells(dev->node); + paw = of_n_addr_cells(dev->dev.of_node); law_start = of_read_number(dt_range + aw, paw); law_size = of_read_number(dt_range + aw + paw, sw); @@ -1089,9 +1089,9 @@ int fsl_rio_setup(struct of_device *dev) port->iores.flags = IORESOURCE_MEM; port->iores.name = "rio_io_win"; - priv->bellirq = irq_of_parse_and_map(dev->node, 2); - priv->txirq = irq_of_parse_and_map(dev->node, 3); - priv->rxirq = irq_of_parse_and_map(dev->node, 4); + priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); + priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); + priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4); dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq, priv->txirq, priv->rxirq); @@ -1195,7 +1195,7 @@ static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, { int rc; printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); rc = fsl_rio_setup(dev); if (rc) diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 652652db4ce2..ff758bff1b7a 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -124,7 +124,7 @@ static void pmi_notify_handlers(struct work_struct *work) static int pmi_of_probe(struct of_device *dev, const struct of_device_id *match) { - struct device_node *np = dev->node; + struct device_node *np = dev->dev.of_node; int rc; if (data) { diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index b83e44729655..e834880be204 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h @@ -18,7 +18,7 @@ static inline int fb_is_primary_device(struct fb_info *info) struct device *dev = info->device; struct device_node *node; - node = dev->archdata.prom_node; + node = dev->of_node; if (node && node == of_console_device) return 1; diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 36439d67ad71..8fac3ab22f36 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -589,7 +589,7 @@ static unsigned long __init sun_floppy_init(void) if (!op) return 0; - state_prop = of_get_property(op->node, "status", NULL); + state_prop = of_get_property(op->dev.of_node, "status", NULL); if (state_prop && !strncmp(state_prop, "disabled", 8)) return 0; @@ -716,7 +716,7 @@ static unsigned long __init sun_floppy_init(void) return sun_floppy_types[0]; } - prop = of_get_property(op->node, "status", NULL); + prop = of_get_property(op->dev.of_node, "status", NULL); if (prop && !strncmp(state, "disabled", 8)) return 0; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index ff9ead640c4a..1bb6a41b00f2 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -113,7 +113,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id struct parport *p; int slot, err; - parent = op->node->parent; + parent = op->dev.of_node->parent; if (!strcmp(parent->name, "dma")) { p = parport_pc_probe_port(base, base + 0x400, op->irqs[0], PARPORT_DMA_NOFIFO, diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 9f52db2d441c..bd8421a26856 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -104,7 +104,7 @@ MODULE_DEVICE_TABLE(of, auxio_match); static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match) { - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; unsigned long size; if (!strcmp(dp->parent->name, "ebus")) { diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 415c86d5a8da..d533f3d5d484 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -168,7 +168,7 @@ static int __devinit fhc_probe(struct of_device *op, goto out; } - if (!strcmp(op->node->parent->name, "central")) + if (!strcmp(op->dev.of_node->parent->name, "central")) p->central = true; p->pregs = of_ioremap(&op->resource[0], 0, @@ -183,7 +183,7 @@ static int __devinit fhc_probe(struct of_device *op, reg = upa_readl(p->pregs + FHC_PREGS_BSR); p->board_num = ((reg >> 16) & 1) | ((reg >> 12) & 0x0e); } else { - p->board_num = of_getintprop_default(op->node, "board#", -1); + p->board_num = of_getintprop_default(op->dev.of_node, "board#", -1); if (p->board_num == -1) { printk(KERN_ERR "fhc: No board# property\n"); goto out_unmap_pregs; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index e1a9598e2a4d..936879639eb6 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -425,7 +425,7 @@ static int __devinit jbusmc_probe(struct of_device *op, INIT_LIST_HEAD(&p->list); err = -ENODEV; - prop = of_get_property(op->node, "portid", &len); + prop = of_get_property(op->dev.of_node, "portid", &len); if (!prop || len != 4) { printk(KERN_ERR PFX "Cannot find portid.\n"); goto out_free; @@ -433,7 +433,7 @@ static int __devinit jbusmc_probe(struct of_device *op, p->portid = *prop; - prop = of_get_property(op->node, "memory-control-register-1", &len); + prop = of_get_property(op->dev.of_node, "memory-control-register-1", &len); if (!prop || len != 8) { printk(KERN_ERR PFX "Cannot get memory control register 1.\n"); goto out_free; @@ -449,7 +449,7 @@ static int __devinit jbusmc_probe(struct of_device *op, } err = -ENODEV; - ml = of_get_property(op->node, "memory-layout", &p->layout_len); + ml = of_get_property(op->dev.of_node, "memory-layout", &p->layout_len); if (!ml) { printk(KERN_ERR PFX "Cannot get memory layout property.\n"); goto out_iounmap; @@ -466,7 +466,7 @@ static int __devinit jbusmc_probe(struct of_device *op, mc_list_add(&p->list); printk(KERN_INFO PFX "UltraSPARC-IIIi memory controller at %s\n", - op->node->full_name); + op->dev.of_node->full_name); dev_set_drvdata(&op->dev, p); @@ -693,7 +693,7 @@ static void chmc_fetch_decode_regs(struct chmc *p) static int __devinit chmc_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; unsigned long ver; const void *pval; int len, portid; diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 84e5386714cd..703e4aa9bc38 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -290,7 +290,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) goto err_noiommu; - res->name = op->node->name; + res->name = op->dev.of_node->name; return (void *)(unsigned long)res->start; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4926c1babd84..707311716142 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -254,10 +254,10 @@ static void __init build_device_resources(struct of_device *op, return; p_op = to_of_device(parent); - bus = of_match_bus(p_op->node); - bus->count_cells(op->node, &na, &ns); + bus = of_match_bus(p_op->dev.of_node); + bus->count_cells(op->dev.of_node, &na, &ns); - preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); + preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); if (!preg || num_reg == 0) return; @@ -271,8 +271,8 @@ static void __init build_device_resources(struct of_device *op, struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; const u32 *reg = (preg + (index * ((na + ns) * 4))); - struct device_node *dp = op->node; - struct device_node *pp = p_op->node; + struct device_node *dp = op->dev.of_node; + struct device_node *pp = p_op->dev.of_node; struct of_bus *pbus, *dbus; u64 size, result = OF_BAD_ADDR; unsigned long flags; @@ -321,7 +321,7 @@ static void __init build_device_resources(struct of_device *op, if (of_resource_verbose) printk("%s reg[%d] -> %llx\n", - op->node->full_name, index, + op->dev.of_node->full_name, index, result); if (result != OF_BAD_ADDR) { @@ -329,7 +329,7 @@ static void __init build_device_resources(struct of_device *op, r->end = result + size - 1; r->flags = flags | ((result >> 32ULL) & 0xffUL); } - r->name = op->node->name; + r->name = op->dev.of_node->name; } } diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5bc74161667c..c8e352e0a098 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -323,10 +323,10 @@ static void __init build_device_resources(struct of_device *op, return; p_op = to_of_device(parent); - bus = of_match_bus(p_op->node); - bus->count_cells(op->node, &na, &ns); + bus = of_match_bus(p_op->dev.of_node); + bus->count_cells(op->dev.of_node, &na, &ns); - preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); + preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); if (!preg || num_reg == 0) return; @@ -340,7 +340,7 @@ static void __init build_device_resources(struct of_device *op, if (num_reg > PROMREG_MAX) { printk(KERN_WARNING "%s: Too many regs (%d), " "limiting to %d.\n", - op->node->full_name, num_reg, PROMREG_MAX); + op->dev.of_node->full_name, num_reg, PROMREG_MAX); num_reg = PROMREG_MAX; } @@ -348,8 +348,8 @@ static void __init build_device_resources(struct of_device *op, struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; const u32 *reg = (preg + (index * ((na + ns) * 4))); - struct device_node *dp = op->node; - struct device_node *pp = p_op->node; + struct device_node *dp = op->dev.of_node; + struct device_node *pp = p_op->dev.of_node; struct of_bus *pbus, *dbus; u64 size, result = OF_BAD_ADDR; unsigned long flags; @@ -397,7 +397,7 @@ static void __init build_device_resources(struct of_device *op, if (of_resource_verbose) printk("%s reg[%d] -> %llx\n", - op->node->full_name, index, + op->dev.of_node->full_name, index, result); if (result != OF_BAD_ADDR) { @@ -408,7 +408,7 @@ static void __init build_device_resources(struct of_device *op, r->end = result + size - 1; r->flags = flags; } - r->name = op->node->name; + r->name = op->dev.of_node->name; } } @@ -530,7 +530,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, struct device *parent, unsigned int irq) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct device_node *pp, *ip; unsigned int orig_irq = irq; int nid; @@ -575,7 +575,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (of_irq_verbose) printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", - op->node->full_name, + op->dev.of_node->full_name, pp->full_name, this_orig_irq, (iret ? iret->full_name : "NULL"), irq); @@ -594,7 +594,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (of_irq_verbose) printk("%s: PCI swizzle [%s] " "%x --> %x\n", - op->node->full_name, + op->dev.of_node->full_name, pp->full_name, this_orig_irq, irq); @@ -611,11 +611,11 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (!ip) return orig_irq; - irq = ip->irq_trans->irq_build(op->node, irq, + irq = ip->irq_trans->irq_build(op->dev.of_node, irq, ip->irq_trans->data); if (of_irq_verbose) printk("%s: Apply IRQ trans [%s] %x --> %x\n", - op->node->full_name, ip->full_name, orig_irq, irq); + op->dev.of_node->full_name, ip->full_name, orig_irq, irq); out: nid = of_node_to_nid(dp); diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 0247e68210b3..10c6c36a6e75 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -16,7 +16,7 @@ static int node_match(struct device *dev, void *data) struct of_device *op = to_of_device(dev); struct device_node *dp = data; - return (op->node == dp); + return (op->dev.of_node == dp); } struct of_device *of_find_device_by_node(struct device_node *dp) @@ -48,7 +48,7 @@ EXPORT_SYMBOL(irq_of_parse_and_map); void of_propagate_archdata(struct of_device *bus) { struct dev_archdata *bus_sd = &bus->dev.archdata; - struct device_node *bus_dp = bus->node; + struct device_node *bus_dp = bus->dev.of_node; struct device_node *dp; for (dp = bus_dp->child; dp; dp = dp->sibling) { diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 0c920147b4ef..c7a214ec5aff 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -654,7 +654,7 @@ show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * struct device_node *dp; pdev = to_pci_dev(dev); - dp = pdev->dev.archdata.prom_node; + dp = pdev->dev.of_node; return snprintf (buf, PAGE_SIZE, "%s\n", dp->full_name); } @@ -684,7 +684,7 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, struct device *parent) { - struct device_node *node = pbm->op->node; + struct device_node *node = pbm->op->dev.of_node; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -1023,7 +1023,7 @@ void arch_teardown_msi_irq(unsigned int virt_irq) struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) { - return pdev->dev.archdata.prom_node; + return pdev->dev.of_node; } EXPORT_SYMBOL(pci_device_to_OF_node); @@ -1152,15 +1152,13 @@ static int __init of_pci_slot_init(void) struct device_node *node; if (pbus->self) { - struct dev_archdata *sd = pbus->self->sysdata; - /* PCI->PCI bridge */ - node = sd->prom_node; + node = pbus->self->dev.of_node; } else { struct pci_pbm_info *pbm = pbus->sysdata; /* Host PCI controller */ - node = pbm->op->node; + node = pbm->op->dev.of_node; } pci_bus_slot_names(node, pbus); diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 8a000583b5cf..6c7a33af3ba6 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -314,12 +314,12 @@ struct pci_ops sun4v_pci_ops = { void pci_get_pbm_props(struct pci_pbm_info *pbm) { - const u32 *val = of_get_property(pbm->op->node, "bus-range", NULL); + const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL); pbm->pci_first_busno = val[0]; pbm->pci_last_busno = val[1]; - val = of_get_property(pbm->op->node, "ino-bitmap", NULL); + val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL); if (val) { pbm->ino_bitmap = (((u64)val[1] << 32UL) | ((u64)val[0] << 0UL)); @@ -365,7 +365,8 @@ static void pci_register_legacy_regions(struct resource *io_res, static void pci_register_iommu_region(struct pci_pbm_info *pbm) { - const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + const u32 *vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", + NULL); if (vdma) { struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); @@ -394,7 +395,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) int num_pbm_ranges; saw_mem = saw_io = 0; - pbm_ranges = of_get_property(pbm->op->node, "ranges", &i); + pbm_ranges = of_get_property(pbm->op->dev.of_node, "ranges", &i); if (!pbm_ranges) { prom_printf("PCI: Fatal error, missing PBM ranges property " " for %s\n", diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index d53f45bc7dda..ff844baa28e6 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -413,7 +413,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 portid) { const struct linux_prom64_registers *regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; int err; pbm->numa_node = -1; @@ -458,7 +458,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, static int __devinit fire_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index e0ef847219c3..548b8ca9c210 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -324,7 +324,7 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, const u32 *val; int len; - val = of_get_property(pbm->op->node, "#msi-eqs", &len); + val = of_get_property(pbm->op->dev.of_node, "#msi-eqs", &len); if (!val || len != 4) goto no_msi; pbm->msiq_num = *val; @@ -347,16 +347,16 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, u32 msi64_len; } *arng; - val = of_get_property(pbm->op->node, "msi-eq-size", &len); + val = of_get_property(pbm->op->dev.of_node, "msi-eq-size", &len); if (!val || len != 4) goto no_msi; pbm->msiq_ent_count = *val; - mqp = of_get_property(pbm->op->node, + mqp = of_get_property(pbm->op->dev.of_node, "msi-eq-to-devino", &len); if (!mqp) - mqp = of_get_property(pbm->op->node, + mqp = of_get_property(pbm->op->dev.of_node, "msi-eq-devino", &len); if (!mqp || len != sizeof(struct msiq_prop)) goto no_msi; @@ -364,27 +364,27 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, pbm->msiq_first = mqp->first_msiq; pbm->msiq_first_devino = mqp->first_devino; - val = of_get_property(pbm->op->node, "#msi", &len); + val = of_get_property(pbm->op->dev.of_node, "#msi", &len); if (!val || len != 4) goto no_msi; pbm->msi_num = *val; - mrng = of_get_property(pbm->op->node, "msi-ranges", &len); + mrng = of_get_property(pbm->op->dev.of_node, "msi-ranges", &len); if (!mrng || len != sizeof(struct msi_range_prop)) goto no_msi; pbm->msi_first = mrng->first_msi; - val = of_get_property(pbm->op->node, "msi-data-mask", &len); + val = of_get_property(pbm->op->dev.of_node, "msi-data-mask", &len); if (!val || len != 4) goto no_msi; pbm->msi_data_mask = *val; - val = of_get_property(pbm->op->node, "msix-data-width", &len); + val = of_get_property(pbm->op->dev.of_node, "msix-data-width", &len); if (!val || len != 4) goto no_msi; pbm->msix_data_width = *val; - arng = of_get_property(pbm->op->node, "msi-address-ranges", + arng = of_get_property(pbm->op->dev.of_node, "msi-address-ranges", &len); if (!arng || len != sizeof(struct addr_range_prop)) goto no_msi; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 142b9d6984a8..e675e21c6df6 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -285,7 +285,7 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ static void psycho_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); unsigned long base = pbm->controller_regs; u64 tmp; int err; @@ -507,7 +507,7 @@ static int __devinit psycho_probe(struct of_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; int is_pbm_a, err; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index ba6fbeba3e2c..5048498daade 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -310,7 +310,7 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) static void sabre_register_error_handlers(struct pci_pbm_info *pbm) { - struct device_node *dp = pbm->op->node; + struct device_node *dp = pbm->op->dev.of_node; struct of_device *op; unsigned long base = pbm->controller_regs; u64 tmp; @@ -456,7 +456,7 @@ static int __devinit sabre_probe(struct of_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; u32 upa_portid, dma_mask; struct iommu *iommu; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 2b5cdde77af7..2f3f9212b063 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -844,7 +844,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) */ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -939,7 +939,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) static void schizo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -1068,7 +1068,7 @@ static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm, { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = - (of_find_property(pbm->op->node, "66mhz-capable", NULL) + (of_find_property(pbm->op->dev.of_node, "66mhz-capable", NULL) != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -1138,7 +1138,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask; u64 control; - vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -1268,7 +1268,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - if (!of_find_property(pbm->op->node, "no-bus-parking", NULL)) + if (!of_find_property(pbm->op->dev.of_node, "no-bus-parking", NULL)) tmp |= SCHIZO_PCICTRL_PARK; else tmp &= ~SCHIZO_PCICTRL_PARK; @@ -1311,7 +1311,7 @@ static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, int chip_type) { const struct linux_prom64_registers *regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *chipset_name; int is_pbm_a, err; @@ -1415,7 +1415,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 23c33ff9c31e..5c11f56cedf8 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -540,7 +540,7 @@ static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, struct property *prop; struct device_node *dp; - dp = pbm->op->node; + dp = pbm->op->dev.of_node; prop = of_find_property(dp, "66mhz-capable", NULL); pbm->is_66mhz_capable = (prop != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -584,7 +584,7 @@ static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask, dma_offset; const u32 *vdma; - vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -881,7 +881,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 devhandle) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; int err; pbm->numa_node = of_node_to_nid(dp); @@ -929,7 +929,7 @@ static int __devinit pci_sun4v_probe(struct of_device *op, u32 devhandle; int i, err; - dp = op->node; + dp = op->dev.of_node; if (!hvapi_negotiated++) { err = sun4v_hvapi_register(HV_GRP_PCI, diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index e2a045c235a1..e3f806a7423b 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -41,9 +41,9 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id power_reg = of_ioremap(res, 0, 0x4, "power"); printk(KERN_INFO "%s: Control reg at %llx\n", - op->node->name, res->start); + op->dev.of_node->name, res->start); - if (has_button_interrupt(irq, op->node)) { + if (has_button_interrupt(irq, op->dev.of_node)) { if (request_irq(irq, power_handler, 0, "power", NULL) < 0) printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c index 8f1478475421..3f34ac853931 100644 --- a/arch/sparc/kernel/psycho_common.c +++ b/arch/sparc/kernel/psycho_common.c @@ -450,7 +450,7 @@ int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct of_device *op, const char *chip_name, int chip_type) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; pbm->name = dp->full_name; pbm->numa_node = -1; diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index 406e0872504e..cfeaf04b9cdf 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -63,10 +63,10 @@ void sbus_set_sbus64(struct device *dev, int bursts) int slot; u64 val; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); if (!regs) { printk(KERN_ERR "sbus_set_sbus64: Cannot find regs for %s\n", - op->node->full_name); + op->dev.of_node->full_name); return; } slot = regs->which_io; @@ -287,7 +287,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); /* Log the error. */ printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n", @@ -361,7 +361,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n", portid, @@ -439,7 +439,7 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); /* Log the error. */ printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n", @@ -496,7 +496,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) u64 control; int portid; - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); irq = sbus_build_irq(op, SYSIO_UE_INO); if (request_irq(irq, sysio_ue_handler, 0, @@ -537,7 +537,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) static void __init sbus_iommu_init(struct of_device *op) { const struct linux_prom64_registers *pr; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct iommu *iommu; struct strbuf *strbuf; unsigned long regs, reg_base; @@ -589,7 +589,7 @@ static void __init sbus_iommu_init(struct of_device *op) */ iommu->write_complete_reg = regs + 0x2000UL; - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); printk(KERN_INFO "SYSIO: UPA portID %x, at %016lx\n", portid, regs); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 0d4c09b15efc..e0dbed9503d4 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -152,7 +152,7 @@ static struct platform_device m48t59_rtc = { static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); if (!model) diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index c7bbe6cf7b85..9099ca095641 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -424,7 +424,7 @@ static int __devinit rtc_probe(struct of_device *op, const struct of_device_id * struct resource *r; printk(KERN_INFO "%s: RTC regs at 0x%llx\n", - op->node->full_name, op->resource[0].start); + op->dev.of_node->full_name, op->resource[0].start); /* The CMOS RTC driver only accepts IORESOURCE_IO, so cons * up a fake resource so that the probe works for all cases. @@ -480,7 +480,7 @@ static int __devinit bq4802_probe(struct of_device *op, const struct of_device_i { printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", - op->node->full_name, op->resource[0].start); + op->dev.of_node->full_name, op->resource[0].start); rtc_bq4802_device.resource = &op->resource[0]; return platform_device_register(&rtc_bq4802_device); @@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = { static int __devinit mostek_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; /* On an Enterprise system there can be multiple mostek clocks. * We should only match the one that is on the central FHC bus. diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 211b6438b3a0..c74f13bc9876 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1139,7 +1139,7 @@ static int __devinit pata_macio_attach(struct macio_dev *mdev, "Failed to allocate private memory\n"); return -ENOMEM; } - priv->node = of_node_get(mdev->ofdev.node); + priv->node = of_node_get(mdev->ofdev.dev.of_node); priv->mdev = mdev; priv->dev = &mdev->ofdev.dev; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 9f5b053611dd..4cce719add3f 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -694,7 +694,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) struct bcom_task *dmatsk = NULL; /* Get ipb frequency */ - ipb_freq = mpc5xxx_get_bus_frequency(op->node); + ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); if (!ipb_freq) { dev_err(&op->dev, "could not determine IPB bus frequency\n"); return -ENODEV; @@ -702,7 +702,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) /* Get device base address from device tree, request the region * and ioremap it. */ - rv = of_address_to_resource(op->node, 0, &res_mem); + rv = of_address_to_resource(op->dev.of_node, 0, &res_mem); if (rv) { dev_err(&op->dev, "could not determine device base address\n"); return rv; @@ -735,14 +735,14 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) * The MPC5200 ATA controller supports MWDMA modes 0, 1 and 2 and * UDMA modes 0, 1 and 2. */ - prop = of_get_property(op->node, "mwdma-mode", &proplen); + prop = of_get_property(op->dev.of_node, "mwdma-mode", &proplen); if ((prop) && (proplen >= 4)) mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1); - prop = of_get_property(op->node, "udma-mode", &proplen); + prop = of_get_property(op->dev.of_node, "udma-mode", &proplen); if ((prop) && (proplen >= 4)) udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1); - ata_irq = irq_of_parse_and_map(op->node, 0); + ata_irq = irq_of_parse_and_map(op->dev.of_node, 0); if (ata_irq == NO_IRQ) { dev_err(&op->dev, "error mapping irq\n"); return -EINVAL; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 1f18ad9e4fe1..19da29f011db 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -18,7 +18,7 @@ static int __devinit pata_of_platform_probe(struct of_device *ofdev, const struct of_device_id *match) { int ret; - struct device_node *dn = ofdev->node; + struct device_node *dn = ofdev->dev.of_node; struct resource io_res; struct resource ctl_res; struct resource irq_res; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index a69192b38b43..e3339e25b152 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1313,7 +1313,7 @@ static int sata_fsl_probe(struct of_device *ofdev, dev_printk(KERN_INFO, &ofdev->dev, "Sata FSL Platform/CSB Driver init\n"); - hcr_base = of_iomap(ofdev->node, 0); + hcr_base = of_iomap(ofdev->dev.of_node, 0); if (!hcr_base) goto error_exit_with_cleanup; @@ -1332,7 +1332,7 @@ static int sata_fsl_probe(struct of_device *ofdev, host_priv->ssr_base = ssr_base; host_priv->csr_base = csr_base; - irq = irq_of_parse_and_map(ofdev->node, 0); + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (irq < 0) { dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n"); goto error_exit_with_cleanup; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index f7d6ebaa0418..593a03a376e4 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -789,7 +789,7 @@ static int __init fore200e_sba_map(struct fore200e *fore200e) fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ /* get the supported DVMA burst sizes */ - bursts = of_getintprop_default(op->node->parent, "burst-sizes", 0x00); + bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00); if (sbus_can_dma_64bit()) sbus_set_sbus64(&op->dev, bursts); @@ -820,18 +820,20 @@ static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_ const u8 *prop; int len; - prop = of_get_property(op->node, "madaddrlo2", &len); + prop = of_get_property(op->dev.of_node, "madaddrlo2", &len); if (!prop) return -ENODEV; memcpy(&prom->mac_addr[4], prop, 4); - prop = of_get_property(op->node, "madaddrhi4", &len); + prop = of_get_property(op->dev.of_node, "madaddrhi4", &len); if (!prop) return -ENODEV; memcpy(&prom->mac_addr[2], prop, 4); - prom->serial_number = of_getintprop_default(op->node, "serialnumber", 0); - prom->hw_revision = of_getintprop_default(op->node, "promversion", 0); + prom->serial_number = of_getintprop_default(op->dev.of_node, + "serialnumber", 0); + prom->hw_revision = of_getintprop_default(op->dev.of_node, + "promversion", 0); return 0; } @@ -841,10 +843,10 @@ static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page) struct of_device *op = fore200e->bus_dev; const struct linux_prom_registers *regs; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", - (regs ? regs->which_io : 0), op->node->name); + (regs ? regs->which_io : 0), op->dev.of_node->name); } #endif /* CONFIG_SBUS */ diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 59ca2b77b574..52f2d11bc7b9 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -1004,7 +1004,7 @@ static const struct block_device_operations floppy_fops = { static int swim3_add_device(struct macio_dev *mdev, int index) { - struct device_node *swim = mdev->ofdev.node; + struct device_node *swim = mdev->ofdev.dev.of_node; struct floppy_state *fs = &floppy_states[index]; int rc = -EBUSY; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index e1c95e208a66..3094909b0613 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1198,10 +1198,10 @@ ace_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match); /* device id */ - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); /* physaddr */ - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; @@ -1209,11 +1209,11 @@ ace_of_probe(struct of_device *op, const struct of_device_id *match) physaddr = res.start; /* irq */ - irq = irq_of_parse_and_map(op->node, 0); + irq = irq_of_parse_and_map(op->dev.of_node, 0); /* bus width */ bus_width = ACE_BUS_WIDTH_16; - if (of_find_property(op->node, "8-bit", NULL)) + if (of_find_property(op->dev.of_node, "8-bit", NULL)) bus_width = ACE_BUS_WIDTH_8; /* Call the bus-independant setup code */ diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index cc435be0bc13..451cd7071b1d 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -567,7 +567,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct disk_info *d; struct cdrom_device_info *c; struct request_queue *q; - struct device_node *node = vdev->dev.archdata.of_node; + struct device_node *node = vdev->dev.of_node; deviceno = vdev->unit_address; if (deviceno >= VIOCD_MAX_CD) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 10f868eefaa6..0861d99cd75b 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -660,7 +660,7 @@ static int __devinit n2rng_probe(struct of_device *op, np->hvapi_major); goto out_hvapi_unregister; } - np->num_units = of_getintprop_default(op->node, + np->num_units = of_getintprop_default(op->dev.of_node, "rng-#units", 0); if (!np->num_units) { dev_err(&op->dev, "VF RNG lacks rng-#units property\n"); diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 7fa61dd1d9d9..b213855bae68 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -98,7 +98,7 @@ static int __devinit rng_probe(struct of_device *ofdev, const struct of_device_id *match) { void __iomem *rng_regs; - struct device_node *rng_np = ofdev->node; + struct device_node *rng_np = ofdev->dev.of_node; struct resource res; int err = 0; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 4462b113ba3f..2b44a0e1b988 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2469,7 +2469,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, struct smi_info *info; struct resource resource; const int *regsize, *regspacing, *regshift; - struct device_node *np = dev->node; + struct device_node *np = dev->dev.of_node; int ret; int proplen; @@ -2525,7 +2525,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; info->io.regshift = regshift ? *regshift : 0; - info->irq = irq_of_parse_and_map(dev->node, 0); + info->irq = irq_of_parse_and_map(dev->dev.of_node, 0); info->dev = &dev->dev; dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 1144a04cda6e..42f7fa442ff8 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -866,7 +866,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) { int i = vdev->unit_address; int j; - struct device_node *node = vdev->dev.archdata.of_node; + struct device_node *node = vdev->dev.of_node; if (i >= VIOTAPE_MAX_TAPE) return -ENODEV; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 7261b8d9087c..5a0a31e2029c 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -772,18 +772,18 @@ hwicap_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match); - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; } - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); /* It's most likely that we're using V4, if the family is not specified */ regs = &v4_config_registers; - family = of_get_property(op->node, "xlnx,family", NULL); + family = of_get_property(op->dev.of_node, "xlnx,family", NULL); if (family) { if (!strcmp(family, "virtex2p")) { diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc558a097311..5a02f3482dba 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1807,7 +1807,7 @@ static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct talitos_private *priv; const unsigned int *prop; int i, err; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 88f470f0d820..0e376eb37417 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1313,7 +1313,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, INIT_LIST_HEAD(&fdev->common.channels); /* ioremap the registers for use */ - fdev->regs = of_iomap(op->node, 0); + fdev->regs = of_iomap(op->dev.of_node, 0); if (!fdev->regs) { dev_err(&op->dev, "unable to ioremap registers\n"); err = -ENOMEM; @@ -1321,7 +1321,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, } /* map the channel IRQ if it exists, but don't hookup the handler yet */ - fdev->irq = irq_of_parse_and_map(op->node, 0); + fdev->irq = irq_of_parse_and_map(op->dev.of_node, 0); dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); @@ -1343,7 +1343,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, * of_platform_bus_remove(). Instead, we manually instantiate every DMA * channel object. */ - for_each_child_of_node(op->node, child) { + for_each_child_of_node(op->dev.of_node, child) { if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) { fsl_dma_chan_probe(fdev, child, FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 7d521e1d17e1..1db114b09990 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -437,7 +437,7 @@ pca953x_get_alt_pdata(struct i2c_client *client) struct device_node *node; const uint16_t *val; - node = dev_archdata_get_node(&client->dev.archdata); + node = client->dev.of_node; if (node == NULL) return NULL; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 9c2e10082b79..48d2c1a0d4ce 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -440,7 +440,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) init_waitqueue_head(&cpm->i2c_wait); - cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL); + cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (cpm->irq == NO_IRQ) return -EINVAL; @@ -451,13 +451,13 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) return ret; /* I2C parameter RAM */ - i2c_base = of_iomap(ofdev->node, 1); + i2c_base = of_iomap(ofdev->dev.of_node, 1); if (i2c_base == NULL) { ret = -EINVAL; goto out_irq; } - if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) { + if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm1-i2c")) { /* Check for and use a microcode relocation patch. */ cpm->i2c_ram = i2c_base; @@ -474,7 +474,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) cpm->version = 1; - } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) { + } else if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm2-i2c")) { cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64); cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); out_be16(i2c_base, cpm->i2c_addr); @@ -489,24 +489,24 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) } /* I2C control/status registers */ - cpm->i2c_reg = of_iomap(ofdev->node, 0); + cpm->i2c_reg = of_iomap(ofdev->dev.of_node, 0); if (cpm->i2c_reg == NULL) { ret = -EINVAL; goto out_ram; } - data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) { ret = -EINVAL; goto out_reg; } cpm->cp_command = *data; - data = of_get_property(ofdev->node, "linux,i2c-class", &len); + data = of_get_property(ofdev->dev.of_node, "linux,i2c-class", &len); if (data && len == 4) cpm->adap.class = *data; - data = of_get_property(ofdev->node, "clock-frequency", &len); + data = of_get_property(ofdev->dev.of_node, "clock-frequency", &len); if (data && len == 4) cpm->freq = *data; else @@ -661,7 +661,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* register new adapter to i2c module... */ - data = of_get_property(ofdev->node, "linux,i2c-index", &len); + data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len); if (data && len == 4) { cpm->adap.nr = *data; result = i2c_add_numbered_adapter(&cpm->adap); @@ -679,7 +679,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* * register OF I2C devices */ - of_register_i2c_devices(&cpm->adap, ofdev->node); + of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); return 0; out_shut: diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index b1bc6e277d2a..e66dc83953c5 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -664,7 +664,7 @@ static inline u8 iic_clckdiv(unsigned int opb) static int __devinit iic_request_irq(struct of_device *ofdev, struct ibm_iic_private *dev) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; int irq; if (iic_force_poll) @@ -695,7 +695,7 @@ static int __devinit iic_request_irq(struct of_device *ofdev, static int __devinit iic_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct ibm_iic_private *dev; struct i2c_adapter *adap; const u32 *freq; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f1321f763789..69473b6c260c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -560,14 +560,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op, init_waitqueue_head(&i2c->queue); - i2c->base = of_iomap(op->node, 0); + i2c->base = of_iomap(op->dev.of_node, 0); if (!i2c->base) { dev_err(i2c->dev, "failed to map controller\n"); result = -ENOMEM; goto fail_map; } - i2c->irq = irq_of_parse_and_map(op->node, 0); + i2c->irq = irq_of_parse_and_map(op->dev.of_node, 0); if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ result = request_irq(i2c->irq, mpc_i2c_isr, IRQF_SHARED, "i2c-mpc", i2c); @@ -577,21 +577,22 @@ static int __devinit fsl_i2c_probe(struct of_device *op, } } - if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) { + if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) { clock = MPC_I2C_CLOCK_PRESERVE; } else { - prop = of_get_property(op->node, "clock-frequency", &plen); + prop = of_get_property(op->dev.of_node, "clock-frequency", + &plen); if (prop && plen == sizeof(u32)) clock = *prop; } if (match->data) { struct mpc_i2c_data *data = match->data; - data->setup(op->node, i2c, clock, data->prescaler); + data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ - if (of_get_property(op->node, "dfsrr", NULL)) - mpc_i2c_setup_8xxx(op->node, i2c, clock, 0); + if (of_get_property(op->dev.of_node, "dfsrr", NULL)) + mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); } dev_set_drvdata(&op->dev, i2c); @@ -605,7 +606,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } - of_register_i2c_devices(&i2c->adap, op->node); + of_register_i2c_devices(&i2c->adap, op->dev.of_node); return result; diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 159955d16c47..183fa38760d8 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1153,7 +1153,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) if (macio_resource_count(mdev) == 0) { printk(KERN_WARNING "ide-pmac: no address for %s\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); rc = -ENXIO; goto out_free_pmif; } @@ -1161,7 +1161,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) /* Request memory resource for IO ports */ if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { printk(KERN_ERR "ide-pmac: can't request MMIO resource for " - "%s!\n", mdev->ofdev.node->full_name); + "%s!\n", mdev->ofdev.dev.of_node->full_name); rc = -EBUSY; goto out_free_pmif; } @@ -1173,7 +1173,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) */ if (macio_irq_count(mdev) == 0) { printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " - "13\n", mdev->ofdev.node->full_name); + "13\n", mdev->ofdev.dev.of_node->full_name); irq = irq_create_mapping(NULL, 13); } else irq = macio_irq(mdev, 0); @@ -1182,7 +1182,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) regbase = (unsigned long) base; pmif->mdev = mdev; - pmif->node = mdev->ofdev.node; + pmif->node = mdev->ofdev.dev.of_node; pmif->regbase = regbase; pmif->irq = irq; pmif->kauai_fcr = NULL; @@ -1191,7 +1191,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) printk(KERN_WARNING "ide-pmac: can't request DMA " "resource for %s!\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); else pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); } else diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 129a6bebd6e3..26391853277f 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -291,8 +291,9 @@ static int ehca_sense_attributes(struct ehca_shca *shca) }; ehca_gen_dbg("Probing adapter %s...", - shca->ofdev->node->full_name); - loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL); + shca->ofdev->dev.of_node->full_name); + loc_code = of_get_property(shca->ofdev->dev.of_node, "ibm,loc-code", + NULL); if (loc_code) ehca_gen_dbg(" ... location lode=%s", loc_code); @@ -720,16 +721,16 @@ static int __devinit ehca_probe(struct of_device *dev, int ret, i, eq_size; unsigned long flags; - handle = of_get_property(dev->node, "ibm,hca-handle", NULL); + handle = of_get_property(dev->dev.of_node, "ibm,hca-handle", NULL); if (!handle) { ehca_gen_err("Cannot get eHCA handle for adapter: %s.", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENODEV; } if (!(*handle)) { ehca_gen_err("Wrong eHCA handle for adapter: %s.", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENODEV; } diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 5071af2c0604..29e17698b2a4 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -51,7 +51,7 @@ static inline void i8042_write_command(int val) static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; dp = dp->child; while (dp) { diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index f84f8e32e3f1..7a288c0ef1a6 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -244,17 +244,17 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, int error; dev_info(dev, "Device Tree Probing \'%s\'\n", - ofdev->node->name); + ofdev->dev.of_node->name); /* Get iospace for the device */ - error = of_address_to_resource(ofdev->node, 0, &r_mem); + error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (error) { dev_err(dev, "invalid address\n"); return error; } /* Get IRQ for the device */ - if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) { + if (of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq) == NO_IRQ) { dev_err(dev, "no IRQ found\n"); return -ENODEV; } @@ -342,7 +342,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) iounmap(drvdata->base_address); /* Get iospace of the device */ - if (of_address_to_resource(of_dev->node, 0, &r_mem)) + if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) dev_err(dev, "invalid address\n"); else release_mem_region(r_mem.start, resource_size(&r_mem)); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index c6e4b772b757..a77a23e783db 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -211,7 +211,7 @@ struct gpio_led_of_platform_data { static int __devinit of_gpio_leds_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node, *child; + struct device_node *np = ofdev->dev.of_node, *child; struct gpio_led_of_platform_data *pdata; int count = 0, ret; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 26a303a1d1ab..67fe13ffe90b 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -248,7 +248,7 @@ static void macio_create_fixup_irq(struct macio_dev *dev, int index, static void macio_add_missing_resources(struct macio_dev *dev) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; unsigned int irq_base; /* Gatwick has some missing interrupts on child nodes */ @@ -289,7 +289,7 @@ static void macio_add_missing_resources(struct macio_dev *dev) static void macio_setup_interrupts(struct macio_dev *dev) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; unsigned int irq; int i = 0, j = 0; @@ -317,7 +317,7 @@ static void macio_setup_interrupts(struct macio_dev *dev) static void macio_setup_resources(struct macio_dev *dev, struct resource *parent_res) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; struct resource r; int index; @@ -373,7 +373,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->bus = &chip->lbus; dev->media_bay = in_bay; - dev->ofdev.node = np; + dev->ofdev.dev.of_node = np; dev->ofdev.dma_mask = 0xffffffffUL; dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; dev->ofdev.dev.parent = parent; @@ -494,9 +494,9 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add media bay devices if any */ + pnode = mbdev->ofdev.dev.of_node; if (mbdev) - for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) - != NULL;) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; of_node_get(np); @@ -506,9 +506,9 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add serial ports if any */ + pnode = sdev->ofdev.dev.of_node; if (sdev) { - for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) - != NULL;) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; of_node_get(np); diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 9e9453b58425..6999ce59fd10 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct macio_dev *mdev = to_macio_device (dev); \ - return sprintf (buf, format_string, mdev->ofdev.node->field); \ + return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \ } static ssize_t @@ -21,7 +21,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) int length = 0; of = &to_macio_device (dev)->ofdev; - compat = of_get_property(of->node, "compatible", &cplen); + compat = of_get_property(of->dev.of_node, "compatible", &cplen); if (!compat) { *buf = '\0'; return 0; @@ -58,7 +58,7 @@ static ssize_t devspec_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } macio_config_of_attr (name, "%s\n"); diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 08002b88f342..288acce76b74 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -564,7 +564,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de unsigned long base; int i; - ofnode = mdev->ofdev.node; + ofnode = mdev->ofdev.dev.of_node; if (macio_resource_count(mdev) < 1) return -ENODEV; diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 7c54d80c4fb2..12946c5f583f 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -375,7 +375,7 @@ static int __devinit rackmeter_probe(struct macio_dev* mdev, pr_debug("rackmeter_probe()\n"); /* Get i2s-a node */ - while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL) + while ((i2s = of_get_next_child(mdev->ofdev.dev.of_node, i2s)) != NULL) if (strcmp(i2s->name, "i2s-a") == 0) break; if (i2s == NULL) { @@ -431,7 +431,7 @@ static int __devinit rackmeter_probe(struct macio_dev* mdev, of_address_to_resource(i2s, 1, &rdma)) { printk(KERN_ERR "rackmeter: found match but lacks resources: %s", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); rc = -ENXIO; goto bail_free; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index b18fa948f3d1..9314be9a2fc8 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2215,7 +2215,7 @@ static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match) state = state_detached; /* Lookup the fans in the device tree */ - fcu_lookup_fans(dev->node); + fcu_lookup_fans(dev->dev.of_node); /* Add the driver */ return i2c_add_driver(&therm_pm72_driver); diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index bb6cc54b558e..1247e5de9faa 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -64,7 +64,7 @@ static int of_mmc_spi_get_ro(struct device *dev) struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) { struct device *dev = &spi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct of_mmc_spi *oms; const u32 *voltage_ranges; int num_ranges; @@ -135,7 +135,7 @@ EXPORT_SYMBOL(mmc_spi_get_pdata); void mmc_spi_put_pdata(struct spi_device *spi) { struct device *dev = &spi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct of_mmc_spi *oms = to_of_mmc_spi(dev); int i; diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index 55e33135edb4..dfe5ceae6794 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -118,7 +118,7 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) static int __devinit sdhci_of_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct sdhci_of_data *sdhci_of_data = match->data; struct sdhci_host *host; struct sdhci_of_host *of_host; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 101ee6ead05c..3dc7a2fbf025 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -143,7 +143,7 @@ static int of_flash_remove(struct of_device *dev) static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, struct map_info *map) { - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; const char *of_probe; struct mtd_info *mtd; static const char *rom_probe_types[] @@ -180,7 +180,7 @@ static int __devinit of_flash_probe(struct of_device *dev, static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; #endif - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; const char *probe_type = match->data; @@ -204,7 +204,7 @@ static int __devinit of_flash_probe(struct of_device *dev, p = of_get_property(dp, "reg", &count); if (count % reg_tuple_size != 0) { dev_err(&dev->dev, "Malformed reg property on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -EINVAL; goto err_flash_remove; } diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index fadc4c45b455..5945a23e681f 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -110,7 +110,7 @@ int uflash_devinit(struct of_device *op, struct device_node *dp) static int __devinit uflash_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; /* Flashprom must have the "user" property in order to * be used by this driver. diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ae30fb6eed97..4a6079588ab2 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -1030,14 +1030,14 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev, init_waitqueue_head(&ctrl->controller.wq); init_waitqueue_head(&ctrl->irq_wait); - ctrl->regs = of_iomap(ofdev->node, 0); + ctrl->regs = of_iomap(ofdev->dev.of_node, 0); if (!ctrl->regs) { dev_err(&ofdev->dev, "failed to get memory region\n"); ret = -ENODEV; goto err; } - ctrl->irq = of_irq_to_resource(ofdev->node, 0, NULL); + ctrl->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (ctrl->irq == NO_IRQ) { dev_err(&ofdev->dev, "failed to get irq resource\n"); ret = -ENODEV; @@ -1058,7 +1058,7 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev, goto err; } - for_each_child_of_node(ofdev->node, child) + for_each_child_of_node(ofdev->dev.of_node, child) if (of_device_is_compatible(child, "fsl,elbc-fcm-nand")) fsl_elbc_chip_probe(ctrl, child); diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index b983cae8c298..c0e05f5ff8a4 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -239,14 +239,14 @@ static int __devinit ndfc_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, ndfc); /* Read the reg property to get the chip select */ - reg = of_get_property(ofdev->node, "reg", &len); + reg = of_get_property(ofdev->dev.of_node, "reg", &len); if (reg == NULL || len != 12) { dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); return -ENOENT; } ndfc->chip_select = reg[0]; - ndfc->ndfcbase = of_iomap(ofdev->node, 0); + ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); if (!ndfc->ndfcbase) { dev_err(&ofdev->dev, "failed to get memory\n"); return -EIO; @@ -255,20 +255,20 @@ static int __devinit ndfc_probe(struct of_device *ofdev, ccr = NDFC_CCR_BS(ndfc->chip_select); /* It is ok if ccr does not exist - just default to 0 */ - reg = of_get_property(ofdev->node, "ccr", NULL); + reg = of_get_property(ofdev->dev.of_node, "ccr", NULL); if (reg) ccr |= *reg; out_be32(ndfc->ndfcbase + NDFC_CCR, ccr); /* Set the bank settings if given */ - reg = of_get_property(ofdev->node, "bank-settings", NULL); + reg = of_get_property(ofdev->dev.of_node, "bank-settings", NULL); if (reg) { int offset = NDFC_BCFG0 + (ndfc->chip_select << 2); out_be32(ndfc->ndfcbase + offset, *reg); } - err = ndfc_chip_init(ndfc, ofdev->node); + err = ndfc_chip_init(ndfc, ofdev->dev.of_node); if (err) { iounmap(ndfc->ndfcbase); return err; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index a8b9376cf324..edfc27b78513 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -93,7 +93,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev, const struct of_device_id *match) { struct pci_dev *pdev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct nand_chip *chip; int err = 0; diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 9dd076a626a5..dc5f20cdf93c 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -72,7 +72,7 @@ static int __devexit sja1000_ofp_remove(struct of_device *ofdev) { struct net_device *dev = dev_get_drvdata(&ofdev->dev); struct sja1000_priv *priv = netdev_priv(dev); - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; dev_set_drvdata(&ofdev->dev, NULL); @@ -91,7 +91,7 @@ static int __devexit sja1000_ofp_remove(struct of_device *ofdev) static int __devinit sja1000_ofp_probe(struct of_device *ofdev, const struct of_device_id *id) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev; struct sja1000_priv *priv; struct resource res; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 809ccc9ff09c..59dac232006c 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3035,7 +3035,7 @@ static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, static void __devinit logical_port_release(struct device *dev) { struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); - of_node_put(port->ofdev.node); + of_node_put(port->ofdev.dev.of_node); } static struct device *ehea_register_port(struct ehea_port *port, @@ -3043,7 +3043,7 @@ static struct device *ehea_register_port(struct ehea_port *port, { int ret; - port->ofdev.node = of_node_get(dn); + port->ofdev.dev.of_node = of_node_get(dn); port->ofdev.dev.parent = &port->adapter->ofdev->dev; port->ofdev.dev.bus = &ibmebus_bus_type; @@ -3210,7 +3210,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) const u32 *dn_log_port_id; int i = 0; - lhea_dn = adapter->ofdev->node; + lhea_dn = adapter->ofdev->dev.of_node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3249,7 +3249,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, struct device_node *eth_dn = NULL; const u32 *dn_log_port_id; - lhea_dn = adapter->ofdev->node; + lhea_dn = adapter->ofdev->dev.of_node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3379,7 +3379,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, const u64 *adapter_handle; int ret; - if (!dev || !dev->node) { + if (!dev || !dev->dev.of_node) { ehea_error("Invalid ibmebus device probed"); return -EINVAL; } @@ -3395,14 +3395,14 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, adapter->ofdev = dev; - adapter_handle = of_get_property(dev->node, "ibm,hea-handle", + adapter_handle = of_get_property(dev->dev.of_node, "ibm,hea-handle", NULL); if (adapter_handle) adapter->handle = *adapter_handle; if (!adapter->handle) { dev_err(&dev->dev, "failed getting handle for adapter" - " '%s'\n", dev->node->full_name); + " '%s'\n", dev->dev.of_node->full_name); ret = -ENODEV; goto out_free_ad; } diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 4a43e56b7394..3342056f8aac 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -873,7 +873,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) priv->ndev = ndev; /* Reserve FEC control zone */ - rv = of_address_to_resource(op->node, 0, &mem); + rv = of_address_to_resource(op->dev.of_node, 0, &mem); if (rv) { printk(KERN_ERR DRIVER_NAME ": " "Error while parsing device node resource\n" ); @@ -921,7 +921,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Get the IRQ we need one by one */ /* Control */ - ndev->irq = irq_of_parse_and_map(op->node, 0); + ndev->irq = irq_of_parse_and_map(op->dev.of_node, 0); /* RX */ priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk); @@ -944,20 +944,20 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Start with safe defaults for link connection */ priv->speed = 100; priv->duplex = DUPLEX_HALF; - priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->node) >> 20) / 5) << 1; + priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->dev.of_node) >> 20) / 5) << 1; /* The current speed preconfigures the speed of the MII link */ - prop = of_get_property(op->node, "current-speed", &prop_size); + prop = of_get_property(op->dev.of_node, "current-speed", &prop_size); if (prop && (prop_size >= sizeof(u32) * 2)) { priv->speed = prop[0]; priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; } /* If there is a phy handle, then get the PHY node */ - priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + priv->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); /* the 7-wire property means don't use MII mode */ - if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) { + if (of_find_property(op->dev.of_node, "fsl,7-wire-mode", NULL)) { priv->seven_wire_mode = 1; dev_info(&ndev->dev, "using 7-wire PHY mode\n"); } diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 7658a082e390..0d099e5a652d 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -66,7 +66,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match) { struct device *dev = &of->dev; - struct device_node *np = of->node; + struct device_node *np = of->dev.of_node; struct mii_bus *bus; struct mpc52xx_fec_mdio_priv *priv; struct resource res = {}; @@ -107,7 +107,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, /* set MII speed */ out_be32(&priv->regs->mii_speed, - ((mpc5xxx_get_bus_frequency(of->node) >> 20) / 5) << 1); + ((mpc5xxx_get_bus_frequency(of->dev.of_node) >> 20) / 5) << 1); err = of_mdiobus_register(bus, np); if (err) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 0770e2f6da6b..caeb88b67bc6 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1015,7 +1015,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, return -ENOMEM; if (!IS_FEC(match)) { - data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1027,8 +1027,8 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; - fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); - if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link", + fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); + if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) goto out_free_fpi; @@ -1061,7 +1061,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); - mac_addr = of_get_mac_address(ofdev->node); + mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, 6); diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 0a973e71876b..9d4f272137d6 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -88,19 +88,19 @@ static int do_pd_setup(struct fs_enet_private *fep) struct fs_platform_info *fpi = fep->fpi; int ret = -EINVAL; - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) goto out; - fep->fcc.fccp = of_iomap(ofdev->node, 0); + fep->fcc.fccp = of_iomap(ofdev->dev.of_node, 0); if (!fep->fcc.fccp) goto out; - fep->fcc.ep = of_iomap(ofdev->node, 1); + fep->fcc.ep = of_iomap(ofdev->dev.of_node, 1); if (!fep->fcc.ep) goto out_fccp; - fep->fcc.fcccp = of_iomap(ofdev->node, 2); + fep->fcc.fcccp = of_iomap(ofdev->dev.of_node, 2); if (!fep->fcc.fcccp) goto out_ep; diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index ec81f50d5919..bd7a6e7064bb 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -98,11 +98,11 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) return -EINVAL; - fep->fec.fecp = of_iomap(ofdev->node, 0); + fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0); if (!fep->fcc.fccp) return -EINVAL; diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 34d3da751eb4..49a4d8c60168 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -98,15 +98,15 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) return -EINVAL; - fep->scc.sccp = of_iomap(ofdev->node, 0); + fep->scc.sccp = of_iomap(ofdev->dev.of_node, 0); if (!fep->scc.sccp) return -EINVAL; - fep->scc.ep = of_iomap(ofdev->node, 1); + fep->scc.ep = of_iomap(ofdev->dev.of_node, 1); if (!fep->scc.ep) { iounmap(fep->scc.sccp); return -EINVAL; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 5944b65082cb..dc862e779c1f 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -124,7 +124,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->write = &fs_enet_fec_mii_write; new_bus->reset = &fs_enet_fec_mii_reset; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) goto out_res; @@ -135,7 +135,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, goto out_fec; if (get_bus_freq) { - clock = get_bus_freq(ofdev->node); + clock = get_bus_freq(ofdev->dev.of_node); if (!clock) { /* Use maximum divider if clock is unknown */ dev_warn(&ofdev->dev, "could not determine IPS clock\n"); @@ -172,7 +172,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) goto out_free_irqs; diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index d5160edf2fcf..72489a213bf7 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -271,7 +271,7 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) static int fsl_pq_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *tbi; struct fsl_pq_mdio_priv *priv; struct fsl_pq_mdio __iomem *regs = NULL; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 080d1cea5b26..b71bba91064c 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -603,7 +603,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) int err = 0, i; struct net_device *dev = NULL; struct gfar_private *priv = NULL; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *child = NULL; const u32 *stash; const u32 *stash_len; @@ -641,7 +641,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) return -ENOMEM; priv = netdev_priv(dev); - priv->node = ofdev->node; + priv->node = ofdev->dev.of_node; priv->ndev = dev; dev->num_tx_queues = num_tx_qs; @@ -888,7 +888,7 @@ static int gfar_probe(struct of_device *ofdev, priv = netdev_priv(dev); priv->ndev = dev; priv->ofdev = ofdev; - priv->node = ofdev->node; + priv->node = ofdev->dev.of_node; SET_NETDEV_DEV(dev, &ofdev->dev); spin_lock_init(&priv->bflock); diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 3a90430de918..61fd54d35f63 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1500,7 +1500,8 @@ static int __devinit greth_of_probe(struct of_device *ofdev, const struct of_dev if (i == 6) { const unsigned char *addr; int len; - addr = of_get_property(ofdev->node, "local-mac-address", &len); + addr = of_get_property(ofdev->dev.of_node, "local-mac-address", + &len); if (addr != NULL && len == 6) { for (i = 0; i < 6; i++) macaddr[i] = (unsigned int) addr[i]; diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index dd873cc41c2b..cda2ba891344 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -136,7 +136,8 @@ static inline void emac_report_timeout_error(struct emac_instance *dev, EMAC_FTR_440EP_PHY_CLK_FIX)) DBG(dev, "%s" NL, error); else if (net_ratelimit()) - printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error); + printk(KERN_ERR "%s: %s\n", dev->ofdev->dev.of_node->full_name, + error); } /* EMAC PHY clock workaround: @@ -2185,7 +2186,7 @@ static void emac_ethtool_get_drvinfo(struct net_device *ndev, strcpy(info->version, DRV_VERSION); info->fw_version[0] = '\0'; sprintf(info->bus_info, "PPC 4xx EMAC-%d %s", - dev->cell_index, dev->ofdev->node->full_name); + dev->cell_index, dev->ofdev->dev.of_node->full_name); info->regdump_len = emac_ethtool_get_regs_len(ndev); } @@ -2379,7 +2380,7 @@ static int __devinit emac_read_uint_prop(struct device_node *np, const char *nam static int __devinit emac_init_phy(struct emac_instance *dev) { - struct device_node *np = dev->ofdev->node; + struct device_node *np = dev->ofdev->dev.of_node; struct net_device *ndev = dev->ndev; u32 phy_map, adv; int i; @@ -2514,7 +2515,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) static int __devinit emac_init_config(struct emac_instance *dev) { - struct device_node *np = dev->ofdev->node; + struct device_node *np = dev->ofdev->dev.of_node; const void *p; unsigned int plen; const char *pm, *phy_modes[] = { @@ -2723,7 +2724,7 @@ static int __devinit emac_probe(struct of_device *ofdev, { struct net_device *ndev; struct emac_instance *dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node **blist = NULL; int err, i; @@ -2810,7 +2811,7 @@ static int __devinit emac_probe(struct of_device *ofdev, err = mal_register_commac(dev->mal, &dev->commac); if (err) { printk(KERN_ERR "%s: failed to register with mal %s!\n", - np->full_name, dev->mal_dev->node->full_name); + np->full_name, dev->mal_dev->dev.of_node->full_name); goto err_rel_deps; } dev->rx_skb_size = emac_rx_skb_size(ndev->mtu); diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 775c850a425a..3995fafc1e08 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c @@ -33,7 +33,7 @@ static void emac_desc_dump(struct emac_instance *p) int i; printk("** EMAC %s TX BDs **\n" " tx_cnt = %d tx_slot = %d ack_slot = %d\n", - p->ofdev->node->full_name, + p->ofdev->dev.of_node->full_name, p->tx_cnt, p->tx_slot, p->ack_slot); for (i = 0; i < NUM_TX_BUFF / 2; ++i) printk @@ -49,7 +49,7 @@ static void emac_desc_dump(struct emac_instance *p) printk("** EMAC %s RX BDs **\n" " rx_slot = %d flags = 0x%lx rx_skb_size = %d rx_sync_size = %d\n" " rx_sg_skb = 0x%p\n", - p->ofdev->node->full_name, + p->ofdev->dev.of_node->full_name, p->rx_slot, p->commac.flags, p->rx_skb_size, p->rx_sync_size, p->rx_sg_skb); for (i = 0; i < NUM_RX_BUFF / 2; ++i) @@ -77,7 +77,8 @@ static void emac_mac_dump(struct emac_instance *dev) "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n", - dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), + dev->ofdev->dev.of_node->full_name, + in_be32(&p->mr0), in_be32(&p->mr1), in_be32(&p->tmr0), in_be32(&p->tmr1), in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), @@ -128,7 +129,7 @@ static void emac_mal_dump(struct mal_instance *mal) "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n" "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n" "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n", - mal->ofdev->node->full_name, + mal->ofdev->dev.of_node->full_name, get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR), get_mal_dcrn(mal, MAL_IER), get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR), diff --git a/drivers/net/ibm_newemac/debug.h b/drivers/net/ibm_newemac/debug.h index b631842ec8d0..e596c77ccdf7 100644 --- a/drivers/net/ibm_newemac/debug.h +++ b/drivers/net/ibm_newemac/debug.h @@ -53,8 +53,8 @@ extern void emac_dbg_dump_all(void); #endif -#define EMAC_DBG(dev, name, fmt, arg...) \ - printk(KERN_DEBUG #name "%s: " fmt, dev->ofdev->node->full_name, ## arg) +#define EMAC_DBG(d, name, fmt, arg...) \ + printk(KERN_DEBUG #name "%s: " fmt, d->ofdev->dev.of_node->full_name, ## arg) #if DBG_LEVEL > 0 # define DBG(d,f,x...) EMAC_DBG(d, emac, f, ##x) diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index 5b3d94419fe6..aba17947e208 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -538,11 +538,11 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->index = index; mal->ofdev = ofdev; - mal->version = of_device_is_compatible(ofdev->node, "ibm,mcmal2") ? 2 : 1; + mal->version = of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal2") ? 2 : 1; MAL_DBG(mal, "probe" NL); - prop = of_get_property(ofdev->node, "num-tx-chans", NULL); + prop = of_get_property(ofdev->dev.of_node, "num-tx-chans", NULL); if (prop == NULL) { printk(KERN_ERR "mal%d: can't find MAL num-tx-chans property!\n", @@ -552,7 +552,7 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->num_tx_chans = prop[0]; - prop = of_get_property(ofdev->node, "num-rx-chans", NULL); + prop = of_get_property(ofdev->dev.of_node, "num-rx-chans", NULL); if (prop == NULL) { printk(KERN_ERR "mal%d: can't find MAL num-rx-chans property!\n", @@ -562,14 +562,14 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->num_rx_chans = prop[0]; - dcr_base = dcr_resource_start(ofdev->node, 0); + dcr_base = dcr_resource_start(ofdev->dev.of_node, 0); if (dcr_base == 0) { printk(KERN_ERR "mal%d: can't find DCR resource!\n", index); err = -ENODEV; goto fail; } - mal->dcr_host = dcr_map(ofdev->node, dcr_base, 0x100); + mal->dcr_host = dcr_map(ofdev->dev.of_node, dcr_base, 0x100); if (!DCR_MAP_OK(mal->dcr_host)) { printk(KERN_ERR "mal%d: failed to map DCRs !\n", index); @@ -577,28 +577,28 @@ static int __devinit mal_probe(struct of_device *ofdev, goto fail; } - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) { + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-405ez")) { #if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \ defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR) mal->features |= (MAL_FTR_CLEAR_ICINTSTAT | MAL_FTR_COMMON_ERR_INT); #else printk(KERN_ERR "%s: Support for 405EZ not enabled!\n", - ofdev->node->full_name); + ofdev->dev.of_node->full_name); err = -ENODEV; goto fail; #endif } - mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0); - mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1); - mal->serr_irq = irq_of_parse_and_map(ofdev->node, 2); + mal->txeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + mal->rxeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 1); + mal->serr_irq = irq_of_parse_and_map(ofdev->dev.of_node, 2); if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) { mal->txde_irq = mal->rxde_irq = mal->serr_irq; } else { - mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3); - mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4); + mal->txde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 3); + mal->rxde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 4); } if (mal->txeob_irq == NO_IRQ || mal->rxeob_irq == NO_IRQ || @@ -629,7 +629,7 @@ static int __devinit mal_probe(struct of_device *ofdev, /* Current Axon is not happy with priority being non-0, it can * deadlock, fix it up here */ - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-axon")) + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-axon")) cfg &= ~(MAL2_CFG_RPP_10 | MAL2_CFG_WPP_10); /* Apply configuration */ @@ -701,7 +701,7 @@ static int __devinit mal_probe(struct of_device *ofdev, printk(KERN_INFO "MAL v%d %s, %d TX channels, %d RX channels\n", - mal->version, ofdev->node->full_name, + mal->version, ofdev->dev.of_node->full_name, mal->num_tx_chans, mal->num_rx_chans); /* Advertise this instance to the rest of the world */ diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 5b90d34c8455..6ab630a79e31 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -103,7 +103,7 @@ int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) /* Check if we need to attach to a RGMII */ if (input < 0 || !rgmii_valid_mode(mode)) { printk(KERN_ERR "%s: unsupported settings !\n", - ofdev->node->full_name); + ofdev->dev.of_node->full_name); return -ENODEV; } @@ -113,7 +113,7 @@ int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); printk(KERN_NOTICE "%s: input %d in %s mode\n", - ofdev->node->full_name, input, rgmii_mode_name(mode)); + ofdev->dev.of_node->full_name, input, rgmii_mode_name(mode)); ++dev->users; @@ -231,7 +231,7 @@ void *rgmii_dump_regs(struct of_device *ofdev, void *buf) static int __devinit rgmii_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct rgmii_instance *dev; struct resource regs; int rc; @@ -264,11 +264,11 @@ static int __devinit rgmii_probe(struct of_device *ofdev, } /* Check for RGMII flags */ - if (of_get_property(ofdev->node, "has-mdio", NULL)) + if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL)) dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; /* CAB lacks the right properties, fix this up */ - if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon")) + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,rgmii-axon")) dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n", @@ -279,7 +279,7 @@ static int __devinit rgmii_probe(struct of_device *ofdev, printk(KERN_INFO "RGMII %s initialized with%s MDIO support\n", - ofdev->node->full_name, + ofdev->dev.of_node->full_name, (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out"); wmb(); diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 30173a9fb557..4f64b00dd5e8 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -57,7 +57,8 @@ void tah_reset(struct of_device *ofdev) --n; if (unlikely(!n)) - printk(KERN_ERR "%s: reset timeout\n", ofdev->node->full_name); + printk(KERN_ERR "%s: reset timeout\n", + ofdev->dev.of_node->full_name); /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */ out_be32(&p->mr, @@ -89,7 +90,7 @@ void *tah_dump_regs(struct of_device *ofdev, void *buf) static int __devinit tah_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct tah_instance *dev; struct resource regs; int rc; @@ -127,7 +128,7 @@ static int __devinit tah_probe(struct of_device *ofdev, tah_reset(ofdev); printk(KERN_INFO - "TAH %s initialized\n", ofdev->node->full_name); + "TAH %s initialized\n", ofdev->dev.of_node->full_name); wmb(); return 0; diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index 1f038f808ab3..b4fa823ed201 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -121,13 +121,14 @@ int __devinit zmii_attach(struct of_device *ofdev, int input, int *mode) dev->mode = *mode; printk(KERN_NOTICE "%s: bridge in %s mode\n", - ofdev->node->full_name, zmii_mode_name(dev->mode)); + ofdev->dev.of_node->full_name, + zmii_mode_name(dev->mode)); } else { /* All inputs must use the same mode */ if (*mode != PHY_MODE_NA && *mode != dev->mode) { printk(KERN_ERR "%s: invalid mode %d specified for input %d\n", - ofdev->node->full_name, *mode, input); + ofdev->dev.of_node->full_name, *mode, input); mutex_unlock(&dev->lock); return -EINVAL; } @@ -233,7 +234,7 @@ void *zmii_dump_regs(struct of_device *ofdev, void *buf) static int __devinit zmii_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct zmii_instance *dev; struct resource regs; int rc; @@ -273,7 +274,7 @@ static int __devinit zmii_probe(struct of_device *ofdev, out_be32(&dev->base->fer, 0); printk(KERN_INFO - "ZMII %s initialized\n", ofdev->node->full_name); + "ZMII %s initialized\n", ofdev->dev.of_node->full_name); wmb(); dev_set_drvdata(&ofdev->dev, dev); diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index ba617e3cf1bb..9c7395c10e44 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -858,14 +858,14 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) mutex_init(&lp->indirect_mutex); /* map device registers */ - lp->regs = of_iomap(op->node, 0); + lp->regs = of_iomap(op->dev.of_node, 0); if (!lp->regs) { dev_err(&op->dev, "could not map temac regs.\n"); goto nodev; } /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ - np = of_parse_phandle(op->node, "llink-connected", 0); + np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); if (!np) { dev_err(&op->dev, "could not find DMA node\n"); goto nodev; @@ -890,7 +890,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) of_node_put(np); /* Finished with the DMA node; drop the reference */ /* Retrieve the MAC address */ - addr = of_get_property(op->node, "local-mac-address", &size); + addr = of_get_property(op->dev.of_node, "local-mac-address", &size); if ((!addr) || (size != 6)) { dev_err(&op->dev, "could not find MAC address\n"); rc = -ENODEV; @@ -898,11 +898,11 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) } temac_set_mac_address(ndev, (void *)addr); - rc = temac_mdio_setup(lp, op->node); + rc = temac_mdio_setup(lp, op->dev.of_node); if (rc) dev_warn(&op->dev, "error registering MDIO bus\n"); - lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); if (lp->phy_node) dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index b72e749afdf1..e21439f1e775 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -928,7 +928,7 @@ static const struct net_device_ops myri_ops = { static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; static unsigned version_printed; struct net_device *dev; struct myri_eth *mp; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index d5cd16bfc907..9c1604c04450 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9094,7 +9094,7 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map) const u32 *int_prop; int i; - int_prop = of_get_property(op->node, "interrupts", NULL); + int_prop = of_get_property(op->dev.of_node, "interrupts", NULL); if (!int_prop) return -ENODEV; @@ -9245,7 +9245,7 @@ static int __devinit niu_get_of_props(struct niu *np) int prop_len; if (np->parent->plat_type == PLAT_TYPE_NIU) - dp = np->op->node; + dp = np->op->dev.of_node; else dp = pci_device_to_OF_node(np->pdev); @@ -10056,10 +10056,10 @@ static int __devinit niu_of_probe(struct of_device *op, niu_driver_version(); - reg = of_get_property(op->node, "reg", NULL); + reg = of_get_property(op->dev.of_node, "reg", NULL); if (!reg) { dev_err(&op->dev, "%s: No 'reg' property, aborting\n", - op->node->full_name); + op->dev.of_node->full_name); return -ENODEV; } @@ -10072,7 +10072,7 @@ static int __devinit niu_of_probe(struct of_device *op, np = netdev_priv(dev); memset(&parent_id, 0, sizeof(parent_id)); - parent_id.of = of_get_parent(op->node); + parent_id.of = of_get_parent(op->dev.of_node); np->parent = niu_get_parent(np, &parent_id, PLAT_TYPE_NIU); diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 35897134a5dd..641973ca2417 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -199,12 +199,12 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, if (!pdata) return -ENOMEM; - ret = of_get_gpio(ofdev->node, 0); + ret = of_get_gpio(ofdev->dev.of_node, 0); if (ret < 0) goto out_free; pdata->mdc = ret; - ret = of_get_gpio(ofdev->node, 1); + ret = of_get_gpio(ofdev->dev.of_node, 1); if (ret < 0) goto out_free; pdata->mdio = ret; @@ -213,7 +213,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, if (!new_bus) goto out_free; - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) mdio_gpio_bus_deinit(&ofdev->dev); diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index ed7865a0b5b2..bd286ec5abd9 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1133,8 +1133,8 @@ static int __devinit bigmac_ether_init(struct of_device *op, goto fail_and_cleanup; /* Get supported SBUS burst sizes. */ - bsizes = of_getintprop_default(qec_op->node, "burst-sizes", 0xff); - bsizes_more = of_getintprop_default(qec_op->node, "burst-sizes", 0xff); + bsizes = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff); + bsizes_more = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff); bsizes &= 0xff; if (bsizes_more != 0xff) @@ -1186,7 +1186,7 @@ static int __devinit bigmac_ether_init(struct of_device *op, } /* Get the board revision of this BigMAC. */ - bp->board_rev = of_getintprop_default(bp->bigmac_op->node, + bp->board_rev = of_getintprop_default(bp->bigmac_op->dev.of_node, "board-version", 1); /* Init auto-negotiation timer state. */ diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b17dbb11bd67..c6463f71c916 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2483,7 +2483,7 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info else { const struct linux_prom_registers *regs; struct of_device *op = hp->happy_dev; - regs = of_get_property(op->node, "regs", NULL); + regs = of_get_property(op->dev.of_node, "regs", NULL); if (regs) sprintf(info->bus_info, "SBUS:%d", regs->which_io); @@ -2643,14 +2643,14 @@ static const struct net_device_ops hme_netdev_ops = { #ifdef CONFIG_SBUS static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) { - struct device_node *dp = op->node, *sbus_dp; + struct device_node *dp = op->dev.of_node, *sbus_dp; struct quattro *qp = NULL; struct happy_meal *hp; struct net_device *dev; int i, qfe_slot = -1; int err = -ENODEV; - sbus_dp = to_of_device(op->dev.parent)->node; + sbus_dp = to_of_device(op->dev.parent)->dev.of_node; /* We can match PCI devices too, do not accept those here. */ if (strcmp(sbus_dp->name, "sbus")) @@ -3241,7 +3241,7 @@ static void happy_meal_pci_exit(void) #ifdef CONFIG_SBUS static int __devinit hme_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); int is_qfe = (match->data != NULL); diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 0c21653ff9f9..28afc86e0694 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1324,7 +1324,7 @@ static int __devinit sparc_lance_probe_one(struct of_device *op, struct of_device *ledma, struct of_device *lebuffer) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; static unsigned version_printed; struct lance_private *lp; struct net_device *dev; @@ -1411,7 +1411,7 @@ static int __devinit sparc_lance_probe_one(struct of_device *op, lp->burst_sizes = 0; if (lp->ledma) { - struct device_node *ledma_dp = ledma->node; + struct device_node *ledma_dp = ledma->dev.of_node; struct device_node *sbus_dp; unsigned int sbmask; const char *prop; @@ -1507,7 +1507,7 @@ fail: static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct of_device *parent = to_of_device(op->dev.parent); - struct device_node *parent_dp = parent->node; + struct device_node *parent_dp = parent->dev.of_node; int err; if (!strcmp(parent_dp->name, "ledma")) { diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index be637dce944c..9864f4fa69d5 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -696,7 +696,7 @@ static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) strcpy(info->version, "3.0"); op = qep->op; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); if (regs) sprintf(info->bus_info, "SBUS:%d", regs->which_io); @@ -800,7 +800,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child) if (qec_global_reset(qecp->gregs)) goto fail; - qecp->qec_bursts = qec_get_burst(op->node); + qecp->qec_bursts = qec_get_burst(op->dev.of_node); qec_init_once(qecp, op); @@ -858,7 +858,7 @@ static int __devinit qec_ether_init(struct of_device *op) res = -ENODEV; - i = of_getintprop_default(op->node, "channel#", -1); + i = of_getintprop_default(op->dev.of_node, "channel#", -1); if (i == -1) goto fail; qe->channel = i; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 1b0aef37e495..88ebfc976735 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3721,7 +3721,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = { static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) { struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 1e783ccc306e..3dd2416db540 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1090,7 +1090,7 @@ static void xemaclite_remove_ndev(struct net_device *ndev) */ static bool get_bool(struct of_device *ofdev, const char *s) { - u32 *p = (u32 *)of_get_property(ofdev->node, s, NULL); + u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL); if (p) { return (bool)*p; @@ -1132,14 +1132,14 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, dev_info(dev, "Device Tree Probing\n"); /* Get iospace for the device */ - rc = of_address_to_resource(ofdev->node, 0, &r_mem); + rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (rc) { dev_err(dev, "invalid address\n"); return rc; } /* Get IRQ for the device */ - rc = of_irq_to_resource(ofdev->node, 0, &r_irq); + rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); if (rc == NO_IRQ) { dev_err(dev, "no IRQ found\n"); return rc; @@ -1184,7 +1184,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, lp->next_rx_buf_to_use = 0x0; lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong"); lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); - mac_address = of_get_mac_address(ofdev->node); + mac_address = of_get_mac_address(ofdev->dev.of_node); if (mac_address) /* Set the MAC address. */ @@ -1199,7 +1199,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, /* Set the MAC address in the EmacLite device */ xemaclite_update_address(lp, ndev->dev_addr); - lp->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); + lp->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); rc = xemaclite_mdio_setup(lp, &ofdev->dev); if (rc) dev_warn(&ofdev->dev, "error registering MDIO bus\n"); diff --git a/drivers/of/device.c b/drivers/of/device.c index 224ae6bc67b6..24068bbbce1a 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -21,9 +21,9 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct of_device *dev) { - if (!dev->node) + if (!dev->dev.of_node) return NULL; - return of_match_node(matches, dev->node); + return of_match_node(matches, dev->dev.of_node); } EXPORT_SYMBOL(of_match_device); @@ -54,7 +54,7 @@ static ssize_t devspec_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } static ssize_t name_show(struct device *dev, @@ -63,7 +63,7 @@ static ssize_t name_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->name); } static ssize_t modalias_show(struct device *dev, @@ -97,14 +97,14 @@ void of_release_dev(struct device *dev) struct of_device *ofdev; ofdev = to_of_device(dev); - of_node_put(ofdev->node); + of_node_put(ofdev->dev.of_node); kfree(ofdev); } EXPORT_SYMBOL(of_release_dev); int of_device_register(struct of_device *ofdev) { - BUG_ON(ofdev->node == NULL); + BUG_ON(ofdev->dev.of_node == NULL); device_initialize(&ofdev->dev); @@ -112,7 +112,7 @@ int of_device_register(struct of_device *ofdev) * the parent. If there is no parent defined, set the node * explicitly */ if (!ofdev->dev.parent) - set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->node)); + set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node)); return device_add(&ofdev->dev); } @@ -132,11 +132,11 @@ ssize_t of_device_get_modalias(struct of_device *ofdev, ssize_t tsize, csize, repend; /* Name & Type */ - csize = snprintf(str, len, "of:N%sT%s", - ofdev->node->name, ofdev->node->type); + csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name, + ofdev->dev.of_node->type); /* Get compatible property if any */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); if (!compat) return csize; diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index e690a2aa6fef..604ba966e1c9 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -69,7 +69,7 @@ EXPORT_SYMBOL(of_register_i2c_devices); static int of_dev_node_match(struct device *dev, void *data) { - return dev_archdata_get_node(&dev->archdata) == data; + return dev->of_node == data; } /* must call put_device() when done with returned i2c_client device */ diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 12090f57dc87..01d794abe105 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -101,7 +101,7 @@ EXPORT_SYMBOL(of_mdiobus_register); /* Helper function for of_phy_find_device */ static int of_phy_match(struct device *dev, void *phy_np) { - return dev_archdata_get_node(&dev->archdata) == phy_np; + return dev->of_node == phy_np; } /** @@ -167,7 +167,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, if (!dev->dev.parent) return NULL; - net_np = dev_archdata_get_node(&dev->dev.parent->archdata); + net_np = dev->dev.parent->of_node; if (!net_np) return NULL; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 2e59fe947d28..a22d32d71bf2 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -185,7 +185,7 @@ static int __devinit electra_cf_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct electra_cf_socket *cf; struct resource mem, io; int status; diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index b4951eb0358e..103fdf6b0b89 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -565,9 +565,9 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp) int devidx = 0; while ((op = bbc_i2c_getdev(bp, devidx++)) != NULL) { - if (!strcmp(op->node->name, "temperature")) + if (!strcmp(op->dev.of_node->name, "temperature")) attach_one_temp(bp, op, temp_index++); - if (!strcmp(op->node->name, "fan-control")) + if (!strcmp(op->dev.of_node->name, "fan-control")) attach_one_fan(bp, op, fan_index++); } if (temp_index != 0 && fan_index != 0) { diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 7e30e5f6e032..1543ac32b79b 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -97,7 +97,7 @@ struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct of_device * client->bp = bp; client->op = op; - reg = of_get_property(op->node, "reg", NULL); + reg = of_get_property(op->dev.of_node, "reg", NULL); if (!reg) { kfree(client); return NULL; @@ -327,7 +327,7 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int inde spin_lock_init(&bp->lock); entry = 0; - for (dp = op->node->child; + for (dp = op->dev.of_node->child; dp && entry < 8; dp = dp->sibling, entry++) { struct of_device *child_op; diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 3e59189f4137..7fc7f34f3466 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -216,7 +216,7 @@ static int __devinit d7s_probe(struct of_device *op, writeb(regs, p->regs); printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n", - op->node->full_name, + op->dev.of_node->full_name, (regs & D7S_FLIP) ? " (FLIPPED)" : "", op->resource[0].start, sol_compat ? "in sol_compat mode" : ""); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index c6e2eff19409..a5fe20faf4f7 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1043,7 +1043,7 @@ static int __devinit envctrl_probe(struct of_device *op, return -ENOMEM; index = 0; - dp = op->node->child; + dp = op->dev.of_node->child; while (dp) { if (!strcmp(dp->name, "gpio")) { i2c_childlist[index].i2ctype = I2C_GPIO; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 19f255b97c86..202ff8f75afb 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -162,7 +162,7 @@ static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops }; static int __devinit flash_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct device_node *parent; parent = dp->parent; @@ -184,7 +184,7 @@ static int __devinit flash_probe(struct of_device *op, flash.busy = 0; printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n", - op->node->full_name, + op->dev.of_node->full_name, flash.read_base, flash.read_size, flash.write_base, flash.write_size); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 2c56fd56ec63..acc6738aa61f 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -382,7 +382,7 @@ static int __devinit uctrl_probe(struct of_device *op, sbus_writel(UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK, &p->regs->uctrl_intr); printk(KERN_INFO "%s: uctrl regs[0x%p] (irq %d)\n", - op->node->full_name, p->regs, p->irq); + op->dev.of_node->full_name, p->regs, p->irq); uctrl_get_event_status(p); uctrl_get_external_status(p); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c2eea711a5ce..60cd4ec51eae 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1157,7 +1157,7 @@ static void ibmvfc_gather_partition_info(struct ibmvfc_host *vhost) static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) { struct ibmvfc_npiv_login *login_info = &vhost->login_info; - struct device_node *of_node = vhost->dev->archdata.of_node; + struct device_node *of_node = vhost->dev->of_node; const char *location; memset(login_info, 0, sizeof(*login_info)); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index ff5ec5ac1fb5..cc38fefc2612 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -957,7 +957,7 @@ static void send_mad_capabilities(struct ibmvscsi_host_data *hostdata) struct viosrp_capabilities *req; struct srp_event_struct *evt_struct; unsigned long flags; - struct device_node *of_node = hostdata->dev->archdata.of_node; + struct device_node *of_node = hostdata->dev->of_node; const char *location; evt_struct = get_event_struct(&hostdata->pool); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index aa406497eebc..35433d23b7ce 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -755,7 +755,7 @@ static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti) struct of_device *op = qpti->op; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1); if (qpti->scsi_id == -1) @@ -776,8 +776,8 @@ static void qpti_get_bursts(struct qlogicpti *qpti) struct of_device *op = qpti->op; u8 bursts, bmask; - bursts = of_getintprop_default(op->node, "burst-sizes", 0xff); - bmask = of_getintprop_default(op->node->parent, "burst-sizes", 0xff); + bursts = of_getintprop_default(op->dev.of_node, "burst-sizes", 0xff); + bmask = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0xff); if (bmask != 0xff) bursts &= bmask; if (bursts == 0xff || @@ -1293,7 +1293,7 @@ static struct scsi_host_template qpti_template = { static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct scsi_host_template *tpnt = match->data; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; @@ -1315,7 +1315,7 @@ static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_devic qpti->qhost = host; qpti->op = op; qpti->qpti_id = nqptis; - strcpy(qpti->prom_name, op->node->name); + strcpy(qpti->prom_name, op->dev.of_node->name); qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp"); if (qpti_map_regs(qpti) < 0) diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index fc23d273fb1a..151df73df475 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -125,7 +125,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) struct of_device *op = esp->dev; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff); if (esp->scsi_id != 0xff) goto done; @@ -134,7 +134,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) if (esp->scsi_id != 0xff) goto done; - esp->scsi_id = of_getintprop_default(espdma->node, + esp->scsi_id = of_getintprop_default(espdma->dev.of_node, "scsi-initiator-id", 7); done: @@ -147,7 +147,7 @@ static void __devinit esp_get_differential(struct esp *esp) struct of_device *op = esp->dev; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; if (of_find_property(dp, "differential", NULL)) esp->flags |= ESP_FLAG_DIFFERENTIAL; else @@ -160,7 +160,7 @@ static void __devinit esp_get_clock_params(struct esp *esp) struct device_node *bus_dp, *dp; int fmhz; - dp = op->node; + dp = op->dev.of_node; bus_dp = dp->parent; fmhz = of_getintprop_default(dp, "clock-frequency", 0); @@ -172,12 +172,12 @@ static void __devinit esp_get_clock_params(struct esp *esp) static void __devinit esp_get_bursts(struct esp *esp, struct of_device *dma_of) { - struct device_node *dma_dp = dma_of->node; + struct device_node *dma_dp = dma_of->dev.of_node; struct of_device *op = esp->dev; struct device_node *dp; u8 bursts, val; - dp = op->node; + dp = op->dev.of_node; bursts = of_getintprop_default(dp, "burst-sizes", 0xff); val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); if (val != 0xff) @@ -565,7 +565,7 @@ fail: static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dma_node = NULL; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct of_device *dma_of = NULL; int hme = 0; @@ -574,7 +574,7 @@ static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device !strcmp(dp->parent->name, "dma"))) dma_node = dp->parent; else if (!strcmp(dp->name, "SUNW,fas")) { - dma_node = op->node; + dma_node = op->dev.of_node; hme = 1; } if (dma_node) diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index fe91319b5f65..52015d7031bb 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c @@ -559,7 +559,7 @@ static int __devinit apbuart_probe(struct of_device *op, i = 0; for (i = 0; i < grlib_apbuart_port_nr; i++) { - if (op->node == grlib_apbuart_nodes[i]) + if (op->dev.of_node == grlib_apbuart_nodes[i]) break; } diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 300cea768d74..7866cdf8a754 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1342,7 +1342,7 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev, /* initialize the device pointer for the port */ pinfo->port.dev = &ofdev->dev; - ret = cpm_uart_init_port(ofdev->node, pinfo); + ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); if (ret) return ret; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 3119fddaedb5..cb079387c5ae 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1328,14 +1328,14 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) /* Check validity & presence */ for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) - if (mpc52xx_uart_nodes[idx] == op->node) + if (mpc52xx_uart_nodes[idx] == op->dev.of_node) break; if (idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; pr_debug("Found %s assigned to ttyPSC%x\n", mpc52xx_uart_nodes[idx]->full_name, idx); - uartclk = psc_ops->getuartclk(op->node); + uartclk = psc_ops->getuartclk(op->dev.of_node); if (uartclk == 0) { dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); return -EINVAL; @@ -1355,7 +1355,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) port->dev = &op->dev; /* Search for IRQ and mapbase */ - ret = of_address_to_resource(op->node, 0, &res); + ret = of_address_to_resource(op->dev.of_node, 0, &res); if (ret) return ret; @@ -1365,7 +1365,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) return -EINVAL; } - psc_ops->get_irq(port, op->node); + psc_ops->get_irq(port, op->dev.of_node); if (port->irq == NO_IRQ) { dev_dbg(&op->dev, "Could not get irq\n"); return -EINVAL; diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c index e1ab8ec0a4a6..3c02fa96f282 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/serial/nwpserial.c @@ -344,7 +344,7 @@ int nwpserial_register_port(struct uart_port *port) mutex_lock(&nwpserial_mutex); - dn = to_of_device(port->dev)->node; + dn = to_of_device(port->dev)->dev.of_node; if (dn == NULL) goto out; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 4abfebdb0fcc..29539805e593 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -31,7 +31,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, int type, struct uart_port *port) { struct resource resource; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; const unsigned int *clk, *spd; const u32 *prop; int ret, prop_size; @@ -88,7 +88,7 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev, int port_type; int ret; - if (of_find_property(ofdev->node, "used-by-rtas", NULL)) + if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) return -EBUSY; info = kmalloc(sizeof(*info), GFP_KERNEL); diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4eaa043ca2a8..1e43bf59c44d 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1609,7 +1609,7 @@ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) /* Iterate the pmz_ports array to find a matching entry */ for (i = 0; i < MAX_ZS_PORTS; i++) - if (pmz_ports[i].node == mdev->ofdev.node) { + if (pmz_ports[i].node == mdev->ofdev.dev.of_node) { struct uart_pmac_port *uap = &pmz_ports[i]; uap->dev = mdev; diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d14cca7fb88d..d1eedf13d85c 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -565,7 +565,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m if (err) goto out_free_con_read_page; - sunserial_console_match(&sunhv_console, op->node, + sunserial_console_match(&sunhv_console, op->dev.of_node, &sunhv_reg, port->line, false); err = uart_add_one_port(&sunhv_reg, port); diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d2e0321049e2..9176c41b74ad 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) printk("Console: ttyS%d (SAB82532)\n", (sunsab_reg.minor - 64) + con->index); - sunserial_console_termios(con, to_of_device(up->port.dev)->node); + sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); switch (con->cflag & CBAUD) { case B150: baud = 150; break; @@ -1026,11 +1026,11 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * if (err) goto out1; - sunserial_console_match(SUNSAB_CONSOLE(), op->node, + sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, &sunsab_reg, up[0].port.line, false); - sunserial_console_match(SUNSAB_CONSOLE(), op->node, + sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, &sunsab_reg, up[1].port.line, false); diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 01f7731e59b8..a647b2448071 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1200,7 +1200,7 @@ static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up) return -ENODEV; printk("%s: %s port at %llx, irq %u\n", - to_of_device(up->port.dev)->node->full_name, + to_of_device(up->port.dev)->dev.of_node->full_name, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", (unsigned long long) up->port.mapbase, up->port.irq); @@ -1352,7 +1352,7 @@ static int __init sunsu_console_setup(struct console *co, char *options) spin_lock_init(&port->lock); /* Get firmware console settings. */ - sunserial_console_termios(co, to_of_device(port->dev)->node); + sunserial_console_termios(co, to_of_device(port->dev)->dev.of_node); memset(&termios, 0, sizeof(struct ktermios)); termios.c_cflag = co->cflag; @@ -1409,7 +1409,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp) static int __devinit su_probe(struct of_device *op, const struct of_device_id *match) { static int inst; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct uart_sunsu_port *up; struct resource *rp; enum su_type type; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 2c7a66af4f52..20f9be8cd949 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) (sunzilog_reg.minor - 64) + con->index, con->index); /* Get firmware console settings. */ - sunserial_console_termios(con, to_of_device(up->port.dev)->node); + sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); /* Firmware console speed is limited to 150-->38400 baud so * this hackish cflag thing is OK. @@ -1358,7 +1358,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m int keyboard_mouse = 0; int err; - if (of_find_property(op->node, "keyboard", NULL)) + if (of_find_property(op->dev.of_node, "keyboard", NULL)) keyboard_mouse = 1; /* uarts must come before keyboards/mice */ @@ -1415,7 +1415,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m sunzilog_init_hw(&up[1]); if (!keyboard_mouse) { - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, &sunzilog_reg, up[0].port.line, false)) up->flags |= SUNZILOG_FLAG_IS_CONS; @@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m rp, sizeof(struct zilog_layout)); return err; } - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, &sunzilog_reg, up[1].port.line, false)) up->flags |= SUNZILOG_FLAG_IS_CONS; diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index f0a6c61b17f7..8fc2583d06ff 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -591,15 +591,15 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; } - irq = irq_of_parse_and_map(op->node, 0); + irq = irq_of_parse_and_map(op->dev.of_node, 0); - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); } diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 074904912f64..529890f044e2 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -1197,7 +1197,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) static int ucc_uart_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; const unsigned int *iprop; /* Integer OF properties */ const char *sprop; /* String OF properties */ struct uart_qe_port *qe_port = NULL; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 77d4cc88edea..7fcf28405860 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -472,18 +472,18 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, s16 id = -1; int rc; - regaddr_p = of_get_address(op->node, 0, &size64, NULL); + regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { dev_err(&op->dev, "Invalid PSC address\n"); return -EINVAL; } - regaddr64 = of_translate_address(op->node, regaddr_p); + regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (1..6, used by port_config) */ if (op->dev.platform_data == NULL) { const u32 *psc_nump; - psc_nump = of_get_property(op->node, "cell-index", NULL); + psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); if (!psc_nump || *psc_nump > 5) { dev_err(&op->dev, "Invalid cell-index property\n"); return -EINVAL; @@ -492,9 +492,10 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, } rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, - irq_of_parse_and_map(op->node, 0), id); + irq_of_parse_and_map(op->dev.of_node, 0), id); if (rc == 0) - of_register_spi_devices(dev_get_drvdata(&op->dev), op->node); + of_register_spi_devices(dev_get_drvdata(&op->dev), + op->dev.of_node); return rc; } diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index cd68f1ce5cc3..6573233bf7c9 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -403,7 +403,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, /* MMIO registers */ dev_dbg(&op->dev, "probing mpc5200 SPI device\n"); - regs = of_iomap(op->node, 0); + regs = of_iomap(op->dev.of_node, 0); if (!regs) return -ENODEV; @@ -445,11 +445,11 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, ms = spi_master_get_devdata(master); ms->master = master; ms->regs = regs; - ms->irq0 = irq_of_parse_and_map(op->node, 0); - ms->irq1 = irq_of_parse_and_map(op->node, 1); + ms->irq0 = irq_of_parse_and_map(op->dev.of_node, 0); + ms->irq1 = irq_of_parse_and_map(op->dev.of_node, 1); ms->state = mpc52xx_spi_fsmstate_idle; - ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node); - ms->gpio_cs_count = of_gpio_count(op->node); + ms->ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); + ms->gpio_cs_count = of_gpio_count(op->dev.of_node); if (ms->gpio_cs_count > 0) { master->num_chipselect = ms->gpio_cs_count; ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int), @@ -460,7 +460,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, } for (i = 0; i < ms->gpio_cs_count; i++) { - gpio_cs = of_get_gpio(op->node, i); + gpio_cs = of_get_gpio(op->dev.of_node, i); if (gpio_cs < 0) { dev_err(&op->dev, "could not parse the gpio field " @@ -512,7 +512,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, if (rc) goto err_register; - of_register_spi_devices(master, op->node); + of_register_spi_devices(master, op->dev.of_node); dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n"); return rc; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 14d052316502..7572f98a419e 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -797,7 +797,7 @@ static void mpc8xxx_spi_free_dummy_rx(void) static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) { struct device *dev = mspi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; const u32 *iprop; int size; unsigned long spi_base_ofs; @@ -851,7 +851,7 @@ static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) static int mpc8xxx_spi_cpm_init(struct mpc8xxx_spi *mspi) { struct device *dev = mspi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; const u32 *iprop; int size; unsigned long pram_ofs; @@ -1123,7 +1123,7 @@ static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on) static int of_mpc8xxx_spi_get_chipselects(struct device *dev) { - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct fsl_spi_platform_data *pdata = dev->platform_data; struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); unsigned int ngpios; @@ -1224,7 +1224,7 @@ static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_spi_probe_info *pinfo; struct fsl_spi_platform_data *pdata; struct spi_master *master; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 8df33b8a634c..ad0662354a5e 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -108,7 +108,7 @@ ppc44x_enable_bmt(struct device_node *dn) static int __devinit ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ehci_hcd *ehci = NULL; struct resource res; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 15379c636143..6135732d8057 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -565,7 +565,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; - struct device_node *node = ofdev->node; + struct device_node *node = dev->of_node; struct usb_hcd *hcd; struct fhci_hcd *fhci; struct resource usb_regs; @@ -670,7 +670,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, } for (j = 0; j < NUM_PINS; j++) { - fhci->pins[j] = qe_pin_request(ofdev->node, j); + fhci->pins[j] = qe_pin_request(node, j); if (IS_ERR(fhci->pins[j])) { ret = PTR_ERR(fhci->pins[j]); dev_err(dev, "can't get pin %d: %d\n", j, ret); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 4293cfd28d61..36360e24a9b9 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -31,7 +31,7 @@ static int of_isp1760_probe(struct of_device *dev, const struct of_device_id *match) { struct usb_hcd *hcd; - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; struct of_irq oirq; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 103263c230cf..003aea21c35e 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -83,7 +83,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { static int __devinit ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ohci_hcd *ohci; struct resource res; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 6d0fcb43696e..7f59b0fe5dc2 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -740,7 +740,7 @@ static void cg6_unmap_regs(struct of_device *op, struct fb_info *info, static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg6_par *par; int linebytes, err; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index a42fabab69df..ddd46f71e250 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -896,7 +896,7 @@ static void ffb_init_fix(struct fb_info *info) static int __devinit ffb_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct ffb_fbc __iomem *fbc; struct ffb_dac __iomem *dac; struct fb_info *info; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 994358a4f302..930a2522a631 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1421,7 +1421,7 @@ static ssize_t show_monitor(struct device *device, static int __devinit fsl_diu_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mfb_info *mfbi; phys_addr_t dummy_ad_addr; int ret, i, error = 0; diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 8a204e7a5b5b..69d78d50f0f6 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -536,7 +536,7 @@ static int __init platinumfb_setup(char *options) static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) { - struct device_node *dp = odev->node; + struct device_node *dp = odev->dev.of_node; struct fb_info *info; struct fb_info_platinum *pinfo; volatile __u8 *fbuffer; diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index 23e69e834a18..ad92a200fafa 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -114,7 +114,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp) static int __devinit gfb_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct gfb_info *gp; int err; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 3fcb83f03881..6fcec553662c 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -423,7 +423,7 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) * To check whether the core is connected directly to DCR or PLB * interface and initialize the tft_access accordingly. */ - p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", NULL); + p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL); tft_access = p ? *p : 0; /* @@ -432,41 +432,41 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) */ if (tft_access) { drvdata->flags |= PLB_ACCESS_FLAG; - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); goto err; } } else { res.start = 0; - start = dcr_resource_start(op->node, 0); - drvdata->dcr_len = dcr_resource_len(op->node, 0); - drvdata->dcr_host = dcr_map(op->node, start, drvdata->dcr_len); + start = dcr_resource_start(op->dev.of_node, 0); + drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); + drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); if (!DCR_MAP_OK(drvdata->dcr_host)) { dev_err(&op->dev, "invalid DCR address\n"); goto err; } } - prop = of_get_property(op->node, "phys-size", &size); + prop = of_get_property(op->dev.of_node, "phys-size", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.screen_width_mm = prop[0]; pdata.screen_height_mm = prop[1]; } - prop = of_get_property(op->node, "resolution", &size); + prop = of_get_property(op->dev.of_node, "resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.xres = prop[0]; pdata.yres = prop[1]; } - prop = of_get_property(op->node, "virtual-resolution", &size); + prop = of_get_property(op->dev.of_node, "virtual-resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.xvirt = prop[0]; pdata.yvirt = prop[1]; } - if (of_find_property(op->node, "rotate-display", NULL)) + if (of_find_property(op->dev.of_node, "rotate-display", NULL)) pdata.rotate_screen = 1; dev_set_drvdata(&op->dev, drvdata); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index ba2efce4b40e..2fcc3cf7ef62 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -577,7 +577,7 @@ static int __devinit cpwd_probe(struct of_device *op, * interrupt_mask register cannot be written, so no timer * interrupts can be masked within the PLD. */ - str_prop = of_get_property(op->node, "model", NULL); + str_prop = of_get_property(op->dev.of_node, "model", NULL); p->broken = (str_prop && !strcmp(str_prop, WD_BADMODEL)); if (!p->enabled) diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index 1cd9b301df03..3fd1a7e24928 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c @@ -992,7 +992,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) return -ENODEV; /* by breaking out we keep a reference */ - while ((sound = of_get_next_child(sdev->ofdev.node, sound))) { + while ((sound = of_get_next_child(sdev->ofdev.dev.of_node, sound))) { if (sound->type && strcasecmp(sound->type, "soundchip") == 0) break; } diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index fa8ab2815a98..99ca7120e269 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c @@ -74,11 +74,11 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) of = &soundbus_dev->ofdev; /* stuff we want to pass to /sbin/hotplug */ - retval = add_uevent_var(env, "OF_NAME=%s", of->node->name); + retval = add_uevent_var(env, "OF_NAME=%s", of->dev.of_node->name); if (retval) return retval; - retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type); + retval = add_uevent_var(env, "OF_TYPE=%s", of->dev.of_node->type); if (retval) return retval; @@ -86,7 +86,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(of->node, "compatible", &cplen); + compat = of_get_property(of->dev.of_node, "compatible", &cplen); while (compat && cplen > 0) { int tmp = env->buflen; retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); @@ -169,7 +169,7 @@ int soundbus_add_one(struct soundbus_dev *dev) /* sanity checks */ if (!dev->attach_codec || - !dev->ofdev.node || + !dev->ofdev.dev.of_node || dev->pcmname || dev->pcmid != -1) { printk(KERN_ERR "soundbus: adding device failed sanity check!\n"); diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c index 47f854c2001f..4dc9b49c02cf 100644 --- a/sound/aoa/soundbus/i2sbus/control.c +++ b/sound/aoa/soundbus/i2sbus/control.c @@ -42,7 +42,7 @@ int i2sbus_control_add_dev(struct i2sbus_control *c, { struct device_node *np; - np = i2sdev->sound.ofdev.node; + np = i2sdev->sound.ofdev.dev.of_node; i2sdev->enable = pmf_find_function(np, "enable"); i2sdev->cell_enable = pmf_find_function(np, "cell-enable"); i2sdev->clock_enable = pmf_find_function(np, "clock-enable"); diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 9d6f3b176ed1..7672b4d145ae 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -221,8 +221,8 @@ static int i2sbus_add_dev(struct macio_dev *macio, mutex_init(&dev->lock); spin_lock_init(&dev->low_lock); - dev->sound.ofdev.node = np; dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; + dev->sound.ofdev.dev.of_node = np; dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; dev->sound.ofdev.dev.parent = &macio->ofdev.dev; dev->sound.ofdev.dev.release = i2sbus_release_dev; @@ -346,7 +346,7 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) return -ENODEV; } - while ((np = of_get_next_child(dev->ofdev.node, np))) { + while ((np = of_get_next_child(dev->ofdev.dev.of_node, np))) { if (of_device_is_compatible(np, "i2sbus") || of_device_is_compatible(np, "i2s-modem")) { got += i2sbus_add_dev(dev, control, np); diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c index f580942b5c09..6496e754f00a 100644 --- a/sound/aoa/soundbus/sysfs.c +++ b/sound/aoa/soundbus/sysfs.c @@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct soundbus_dev *mdev = to_soundbus_device (dev); \ - return sprintf (buf, format_string, mdev->ofdev.node->field); \ + return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \ } static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, @@ -25,7 +25,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, length = strlen(buf); } else { length = sprintf(buf, "of:N%sT%s\n", - of->node->name, of->node->type); + of->dev.of_node->name, of->dev.of_node->type); } return length; diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index d639e55c5124..1d4e7164e80a 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -380,8 +380,8 @@ int mpc5200_audio_dma_create(struct of_device *op) int ret; /* Fetch the registers and IRQ of the PSC */ - irq = irq_of_parse_and_map(op->node, 0); - if (of_address_to_resource(op->node, 0, &res)) { + irq = irq_of_parse_and_map(op->dev.of_node, 0); + if (of_address_to_resource(op->dev.of_node, 0, &res)) { dev_err(&op->dev, "Missing reg property\n"); return -ENODEV; } @@ -399,7 +399,7 @@ int mpc5200_audio_dma_create(struct of_device *op) } /* Get the PSC ID */ - prop = of_get_property(op->node, "cell-index", &size); + prop = of_get_property(op->dev.of_node, "cell-index", &size); if (!prop || size < sizeof *prop) { ret = -ENODEV; goto out_free; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index ce8de90fb94a..748cc0f0df38 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -181,7 +181,7 @@ static int __devinit psc_i2s_of_probe(struct of_device *op, /* Check for the codec handle. If it is not present then we * are done */ - if (!of_get_property(op->node, "codec-handle", NULL)) + if (!of_get_property(op->dev.of_node, "codec-handle", NULL)) return 0; /* Due to errata in the dma mode; need to line up enabling diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 83de1c81c8c4..e3f78f255a60 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -203,7 +203,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = { static int mpc8610_hpcd_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *codec_np = NULL; struct device_node *guts_np = NULL; struct device_node *dma_np = NULL; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 7dcc06512e86..6a4c872e00df 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2075,12 +2075,12 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) { #ifdef EBUS_SUPPORT - if (!strcmp(op->node->parent->name, "ebus")) + if (!strcmp(op->dev.of_node->parent->name, "ebus")) return cs4231_ebus_probe(op, match); #endif #ifdef SBUS_SUPPORT - if (!strcmp(op->node->parent->name, "sbus") || - !strcmp(op->node->parent->name, "sbi")) + if (!strcmp(op->dev.of_node->parent->name, "sbus") || + !strcmp(op->dev.of_node->parent->name, "sbi")) return cs4231_sbus_probe(op, match); #endif return -ENODEV; diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 2eab6ce48852..1b5192eb5ae5 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2651,7 +2651,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", dev, dbri->regs, - dbri->irq, op->node->name[9], dbri->mm.version); + dbri->irq, op->dev.of_node->name[9], dbri->mm.version); dev++; return 0; -- cgit v1.2.3 From 4018294b53d1dae026880e45f174c1cc63b5d435 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:02 -0700 Subject: of: Remove duplicate fields from of_platform_driver .name, .match_table and .owner are duplicated in both of_platform_driver and device_driver. This patch is a removes the extra copies from struct of_platform_driver and converts all users to the device_driver members. This patch is a pretty mechanical change. The usage model doesn't change and if any drivers have been missed, or if anything has been fixed up incorrectly, then it will fail with a compile time error, and the fixup will be trivial. This patch looks big and scary because it touches so many files, but it should be pretty safe. Signed-off-by: Grant Likely Acked-by: Sean MacLennan --- arch/powerpc/kernel/ibmebus.c | 3 --- arch/powerpc/kernel/of_platform.c | 3 ++- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 14 +++++++++---- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 7 +++++-- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 8 ++++--- arch/powerpc/platforms/82xx/ep8248e.c | 3 ++- arch/powerpc/platforms/83xx/suspend.c | 7 +++++-- arch/powerpc/platforms/cell/axon_msi.c | 7 ++++--- arch/powerpc/platforms/pasemi/gpio_mdio.c | 7 ++++--- arch/powerpc/sysdev/axonram.c | 8 +++---- arch/powerpc/sysdev/bestcomm/bestcomm.c | 10 ++++----- arch/powerpc/sysdev/fsl_msi.c | 7 +++++-- arch/powerpc/sysdev/fsl_pmc.c | 7 +++++-- arch/powerpc/sysdev/fsl_rio.c | 7 +++++-- arch/powerpc/sysdev/pmi.c | 7 ++++--- arch/powerpc/sysdev/qe_lib/qe.c | 7 +++++-- arch/sparc/include/asm/parport.h | 7 +++++-- arch/sparc/kernel/apc.c | 7 +++++-- arch/sparc/kernel/auxio_64.c | 7 ++++--- arch/sparc/kernel/central.c | 14 +++++++------ arch/sparc/kernel/chmc.c | 7 +++++-- arch/sparc/kernel/pci_fire.c | 7 +++++-- arch/sparc/kernel/pci_psycho.c | 7 +++++-- arch/sparc/kernel/pci_sabre.c | 7 +++++-- arch/sparc/kernel/pci_schizo.c | 7 +++++-- arch/sparc/kernel/pci_sun4v.c | 7 +++++-- arch/sparc/kernel/pmc.c | 7 +++++-- arch/sparc/kernel/power.c | 7 ++++--- arch/sparc/kernel/time_32.c | 7 ++++--- arch/sparc/kernel/time_64.c | 21 +++++++++++-------- drivers/ata/pata_mpc52xx.c | 4 +--- drivers/ata/pata_of_platform.c | 7 +++++-- drivers/ata/sata_fsl.c | 7 +++++-- drivers/atm/fore200e.c | 7 +++++-- drivers/block/xsysace.c | 5 ++--- drivers/char/hw_random/n2-drv.c | 7 +++++-- drivers/char/hw_random/pasemi-rng.c | 7 +++++-- drivers/char/ipmi/ipmi_si_intf.c | 7 +++++-- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 5 ++--- drivers/crypto/amcc/crypto4xx_core.c | 7 +++++-- drivers/crypto/talitos.c | 7 +++++-- drivers/dma/fsldma.c | 11 ++++++---- drivers/dma/ppc4xx/adma.c | 2 +- drivers/edac/mpc85xx_edac.c | 30 +++++++++++---------------- drivers/edac/ppc4xx_edac.c | 10 ++++----- drivers/hwmon/ultra45_env.c | 7 +++++-- drivers/i2c/busses/i2c-cpm.c | 10 ++++----- drivers/i2c/busses/i2c-ibm_iic.c | 7 +++++-- drivers/i2c/busses/i2c-mpc.c | 8 +++---- drivers/infiniband/hw/ehca/ehca_main.c | 7 ++++--- drivers/input/misc/sparcspkr.c | 14 +++++++++---- drivers/input/serio/i8042-sparcio.h | 7 +++++-- drivers/input/serio/xilinx_ps2.c | 7 +++++-- drivers/leds/leds-gpio.c | 2 +- drivers/macintosh/smu.c | 7 +++++-- drivers/macintosh/therm_pm72.c | 7 +++++-- drivers/macintosh/therm_windtunnel.c | 7 +++++-- drivers/mmc/host/sdhci-of-core.c | 7 +++++-- drivers/mtd/maps/physmap_of.c | 7 +++++-- drivers/mtd/maps/sun_uflash.c | 7 +++++-- drivers/mtd/nand/fsl_elbc_nand.c | 5 +++-- drivers/mtd/nand/fsl_upm.c | 7 +++++-- drivers/mtd/nand/ndfc.c | 5 +++-- drivers/mtd/nand/pasemi_nand.c | 7 +++++-- drivers/mtd/nand/socrates_nand.c | 7 +++++-- drivers/net/can/mscan/mpc5xxx_can.c | 8 ++++--- drivers/net/can/sja1000/sja1000_of_platform.c | 8 ++++--- drivers/net/ehea/ehea_main.c | 7 +++++-- drivers/net/fec_mpc52xx.c | 8 ++++--- drivers/net/fec_mpc52xx_phy.c | 7 +++++-- drivers/net/fs_enet/fs_enet-main.c | 7 +++++-- drivers/net/fs_enet/mii-bitbang.c | 7 +++++-- drivers/net/fs_enet/mii-fec.c | 7 +++++-- drivers/net/fsl_pq_mdio.c | 7 +++++-- drivers/net/gianfar.c | 10 +++++---- drivers/net/ibm_newemac/core.c | 8 ++++--- drivers/net/ibm_newemac/mal.c | 8 ++++--- drivers/net/ibm_newemac/rgmii.c | 8 ++++--- drivers/net/ibm_newemac/tah.c | 8 ++++--- drivers/net/ibm_newemac/zmii.c | 8 ++++--- drivers/net/ll_temac_main.c | 2 +- drivers/net/myri_sbus.c | 7 +++++-- drivers/net/niu.c | 7 +++++-- drivers/net/phy/mdio-gpio.c | 7 +++++-- drivers/net/sunbmac.c | 7 +++++-- drivers/net/sunhme.c | 7 +++++-- drivers/net/sunlance.c | 7 +++++-- drivers/net/sunqe.c | 7 +++++-- drivers/net/ucc_geth.c | 7 +++++-- drivers/net/xilinx_emaclite.c | 7 +++++-- drivers/of/platform.c | 7 ------- drivers/parport/parport_sunbpp.c | 7 +++++-- drivers/pcmcia/electra_cf.c | 7 +++++-- drivers/pcmcia/m8xx_pcmcia.c | 7 +++++-- drivers/sbus/char/bbc_i2c.c | 7 +++++-- drivers/sbus/char/display7seg.c | 7 +++++-- drivers/sbus/char/envctrl.c | 7 +++++-- drivers/sbus/char/flash.c | 7 +++++-- drivers/sbus/char/uctrl.c | 7 +++++-- drivers/scsi/qlogicpti.c | 7 +++++-- drivers/scsi/sun_esp.c | 7 +++++-- drivers/serial/apbuart.c | 8 +++---- drivers/serial/cpm_uart/cpm_uart_core.c | 7 +++++-- drivers/serial/mpc52xx_uart.c | 7 ++++--- drivers/serial/of_serial.c | 8 ++++--- drivers/serial/sunhv.c | 7 +++++-- drivers/serial/sunsab.c | 7 +++++-- drivers/serial/sunsu.c | 7 +++++-- drivers/serial/sunzilog.c | 7 +++++-- drivers/serial/uartlite.c | 5 ++--- drivers/serial/ucc_uart.c | 8 ++++--- drivers/spi/mpc52xx_psc_spi.c | 4 +--- drivers/spi/mpc52xx_spi.c | 8 ++++--- drivers/spi/spi_mpc8xxx.c | 7 +++++-- drivers/spi/spi_ppc4xx.c | 2 +- drivers/spi/xilinx_spi_of.c | 2 +- drivers/usb/gadget/fsl_qe_udc.c | 7 +++++-- drivers/usb/host/ehci-ppc-of.c | 9 ++++---- drivers/usb/host/ehci-xilinx-of.c | 9 ++++---- drivers/usb/host/fhci-hcd.c | 7 +++++-- drivers/usb/host/isp1760-if.c | 7 +++++-- drivers/usb/host/ohci-ppc-of.c | 13 ++++-------- drivers/video/bw2.c | 7 +++++-- drivers/video/cg14.c | 7 +++++-- drivers/video/cg3.c | 7 +++++-- drivers/video/cg6.c | 7 +++++-- drivers/video/ffb.c | 7 +++++-- drivers/video/fsl-diu-fb.c | 8 ++++--- drivers/video/leo.c | 7 +++++-- drivers/video/mb862xx/mb862xxfb.c | 8 ++++--- drivers/video/p9100.c | 7 +++++-- drivers/video/platinumfb.c | 7 +++++-- drivers/video/sunxvr1000.c | 7 +++++-- drivers/video/tcx.c | 7 +++++-- drivers/video/xilinxfb.c | 5 ++--- drivers/watchdog/cpwd.c | 7 +++++-- drivers/watchdog/gef_wdt.c | 8 ++++--- drivers/watchdog/mpc8xxx_wdt.c | 8 +++---- drivers/watchdog/riowd.c | 7 +++++-- include/linux/of_platform.h | 4 ---- sound/soc/fsl/mpc5200_psc_ac97.c | 2 +- sound/soc/fsl/mpc5200_psc_i2s.c | 2 +- sound/soc/fsl/mpc8610_hpcd.c | 8 ++++--- sound/sparc/amd7930.c | 7 +++++-- sound/sparc/cs4231.c | 7 +++++-- sound/sparc/dbri.c | 7 +++++-- 146 files changed, 671 insertions(+), 387 deletions(-) (limited to 'drivers/dma') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 355257bb149d..21266abfbda6 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -201,9 +201,6 @@ static int ibmebus_create_devices(const struct of_device_id *matches) int ibmebus_register_driver(struct of_platform_driver *drv) { - if (!drv->driver.of_match_table) - drv->driver.of_match_table = drv->match_table; - /* If the driver uses devices that ibmebus doesn't know, add them */ ibmebus_create_devices(drv->driver.of_match_table); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 218853466510..487a98851ba6 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -306,10 +306,11 @@ static struct of_device_id of_pci_phb_ids[] = { }; static struct of_platform_driver of_pci_phb_driver = { - .match_table = of_pci_phb_ids, .probe = of_pci_phb_probe, .driver = { .name = "of-pci", + .owner = THIS_MODULE, + .of_match_table = of_pci_phb_ids, }, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 576669fc4fbf..ca5305a5bd61 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -193,8 +193,11 @@ static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = { - .name = "gpio_wkup", - .match_table = mpc52xx_wkup_gpiochip_match, + .driver = { + .name = "gpio_wkup", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_wkup_gpiochip_match, + }, .probe = mpc52xx_wkup_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; @@ -349,8 +352,11 @@ static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { - .name = "gpio", - .match_table = mpc52xx_simple_gpiochip_match, + .driver = { + .name = "gpio", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_simple_gpiochip_match, + }, .probe = mpc52xx_simple_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 42c507f9c35b..46c93578cbf0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -784,8 +784,11 @@ static const struct of_device_id mpc52xx_gpt_match[] = { }; static struct of_platform_driver mpc52xx_gpt_driver = { - .name = "mpc52xx-gpt", - .match_table = mpc52xx_gpt_match, + .driver = { + .name = "mpc52xx-gpt", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_gpt_match, + }, .probe = mpc52xx_gpt_probe, .remove = mpc52xx_gpt_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 17b99ba7a8cc..e86aec644501 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -537,9 +537,11 @@ static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = { }; static struct of_platform_driver mpc52xx_lpbfifo_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-lpbfifo", - .match_table = mpc52xx_lpbfifo_match, + .driver = { + .name = "mpc52xx-lpbfifo", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_lpbfifo_match, + }, .probe = mpc52xx_lpbfifo_probe, .remove = __devexit_p(mpc52xx_lpbfifo_remove), }; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 0176ae8249d5..9f2e52b36f91 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -170,8 +170,9 @@ static const struct of_device_id ep8248e_mdio_match[] = { static struct of_platform_driver ep8248e_mdio_driver = { .driver = { .name = "ep8248e-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = ep8248e_mdio_match, }, - .match_table = ep8248e_mdio_match, .probe = ep8248e_mdio_probe, .remove = ep8248e_mdio_remove, }; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index aa0b764b1cc4..ebe6c3537209 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -423,8 +423,11 @@ static struct of_device_id pmc_match[] = { }; static struct of_platform_driver pmc_driver = { - .name = "mpc83xx-pmc", - .match_table = pmc_match, + .driver = { + .name = "mpc83xx-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, .remove = pmc_remove }; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 177a4f1369b4..6257e5378615 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -447,11 +447,12 @@ static const struct of_device_id axon_msi_device_id[] = { }; static struct of_platform_driver axon_msi_driver = { - .match_table = axon_msi_device_id, .probe = axon_msi_probe, .shutdown = axon_msi_shutdown, - .driver = { - .name = "axon-msi" + .driver = { + .name = "axon-msi", + .owner = THIS_MODULE, + .of_match_table = axon_msi_device_id, }, }; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index c44e1b3b91db..627ee089e75d 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -301,11 +301,12 @@ MODULE_DEVICE_TABLE(of, gpio_mdio_match); static struct of_platform_driver gpio_mdio_driver = { - .match_table = gpio_mdio_match, .probe = gpio_mdio_probe, .remove = gpio_mdio_remove, - .driver = { - .name = "gpio-mdio-bitbang", + .driver = { + .name = "gpio-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = gpio_mdio_match, }, }; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88b21fccf0c9..402d2212162f 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -327,12 +327,12 @@ static struct of_device_id axon_ram_device_id[] = { }; static struct of_platform_driver axon_ram_driver = { - .match_table = axon_ram_device_id, .probe = axon_ram_probe, .remove = axon_ram_remove, - .driver = { - .owner = THIS_MODULE, - .name = AXON_RAM_MODULE_NAME, + .driver = { + .name = AXON_RAM_MODULE_NAME, + .owner = THIS_MODULE, + .of_match_table = axon_ram_device_id, }, }; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index d32d5389b67a..a7c5c470af14 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -494,14 +494,12 @@ MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match); static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = mpc52xx_bcom_of_match, .probe = mpc52xx_bcom_probe, .remove = mpc52xx_bcom_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc52xx_bcom_of_match, }, }; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 569dae8ea1ce..a7be144f5874 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -345,8 +345,11 @@ static const struct of_device_id fsl_of_msi_ids[] = { }; static struct of_platform_driver fsl_of_msi_driver = { - .name = "fsl-msi", - .match_table = fsl_of_msi_ids, + .driver = { + .name = "fsl-msi", + .owner = THIS_MODULE, + .of_match_table = fsl_of_msi_ids, + }, .probe = fsl_of_msi_probe, }; diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 2ebe817ca72f..9082eb921ad9 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -76,8 +76,11 @@ static const struct of_device_id pmc_ids[] = { }; static struct of_platform_driver pmc_driver = { - .driver.name = "fsl-pmc", - .match_table = pmc_ids, + .driver = { + .name = "fsl-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_ids, + }, .probe = pmc_probe, }; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index a98d51639243..6a1fde0d22b0 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1215,8 +1215,11 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = { }; static struct of_platform_driver fsl_of_rio_rpn_driver = { - .name = "fsl-of-rio", - .match_table = fsl_of_rio_rpn_ids, + .driver = { + .name = "fsl-of-rio", + .owner = THIS_MODULE, + .of_match_table = fsl_of_rio_rpn_ids, + }, .probe = fsl_of_rio_rpn_probe, }; diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index ff758bff1b7a..d07137a07d75 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -206,11 +206,12 @@ static int pmi_of_remove(struct of_device *dev) } static struct of_platform_driver pmi_of_platform_driver = { - .match_table = pmi_match, .probe = pmi_of_probe, .remove = pmi_of_remove, - .driver = { - .name = "pmi", + .driver = { + .name = "pmi", + .owner = THIS_MODULE, + .of_match_table = pmi_match, }, }; diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 149393c02c3f..093e0ae1a941 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -669,8 +669,11 @@ static const struct of_device_id qe_ids[] = { }; static struct of_platform_driver qe_driver = { - .driver.name = "fsl-qe", - .match_table = qe_ids, + .driver = { + .name = "fsl-qe", + .owner = THIS_MODULE, + .of_match_table = qe_ids, + }, .probe = qe_probe, .resume = qe_resume, }; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 1bb6a41b00f2..c333b8d0949b 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -232,8 +232,11 @@ static const struct of_device_id ecpp_match[] = { }; static struct of_platform_driver ecpp_driver = { - .name = "ecpp", - .match_table = ecpp_match, + .driver = { + .name = "ecpp", + .owner = THIS_MODULE, + .of_match_table = ecpp_match, + }, .probe = ecpp_probe, .remove = __devexit_p(ecpp_remove), }; diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 71ec90b9e316..b27476caa133 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -174,8 +174,11 @@ static struct of_device_id __initdata apc_match[] = { MODULE_DEVICE_TABLE(of, apc_match); static struct of_platform_driver apc_driver = { - .name = "apc", - .match_table = apc_match, + .driver = { + .name = "apc", + .owner = THIS_MODULE, + .of_match_table = apc_match, + }, .probe = apc_probe, }; diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index bd8421a26856..ddc84128b3c2 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -132,10 +132,11 @@ static int __devinit auxio_probe(struct of_device *dev, const struct of_device_i } static struct of_platform_driver auxio_driver = { - .match_table = auxio_match, .probe = auxio_probe, - .driver = { - .name = "auxio", + .driver = { + .name = "auxio", + .owner = THIS_MODULE, + .of_match_table = auxio_match, }, }; diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index d533f3d5d484..434335f65823 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -149,10 +149,11 @@ static struct of_device_id __initdata clock_board_match[] = { }; static struct of_platform_driver clock_board_driver = { - .match_table = clock_board_match, .probe = clock_board_probe, - .driver = { - .name = "clock_board", + .driver = { + .name = "clock_board", + .owner = THIS_MODULE, + .of_match_table = clock_board_match, }, }; @@ -254,10 +255,11 @@ static struct of_device_id __initdata fhc_match[] = { }; static struct of_platform_driver fhc_driver = { - .match_table = fhc_match, .probe = fhc_probe, - .driver = { - .name = "fhc", + .driver = { + .name = "fhc", + .owner = THIS_MODULE, + .of_match_table = fhc_match, }, }; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 936879639eb6..870cb65b3f21 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -811,8 +811,11 @@ static const struct of_device_id us3mc_match[] = { MODULE_DEVICE_TABLE(of, us3mc_match); static struct of_platform_driver us3mc_driver = { - .name = "us3mc", - .match_table = us3mc_match, + .driver = { + .name = "us3mc", + .owner = THIS_MODULE, + .of_match_table = us3mc_match, + }, .probe = us3mc_probe, .remove = __devexit_p(us3mc_remove), }; diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index ff844baa28e6..51cfa09e392a 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -508,8 +508,11 @@ static struct of_device_id __initdata fire_match[] = { }; static struct of_platform_driver fire_driver = { - .name = DRIVER_NAME, - .match_table = fire_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = fire_match, + }, .probe = fire_probe, }; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index e675e21c6df6..558a70512824 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -602,8 +602,11 @@ static struct of_device_id __initdata psycho_match[] = { }; static struct of_platform_driver psycho_driver = { - .name = DRIVER_NAME, - .match_table = psycho_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = psycho_match, + }, .probe = psycho_probe, }; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 5048498daade..6dad8e3b7506 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -596,8 +596,11 @@ static struct of_device_id __initdata sabre_match[] = { }; static struct of_platform_driver sabre_driver = { - .name = DRIVER_NAME, - .match_table = sabre_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = sabre_match, + }, .probe = sabre_probe, }; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 2f3f9212b063..97a1ae2e1c02 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1491,8 +1491,11 @@ static struct of_device_id __initdata schizo_match[] = { }; static struct of_platform_driver schizo_driver = { - .name = DRIVER_NAME, - .match_table = schizo_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = schizo_match, + }, .probe = schizo_probe, }; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 5c11f56cedf8..a24af6f7e17f 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1009,8 +1009,11 @@ static struct of_device_id __initdata pci_sun4v_match[] = { }; static struct of_platform_driver pci_sun4v_driver = { - .name = DRIVER_NAME, - .match_table = pci_sun4v_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = pci_sun4v_match, + }, .probe = pci_sun4v_probe, }; diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 5e4563d86f19..9589d8b9b0c1 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -79,8 +79,11 @@ static struct of_device_id __initdata pmc_match[] = { MODULE_DEVICE_TABLE(of, pmc_match); static struct of_platform_driver pmc_driver = { - .name = "pmc", - .match_table = pmc_match, + .driver = { + .name = "pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, }; diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index e3f806a7423b..168d4cb63f5b 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -60,10 +60,11 @@ static struct of_device_id __initdata power_match[] = { }; static struct of_platform_driver power_driver = { - .match_table = power_match, .probe = power_probe, - .driver = { - .name = "power", + .driver = { + .name = "power", + .owner = THIS_MODULE, + .of_match_table = power_match, }, }; diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index e0dbed9503d4..217ba275cabf 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -185,10 +185,11 @@ static struct of_device_id __initdata clock_match[] = { }; static struct of_platform_driver clock_driver = { - .match_table = clock_match, .probe = clock_probe, - .driver = { - .name = "rtc", + .driver = { + .name = "rtc", + .owner = THIS_MODULE, + .of_match_table = clock_match, }, }; diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 9099ca095641..21e9fcae0668 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -463,10 +463,11 @@ static struct of_device_id __initdata rtc_match[] = { }; static struct of_platform_driver rtc_driver = { - .match_table = rtc_match, .probe = rtc_probe, - .driver = { - .name = "rtc", + .driver = { + .name = "rtc", + .owner = THIS_MODULE, + .of_match_table = rtc_match, }, }; @@ -495,10 +496,11 @@ static struct of_device_id __initdata bq4802_match[] = { }; static struct of_platform_driver bq4802_driver = { - .match_table = bq4802_match, .probe = bq4802_probe, - .driver = { - .name = "bq4802", + .driver = { + .name = "bq4802", + .owner = THIS_MODULE, + .of_match_table = bq4802_match, }, }; @@ -558,10 +560,11 @@ static struct of_device_id __initdata mostek_match[] = { }; static struct of_platform_driver mostek_driver = { - .match_table = mostek_match, .probe = mostek_probe, - .driver = { - .name = "mostek", + .driver = { + .name = "mostek", + .owner = THIS_MODULE, + .of_match_table = mostek_match, }, }; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 4cce719add3f..88e6b6008bd6 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -884,9 +884,6 @@ static struct of_device_id mpc52xx_ata_of_match[] = { static struct of_platform_driver mpc52xx_ata_of_platform_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .match_table = mpc52xx_ata_of_match, .probe = mpc52xx_ata_probe, .remove = mpc52xx_ata_remove, #ifdef CONFIG_PM @@ -896,6 +893,7 @@ static struct of_platform_driver mpc52xx_ata_of_platform_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = mpc52xx_ata_of_match, }, }; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 19da29f011db..5a1b82c08be9 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -91,8 +91,11 @@ static struct of_device_id pata_of_platform_match[] = { MODULE_DEVICE_TABLE(of, pata_of_platform_match); static struct of_platform_driver pata_of_platform_driver = { - .name = "pata_of_platform", - .match_table = pata_of_platform_match, + .driver = { + .name = "pata_of_platform", + .owner = THIS_MODULE, + .of_match_table = pata_of_platform_match, + }, .probe = pata_of_platform_probe, .remove = __devexit_p(pata_of_platform_remove), }; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index e3339e25b152..61c89b54ea23 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1427,8 +1427,11 @@ static struct of_device_id fsl_sata_match[] = { MODULE_DEVICE_TABLE(of, fsl_sata_match); static struct of_platform_driver fsl_sata_driver = { - .name = "fsl-sata", - .match_table = fsl_sata_match, + .driver = { + .name = "fsl-sata", + .owner = THIS_MODULE, + .of_match_table = fsl_sata_match, + }, .probe = sata_fsl_probe, .remove = sata_fsl_remove, #ifdef CONFIG_PM diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 593a03a376e4..da8f176c051e 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2695,8 +2695,11 @@ static const struct of_device_id fore200e_sba_match[] = { MODULE_DEVICE_TABLE(of, fore200e_sba_match); static struct of_platform_driver fore200e_sba_driver = { - .name = "fore_200e", - .match_table = fore200e_sba_match, + .driver = { + .name = "fore_200e", + .owner = THIS_MODULE, + .of_match_table = fore200e_sba_match, + }, .probe = fore200e_sba_probe, .remove = __devexit_p(fore200e_sba_remove), }; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 3094909b0613..a7b83c0a7eb5 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1237,13 +1237,12 @@ static const struct of_device_id ace_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, ace_of_match); static struct of_platform_driver ace_of_driver = { - .owner = THIS_MODULE, - .name = "xsysace", - .match_table = ace_of_match, .probe = ace_of_probe, .remove = __devexit_p(ace_of_remove), .driver = { .name = "xsysace", + .owner = THIS_MODULE, + .of_match_table = ace_of_match, }, }; diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 0861d99cd75b..0f9cbf1aaf15 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -751,8 +751,11 @@ static const struct of_device_id n2rng_match[] = { MODULE_DEVICE_TABLE(of, n2rng_match); static struct of_platform_driver n2rng_driver = { - .name = "n2rng", - .match_table = n2rng_match, + .driver = { + .name = "n2rng", + .owner = THIS_MODULE, + .of_match_table = n2rng_match, + }, .probe = n2rng_probe, .remove = __devexit_p(n2rng_remove), }; diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index b213855bae68..261ba8f22b8b 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -140,8 +140,11 @@ static struct of_device_id rng_match[] = { }; static struct of_platform_driver rng_driver = { - .name = "pasemi-rng", - .match_table = rng_match, + .driver = { + .name = "pasemi-rng", + .owner = THIS_MODULE, + .of_match_table = rng_match, + }, .probe = rng_probe, .remove = rng_remove, }; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 2b44a0e1b988..47ffe4a90a95 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2555,8 +2555,11 @@ static struct of_device_id ipmi_match[] = }; static struct of_platform_driver ipmi_of_platform_driver = { - .name = "ipmi", - .match_table = ipmi_match, + .driver = { + .name = "ipmi", + .owner = THIS_MODULE, + .of_match_table = ipmi_match, + }, .probe = ipmi_of_probe, .remove = __devexit_p(ipmi_of_remove), }; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 5a0a31e2029c..ed8a9cec2a05 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -812,13 +812,12 @@ static const struct of_device_id __devinitconst hwicap_of_match[] = { MODULE_DEVICE_TABLE(of, hwicap_of_match); static struct of_platform_driver hwicap_of_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = hwicap_of_match, .probe = hwicap_of_probe, .remove = __devexit_p(hwicap_of_remove), .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = hwicap_of_match, }, }; diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 6c4c8b7ce3aa..9d65b371de64 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1281,8 +1281,11 @@ static const struct of_device_id crypto4xx_match[] = { }; static struct of_platform_driver crypto4xx_driver = { - .name = "crypto4xx", - .match_table = crypto4xx_match, + .driver = { + .name = "crypto4xx", + .owner = THIS_MODULE, + .of_match_table = crypto4xx_match, + }, .probe = crypto4xx_probe, .remove = crypto4xx_remove, }; diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 5a02f3482dba..7e4e42d85fe4 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1968,8 +1968,11 @@ static const struct of_device_id talitos_match[] = { MODULE_DEVICE_TABLE(of, talitos_match); static struct of_platform_driver talitos_driver = { - .name = "talitos", - .match_table = talitos_match, + .driver = { + .name = "talitos", + .owner = THIS_MODULE, + .of_match_table = talitos_match, + }, .probe = talitos_probe, .remove = talitos_remove, }; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 0e376eb37417..c3d74697f5a9 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1409,10 +1409,13 @@ static const struct of_device_id fsldma_of_ids[] = { }; static struct of_platform_driver fsldma_of_driver = { - .name = "fsl-elo-dma", - .match_table = fsldma_of_ids, - .probe = fsldma_of_probe, - .remove = fsldma_of_remove, + .driver = { + .name = "fsl-elo-dma", + .owner = THIS_MODULE, + .of_match_table = fsldma_of_ids, + }, + .probe = fsldma_of_probe, + .remove = fsldma_of_remove, }; /*----------------------------------------------------------------------------*/ diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index d44626fa35ad..a7b05447e0ab 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4949,12 +4949,12 @@ static const struct of_device_id ppc440spe_adma_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match); static struct of_platform_driver ppc440spe_adma_driver = { - .match_table = ppc440spe_adma_of_match, .probe = ppc440spe_adma_probe, .remove = __devexit_p(ppc440spe_adma_remove), .driver = { .name = "PPC440SP(E)-ADMA", .owner = THIS_MODULE, + .of_match_table = ppc440spe_adma_of_match, }, }; diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4471647b4807..6c1886b497ff 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -338,15 +338,13 @@ static struct of_device_id mpc85xx_pci_err_of_match[] = { }; static struct of_platform_driver mpc85xx_pci_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_pci_err", - .match_table = mpc85xx_pci_err_of_match, .probe = mpc85xx_pci_err_probe, .remove = __devexit_p(mpc85xx_pci_err_remove), .driver = { - .name = "mpc85xx_pci_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_pci_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_pci_err_of_match, + }, }; #endif /* CONFIG_PCI */ @@ -654,15 +652,13 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { }; static struct of_platform_driver mpc85xx_l2_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_l2_err", - .match_table = mpc85xx_l2_err_of_match, .probe = mpc85xx_l2_err_probe, .remove = mpc85xx_l2_err_remove, .driver = { - .name = "mpc85xx_l2_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_l2_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_l2_err_of_match, + }, }; /**************************** MC Err device ***************************/ @@ -1131,15 +1127,13 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { }; static struct of_platform_driver mpc85xx_mc_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_mc_err", - .match_table = mpc85xx_mc_err_of_match, .probe = mpc85xx_mc_err_probe, .remove = mpc85xx_mc_err_remove, .driver = { - .name = "mpc85xx_mc_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_mc_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_mc_err_of_match, + }, }; #ifdef CONFIG_MPC85xx diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 11f2172aa1e6..9d6f6783328c 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -202,13 +202,13 @@ static struct of_device_id ppc4xx_edac_match[] = { }; static struct of_platform_driver ppc4xx_edac_driver = { - .match_table = ppc4xx_edac_match, .probe = ppc4xx_edac_probe, .remove = ppc4xx_edac_remove, - .driver = { - .owner = THIS_MODULE, - .name = PPC4XX_EDAC_MODULE_NAME - } + .driver = { + .owner = THIS_MODULE, + .name = PPC4XX_EDAC_MODULE_NAME + .of_match_table = ppc4xx_edac_match, + }, }; /* diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 68e90abeba96..5da5942cf970 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -300,8 +300,11 @@ static const struct of_device_id env_match[] = { MODULE_DEVICE_TABLE(of, env_match); static struct of_platform_driver env_driver = { - .name = "ultra45_env", - .match_table = env_match, + .driver = { + .name = "ultra45_env", + .owner = THIS_MODULE, + .of_match_table = env_match, + }, .probe = env_probe, .remove = __devexit_p(env_remove), }; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 48d2c1a0d4ce..7637e1234142 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -718,13 +718,13 @@ static const struct of_device_id cpm_i2c_match[] = { MODULE_DEVICE_TABLE(of, cpm_i2c_match); static struct of_platform_driver cpm_i2c_driver = { - .match_table = cpm_i2c_match, .probe = cpm_i2c_probe, .remove = __devexit_p(cpm_i2c_remove), - .driver = { - .name = "fsl-i2c-cpm", - .owner = THIS_MODULE, - } + .driver = { + .name = "fsl-i2c-cpm", + .owner = THIS_MODULE, + .of_match_table = cpm_i2c_match, + }, }; static int __init cpm_i2c_init(void) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index e66dc83953c5..3876f993fe76 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -807,8 +807,11 @@ static const struct of_device_id ibm_iic_match[] = { }; static struct of_platform_driver ibm_iic_driver = { - .name = "ibm-iic", - .match_table = ibm_iic_match, + .driver = { + .name = "ibm-iic", + .owner = THIS_MODULE, + .of_match_table = ibm_iic_match, + }, .probe = iic_probe, .remove = __devexit_p(iic_remove), }; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 69473b6c260c..791b71f46f7b 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -675,12 +675,12 @@ MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); /* Structure for a device driver */ static struct of_platform_driver mpc_i2c_driver = { - .match_table = mpc_i2c_of_match, .probe = fsl_i2c_probe, .remove = __devexit_p(fsl_i2c_remove), - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = mpc_i2c_of_match, }, }; diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 26391853277f..252489e88369 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -937,12 +937,13 @@ static struct of_device_id ehca_device_table[] = MODULE_DEVICE_TABLE(of, ehca_device_table); static struct of_platform_driver ehca_driver = { - .name = "ehca", - .match_table = ehca_device_table, .probe = ehca_probe, .remove = ehca_remove, - .driver = { + .driver = { + .name = "ehca", + .owner = THIS_MODULE, .groups = ehca_drv_attr_groups, + .of_match_table = ehca_device_table, }, }; diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 0d45422f8095..1dacae4b43f0 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -259,8 +259,11 @@ static const struct of_device_id bbc_beep_match[] = { }; static struct of_platform_driver bbc_beep_driver = { - .name = "bbcbeep", - .match_table = bbc_beep_match, + .driver = { + .name = "bbcbeep", + .owner = THIS_MODULE, + .of_match_table = bbc_beep_match, + }, .probe = bbc_beep_probe, .remove = __devexit_p(bbc_remove), .shutdown = sparcspkr_shutdown, @@ -338,8 +341,11 @@ static const struct of_device_id grover_beep_match[] = { }; static struct of_platform_driver grover_beep_driver = { - .name = "groverbeep", - .match_table = grover_beep_match, + .driver = { + .name = "groverbeep", + .owner = THIS_MODULE, + .of_match_table = grover_beep_match, + }, .probe = grover_beep_probe, .remove = __devexit_p(grover_remove), .shutdown = sparcspkr_shutdown, diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 29e17698b2a4..04e32f2d1241 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -96,8 +96,11 @@ static const struct of_device_id sparc_i8042_match[] = { MODULE_DEVICE_TABLE(of, sparc_i8042_match); static struct of_platform_driver sparc_i8042_driver = { - .name = "i8042", - .match_table = sparc_i8042_match, + .driver = { + .name = "i8042", + .owner = THIS_MODULE, + .of_match_table = sparc_i8042_match, + }, .probe = sparc_i8042_probe, .remove = __devexit_p(sparc_i8042_remove), }; diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 7a288c0ef1a6..e2c028d2638f 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -362,8 +362,11 @@ static const struct of_device_id xps2_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, xps2_of_match); static struct of_platform_driver xps2_of_driver = { - .name = DRIVER_NAME, - .match_table = xps2_of_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xps2_of_match, + }, .probe = xps2_of_probe, .remove = __devexit_p(xps2_of_remove), }; diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index a77a23e783db..6d94b0b9979c 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -291,8 +291,8 @@ static struct of_platform_driver of_gpio_leds_driver = { .driver = { .name = "of_gpio_leds", .owner = THIS_MODULE, + .of_match_table = of_gpio_leds_match, }, - .match_table = of_gpio_leds_match, .probe = of_gpio_leds_probe, .remove = __devexit_p(of_gpio_leds_remove), }; diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 888448cf7f1f..ef1f3330a10e 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -671,8 +671,11 @@ static const struct of_device_id smu_platform_match[] = static struct of_platform_driver smu_of_platform_driver = { - .name = "smu", - .match_table = smu_platform_match, + .driver = { + .name = "smu", + .owner = THIS_MODULE, + .of_match_table = smu_platform_match, + }, .probe = smu_platform_probe, }; diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 9314be9a2fc8..e60605bd0ea9 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2238,8 +2238,11 @@ static const struct of_device_id fcu_match[] = static struct of_platform_driver fcu_of_platform_driver = { - .name = "temperature", - .match_table = fcu_match, + .driver = { + .name = "temperature", + .owner = THIS_MODULE, + .of_match_table = fcu_match, + }, .probe = fcu_of_probe, .remove = fcu_of_remove }; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 0839770e4ec5..5c9367acf0cf 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -463,8 +463,11 @@ static const struct of_device_id therm_of_match[] = {{ }; static struct of_platform_driver therm_of_driver = { - .name = "temperature", - .match_table = therm_of_match, + .driver = { + .name = "temperature", + .owner = THIS_MODULE, + .of_match_table = therm_of_match, + }, .probe = therm_of_probe, .remove = therm_of_remove, }; diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index dfe5ceae6794..7802a543d8fc 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -205,8 +205,11 @@ static const struct of_device_id sdhci_of_match[] = { MODULE_DEVICE_TABLE(of, sdhci_of_match); static struct of_platform_driver sdhci_of_driver = { - .driver.name = "sdhci-of", - .match_table = sdhci_of_match, + .driver = { + .name = "sdhci-of", + .owner = THIS_MODULE, + .of_match_table = sdhci_of_match, + }, .probe = sdhci_of_probe, .remove = __devexit_p(sdhci_of_remove), .suspend = sdhci_of_suspend, diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 3dc7a2fbf025..4147fe328c55 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -375,8 +375,11 @@ static struct of_device_id of_flash_match[] = { MODULE_DEVICE_TABLE(of, of_flash_match); static struct of_platform_driver of_flash_driver = { - .name = "of-flash", - .match_table = of_flash_match, + .driver = { + .name = "of-flash", + .owner = THIS_MODULE, + .of_match_table = of_flash_match, + }, .probe = of_flash_probe, .remove = of_flash_remove, }; diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 5945a23e681f..0391c2527bd7 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -149,8 +149,11 @@ static const struct of_device_id uflash_match[] = { MODULE_DEVICE_TABLE(of, uflash_match); static struct of_platform_driver uflash_driver = { - .name = DRIVER_NAME, - .match_table = uflash_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = uflash_match, + }, .probe = uflash_probe, .remove = __devexit_p(uflash_remove), }; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 4a6079588ab2..f45a8d0c1508 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -1078,9 +1078,10 @@ static const struct of_device_id fsl_elbc_match[] = { static struct of_platform_driver fsl_elbc_ctrl_driver = { .driver = { - .name = "fsl-elbc", + .name = "fsl-elbc", + .owner = THIS_MODULE, + .of_match_table = fsl_elbc_match, }, - .match_table = fsl_elbc_match, .probe = fsl_elbc_ctrl_probe, .remove = fsl_elbc_ctrl_remove, }; diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 4b96296af321..b7ab5a0ec35d 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -357,8 +357,11 @@ static struct of_device_id of_fun_match[] = { MODULE_DEVICE_TABLE(of, of_fun_match); static struct of_platform_driver of_fun_driver = { - .name = "fsl,upm-nand", - .match_table = of_fun_match, + .driver = { + .name = "fsl,upm-nand", + .owner = THIS_MODULE, + .of_match_table = of_fun_match, + }, .probe = fun_probe, .remove = __devexit_p(fun_remove), }; diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index c0e05f5ff8a4..98fd2bdf8be1 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -294,9 +294,10 @@ MODULE_DEVICE_TABLE(of, ndfc_match); static struct of_platform_driver ndfc_driver = { .driver = { - .name = "ndfc", + .name = "ndfc", + .owner = THIS_MODULE, + .of_match_table = ndfc_match, }, - .match_table = ndfc_match, .probe = ndfc_probe, .remove = __devexit_p(ndfc_remove), }; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index edfc27b78513..a97e9c95ab6a 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -221,8 +221,11 @@ MODULE_DEVICE_TABLE(of, pasemi_nand_match); static struct of_platform_driver pasemi_nand_driver = { - .name = (char*)driver_name, - .match_table = pasemi_nand_match, + .driver = { + .name = (char*)driver_name, + .owner = THIS_MODULE, + .of_match_table = pasemi_nand_match, + }, .probe = pasemi_nand_probe, .remove = pasemi_nand_remove, }; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index a4519a7bd683..edb9b1384143 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -301,8 +301,11 @@ static struct of_device_id socrates_nand_match[] = MODULE_DEVICE_TABLE(of, socrates_nand_match); static struct of_platform_driver socrates_nand_driver = { - .name = "socrates_nand", - .match_table = socrates_nand_match, + .driver = { + .name = "socrates_nand", + .owner = THIS_MODULE, + .of_match_table = socrates_nand_match, + }, .probe = socrates_nand_probe, .remove = __devexit_p(socrates_nand_remove), }; diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 03e7c48465a2..2120784f8db4 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -393,15 +393,17 @@ static struct of_device_id __devinitdata mpc5xxx_can_table[] = { }; static struct of_platform_driver mpc5xxx_can_driver = { - .owner = THIS_MODULE, - .name = "mpc5xxx_can", + .driver = { + .name = "mpc5xxx_can", + .owner = THIS_MODULE, + .of_match_table = mpc5xxx_can_table, + }, .probe = mpc5xxx_can_probe, .remove = __devexit_p(mpc5xxx_can_remove), #ifdef CONFIG_PM .suspend = mpc5xxx_can_suspend, .resume = mpc5xxx_can_resume, #endif - .match_table = mpc5xxx_can_table, }; static int __init mpc5xxx_can_init(void) diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index dc5f20cdf93c..158b76ebf3ea 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -216,11 +216,13 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = { MODULE_DEVICE_TABLE(of, sja1000_ofp_table); static struct of_platform_driver sja1000_ofp_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = sja1000_ofp_table, + }, .probe = sja1000_ofp_probe, .remove = __devexit_p(sja1000_ofp_remove), - .match_table = sja1000_ofp_table, }; static int __init sja1000_ofp_init(void) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 59dac232006c..b23173864c60 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -122,8 +122,11 @@ static struct of_device_id ehea_device_table[] = { MODULE_DEVICE_TABLE(of, ehea_device_table); static struct of_platform_driver ehea_driver = { - .name = "ehea", - .match_table = ehea_device_table, + .driver = { + .name = "ehea", + .owner = THIS_MODULE, + .of_match_table = ehea_device_table, + }, .probe = ehea_probe_adapter, .remove = ehea_remove, }; diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 3342056f8aac..be540b67ea57 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -1065,9 +1065,11 @@ static struct of_device_id mpc52xx_fec_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_match); static struct of_platform_driver mpc52xx_fec_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = mpc52xx_fec_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc52xx_fec_match, + }, .probe = mpc52xx_fec_probe, .remove = mpc52xx_fec_remove, #ifdef CONFIG_PM diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 0d099e5a652d..006f64d9f96a 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -159,10 +159,13 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match); struct of_platform_driver mpc52xx_fec_mdio_driver = { - .name = "mpc5200b-fec-phy", + .driver = { + .name = "mpc5200b-fec-phy", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_fec_mdio_match, + }, .probe = mpc52xx_fec_mdio_probe, .remove = mpc52xx_fec_mdio_remove, - .match_table = mpc52xx_fec_mdio_match, }; /* let fec driver call it, since this has to be registered before it */ diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index caeb88b67bc6..cae2d16858d1 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1158,8 +1158,11 @@ static struct of_device_id fs_enet_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_match); static struct of_platform_driver fs_enet_driver = { - .name = "fs_enet", - .match_table = fs_enet_match, + .driver = { + .owner = THIS_MODULE, + .name = "fs_enet", + .of_match_table = fs_enet_match, + }, .probe = fs_enet_probe, .remove = fs_enet_remove, }; diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 24ff9f43a62b..0f90685d3d19 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -224,8 +224,11 @@ static struct of_device_id fs_enet_mdio_bb_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match); static struct of_platform_driver fs_enet_bb_mdio_driver = { - .name = "fsl-bb-mdio", - .match_table = fs_enet_mdio_bb_match, + .driver = { + .name = "fsl-bb-mdio", + .owner = THIS_MODULE, + .of_match_table = fs_enet_mdio_bb_match, + }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index dc862e779c1f..bddffd169b93 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -222,8 +222,11 @@ static struct of_device_id fs_enet_mdio_fec_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match); static struct of_platform_driver fs_enet_fec_mdio_driver = { - .name = "fsl-fec-mdio", - .match_table = fs_enet_mdio_fec_match, + .driver = { + .name = "fsl-fec-mdio", + .owner = THIS_MODULE, + .of_match_table = fs_enet_mdio_fec_match, + }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 72489a213bf7..16508535720a 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -461,10 +461,13 @@ static struct of_device_id fsl_pq_mdio_match[] = { MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); static struct of_platform_driver fsl_pq_mdio_driver = { - .name = "fsl-pq_mdio", + .driver = { + .name = "fsl-pq_mdio", + .owner = THIS_MODULE, + .of_match_table = fsl_pq_mdio_match, + }, .probe = fsl_pq_mdio_probe, .remove = fsl_pq_mdio_remove, - .match_table = fsl_pq_mdio_match, }; int __init fsl_pq_mdio_init(void) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b71bba91064c..c3b292a31328 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -3054,14 +3054,16 @@ MODULE_DEVICE_TABLE(of, gfar_match); /* Structure for a device driver */ static struct of_platform_driver gfar_driver = { - .name = "fsl-gianfar", - .match_table = gfar_match, - + .driver = { + .name = "fsl-gianfar", + .owner = THIS_MODULE, + .pm = GFAR_PM_OPS, + .of_match_table = gfar_match, + }, .probe = gfar_probe, .remove = gfar_remove, .suspend = gfar_legacy_suspend, .resume = gfar_legacy_resume, - .driver.pm = GFAR_PM_OPS, }; static int __init gfar_init(void) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index cda2ba891344..f8c36a5eb4d7 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2996,9 +2996,11 @@ static struct of_device_id emac_match[] = MODULE_DEVICE_TABLE(of, emac_match); static struct of_platform_driver emac_driver = { - .name = "emac", - .match_table = emac_match, - + .driver = { + .name = "emac", + .owner = THIS_MODULE, + .of_match_table = emac_match, + }, .probe = emac_probe, .remove = emac_remove, }; diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index aba17947e208..fcff9e0bd382 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -790,9 +790,11 @@ static struct of_device_id mal_platform_match[] = }; static struct of_platform_driver mal_of_driver = { - .name = "mcmal", - .match_table = mal_platform_match, - + .driver = { + .name = "mcmal", + .owner = THIS_MODULE, + .of_match_table = mal_platform_match, + }, .probe = mal_probe, .remove = mal_remove, }; diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 6ab630a79e31..108919bcdf13 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -319,9 +319,11 @@ static struct of_device_id rgmii_match[] = }; static struct of_platform_driver rgmii_driver = { - .name = "emac-rgmii", - .match_table = rgmii_match, - + .driver = { + .name = "emac-rgmii", + .owner = THIS_MODULE, + .of_match_table = rgmii_match, + }, .probe = rgmii_probe, .remove = rgmii_remove, }; diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 4f64b00dd5e8..044637144c43 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -166,9 +166,11 @@ static struct of_device_id tah_match[] = }; static struct of_platform_driver tah_driver = { - .name = "emac-tah", - .match_table = tah_match, - + .driver = { + .name = "emac-tah", + .owner = THIS_MODULE, + .of_match_table = tah_match, + }, .probe = tah_probe, .remove = tah_remove, }; diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index b4fa823ed201..046dcd069c45 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -313,9 +313,11 @@ static struct of_device_id zmii_match[] = }; static struct of_platform_driver zmii_driver = { - .name = "emac-zmii", - .match_table = zmii_match, - + .driver = { + .name = "emac-zmii", + .owner = THIS_MODULE, + .of_match_table = zmii_match, + }, .probe = zmii_probe, .remove = zmii_remove, }; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 9c7395c10e44..dc318330ec79 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -955,12 +955,12 @@ static struct of_device_id temac_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, temac_of_match); static struct of_platform_driver temac_of_driver = { - .match_table = temac_of_match, .probe = temac_of_probe, .remove = __devexit_p(temac_of_remove), .driver = { .owner = THIS_MODULE, .name = "xilinx_temac", + .of_match_table = temac_of_match, }, }; diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index e21439f1e775..77835df4d013 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1161,8 +1161,11 @@ static const struct of_device_id myri_sbus_match[] = { MODULE_DEVICE_TABLE(of, myri_sbus_match); static struct of_platform_driver myri_sbus_driver = { - .name = "myri", - .match_table = myri_sbus_match, + .driver = { + .name = "myri", + .owner = THIS_MODULE, + .of_match_table = myri_sbus_match, + }, .probe = myri_sbus_probe, .remove = __devexit_p(myri_sbus_remove), }; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9c1604c04450..406d72c4eb71 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -10207,8 +10207,11 @@ static const struct of_device_id niu_match[] = { MODULE_DEVICE_TABLE(of, niu_match); static struct of_platform_driver niu_of_driver = { - .name = "niu", - .match_table = niu_match, + .driver = { + .name = "niu", + .owner = THIS_MODULE, + .of_match_table = niu_match, + }, .probe = niu_of_probe, .remove = __devexit_p(niu_of_remove), }; diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 641973ca2417..fc5fef2a8175 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -241,8 +241,11 @@ static struct of_device_id mdio_ofgpio_match[] = { MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); static struct of_platform_driver mdio_ofgpio_driver = { - .name = "mdio-gpio", - .match_table = mdio_ofgpio_match, + .driver = { + .name = "mdio-gpio", + .owner = THIS_MODULE, + .of_match_table = mdio_ofgpio_match, + }, .probe = mdio_ofgpio_probe, .remove = __devexit_p(mdio_ofgpio_remove), }; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index bd286ec5abd9..5f0ec390d6fc 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1292,8 +1292,11 @@ static const struct of_device_id bigmac_sbus_match[] = { MODULE_DEVICE_TABLE(of, bigmac_sbus_match); static struct of_platform_driver bigmac_sbus_driver = { - .name = "sunbmac", - .match_table = bigmac_sbus_match, + .driver = { + .name = "sunbmac", + .owner = THIS_MODULE, + .of_match_table = bigmac_sbus_match, + }, .probe = bigmac_sbus_probe, .remove = __devexit_p(bigmac_sbus_remove), }; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index c6463f71c916..ad2cfc5bb9e1 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3295,8 +3295,11 @@ static const struct of_device_id hme_sbus_match[] = { MODULE_DEVICE_TABLE(of, hme_sbus_match); static struct of_platform_driver hme_sbus_driver = { - .name = "hme", - .match_table = hme_sbus_match, + .driver = { + .name = "hme", + .owner = THIS_MODULE, + .of_match_table = hme_sbus_match, + }, .probe = hme_sbus_probe, .remove = __devexit_p(hme_sbus_remove), }; diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 28afc86e0694..0fc014ef9e98 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1546,8 +1546,11 @@ static const struct of_device_id sunlance_sbus_match[] = { MODULE_DEVICE_TABLE(of, sunlance_sbus_match); static struct of_platform_driver sunlance_sbus_driver = { - .name = "sunlance", - .match_table = sunlance_sbus_match, + .driver = { + .name = "sunlance", + .owner = THIS_MODULE, + .of_match_table = sunlance_sbus_match, + }, .probe = sunlance_sbus_probe, .remove = __devexit_p(sunlance_sbus_remove), }; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 9864f4fa69d5..8fe86b287e51 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -978,8 +978,11 @@ static const struct of_device_id qec_sbus_match[] = { MODULE_DEVICE_TABLE(of, qec_sbus_match); static struct of_platform_driver qec_sbus_driver = { - .name = "qec", - .match_table = qec_sbus_match, + .driver = { + .name = "qec", + .owner = THIS_MODULE, + .of_match_table = qec_sbus_match, + }, .probe = qec_sbus_probe, .remove = __devexit_p(qec_sbus_remove), }; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 88ebfc976735..0ab51037bf88 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3965,8 +3965,11 @@ static struct of_device_id ucc_geth_match[] = { MODULE_DEVICE_TABLE(of, ucc_geth_match); static struct of_platform_driver ucc_geth_driver = { - .name = DRV_NAME, - .match_table = ucc_geth_match, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = ucc_geth_match, + }, .probe = ucc_geth_probe, .remove = ucc_geth_remove, .suspend = ucc_geth_suspend, diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 3dd2416db540..67f9237237dd 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1293,8 +1293,11 @@ static struct of_device_id xemaclite_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, xemaclite_of_match); static struct of_platform_driver xemaclite_of_driver = { - .name = DRIVER_NAME, - .match_table = xemaclite_of_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xemaclite_of_match, + }, .probe = xemaclite_of_probe, .remove = __devexit_p(xemaclite_of_remove), }; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9fd7f7d0a0d1..ba402c613ede 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -385,13 +385,6 @@ int of_bus_type_init(struct bus_type *bus, const char *name) int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { - /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; - if (!drv->driver.of_match_table) - drv->driver.of_match_table = drv->match_table; drv->driver.bus = bus; /* register with core */ diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 065f229580d5..9a5b4b894161 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -382,8 +382,11 @@ static const struct of_device_id bpp_match[] = { MODULE_DEVICE_TABLE(of, bpp_match); static struct of_platform_driver bpp_sbus_driver = { - .name = "bpp", - .match_table = bpp_match, + .driver = { + .name = "bpp", + .owner = THIS_MODULE, + .of_match_table = bpp_match, + }, .probe = bpp_probe, .remove = __devexit_p(bpp_remove), }; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a22d32d71bf2..f94d8281cfb0 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -357,8 +357,11 @@ static const struct of_device_id electra_cf_match[] = { MODULE_DEVICE_TABLE(of, electra_cf_match); static struct of_platform_driver electra_cf_driver = { - .name = (char *)driver_name, - .match_table = electra_cf_match, + .driver = { + .name = (char *)driver_name, + .owner = THIS_MODULE, + .of_match_table = electra_cf_match, + }, .probe = electra_cf_probe, .remove = electra_cf_remove, }; diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 41cc954a5ffe..1a648b90b634 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1298,8 +1298,11 @@ static const struct of_device_id m8xx_pcmcia_match[] = { MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); static struct of_platform_driver m8xx_pcmcia_driver = { - .name = driver_name, - .match_table = m8xx_pcmcia_match, + .driver = { + .name = driver_name, + .owner = THIS_MODULE, + .match_table = m8xx_pcmcia_match, + }, .probe = m8xx_probe, .remove = m8xx_remove, }; diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 1543ac32b79b..8bfdd63a1fcb 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -414,8 +414,11 @@ static const struct of_device_id bbc_i2c_match[] = { MODULE_DEVICE_TABLE(of, bbc_i2c_match); static struct of_platform_driver bbc_i2c_driver = { - .name = "bbc_i2c", - .match_table = bbc_i2c_match, + .driver = { + .name = "bbc_i2c", + .owner = THIS_MODULE, + .of_match_table = bbc_i2c_match, + }, .probe = bbc_i2c_probe, .remove = __devexit_p(bbc_i2c_remove), }; diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 7fc7f34f3466..7baf1b644039 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -266,8 +266,11 @@ static const struct of_device_id d7s_match[] = { MODULE_DEVICE_TABLE(of, d7s_match); static struct of_platform_driver d7s_driver = { - .name = DRIVER_NAME, - .match_table = d7s_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = d7s_match, + }, .probe = d7s_probe, .remove = __devexit_p(d7s_remove), }; diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index a5fe20faf4f7..c8166ecf5276 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1131,8 +1131,11 @@ static const struct of_device_id envctrl_match[] = { MODULE_DEVICE_TABLE(of, envctrl_match); static struct of_platform_driver envctrl_driver = { - .name = DRIVER_NAME, - .match_table = envctrl_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = envctrl_match, + }, .probe = envctrl_probe, .remove = __devexit_p(envctrl_remove), }; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 202ff8f75afb..0427e586975f 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -207,8 +207,11 @@ static const struct of_device_id flash_match[] = { MODULE_DEVICE_TABLE(of, flash_match); static struct of_platform_driver flash_driver = { - .name = "flash", - .match_table = flash_match, + .driver = { + .name = "flash", + .owner = THIS_MODULE, + .of_match_table = flash_match, + }, .probe = flash_probe, .remove = __devexit_p(flash_remove), }; diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index acc6738aa61f..5f253665a1da 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -425,8 +425,11 @@ static const struct of_device_id uctrl_match[] = { MODULE_DEVICE_TABLE(of, uctrl_match); static struct of_platform_driver uctrl_driver = { - .name = "uctrl", - .match_table = uctrl_match, + .driver = { + .name = "uctrl", + .owner = THIS_MODULE, + .of_match_table = uctrl_match, + }, .probe = uctrl_probe, .remove = __devexit_p(uctrl_remove), }; diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 35433d23b7ce..ca5c15c779cf 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1456,8 +1456,11 @@ static const struct of_device_id qpti_match[] = { MODULE_DEVICE_TABLE(of, qpti_match); static struct of_platform_driver qpti_sbus_driver = { - .name = "qpti", - .match_table = qpti_match, + .driver = { + .name = "qpti", + .owner = THIS_MODULE, + .of_match_table = qpti_match, + }, .probe = qpti_sbus_probe, .remove = __devexit_p(qpti_sbus_remove), }; diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 151df73df475..386dd9d602b6 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -633,8 +633,11 @@ static const struct of_device_id esp_match[] = { MODULE_DEVICE_TABLE(of, esp_match); static struct of_platform_driver esp_sbus_driver = { - .name = "esp", - .match_table = esp_match, + .driver = { + .name = "esp", + .owner = THIS_MODULE, + .of_match_table = esp_match, + }, .probe = esp_sbus_probe, .remove = __devexit_p(esp_sbus_remove), }; diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index 52015d7031bb..0099b8692b60 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c @@ -584,12 +584,12 @@ static struct of_device_id __initdata apbuart_match[] = { }; static struct of_platform_driver grlib_apbuart_of_driver = { - .match_table = apbuart_match, .probe = apbuart_probe, .driver = { - .owner = THIS_MODULE, - .name = "grlib-apbuart", - }, + .owner = THIS_MODULE, + .name = "grlib-apbuart", + .of_match_table = apbuart_match, + }, }; diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 7866cdf8a754..9eb62a256e9a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1372,8 +1372,11 @@ static struct of_device_id cpm_uart_match[] = { }; static struct of_platform_driver cpm_uart_driver = { - .name = "cpm_uart", - .match_table = cpm_uart_match, + .driver = { + .name = "cpm_uart", + .owner = THIS_MODULE, + .of_match_table = cpm_uart_match, + }, .probe = cpm_uart_probe, .remove = cpm_uart_remove, }; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index cb079387c5ae..4fb32e3748c2 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1464,15 +1464,16 @@ mpc52xx_uart_of_enumerate(void) MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); static struct of_platform_driver mpc52xx_uart_of_driver = { - .match_table = mpc52xx_uart_of_match, .probe = mpc52xx_uart_of_probe, .remove = mpc52xx_uart_of_remove, #ifdef CONFIG_PM .suspend = mpc52xx_uart_of_suspend, .resume = mpc52xx_uart_of_resume, #endif - .driver = { - .name = "mpc52xx-psc-uart", + .driver = { + .name = "mpc52xx-psc-uart", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_uart_of_match, }, }; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 29539805e593..a48d9080f552 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -175,11 +175,13 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { }; static struct of_platform_driver of_platform_serial_driver = { - .owner = THIS_MODULE, - .name = "of_serial", + .driver = { + .name = "of_serial", + .owner = THIS_MODULE, + .of_match_table = of_platform_serial_table, + }, .probe = of_platform_serial_probe, .remove = of_platform_serial_remove, - .match_table = of_platform_serial_table, }; static int __init of_platform_serial_init(void) diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d1eedf13d85c..890f91742962 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -630,8 +630,11 @@ static const struct of_device_id hv_match[] = { MODULE_DEVICE_TABLE(of, hv_match); static struct of_platform_driver hv_driver = { - .name = "hv", - .match_table = hv_match, + .driver = { + .name = "hv", + .owner = THIS_MODULE, + .of_match_table = hv_match, + }, .probe = hv_probe, .remove = __devexit_p(hv_remove), }; diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 9176c41b74ad..5e81bc6b48b0 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -1093,8 +1093,11 @@ static const struct of_device_id sab_match[] = { MODULE_DEVICE_TABLE(of, sab_match); static struct of_platform_driver sab_driver = { - .name = "sab", - .match_table = sab_match, + .driver = { + .name = "sab", + .owner = THIS_MODULE, + .of_match_table = sab_match, + }, .probe = sab_probe, .remove = __devexit_p(sab_remove), }; diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index a647b2448071..234459c2f012 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1539,8 +1539,11 @@ static const struct of_device_id su_match[] = { MODULE_DEVICE_TABLE(of, su_match); static struct of_platform_driver su_driver = { - .name = "su", - .match_table = su_match, + .driver = { + .name = "su", + .owner = THIS_MODULE, + .of_match_table = su_match, + }, .probe = su_probe, .remove = __devexit_p(su_remove), }; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 20f9be8cd949..34fb8e84504f 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1491,8 +1491,11 @@ static const struct of_device_id zs_match[] = { MODULE_DEVICE_TABLE(of, zs_match); static struct of_platform_driver zs_driver = { - .name = "zs", - .match_table = zs_match, + .driver = { + .name = "zs", + .owner = THIS_MODULE, + .of_match_table = zs_match, + }, .probe = zs_probe, .remove = __devexit_p(zs_remove), }; diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 8fc2583d06ff..81073e3426e0 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -610,13 +610,12 @@ static int __devexit ulite_of_remove(struct of_device *op) } static struct of_platform_driver ulite_of_driver = { - .owner = THIS_MODULE, - .name = "uartlite", - .match_table = ulite_of_match, .probe = ulite_of_probe, .remove = __devexit_p(ulite_of_remove), .driver = { .name = "uartlite", + .owner = THIS_MODULE, + .of_match_table = ulite_of_match, }, }; diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 529890f044e2..907b06f5c447 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -1486,9 +1486,11 @@ static struct of_device_id ucc_uart_match[] = { MODULE_DEVICE_TABLE(of, ucc_uart_match); static struct of_platform_driver ucc_uart_of_driver = { - .owner = THIS_MODULE, - .name = "ucc_uart", - .match_table = ucc_uart_match, + .driver = { + .name = "ucc_uart", + .owner = THIS_MODULE, + .of_match_table = ucc_uart_match, + }, .probe = ucc_uart_probe, .remove = ucc_uart_remove, }; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7fcf28405860..7104cb739da7 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -514,14 +514,12 @@ static const struct of_device_id mpc52xx_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); static struct of_platform_driver mpc52xx_psc_spi_of_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-psc-spi", - .match_table = mpc52xx_psc_spi_of_match, .probe = mpc52xx_psc_spi_of_probe, .remove = __exit_p(mpc52xx_psc_spi_of_remove), .driver = { .name = "mpc52xx-psc-spi", .owner = THIS_MODULE, + .of_match_table = mpc52xx_psc_spi_of_match, }, }; diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index 6573233bf7c9..b1a76bff775f 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -558,9 +558,11 @@ static const struct of_device_id mpc52xx_spi_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); static struct of_platform_driver mpc52xx_spi_of_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-spi", - .match_table = mpc52xx_spi_match, + .driver = { + .name = "mpc52xx-spi", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_spi_match, + }, .probe = mpc52xx_spi_probe, .remove = __exit_p(mpc52xx_spi_remove), }; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 7572f98a419e..77ab15e330d0 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -1312,8 +1312,11 @@ static const struct of_device_id of_mpc8xxx_spi_match[] = { MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match); static struct of_platform_driver of_mpc8xxx_spi_driver = { - .name = "mpc8xxx_spi", - .match_table = of_mpc8xxx_spi_match, + .driver = { + .name = "mpc8xxx_spi", + .owner = THIS_MODULE, + .of_match_table = of_mpc8xxx_spi_match, + }, .probe = of_mpc8xxx_spi_probe, .remove = __devexit_p(of_mpc8xxx_spi_remove), }; diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 7cb5ff37f6e2..19c0b3b34fce 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -587,12 +587,12 @@ static const struct of_device_id spi_ppc4xx_of_match[] = { MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); static struct of_platform_driver spi_ppc4xx_of_driver = { - .match_table = spi_ppc4xx_of_match, .probe = spi_ppc4xx_of_probe, .remove = __exit_p(spi_ppc4xx_of_remove), .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .of_match_table = spi_ppc4xx_of_match, }, }; diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index 748d33a76d29..55c58012a028 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -109,12 +109,12 @@ static const struct of_device_id xilinx_spi_of_match[] = { MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); static struct of_platform_driver xilinx_spi_of_driver = { - .match_table = xilinx_spi_of_match, .probe = xilinx_spi_of_probe, .remove = __exit_p(xilinx_spi_of_remove), .driver = { .name = "xilinx-xps-spi", .owner = THIS_MODULE, + .of_match_table = xilinx_spi_of_match, }, }; diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 3537d51073b2..2928523268b5 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2768,8 +2768,11 @@ static const struct of_device_id qe_udc_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, qe_udc_match); static struct of_platform_driver udc_driver = { - .name = (char *)driver_name, - .match_table = qe_udc_match, + .driver = { + .name = (char *)driver_name, + .owner = THIS_MODULE, + .of_match_table = qe_udc_match, + }, .probe = qe_udc_probe, .remove = __devexit_p(qe_udc_remove), #ifdef CONFIG_PM diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ad0662354a5e..5aec92866ab3 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -274,13 +274,12 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); static struct of_platform_driver ehci_hcd_ppc_of_driver = { - .name = "ppc-of-ehci", - .match_table = ehci_hcd_ppc_of_match, .probe = ehci_hcd_ppc_of_probe, .remove = ehci_hcd_ppc_of_remove, .shutdown = ehci_hcd_ppc_of_shutdown, - .driver = { - .name = "ppc-of-ehci", - .owner = THIS_MODULE, + .driver = { + .name = "ppc-of-ehci", + .owner = THIS_MODULE, + .of_match_table = ehci_hcd_ppc_of_match, }, }; diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index f603bb2c0a8e..013972bbde57 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -288,13 +288,12 @@ static const struct of_device_id ehci_hcd_xilinx_of_match[] = { MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match); static struct of_platform_driver ehci_hcd_xilinx_of_driver = { - .name = "xilinx-of-ehci", - .match_table = ehci_hcd_xilinx_of_match, .probe = ehci_hcd_xilinx_of_probe, .remove = ehci_hcd_xilinx_of_remove, .shutdown = ehci_hcd_xilinx_of_shutdown, - .driver = { - .name = "xilinx-of-ehci", - .owner = THIS_MODULE, + .driver = { + .name = "xilinx-of-ehci", + .owner = THIS_MODULE, + .of_match_table = ehci_hcd_xilinx_of_match, }, }; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 6135732d8057..7b5c62654bfd 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -813,8 +813,11 @@ static const struct of_device_id of_fhci_match[] = { MODULE_DEVICE_TABLE(of, of_fhci_match); static struct of_platform_driver of_fhci_driver = { - .name = "fsl,usb-fhci", - .match_table = of_fhci_match, + .driver = { + .name = "fsl,usb-fhci", + .owner = THIS_MODULE, + .of_match_table = of_fhci_match, + }, .probe = of_fhci_probe, .remove = __devexit_p(of_fhci_remove), }; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 36360e24a9b9..100d5faebe3c 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -121,8 +121,11 @@ static const struct of_device_id of_isp1760_match[] = { MODULE_DEVICE_TABLE(of, of_isp1760_match); static struct of_platform_driver isp1760_of_driver = { - .name = "nxp-isp1760", - .match_table = of_isp1760_match, + .driver = { + .name = "nxp-isp1760", + .owner = THIS_MODULE, + .of_match_table = of_isp1760_match, + }, .probe = of_isp1760_probe, .remove = of_isp1760_remove, }; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 003aea21c35e..df165917412a 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -244,18 +244,13 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); static struct of_platform_driver ohci_hcd_ppc_of_driver = { - .name = "ppc-of-ohci", - .match_table = ohci_hcd_ppc_of_match, .probe = ohci_hcd_ppc_of_probe, .remove = ohci_hcd_ppc_of_remove, .shutdown = ohci_hcd_ppc_of_shutdown, -#ifdef CONFIG_PM - /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ - /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ -#endif - .driver = { - .name = "ppc-of-ohci", - .owner = THIS_MODULE, + .driver = { + .name = "ppc-of-ohci", + .owner = THIS_MODULE, + .of_match_table = ohci_hcd_ppc_of_match, }, }; diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 43320925c4ce..2c371c07f0da 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -376,8 +376,11 @@ static const struct of_device_id bw2_match[] = { MODULE_DEVICE_TABLE(of, bw2_match); static struct of_platform_driver bw2_driver = { - .name = "bw2", - .match_table = bw2_match, + .driver = { + .name = "bw2", + .owner = THIS_MODULE, + .of_match_table = bw2_match, + }, .probe = bw2_probe, .remove = __devexit_p(bw2_remove), }; diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 77a040af20a7..d12e05b6e63f 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -596,8 +596,11 @@ static const struct of_device_id cg14_match[] = { MODULE_DEVICE_TABLE(of, cg14_match); static struct of_platform_driver cg14_driver = { - .name = "cg14", - .match_table = cg14_match, + .driver = { + .name = "cg14", + .owner = THIS_MODULE, + .of_match_table = cg14_match, + }, .probe = cg14_probe, .remove = __devexit_p(cg14_remove), }; diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 30eedf79322c..b98f93f7f663 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -463,8 +463,11 @@ static const struct of_device_id cg3_match[] = { MODULE_DEVICE_TABLE(of, cg3_match); static struct of_platform_driver cg3_driver = { - .name = "cg3", - .match_table = cg3_match, + .driver = { + .name = "cg3", + .owner = THIS_MODULE, + .of_match_table = cg3_match, + }, .probe = cg3_probe, .remove = __devexit_p(cg3_remove), }; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 7f59b0fe5dc2..480d761a27a8 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -856,8 +856,11 @@ static const struct of_device_id cg6_match[] = { MODULE_DEVICE_TABLE(of, cg6_match); static struct of_platform_driver cg6_driver = { - .name = "cg6", - .match_table = cg6_match, + .driver = { + .name = "cg6", + .owner = THIS_MODULE, + .of_match_table = cg6_match, + }, .probe = cg6_probe, .remove = __devexit_p(cg6_remove), }; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index ddd46f71e250..95c0227f47fc 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -1053,8 +1053,11 @@ static const struct of_device_id ffb_match[] = { MODULE_DEVICE_TABLE(of, ffb_match); static struct of_platform_driver ffb_driver = { - .name = "ffb", - .match_table = ffb_match, + .driver = { + .name = "ffb", + .owner = THIS_MODULE, + .of_match_table = ffb_match, + }, .probe = ffb_probe, .remove = __devexit_p(ffb_remove), }; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 930a2522a631..27455ce298b7 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1647,9 +1647,11 @@ static struct of_device_id fsl_diu_match[] = { MODULE_DEVICE_TABLE(of, fsl_diu_match); static struct of_platform_driver fsl_diu_driver = { - .owner = THIS_MODULE, - .name = "fsl_diu", - .match_table = fsl_diu_match, + .driver = { + .name = "fsl_diu", + .owner = THIS_MODULE, + .of_match_table = fsl_diu_match, + }, .probe = fsl_diu_probe, .remove = fsl_diu_remove, .suspend = fsl_diu_suspend, diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 1db55f128490..3d7895316eaf 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -663,8 +663,11 @@ static const struct of_device_id leo_match[] = { MODULE_DEVICE_TABLE(of, leo_match); static struct of_platform_driver leo_driver = { - .name = "leo", - .match_table = leo_match, + .driver = { + .name = "leo", + .owner = THIS_MODULE, + .of_match_table = leo_match, + }, .probe = leo_probe, .remove = __devexit_p(leo_remove), }; diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index 8280a58a0e55..0540de4f5cb4 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c @@ -718,9 +718,11 @@ static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { }; static struct of_platform_driver of_platform_mb862xxfb_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .match_table = of_platform_mb862xx_tbl, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_platform_mb862xx_tbl, + }, .probe = of_platform_mb862xx_probe, .remove = __devexit_p(of_platform_mb862xx_remove), }; diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 81440f2b9091..c85dd408a9b8 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -353,8 +353,11 @@ static const struct of_device_id p9100_match[] = { MODULE_DEVICE_TABLE(of, p9100_match); static struct of_platform_driver p9100_driver = { - .name = "p9100", - .match_table = p9100_match, + .driver = { + .name = "p9100", + .owner = THIS_MODULE, + .of_match_table = p9100_match, + }, .probe = p9100_probe, .remove = __devexit_p(p9100_remove), }; diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 69d78d50f0f6..72a1f4c04732 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -679,8 +679,11 @@ static struct of_device_id platinumfb_match[] = static struct of_platform_driver platinum_driver = { - .name = "platinumfb", - .match_table = platinumfb_match, + .driver = { + .name = "platinumfb", + .owner = THIS_MODULE, + .of_match_table = platinumfb_match, + }, .probe = platinumfb_probe, .remove = platinumfb_remove, }; diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index ad92a200fafa..489b44e8db81 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -199,10 +199,13 @@ static const struct of_device_id gfb_match[] = { MODULE_DEVICE_TABLE(of, ffb_match); static struct of_platform_driver gfb_driver = { - .name = "gfb", - .match_table = gfb_match, .probe = gfb_probe, .remove = __devexit_p(gfb_remove), + .driver = { + .name = "gfb", + .owner = THIS_MODULE, + .of_match_table = gfb_match, + }, }; static int __init gfb_init(void) diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index c0c2b18fcdcf..ef7a7bd8b503 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -512,8 +512,11 @@ static const struct of_device_id tcx_match[] = { MODULE_DEVICE_TABLE(of, tcx_match); static struct of_platform_driver tcx_driver = { - .name = "tcx", - .match_table = tcx_match, + .driver = { + .name = "tcx", + .owner = THIS_MODULE, + .of_match_table = tcx_match, + }, .probe = tcx_probe, .remove = __devexit_p(tcx_remove), }; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6fcec553662c..574dc54e12d4 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -492,13 +492,12 @@ static struct of_device_id xilinxfb_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, xilinxfb_of_match); static struct of_platform_driver xilinxfb_of_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = xilinxfb_of_match, .probe = xilinxfb_of_probe, .remove = __devexit_p(xilinxfb_of_remove), .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xilinxfb_of_match, }, }; diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 2fcc3cf7ef62..d62b9ce8f773 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -677,8 +677,11 @@ static const struct of_device_id cpwd_match[] = { MODULE_DEVICE_TABLE(of, cpwd_match); static struct of_platform_driver cpwd_driver = { - .name = DRIVER_NAME, - .match_table = cpwd_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = cpwd_match, + }, .probe = cpwd_probe, .remove = __devexit_p(cpwd_remove), }; diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index abdbad034a6c..ca0f4c6cf5ab 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -303,9 +303,11 @@ static const struct of_device_id gef_wdt_ids[] = { }; static struct of_platform_driver gef_wdt_driver = { - .owner = THIS_MODULE, - .name = "gef_wdt", - .match_table = gef_wdt_ids, + .driver = { + .name = "gef_wdt", + .owner = THIS_MODULE, + .of_match_table = gef_wdt_ids, + }, .probe = gef_wdt_probe, }; diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 4e3941c5e293..7b55974191dd 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -273,12 +273,12 @@ static const struct of_device_id mpc8xxx_wdt_match[] = { MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); static struct of_platform_driver mpc8xxx_wdt_driver = { - .match_table = mpc8xxx_wdt_match, .probe = mpc8xxx_wdt_probe, .remove = __devexit_p(mpc8xxx_wdt_remove), - .driver = { - .name = "mpc8xxx_wdt", - .owner = THIS_MODULE, + .driver = { + .name = "mpc8xxx_wdt", + .owner = THIS_MODULE, + .of_match_table = mpc8xxx_wdt_match, }, }; diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index ea7f803f6248..5dceeddc8859 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -239,8 +239,11 @@ static const struct of_device_id riowd_match[] = { MODULE_DEVICE_TABLE(of, riowd_match); static struct of_platform_driver riowd_driver = { - .name = DRIVER_NAME, - .match_table = riowd_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = riowd_match, + }, .probe = riowd_probe, .remove = __devexit_p(riowd_remove), }; diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index ac3ae0758fbe..1643d3761eb4 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -31,10 +31,6 @@ extern struct bus_type of_platform_bus_type; */ struct of_platform_driver { - const char *name; - const struct of_device_id *match_table; - struct module *owner; - int (*probe)(struct of_device* dev, const struct of_device_id *match); int (*remove)(struct of_device* dev); diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 3dbc7f7cd7b9..e2ee220bfb7e 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -317,12 +317,12 @@ static struct of_device_id psc_ac97_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, psc_ac97_match); static struct of_platform_driver psc_ac97_driver = { - .match_table = psc_ac97_match, .probe = psc_ac97_of_probe, .remove = __devexit_p(psc_ac97_of_remove), .driver = { .name = "mpc5200-psc-ac97", .owner = THIS_MODULE, + .of_match_table = psc_ac97_match, }, }; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 748cc0f0df38..4f455bd6851f 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -220,12 +220,12 @@ static struct of_device_id psc_i2s_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, psc_i2s_match); static struct of_platform_driver psc_i2s_driver = { - .match_table = psc_i2s_match, .probe = psc_i2s_of_probe, .remove = __devexit_p(psc_i2s_of_remove), .driver = { .name = "mpc5200-psc-i2s", .owner = THIS_MODULE, + .of_match_table = psc_i2s_match, }, }; diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index e3f78f255a60..6a2764ee8203 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -580,9 +580,11 @@ static struct of_device_id mpc8610_hpcd_match[] = { MODULE_DEVICE_TABLE(of, mpc8610_hpcd_match); static struct of_platform_driver mpc8610_hpcd_of_driver = { - .owner = THIS_MODULE, - .name = "mpc8610_hpcd", - .match_table = mpc8610_hpcd_match, + .driver = { + .name = "mpc8610_hpcd", + .owner = THIS_MODULE, + .of_match_table = mpc8610_hpcd_match, + }, .probe = mpc8610_hpcd_probe, .remove = mpc8610_hpcd_remove, }; diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 574af56ba8a6..71221fd20944 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1065,8 +1065,11 @@ static const struct of_device_id amd7930_match[] = { }; static struct of_platform_driver amd7930_sbus_driver = { - .name = "audio", - .match_table = amd7930_match, + .driver = { + .name = "audio", + .owner = THIS_MODULE, + .of_match_table = amd7930_match, + }, .probe = amd7930_sbus_probe, }; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 6a4c872e00df..fb4c6f2f29e5 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2109,8 +2109,11 @@ static const struct of_device_id cs4231_match[] = { MODULE_DEVICE_TABLE(of, cs4231_match); static struct of_platform_driver cs4231_driver = { - .name = "audio", - .match_table = cs4231_match, + .driver = { + .name = "audio", + .owner = THIS_MODULE, + .of_match_table = cs4231_match, + }, .probe = cs4231_probe, .remove = __devexit_p(cs4231_remove), }; diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 1b5192eb5ae5..1557bf132e73 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2687,8 +2687,11 @@ static const struct of_device_id dbri_match[] = { MODULE_DEVICE_TABLE(of, dbri_match); static struct of_platform_driver dbri_sbus_driver = { - .name = "dbri", - .match_table = dbri_match, + .driver = { + .name = "dbri", + .owner = THIS_MODULE, + .of_match_table = dbri_match, + }, .probe = dbri_probe, .remove = __devexit_p(dbri_remove), }; -- cgit v1.2.3 From 7a5c106a0e8fd03a806d0da77eef10b4045c43a6 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 21 May 2010 15:28:51 +0000 Subject: sh: prevent the DMA driver from unloading, while in use This prevents the driver from unloading, while it is in use. Unloading of the driver, while its DMA channels are held, leads to a kernel Oops. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/dma/shdma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/dma') diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index a1727522343e..427d514796dd 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -1188,6 +1188,7 @@ static struct platform_driver sh_dmae_driver = { .remove = __exit_p(sh_dmae_remove), .shutdown = sh_dmae_shutdown, .driver = { + .owner = THIS_MODULE, .name = "sh-dma-engine", }, }; -- cgit v1.2.3 From 9255f1deec151ac0e84871d06bc27406cb81f26f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 21 May 2010 15:30:12 +0000 Subject: sh: guard cookie consistency across termination in the DMA driver If all descriptors on a channel are terminated or the channel is released, update the completed cookie counter to match the last cookie. This prevents inconsistency warning on resumed DMA operation. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/dma/shdma.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/dma') diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 427d514796dd..a2a519fd2a24 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -722,6 +722,10 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) { while (__ld_cleanup(sh_chan, all)) ; + + if (all) + /* Terminating - forgive uncompleted cookies */ + sh_chan->completed_cookie = sh_chan->common.cookie; } static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) -- cgit v1.2.3 From b3040e40675ec2c43542331cd30d4ee3dae797e8 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Sun, 23 May 2010 20:28:19 -0700 Subject: DMA: PL330: Add dma api driver Add DMA Engine API driver for the PL330 DMAC. This driver is supposed to be reusable by various platforms that have one or more PL330 DMACs. Atm, DMA_SLAVE and DMA_MEMCPY capabilities have been implemented. Signed-off-by: Jassi Brar Reviewed-by: Linus Walleij [dan.j.williams@intel.com: missing slab.h and ->device_control() fixups] Signed-off-by: Dan Williams --- drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/pl330.c | 866 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/amba/pl330.h | 45 +++ 4 files changed, 921 insertions(+) create mode 100644 drivers/dma/pl330.c create mode 100644 include/linux/amba/pl330.h (limited to 'drivers/dma') diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 1b8877922fb0..9e01e96fee94 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -166,6 +166,15 @@ config TIMB_DMA config ARCH_HAS_ASYNC_TX_FIND_CHANNEL bool +config PL330_DMA + tristate "DMA API Driver for PL330" + select DMA_ENGINE + depends on PL330 + help + Select if your platform has one or more PL330 DMACs. + You need to provide platform specific settings via + platform_data for a dma-pl330 device. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 20881426c1ac..0fe5ebbfda5d 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ obj-$(CONFIG_TIMB_DMA) += timb_dma.o obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o +obj-$(CONFIG_PL330_DMA) += pl330.o diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c new file mode 100644 index 000000000000..7c50f6dfd3f4 --- /dev/null +++ b/drivers/dma/pl330.c @@ -0,0 +1,866 @@ +/* linux/drivers/dma/pl330.c + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NR_DEFAULT_DESC 16 + +enum desc_status { + /* In the DMAC pool */ + FREE, + /* + * Allocted to some channel during prep_xxx + * Also may be sitting on the work_list. + */ + PREP, + /* + * Sitting on the work_list and already submitted + * to the PL330 core. Not more than two descriptors + * of a channel can be BUSY at any time. + */ + BUSY, + /* + * Sitting on the channel work_list but xfer done + * by PL330 core + */ + DONE, +}; + +struct dma_pl330_chan { + /* Schedule desc completion */ + struct tasklet_struct task; + + /* DMA-Engine Channel */ + struct dma_chan chan; + + /* Last completed cookie */ + dma_cookie_t completed; + + /* List of to be xfered descriptors */ + struct list_head work_list; + + /* Pointer to the DMAC that manages this channel, + * NULL if the channel is available to be acquired. + * As the parent, this DMAC also provides descriptors + * to the channel. + */ + struct dma_pl330_dmac *dmac; + + /* To protect channel manipulation */ + spinlock_t lock; + + /* Token of a hardware channel thread of PL330 DMAC + * NULL if the channel is available to be acquired. + */ + void *pl330_chid; +}; + +struct dma_pl330_dmac { + struct pl330_info pif; + + /* DMA-Engine Device */ + struct dma_device ddma; + + /* Pool of descriptors available for the DMAC's channels */ + struct list_head desc_pool; + /* To protect desc_pool manipulation */ + spinlock_t pool_lock; + + /* Peripheral channels connected to this DMAC */ + struct dma_pl330_chan peripherals[0]; /* keep at end */ +}; + +struct dma_pl330_desc { + /* To attach to a queue as child */ + struct list_head node; + + /* Descriptor for the DMA Engine API */ + struct dma_async_tx_descriptor txd; + + /* Xfer for PL330 core */ + struct pl330_xfer px; + + struct pl330_reqcfg rqcfg; + struct pl330_req req; + + enum desc_status status; + + /* The channel which currently holds this desc */ + struct dma_pl330_chan *pchan; +}; + +static inline struct dma_pl330_chan * +to_pchan(struct dma_chan *ch) +{ + if (!ch) + return NULL; + + return container_of(ch, struct dma_pl330_chan, chan); +} + +static inline struct dma_pl330_desc * +to_desc(struct dma_async_tx_descriptor *tx) +{ + return container_of(tx, struct dma_pl330_desc, txd); +} + +static inline void free_desc_list(struct list_head *list) +{ + struct dma_pl330_dmac *pdmac; + struct dma_pl330_desc *desc; + struct dma_pl330_chan *pch; + unsigned long flags; + + if (list_empty(list)) + return; + + /* Finish off the work list */ + list_for_each_entry(desc, list, node) { + dma_async_tx_callback callback; + void *param; + + /* All desc in a list belong to same channel */ + pch = desc->pchan; + callback = desc->txd.callback; + param = desc->txd.callback_param; + + if (callback) + callback(param); + + desc->pchan = NULL; + } + + pdmac = pch->dmac; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + list_splice_tail_init(list, &pdmac->desc_pool); + spin_unlock_irqrestore(&pdmac->pool_lock, flags); +} + +static inline void fill_queue(struct dma_pl330_chan *pch) +{ + struct dma_pl330_desc *desc; + int ret; + + list_for_each_entry(desc, &pch->work_list, node) { + + /* If already submitted */ + if (desc->status == BUSY) + break; + + ret = pl330_submit_req(pch->pl330_chid, + &desc->req); + if (!ret) { + desc->status = BUSY; + break; + } else if (ret == -EAGAIN) { + /* QFull or DMAC Dying */ + break; + } else { + /* Unacceptable request */ + desc->status = DONE; + dev_err(pch->dmac->pif.dev, "%s:%d Bad Desc(%d)\n", + __func__, __LINE__, desc->txd.cookie); + tasklet_schedule(&pch->task); + } + } +} + +static void pl330_tasklet(unsigned long data) +{ + struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; + struct dma_pl330_desc *desc, *_dt; + unsigned long flags; + LIST_HEAD(list); + + spin_lock_irqsave(&pch->lock, flags); + + /* Pick up ripe tomatoes */ + list_for_each_entry_safe(desc, _dt, &pch->work_list, node) + if (desc->status == DONE) { + pch->completed = desc->txd.cookie; + list_move_tail(&desc->node, &list); + } + + /* Try to submit a req imm. next to the last completed cookie */ + fill_queue(pch); + + /* Make sure the PL330 Channel thread is active */ + pl330_chan_ctrl(pch->pl330_chid, PL330_OP_START); + + spin_unlock_irqrestore(&pch->lock, flags); + + free_desc_list(&list); +} + +static void dma_pl330_rqcb(void *token, enum pl330_op_err err) +{ + struct dma_pl330_desc *desc = token; + struct dma_pl330_chan *pch = desc->pchan; + unsigned long flags; + + /* If desc aborted */ + if (!pch) + return; + + spin_lock_irqsave(&pch->lock, flags); + + desc->status = DONE; + + spin_unlock_irqrestore(&pch->lock, flags); + + tasklet_schedule(&pch->task); +} + +static int pl330_alloc_chan_resources(struct dma_chan *chan) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct dma_pl330_dmac *pdmac = pch->dmac; + unsigned long flags; + + spin_lock_irqsave(&pch->lock, flags); + + pch->completed = chan->cookie = 1; + + pch->pl330_chid = pl330_request_channel(&pdmac->pif); + if (!pch->pl330_chid) { + spin_unlock_irqrestore(&pch->lock, flags); + return 0; + } + + tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch); + + spin_unlock_irqrestore(&pch->lock, flags); + + return 1; +} + +static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct dma_pl330_desc *desc; + unsigned long flags; + + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + + spin_lock_irqsave(&pch->lock, flags); + + /* FLUSH the PL330 Channel thread */ + pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH); + + /* Mark all desc done */ + list_for_each_entry(desc, &pch->work_list, node) + desc->status = DONE; + + spin_unlock_irqrestore(&pch->lock, flags); + + pl330_tasklet((unsigned long) pch); + + return 0; +} + +static void pl330_free_chan_resources(struct dma_chan *chan) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + unsigned long flags; + + spin_lock_irqsave(&pch->lock, flags); + + tasklet_kill(&pch->task); + + pl330_release_channel(pch->pl330_chid); + pch->pl330_chid = NULL; + + spin_unlock_irqrestore(&pch->lock, flags); +} + +static enum dma_status +pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + dma_cookie_t last_done, last_used; + int ret; + + last_done = pch->completed; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_done, last_used); + + dma_set_tx_state(txstate, last_done, last_used, 0); + + return ret; +} + +static void pl330_issue_pending(struct dma_chan *chan) +{ + pl330_tasklet((unsigned long) to_pchan(chan)); +} + +/* + * We returned the last one of the circular list of descriptor(s) + * from prep_xxx, so the argument to submit corresponds to the last + * descriptor of the list. + */ +static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct dma_pl330_desc *desc, *last = to_desc(tx); + struct dma_pl330_chan *pch = to_pchan(tx->chan); + dma_cookie_t cookie; + unsigned long flags; + + spin_lock_irqsave(&pch->lock, flags); + + /* Assign cookies to all nodes */ + cookie = tx->chan->cookie; + + while (!list_empty(&last->node)) { + desc = list_entry(last->node.next, struct dma_pl330_desc, node); + + if (++cookie < 0) + cookie = 1; + desc->txd.cookie = cookie; + + list_move_tail(&desc->node, &pch->work_list); + } + + if (++cookie < 0) + cookie = 1; + last->txd.cookie = cookie; + + list_add_tail(&last->node, &pch->work_list); + + tx->chan->cookie = cookie; + + spin_unlock_irqrestore(&pch->lock, flags); + + return cookie; +} + +static inline void _init_desc(struct dma_pl330_desc *desc) +{ + desc->pchan = NULL; + desc->req.x = &desc->px; + desc->req.token = desc; + desc->rqcfg.swap = SWAP_NO; + desc->rqcfg.privileged = 0; + desc->rqcfg.insnaccess = 0; + desc->rqcfg.scctl = SCCTRL0; + desc->rqcfg.dcctl = DCCTRL0; + desc->req.cfg = &desc->rqcfg; + desc->req.xfer_cb = dma_pl330_rqcb; + desc->txd.tx_submit = pl330_tx_submit; + + INIT_LIST_HEAD(&desc->node); +} + +/* Returns the number of descriptors added to the DMAC pool */ +int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +{ + struct dma_pl330_desc *desc; + unsigned long flags; + int i; + + if (!pdmac) + return 0; + + desc = kmalloc(count * sizeof(*desc), flg); + if (!desc) + return 0; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + + for (i = 0; i < count; i++) { + _init_desc(&desc[i]); + list_add_tail(&desc[i].node, &pdmac->desc_pool); + } + + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + + return count; +} + +static struct dma_pl330_desc * +pluck_desc(struct dma_pl330_dmac *pdmac) +{ + struct dma_pl330_desc *desc = NULL; + unsigned long flags; + + if (!pdmac) + return NULL; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + + if (!list_empty(&pdmac->desc_pool)) { + desc = list_entry(pdmac->desc_pool.next, + struct dma_pl330_desc, node); + + list_del_init(&desc->node); + + desc->status = PREP; + desc->txd.callback = NULL; + } + + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + + return desc; +} + +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; + struct dma_pl330_desc *desc; + + /* Pluck one desc from the pool of DMAC */ + desc = pluck_desc(pdmac); + + /* If the DMAC pool is empty, alloc new */ + if (!desc) { + if (!add_desc(pdmac, GFP_ATOMIC, 1)) + return NULL; + + /* Try again */ + desc = pluck_desc(pdmac); + if (!desc) { + dev_err(pch->dmac->pif.dev, + "%s:%d ALERT!\n", __func__, __LINE__); + return NULL; + } + } + + /* Initialize the descriptor */ + desc->pchan = pch; + desc->txd.cookie = 0; + async_tx_ack(&desc->txd); + + desc->req.rqtype = peri->rqtype; + desc->req.peri = peri->peri_id; + + dma_async_tx_descriptor_init(&desc->txd, &pch->chan); + + return desc; +} + +static inline void fill_px(struct pl330_xfer *px, + dma_addr_t dst, dma_addr_t src, size_t len) +{ + px->next = NULL; + px->bytes = len; + px->dst_addr = dst; + px->src_addr = src; +} + +static struct dma_pl330_desc * +__pl330_prep_dma_memcpy(struct dma_pl330_chan *pch, dma_addr_t dst, + dma_addr_t src, size_t len) +{ + struct dma_pl330_desc *desc = pl330_get_desc(pch); + + if (!desc) { + dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n", + __func__, __LINE__); + return NULL; + } + + /* + * Ideally we should lookout for reqs bigger than + * those that can be programmed with 256 bytes of + * MC buffer, but considering a req size is seldom + * going to be word-unaligned and more than 200MB, + * we take it easy. + * Also, should the limit is reached we'd rather + * have the platform increase MC buffer size than + * complicating this API driver. + */ + fill_px(&desc->px, dst, src, len); + + return desc; +} + +/* Call after fixing burst size */ +static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) +{ + struct dma_pl330_chan *pch = desc->pchan; + struct pl330_info *pi = &pch->dmac->pif; + int burst_len; + + burst_len = pi->pcfg.data_bus_width / 8; + burst_len *= pi->pcfg.data_buf_dep; + burst_len >>= desc->rqcfg.brst_size; + + /* src/dst_burst_len can't be more than 16 */ + if (burst_len > 16) + burst_len = 16; + + while (burst_len > 1) { + if (!(len % (burst_len << desc->rqcfg.brst_size))) + break; + burst_len--; + } + + return burst_len; +} + +static struct dma_async_tx_descriptor * +pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, + dma_addr_t src, size_t len, unsigned long flags) +{ + 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 || !peri)) + return NULL; + + if (peri->rqtype != MEMTOMEM) + return NULL; + + pi = &pch->dmac->pif; + + desc = __pl330_prep_dma_memcpy(pch, dst, src, len); + if (!desc) + return NULL; + + desc->rqcfg.src_inc = 1; + desc->rqcfg.dst_inc = 1; + + /* Select max possible burst size */ + burst = pi->pcfg.data_bus_width / 8; + + while (burst > 1) { + if (!(len % burst)) + break; + burst /= 2; + } + + desc->rqcfg.brst_size = 0; + while (burst != (1 << desc->rqcfg.brst_size)) + desc->rqcfg.brst_size++; + + desc->rqcfg.brst_len = get_burst_len(desc, len); + + desc->txd.flags = flags; + + return &desc->txd; +} + +static struct dma_async_tx_descriptor * +pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_data_direction direction, + unsigned long flg) +{ + 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, burst_size; + dma_addr_t addr; + + 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 = peri->fifo_addr; + burst_size = peri->burst_sz; + + first = NULL; + + for_each_sg(sgl, sg, sg_len, i) { + + desc = pl330_get_desc(pch); + if (!desc) { + struct dma_pl330_dmac *pdmac = pch->dmac; + + dev_err(pch->dmac->pif.dev, + "%s:%d Unable to fetch desc\n", + __func__, __LINE__); + if (!first) + return NULL; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + + while (!list_empty(&first->node)) { + desc = list_entry(first->node.next, + struct dma_pl330_desc, node); + list_move_tail(&desc->node, &pdmac->desc_pool); + } + + list_move_tail(&first->node, &pdmac->desc_pool); + + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + + return NULL; + } + + if (!first) + first = desc; + else + list_add_tail(&desc->node, &first->node); + + if (direction == DMA_TO_DEVICE) { + desc->rqcfg.src_inc = 1; + desc->rqcfg.dst_inc = 0; + fill_px(&desc->px, + addr, sg_dma_address(sg), sg_dma_len(sg)); + } else { + desc->rqcfg.src_inc = 0; + desc->rqcfg.dst_inc = 1; + fill_px(&desc->px, + sg_dma_address(sg), addr, sg_dma_len(sg)); + } + + desc->rqcfg.brst_size = burst_size; + desc->rqcfg.brst_len = 1; + } + + /* Return the last desc in the chain */ + desc->txd.flags = flg; + return &desc->txd; +} + +static irqreturn_t pl330_irq_handler(int irq, void *data) +{ + if (pl330_update(data)) + return IRQ_HANDLED; + else + return IRQ_NONE; +} + +static int __devinit +pl330_probe(struct amba_device *adev, struct amba_id *id) +{ + struct dma_pl330_platdata *pdat; + struct dma_pl330_dmac *pdmac; + struct dma_pl330_chan *pch; + struct pl330_info *pi; + struct dma_device *pd; + struct resource *res; + int i, ret, irq; + + pdat = adev->dev.platform_data; + + if (!pdat || !pdat->nr_valid_peri) { + dev_err(&adev->dev, "platform data missing\n"); + return -ENODEV; + } + + /* Allocate a new DMAC and its Channels */ + pdmac = kzalloc(pdat->nr_valid_peri * sizeof(*pch) + + sizeof(*pdmac), GFP_KERNEL); + if (!pdmac) { + dev_err(&adev->dev, "unable to allocate mem\n"); + return -ENOMEM; + } + + pi = &pdmac->pif; + pi->dev = &adev->dev; + pi->pl330_data = NULL; + pi->mcbufsz = pdat->mcbuf_sz; + + res = &adev->res; + request_mem_region(res->start, resource_size(res), "dma-pl330"); + + pi->base = ioremap(res->start, resource_size(res)); + if (!pi->base) { + ret = -ENXIO; + goto probe_err1; + } + + irq = adev->irq[0]; + ret = request_irq(irq, pl330_irq_handler, 0, + dev_name(&adev->dev), pi); + if (ret) + goto probe_err2; + + ret = pl330_add(pi); + if (ret) + goto probe_err3; + + INIT_LIST_HEAD(&pdmac->desc_pool); + spin_lock_init(&pdmac->pool_lock); + + /* Create a descriptor pool of default size */ + if (!add_desc(pdmac, GFP_KERNEL, NR_DEFAULT_DESC)) + dev_warn(&adev->dev, "unable to allocate desc\n"); + + pd = &pdmac->ddma; + INIT_LIST_HEAD(&pd->channels); + + /* Initialize channel parameters */ + for (i = 0; i < pdat->nr_valid_peri; i++) { + struct dma_pl330_peri *peri = &pdat->peri[i]; + pch = &pdmac->peripherals[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); + break; + default: + dev_err(&adev->dev, "DEVTODEV Not Supported\n"); + continue; + } + + INIT_LIST_HEAD(&pch->work_list); + spin_lock_init(&pch->lock); + pch->pl330_chid = NULL; + pch->chan.private = peri; + pch->chan.device = pd; + pch->chan.chan_id = i; + pch->dmac = pdmac; + + /* Add the channel to the DMAC list */ + pd->chancnt++; + list_add_tail(&pch->chan.device_node, &pd->channels); + } + + pd->dev = &adev->dev; + + pd->device_alloc_chan_resources = pl330_alloc_chan_resources; + pd->device_free_chan_resources = pl330_free_chan_resources; + pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy; + pd->device_tx_status = pl330_tx_status; + pd->device_prep_slave_sg = pl330_prep_slave_sg; + pd->device_control = pl330_control; + pd->device_issue_pending = pl330_issue_pending; + + ret = dma_async_device_register(pd); + if (ret) { + dev_err(&adev->dev, "unable to register DMAC\n"); + goto probe_err4; + } + + amba_set_drvdata(adev, pdmac); + + dev_info(&adev->dev, + "Loaded driver for PL330 DMAC-%d\n", adev->periphid); + dev_info(&adev->dev, + "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", + pi->pcfg.data_buf_dep, + pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, + pi->pcfg.num_peri, pi->pcfg.num_events); + + return 0; + +probe_err4: + pl330_del(pi); +probe_err3: + free_irq(irq, pi); +probe_err2: + iounmap(pi->base); +probe_err1: + release_mem_region(res->start, resource_size(res)); + kfree(pdmac); + + return ret; +} + +static int __devexit pl330_remove(struct amba_device *adev) +{ + struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev); + struct dma_pl330_chan *pch, *_p; + struct pl330_info *pi; + struct resource *res; + int irq; + + if (!pdmac) + return 0; + + amba_set_drvdata(adev, NULL); + + /* Idle the DMAC */ + list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels, + chan.device_node) { + + /* Remove the channel */ + list_del(&pch->chan.device_node); + + /* Flush the channel */ + pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); + pl330_free_chan_resources(&pch->chan); + } + + pi = &pdmac->pif; + + pl330_del(pi); + + irq = adev->irq[0]; + free_irq(irq, pi); + + iounmap(pi->base); + + res = &adev->res; + release_mem_region(res->start, resource_size(res)); + + kfree(pdmac); + + return 0; +} + +static struct amba_id pl330_ids[] = { + { + .id = 0x00041330, + .mask = 0x000fffff, + }, + { 0, 0 }, +}; + +static struct amba_driver pl330_driver = { + .drv = { + .owner = THIS_MODULE, + .name = "dma-pl330", + }, + .id_table = pl330_ids, + .probe = pl330_probe, + .remove = pl330_remove, +}; + +static int __init pl330_init(void) +{ + return amba_driver_register(&pl330_driver); +} +module_init(pl330_init); + +static void __exit pl330_exit(void) +{ + amba_driver_unregister(&pl330_driver); + return; +} +module_exit(pl330_exit); + +MODULE_AUTHOR("Jaswinder Singh "); +MODULE_DESCRIPTION("API Driver for PL330 DMAC"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h new file mode 100644 index 000000000000..cbee7de7dd36 --- /dev/null +++ b/include/linux/amba/pl330.h @@ -0,0 +1,45 @@ +/* linux/include/linux/amba/pl330.h + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __AMBA_PL330_H_ +#define __AMBA_PL330_H_ + +#include + +struct dma_pl330_peri { + /* + * Peri_Req i/f of the DMAC that is + * peripheral could be reached from. + */ + u8 peri_id; /* {0, 31} */ + enum pl330_reqtype rqtype; + + /* For M->D and D->M Channels */ + int burst_sz; /* in power of 2 */ + dma_addr_t fifo_addr; +}; + +struct dma_pl330_platdata { + /* + * Number of valid peripherals connected to DMAC. + * This may be different from the value read from + * CR0, as the PL330 implementation might have 'holes' + * in the peri list or the peri could also be reached + * from another DMAC which the platform prefers. + */ + u8 nr_valid_peri; + /* Array of valid peripherals */ + struct dma_pl330_peri *peri; + /* Bytes to allocate for MC buffer */ + unsigned mcbuf_sz; +}; + +#endif /* __AMBA_PL330_H_ */ -- cgit v1.2.3 From 4be929be34f9bdeffa40d815d32d7d60d2c7f03b Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 24 May 2010 14:33:03 -0700 Subject: kernel-wide: replace USHORT_MAX, SHORT_MAX and SHORT_MIN with USHRT_MAX, SHRT_MAX and SHRT_MIN - C99 knows about USHRT_MAX/SHRT_MAX/SHRT_MIN, not USHORT_MAX/SHORT_MAX/SHORT_MIN. - Make SHRT_MIN of type s16, not int, for consistency. [akpm@linux-foundation.org: fix drivers/dma/timb_dma.c] [akpm@linux-foundation.org: fix security/keys/keyring.c] Signed-off-by: Alexey Dobriyan Acked-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/dma/timb_dma.c | 2 +- drivers/scsi/fcoe/fcoe.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_base.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_config.c | 2 +- drivers/vhost/vhost.c | 2 +- fs/nfs/super.c | 4 ++-- fs/nfsd/nfsctl.c | 4 ++-- fs/ocfs2/blockcheck.c | 4 ++-- include/linux/kernel.h | 6 +++--- include/linux/sched.h | 2 +- include/net/ip.h | 6 +++--- include/net/ipv6.h | 6 +++--- ipc/msg.c | 12 ++++++------ ipc/util.c | 4 ++-- lib/vsprintf.c | 2 +- net/9p/protocol.c | 2 +- net/dccp/options.c | 2 +- net/ipv4/udp.c | 8 ++++---- net/mac80211/sta_info.c | 2 +- net/sunrpc/rpcb_clnt.c | 2 +- security/keys/keyring.c | 6 +++--- 21 files changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 0172fa3c7a2b..a1bf77c1993f 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -188,7 +188,7 @@ static void __td_unmap_descs(struct timb_dma_desc *td_desc, bool single) static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, struct scatterlist *sg, bool last) { - if (sg_dma_len(sg) > USHORT_MAX) { + if (sg_dma_len(sg) > USHRT_MAX) { dev_err(chan2dev(&td_chan->chan), "Too big sg element\n"); return -EINVAL; } diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9276121db1ef..44a07593de56 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -688,7 +688,7 @@ static int fcoe_shost_config(struct fc_lport *lport, struct device *dev) } if (!lport->vport) - fc_host_max_npiv_vports(lport->host) = USHORT_MAX; + fc_host_max_npiv_vports(lport->host) = USHRT_MAX; snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE, "%s v%s over %s", FCOE_NAME, FCOE_VERSION, diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index b830d61684dd..0ec1ed389c20 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -3757,7 +3757,7 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) if (ioc->config_cmds.status & MPT2_CMD_PENDING) { ioc->config_cmds.status |= MPT2_CMD_RESET; mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); - ioc->config_cmds.smid = USHORT_MAX; + ioc->config_cmds.smid = USHRT_MAX; complete(&ioc->config_cmds.done); } break; diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index e762dd3e2fcb..c65442982d7b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -258,7 +258,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, #ifdef CONFIG_SCSI_MPT2SAS_LOGGING _config_display_some_debug(ioc, smid, "config_done", mpi_reply); #endif - ioc->config_cmds.smid = USHORT_MAX; + ioc->config_cmds.smid = USHRT_MAX; complete(&ioc->config_cmds.done); return 1; } diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 750effe0f98b..c6fb8e968f21 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -806,7 +806,7 @@ static unsigned get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq, count = indirect->len / sizeof desc; /* Buffers are chained via a 16 bit next field, so * we can have at most 2^16 of these. */ - if (count > USHORT_MAX + 1) { + if (count > USHRT_MAX + 1) { vq_err(vq, "Indirect buffer length too big: %d\n", indirect->len); return -E2BIG; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f8b1157daa2..04214fc5c304 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1060,7 +1060,7 @@ static int nfs_parse_mount_options(char *raw, goto out_nomem; rc = strict_strtoul(string, 10, &option); kfree(string); - if (rc != 0 || option > USHORT_MAX) + if (rc != 0 || option > USHRT_MAX) goto out_invalid_value; mnt->nfs_server.port = option; break; @@ -1181,7 +1181,7 @@ static int nfs_parse_mount_options(char *raw, goto out_nomem; rc = strict_strtoul(string, 10, &option); kfree(string); - if (rc != 0 || option > USHORT_MAX) + if (rc != 0 || option > USHRT_MAX) goto out_invalid_value; mnt->mount_server.port = option; break; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index bc3194ea01f5..508941c23af7 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -998,7 +998,7 @@ static ssize_t __write_ports_addxprt(char *buf) if (sscanf(buf, "%15s %4u", transport, &port) != 2) return -EINVAL; - if (port < 1 || port > USHORT_MAX) + if (port < 1 || port > USHRT_MAX) return -EINVAL; err = nfsd_create_serv(); @@ -1040,7 +1040,7 @@ static ssize_t __write_ports_delxprt(char *buf) if (sscanf(&buf[1], "%15s %4u", transport, &port) != 2) return -EINVAL; - if (port < 1 || port > USHORT_MAX || nfsd_serv == NULL) + if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL) return -EINVAL; xprt = svc_find_xprt(nfsd_serv, transport, AF_UNSPEC, port); diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c index b7428c5d0d3b..ec6d12339593 100644 --- a/fs/ocfs2/blockcheck.c +++ b/fs/ocfs2/blockcheck.c @@ -403,7 +403,7 @@ void ocfs2_block_check_compute(void *data, size_t blocksize, * No ecc'd ocfs2 structure is larger than 4K, so ecc will be no * larger than 16 bits. */ - BUG_ON(ecc > USHORT_MAX); + BUG_ON(ecc > USHRT_MAX); bc->bc_crc32e = cpu_to_le32(crc); bc->bc_ecc = cpu_to_le16((u16)ecc); @@ -508,7 +508,7 @@ void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr, * No ecc'd ocfs2 structure is larger than 4K, so ecc will be no * larger than 16 bits. */ - BUG_ON(ecc > USHORT_MAX); + BUG_ON(ecc > USHRT_MAX); bc->bc_crc32e = cpu_to_le32(crc); bc->bc_ecc = cpu_to_le16((u16)ecc); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index cc5e3ffe9fce..a2e7c32e17e7 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -24,9 +24,9 @@ extern const char linux_banner[]; extern const char linux_proc_banner[]; -#define USHORT_MAX ((u16)(~0U)) -#define SHORT_MAX ((s16)(USHORT_MAX>>1)) -#define SHORT_MIN (-SHORT_MAX - 1) +#define USHRT_MAX ((u16)(~0U)) +#define SHRT_MAX ((s16)(USHRT_MAX>>1)) +#define SHRT_MIN ((s16)(-SHRT_MAX - 1)) #define INT_MAX ((int)(~0U>>1)) #define INT_MIN (-INT_MAX - 1) #define UINT_MAX (~0U) diff --git a/include/linux/sched.h b/include/linux/sched.h index 415b8f8a3f45..c0151ffd3541 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -384,7 +384,7 @@ struct user_namespace; * 1-3 now and depends on arch. We use "5" as safe margin, here. */ #define MAPCOUNT_ELF_CORE_MARGIN (5) -#define DEFAULT_MAX_MAP_COUNT (USHORT_MAX - MAPCOUNT_ELF_CORE_MARGIN) +#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN) extern int sysctl_max_map_count; diff --git a/include/net/ip.h b/include/net/ip.h index 63548f0a44b1..452f229c380a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -358,11 +358,11 @@ enum ip_defrag_users { IP_DEFRAG_LOCAL_DELIVER, IP_DEFRAG_CALL_RA_CHAIN, IP_DEFRAG_CONNTRACK_IN, - __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHORT_MAX, + __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHRT_MAX, IP_DEFRAG_CONNTRACK_OUT, - __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHORT_MAX, + __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX, IP_DEFRAG_CONNTRACK_BRIDGE_IN, - __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, + __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, IP_DEFRAG_VS_IN, IP_DEFRAG_VS_OUT, IP_DEFRAG_VS_FWD diff --git a/include/net/ipv6.h b/include/net/ipv6.h index eba5cc00325a..2600b69757b8 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -354,11 +354,11 @@ struct inet_frag_queue; enum ip6_defrag_users { IP6_DEFRAG_LOCAL_DELIVER, IP6_DEFRAG_CONNTRACK_IN, - __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHORT_MAX, + __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX, IP6_DEFRAG_CONNTRACK_OUT, - __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHORT_MAX, + __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX, IP6_DEFRAG_CONNTRACK_BRIDGE_IN, - __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, + __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, }; struct ip6_create_arg { diff --git a/ipc/msg.c b/ipc/msg.c index 9547cb7ac313..747b65507a91 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -345,19 +345,19 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) out.msg_rtime = in->msg_rtime; out.msg_ctime = in->msg_ctime; - if (in->msg_cbytes > USHORT_MAX) - out.msg_cbytes = USHORT_MAX; + if (in->msg_cbytes > USHRT_MAX) + out.msg_cbytes = USHRT_MAX; else out.msg_cbytes = in->msg_cbytes; out.msg_lcbytes = in->msg_cbytes; - if (in->msg_qnum > USHORT_MAX) - out.msg_qnum = USHORT_MAX; + if (in->msg_qnum > USHRT_MAX) + out.msg_qnum = USHRT_MAX; else out.msg_qnum = in->msg_qnum; - if (in->msg_qbytes > USHORT_MAX) - out.msg_qbytes = USHORT_MAX; + if (in->msg_qbytes > USHRT_MAX) + out.msg_qbytes = USHRT_MAX; else out.msg_qbytes = in->msg_qbytes; out.msg_lqbytes = in->msg_qbytes; diff --git a/ipc/util.c b/ipc/util.c index 79ce84e890f7..69a0cc13d966 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -124,8 +124,8 @@ void ipc_init_ids(struct ipc_ids *ids) ids->seq = 0; { int seq_limit = INT_MAX/SEQ_MULTIPLIER; - if (seq_limit > USHORT_MAX) - ids->seq_max = USHORT_MAX; + if (seq_limit > USHRT_MAX) + ids->seq_max = USHRT_MAX; else ids->seq_max = seq_limit; } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 46d34b0b74a8..20c95121d8a1 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1980,7 +1980,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args) { char *s = (char *)va_arg(args, char *); if (field_width == -1) - field_width = SHORT_MAX; + field_width = SHRT_MAX; /* first, skip leading white space in buffer */ str = skip_spaces(str); diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 77d3aab4036b..149f82160130 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -394,7 +394,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, const char *sptr = va_arg(ap, const char *); int16_t len = 0; if (sptr) - len = MIN(strlen(sptr), USHORT_MAX); + len = MIN(strlen(sptr), USHRT_MAX); errcode = p9pdu_writef(pdu, proto_version, "w", len); diff --git a/net/dccp/options.c b/net/dccp/options.c index 1b08cae9c65b..07395f861d35 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -296,7 +296,7 @@ static inline u8 dccp_ndp_len(const u64 ndp) { if (likely(ndp <= 0xFF)) return 1; - return likely(ndp <= USHORT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6); + return likely(ndp <= USHRT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6); } int dccp_insert_option(struct sock *sk, struct sk_buff *skb, diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 9de6a698f91d..baeec29fe0f1 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1686,8 +1686,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, return -ENOPROTOOPT; if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ val = 8; - else if (val > USHORT_MAX) - val = USHORT_MAX; + else if (val > USHRT_MAX) + val = USHRT_MAX; up->pcslen = val; up->pcflag |= UDPLITE_SEND_CC; break; @@ -1700,8 +1700,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, return -ENOPROTOOPT; if (val != 0 && val < 8) /* Avoid silly minimal values. */ val = 8; - else if (val > USHORT_MAX) - val = USHORT_MAX; + else if (val > USHRT_MAX) + val = USHRT_MAX; up->pcrlen = val; up->pcflag |= UDPLITE_RECV_CC; break; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 730197591ab5..ba9360a475b0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -259,7 +259,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, skb_queue_head_init(&sta->tx_filtered); for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - sta->last_seq_ctrl[i] = cpu_to_le16(USHORT_MAX); + sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG printk(KERN_DEBUG "%s: Allocated STA %pM\n", diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 121105355f60..dac219a56ae1 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -783,7 +783,7 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, port = ntohl(*p); dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, task->tk_msg.rpc_proc->p_name, port); - if (unlikely(port > USHORT_MAX)) + if (unlikely(port > USHRT_MAX)) return -EIO; rpcb->r_port = port; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index ef03a82a0135..d37f713e73ce 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -669,7 +669,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) struct keyring_list *klist = container_of(rcu, struct keyring_list, rcu); - if (klist->delkey != USHORT_MAX) + if (klist->delkey != USHRT_MAX) key_put(klist->keys[klist->delkey]); kfree(klist); } @@ -746,7 +746,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, max += klist->maxkeys; ret = -ENFILE; - if (max > USHORT_MAX - 1) + if (max > USHRT_MAX - 1) goto error_quota; size = sizeof(*klist) + sizeof(struct key *) * max; if (size > PAGE_SIZE) @@ -763,7 +763,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, sizeof(struct key *) * klist->nkeys); nklist->delkey = klist->nkeys; nklist->nkeys = klist->nkeys + 1; - klist->delkey = USHORT_MAX; + klist->delkey = USHRT_MAX; } else { nklist->nkeys = 1; nklist->delkey = 0; -- cgit v1.2.3 From b4a75c91b8a6cb80ba7772f69613025ddf75ebc2 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 31 May 2010 18:39:13 +0200 Subject: of/dma: mpc512x_dma.c: Fix build failures Fixes build errors caused by the: - OF device_node pointer being moved into struct device - removal of the match_table field from struct of_platform_driver Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/dma/mpc512x_dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 201e6e19c344..14a8c0f1698e 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -630,7 +630,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, static int __devinit mpc_dma_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct device *dev = &op->dev; struct dma_device *dma; struct mpc_dma *mdma; @@ -771,12 +771,12 @@ static struct of_device_id mpc_dma_match[] = { }; static struct of_platform_driver mpc_dma_driver = { - .match_table = mpc_dma_match, .probe = mpc_dma_probe, .remove = __devexit_p(mpc_dma_remove), - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc_dma_match, }, }; -- cgit v1.2.3 From 05c02542c20aa00dc9a66f4bfb1a89d1131457f2 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 02:46:37 +0200 Subject: of/dma: fix build breakage in ppc4xx adma driver Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/dma/ppc4xx/adma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index fa98abe4686f..5a22ca6927e5 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4394,7 +4394,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev, static int __devinit ppc440spe_adma_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct ppc440spe_adma_device *adev; struct ppc440spe_adma_chan *chan; @@ -4626,7 +4626,7 @@ out: static int __devexit ppc440spe_adma_remove(struct of_device *ofdev) { struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev); - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct dma_chan *chan, *_chan; struct ppc_dma_chan_ref *ref, *_ref; -- cgit v1.2.3