aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2016-05-16 11:37:22 +0100
committerJon Medhurst <tixy@linaro.org>2016-05-16 11:37:22 +0100
commitb2f6cdee55c97ff5a12447c73a490cb686b7229b (patch)
treeab27ad0e02a8e8afebf631ceae9cf55594bb8595
parent3d0ef705dcf4e718dd912b37d9c616ce79c2406c (diff)
parentd53cdb40428af305277ca214648c0842f6943d3a (diff)
Merge branch 'latest-armlt-misc' into latest-armlt
-rw-r--r--drivers/dma/pl330.c24
-rw-r--r--drivers/net/ethernet/marvell/sky2.c12
-rw-r--r--drivers/staging/android/ion/ion_dummy_driver.c15
3 files changed, 46 insertions, 5 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 372b4359da97..d74d53a54ae6 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2277,6 +2277,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
struct dma_pl330_desc *desc, *running = NULL;
struct dma_pl330_chan *pch = to_pchan(chan);
unsigned int transferred, residual = 0;
+ bool first_busy;
ret = dma_cookie_status(chan, cookie, txstate);
@@ -2290,16 +2291,31 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
if (pch->thread->req_running != -1)
running = pch->thread->req[pch->thread->req_running].desc;
+ first_busy = true;
/* Check in pending list */
list_for_each_entry(desc, &pch->work_list, node) {
if (desc->status == DONE)
transferred = desc->bytes_requested;
- else if (running && desc == running)
- transferred =
- pl330_get_current_xferred_count(pch, desc);
- else
+ else if (desc->status == BUSY && first_busy) {
+ first_busy = false;
+ if (running && desc == running) {
+ transferred =
+ pl330_get_current_xferred_count(pch, desc);
+ } else {
+ /* BUSY but not running means it's just completed */
+ transferred = desc->bytes_requested;
+ }
+ } else {
+ /*
+ * Descriptor is either in PREP state queued for future
+ * transfer or it is the second BUSY descriptor we have
+ * seen. The latter case means it has just, or is about
+ * to be, started, so treat it as having not yet
+ * transferred any bytes, the same as PREP.
+ */
transferred = 0;
+ }
residual += desc->bytes_requested - transferred;
if (desc->txd.cookie == cookie) {
switch (desc->status) {
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index ec0a22119e09..756d558cd4f5 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -3907,6 +3907,18 @@ static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev,
unsigned int start;
u64 _bytes, _packets;
+ /* Try and check if device if off. If it is, abort gathering stats as
+ * any attempt to read hardware registers will generate a bus fault.
+ * This test is hacky and racy as there's nothing stopping the device
+ * being powered off immediately after the test.
+ */
+ if (hw->pdev->pm_cap) {
+ u16 pmcsr;
+ int ret = pci_read_config_word(hw->pdev, hw->pdev->pm_cap + PCI_PM_CTRL, &pmcsr);
+ if (ret || (pmcsr & PCI_PM_CTRL_STATE_MASK) > PCI_D2)
+ return stats; /* Can't read power state or it's state D3 (off) */
+ }
+
do {
start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp);
_bytes = sky2->rx_stats.bytes;
diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c
index 5678870bff48..cf650c6981db 100644
--- a/drivers/staging/android/ion/ion_dummy_driver.c
+++ b/drivers/staging/android/ion/ion_dummy_driver.c
@@ -31,6 +31,11 @@ static struct ion_heap **heaps;
static void *carveout_ptr;
static void *chunk_ptr;
+struct platform_device dummy_device_ion = {
+ .name = "ion-dummy",
+ .id = -1,
+};
+
static struct ion_platform_heap dummy_heaps[] = {
{
.id = ION_HEAP_TYPE_SYSTEM,
@@ -56,6 +61,12 @@ static struct ion_platform_heap dummy_heaps[] = {
.align = SZ_16K,
.priv = (void *)(SZ_16K),
},
+ {
+ .id = ION_HEAP_TYPE_DMA,
+ .type = ION_HEAP_TYPE_DMA,
+ .name = "ion_dma_heap",
+ .priv = &dummy_device_ion.dev,
+ }
};
static struct ion_platform_data dummy_ion_pdata = {
@@ -110,7 +121,9 @@ static int __init ion_dummy_init(void)
}
ion_device_add_heap(idev, heaps[i]);
}
- return 0;
+
+ return platform_device_register(&dummy_device_ion);
+
err:
for (i = 0; i < dummy_ion_pdata.nr; ++i)
ion_heap_destroy(heaps[i]);