aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/visorbus/visorchannel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/unisys/visorbus/visorchannel.c')
-rw-r--r--drivers/staging/unisys/visorbus/visorchannel.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c
index 20b63496e9f2..2693c46afdc0 100644
--- a/drivers/staging/unisys/visorbus/visorchannel.c
+++ b/drivers/staging/unisys/visorbus/visorchannel.c
@@ -1,12 +1,11 @@
/* visorchannel_funcs.c
*
- * Copyright (C) 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
- * 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.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions 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
@@ -21,6 +20,7 @@
*/
#include <linux/uuid.h>
+#include <linux/io.h>
#include "version.h"
#include "visorbus.h"
@@ -36,7 +36,7 @@ static const uuid_le spar_video_guid = SPAR_CONSOLEVIDEO_CHANNEL_PROTOCOL_GUID;
struct visorchannel {
u64 physaddr;
ulong nbytes;
- void __iomem *mapped;
+ void *mapped;
bool requested;
struct channel_header chan_hdr;
uuid_le guid;
@@ -93,7 +93,7 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
}
}
- channel->mapped = ioremap_cache(physaddr, size);
+ channel->mapped = memremap(physaddr, size, MEMREMAP_WB);
if (!channel->mapped) {
release_mem_region(physaddr, size);
goto cleanup;
@@ -113,7 +113,7 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
guid = channel->chan_hdr.chtype;
- iounmap(channel->mapped);
+ memunmap(channel->mapped);
if (channel->requested)
release_mem_region(channel->physaddr, channel->nbytes);
channel->mapped = NULL;
@@ -126,7 +126,8 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
}
}
- channel->mapped = ioremap_cache(channel->physaddr, channel_bytes);
+ channel->mapped = memremap(channel->physaddr, channel_bytes,
+ MEMREMAP_WB);
if (!channel->mapped) {
release_mem_region(channel->physaddr, channel_bytes);
goto cleanup;
@@ -167,7 +168,7 @@ visorchannel_destroy(struct visorchannel *channel)
if (!channel)
return;
if (channel->mapped) {
- iounmap(channel->mapped);
+ memunmap(channel->mapped);
if (channel->requested)
release_mem_region(channel->physaddr, channel->nbytes);
}
@@ -241,7 +242,7 @@ visorchannel_read(struct visorchannel *channel, ulong offset,
if (offset + nbytes > channel->nbytes)
return -EIO;
- memcpy_fromio(local, channel->mapped + offset, nbytes);
+ memcpy(local, channel->mapped + offset, nbytes);
return 0;
}
@@ -259,10 +260,11 @@ visorchannel_write(struct visorchannel *channel, ulong offset,
if (offset < chdr_size) {
copy_size = min(chdr_size - offset, nbytes);
- memcpy(&channel->chan_hdr + offset, local, copy_size);
+ memcpy(((char *)(&channel->chan_hdr)) + offset,
+ local, copy_size);
}
- memcpy_toio(channel->mapped + offset, local, nbytes);
+ memcpy(channel->mapped + offset, local, nbytes);
return 0;
}
@@ -416,11 +418,12 @@ bool
visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
{
bool rc;
+ unsigned long flags;
if (channel->needs_lock) {
- spin_lock(&channel->remove_lock);
+ spin_lock_irqsave(&channel->remove_lock, flags);
rc = signalremove_inner(channel, queue, msg);
- spin_unlock(&channel->remove_lock);
+ spin_unlock_irqrestore(&channel->remove_lock, flags);
} else {
rc = signalremove_inner(channel, queue, msg);
}
@@ -429,6 +432,27 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
}
EXPORT_SYMBOL_GPL(visorchannel_signalremove);
+bool
+visorchannel_signalempty(struct visorchannel *channel, u32 queue)
+{
+ unsigned long flags = 0;
+ struct signal_queue_header sig_hdr;
+ bool rc = false;
+
+ if (channel->needs_lock)
+ spin_lock_irqsave(&channel->remove_lock, flags);
+
+ if (!sig_read_header(channel, queue, &sig_hdr))
+ rc = true;
+ if (sig_hdr.head == sig_hdr.tail)
+ rc = true;
+ if (channel->needs_lock)
+ spin_unlock_irqrestore(&channel->remove_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(visorchannel_signalempty);
+
static bool
signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
{
@@ -470,11 +494,12 @@ bool
visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
{
bool rc;
+ unsigned long flags;
if (channel->needs_lock) {
- spin_lock(&channel->insert_lock);
+ spin_lock_irqsave(&channel->insert_lock, flags);
rc = signalinsert_inner(channel, queue, msg);
- spin_unlock(&channel->insert_lock);
+ spin_unlock_irqrestore(&channel->insert_lock, flags);
} else {
rc = signalinsert_inner(channel, queue, msg);
}