Commit Graph

222797 Commits

Author SHA1 Message Date
Dan Williams 96a608a4bf ARM: PL08x: fix a warning
drivers/dma/amba-pl08x.c: In function 'pl08x_start_txd':
drivers/dma/amba-pl08x.c:205: warning: dereferencing 'void *' pointer

We never dereference llis_va aside from assigning it to a struct
pl08x_lli pointer or calculating the address of array element 0.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 17:51:11 -08:00
Russell King - ARM Linux 98d530fe24 Fix dmaengine_submit() return type
desc->tx_submit's return type is dma_cookie_t, not int.  Therefore,
dmaengine_submit() should match this return type as it's just
wrapping this detail.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 17:07:49 -08:00
Nicolas Ferre dda36f9821 dmaengine: at_hdmac: fix race while monitoring channel status
We were reading channel status then taking a lock. This lead to a race because
this lock may delay us and then make this channel not idle anymore.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:54:44 -08:00
Nicolas Ferre 568f7f0c2e dmaengine: at_hdmac: flags located in first descriptor
Place flags on first descriptor of chain instead of last.
This is the one used by atc_chain_complete() function while unmapping.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:54:44 -08:00
Eric Xu 93d0bec2be dmaengine: at_hdmac: use subsys_initcall instead of module_init
Use subsys_initcall instead of module_init in order to keep DMA engine rolling
before other peripheral drivers.

Signed-off-by: Eric Xu <hong.xu@atmel.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:54:43 -08:00
Nicolas Ferre 58344f25cf dmaengine: at_hdmac: no need set ACK in new descriptor
Following descriptor flow in at_hdmac driver, descriptor comming from
atc_desc_get() as already DMA_CTRL_ACK flag set. No need to set it again.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:54:43 -08:00
Nicolas Ferre ebcf9b80f9 dmaengine: at_hdmac: trivial add precision to unmapping comment
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:54:43 -08:00
Nicolas Ferre 0f70e8cea3 dmaengine: at_hdmac: use dma_address to program DMA hardware
In atc_prep_slave_sg() function we use dma_address field of scatterlist with
sg_dma_address() macro instead of sg_phys(). DMA address is already computed
by dma_map_sg() or another mapping function in calling driver.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:25:58 -08:00
Tomoya MORINAGA 2cdf2455a6 pch_dma: support new device ML7213 IOH
Support new device OKI SEMICONDUCTOR's ML7213 IOH(Input/Output Hub) which is for
IVI(In-Vehicle Infotainment) use.
The ML7213 is companion chip for Intel Atom E6xx series.
The ML7213 is completely compatible for Intel EG20T PCH.

Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-14 16:24:53 -08:00
Dan Williams bc0fa81473 Merge branches 'amba' and 'dma40' into dmaengine 2011-01-07 12:47:05 -08:00
Russell King - ARM Linux b7f7586592 ARM: PL08x: prevent dma_set_runtime_config() reconfiguring memcpy channels
Prevent dma_set_runtime_config() being used to alter the configuration
supplied by the platform for memcpy channel configuration.  No one
should be trying to change this configuration.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux f0fd944625 ARM: PL08x: allow dma_set_runtime_config() to return errors
There are cases in dma_set_runtime_config() where we fail to perform
the requested action - and we just issue a KERN_ERR message in that
case.  We have the facility to return an error to the caller, so that
is what we should do.

When we encounter an error due to invalid parameters, we should not
modify driver state.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux c370e594ef ARM: PL08x: fix locking between prepare function and submit function
The PL08x driver holds on to the channel lock with interrupts disabled
between the prepare and the subsequent submit API functions.  This
means that the locking state when the prepare function returns is
dependent on whether it suceeeds or not.

It did this to ensure that the physical channel wasn't released, and
as it used to add the descriptor onto the pending list at prepare time
rather than submit time.

Now that we have reorganized the code to remove those reasons, we can
now safely release the spinlock at the end of preparation and reacquire
it in our submit function.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux 8087aacda0 ARM: PL08x: introduce 'phychan_hold' to hold on to physical channels
Introduce 'phychan_hold' to hold on to physical DMA channels while we're
preparing a new descriptor for it.  This will be incremented when we
allocate a physical channel and set the MUX registers during the
preparation of the TXD, and will only be decremented when the TXD is
submitted.

This prevents the physical channel being given up before the new TXD
is placed on the queue.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux 501e67e82d ARM: PL08x: put txd's on the pending list in pl08x_tx_submit()
Don't place TXDs on the pending list when they're prepared - place
them on the list when they're ready to be submitted.  Also, only
place memcpy requests in the wait state when they're submitted and
don't have a physical channel associated.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux 15c17232fb ARM: PL08x: rename 'desc_list' as 'pend_list'
This 'desc_list' is actually a list of pending descriptors, so name
it after its function (pending list) rather than what it contains
(descriptors).

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux 3d992e1a6f ARM: PL08x: implement unmapping of memcpy buffers
The DMA engine API requires DMA engine implementations to unmap buffers
passed into the non-slave DMA methods unless the relevant completion
flag is set.  We aren't doing this, so implement this facility.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:14 -08:00
Russell King - ARM Linux c04287948e ARM: PL08x: store prep_* flags in async_tx structure
Like other DMA engine drivers do, store the passed flags into the
async_tx structure, so they can be checked when the operation
completes.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux d7244e9a27 ARM: PL08x: shrink srcbus/dstbus in txd structure
We only need to store the dma address.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux 542361f8e3 ARM: PL08x: don't manipulate txd->srcbus or txd->dstbus during LLI fill
Don't alter any txd->srcbus or txd->dstbus values while building the
LLI list.  This allows us to see the original dma_addr_t values passed
in via the prep_memcpy() method.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux 5f638b4f31 ARM: PL08x: fix fill_bytes calculation
The number of bytes we want to fill into any LLI is the minimum of:
- number of bytes remaining in the transfer
- number of bytes we can transfer in a single LLI
- number of bytes we can transfer without overflowing the source boundary
- number of bytes we can transfer without overflowing the destination boundary

The minimum of the first two is already calculated (target_len).  We
limit the boundary calculations to this number of bytes, which will
then give us the number of bytes we can place into this LLI.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux d6cf7b597f ARM: PL08x: use min() to calculate target_len
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux b61be8d728 ARM: PL08x: ensure pl08x_pre_boundary() works for any value of addr
pl08x_pre_boundary() was unsafe with addresses towards the top of
memory space:

	boundary = ((addr >> PL08X_BOUNDARY_SHIFT) + 1)
			<< PL08X_BOUNDARY_SHIFT;

This can overflow a 32-bit number, producing zero.  When it does:

	if (boundary < addr + len)
		return boundary - addr;
	else
		return len;

results in (boundary - addr) returning either a large positive value.
Also if addr + len overflows, this calculation also fails.

We can fix this trivially as the only thing we're actually interested
in is the value of the least significant PL08X_BOUNDARY_SHIFT bits:

	boundary_len = PL08X_BOUNDARY_SIZE -
		(addr & (PL08X_BOUNDARY_SIZE - 1));

gives us the number of bytes before 'addr' becomes a multiple of
PL08X_BOUNDARY_SIZE.  We can then just take the min() of the two
calculated lengths.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux 0059005f2c ARM: PL08x: make pl08x_fill_lli_for_desc() return void
We don't need pl08x_fill_lli_for_desc() to return num_llis + 1 as
we know that's what it always does.  We can just pass in num_llis
and use post-increment in the caller.

This makes the code slightly easier to read.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00
Russell King - ARM Linux 858c21c0f3 ARM: PL08x: move callback outside spinlock'd region
Calling the callback handler with spinlocks in the tasklet held leads
to deadlock when dmaengine functions are called:

BUG: spinlock lockup on CPU#0, sh/417, c1870a08
Backtrace:
...
[<c017b408>] (do_raw_spin_lock+0x0/0x154) from [<c02c4b98>] (_raw_spin_lock_irqsave+0x54/0x60)
[<c02c4b44>] (_raw_spin_lock_irqsave+0x0/0x60) from [<c01f5828>] (pl08x_prep_channel_resources+0x718/0x8b4)
[<c01f5110>] (pl08x_prep_channel_resources+0x0/0x8b4) from [<c01f5bb4>] (pl08x_prep_slave_sg+0x120/0x19c)
[<c01f5a94>] (pl08x_prep_slave_sg+0x0/0x19c) from [<c01be7a0>] (pl011_dma_tx_refill+0x164/0x224)
[<c01be63c>] (pl011_dma_tx_refill+0x0/0x224) from [<c01bf1c8>] (pl011_dma_tx_callback+0x7c/0xc4)
[<c01bf14c>] (pl011_dma_tx_callback+0x0/0xc4) from [<c01f4d34>] (pl08x_tasklet+0x60/0x368)
[<c01f4cd4>] (pl08x_tasklet+0x0/0x368) from [<c004d978>] (tasklet_action+0xa0/0x100)

Dan quoted the documentation:
> 2/ Completion callback routines cannot submit new operations.  This
>    results in recursion in the synchronous case and spin_locks being
>    acquired twice in the asynchronous case.

but then followed up to say:
> I should clarify, this is the async_memcpy() api requirement which is
> not used outside of md/raid5.  DMA drivers can and do allow new
> submissions from callbacks, and the ones that do so properly move the
> callback outside of the driver lock.

So let's fix it by moving the callback out of the spinlocked region.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2011-01-04 19:16:13 -08:00