aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/visorutil
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/unisys/visorutil')
-rw-r--r--drivers/staging/unisys/visorutil/Kconfig9
-rw-r--r--drivers/staging/unisys/visorutil/Makefile9
-rw-r--r--drivers/staging/unisys/visorutil/charqueue.c127
-rw-r--r--drivers/staging/unisys/visorutil/charqueue.h37
-rw-r--r--drivers/staging/unisys/visorutil/memregion.h43
-rw-r--r--drivers/staging/unisys/visorutil/memregion_direct.c207
-rw-r--r--drivers/staging/unisys/visorutil/periodic_work.c204
-rw-r--r--drivers/staging/unisys/visorutil/visorkmodutils.c71
8 files changed, 0 insertions, 707 deletions
diff --git a/drivers/staging/unisys/visorutil/Kconfig b/drivers/staging/unisys/visorutil/Kconfig
deleted file mode 100644
index be9c2cf890cc..000000000000
--- a/drivers/staging/unisys/visorutil/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Unisys timskmod configuration
-#
-
-config UNISYS_VISORUTIL
- tristate "Unisys visorutil driver"
- ---help---
- If you say Y here, you will enable the Unisys visorutil driver.
-
diff --git a/drivers/staging/unisys/visorutil/Makefile b/drivers/staging/unisys/visorutil/Makefile
deleted file mode 100644
index d9ab5a36e3bf..000000000000
--- a/drivers/staging/unisys/visorutil/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for Unisys timskmod
-#
-
-obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil.o
-
-visorutil-y := charqueue.o periodic_work.o memregion_direct.o visorkmodutils.o
-
-ccflags-y += -Idrivers/staging/unisys/include
diff --git a/drivers/staging/unisys/visorutil/charqueue.c b/drivers/staging/unisys/visorutil/charqueue.c
deleted file mode 100644
index c91752a2d06b..000000000000
--- a/drivers/staging/unisys/visorutil/charqueue.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* charqueue.c
- *
- * Copyright (C) 2010 - 2013 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 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/*
- * Simple character queue implementation for Linux kernel mode.
- */
-
-#include "charqueue.h"
-
-#define MYDRVNAME "charqueue"
-
-#define IS_EMPTY(charqueue) (charqueue->head == charqueue->tail)
-
-struct charqueue {
- int alloc_size;
- int nslots;
- spinlock_t lock; /* read/write lock for this structure */
- int head, tail;
- unsigned char buf[0];
-};
-
-struct charqueue *visor_charqueue_create(ulong nslots)
-{
- int alloc_size = sizeof(struct charqueue) + nslots + 1;
- struct charqueue *cq;
-
- cq = kmalloc(alloc_size, GFP_KERNEL|__GFP_NORETRY);
- if (cq == NULL)
- return NULL;
- cq->alloc_size = alloc_size;
- cq->nslots = nslots;
- cq->head = 0;
- cq->tail = 0;
- spin_lock_init(&cq->lock);
- return cq;
-}
-EXPORT_SYMBOL_GPL(visor_charqueue_create);
-
-void visor_charqueue_enqueue(struct charqueue *charqueue, unsigned char c)
-{
- int alloc_slots = charqueue->nslots+1; /* 1 slot is always empty */
-
- spin_lock(&charqueue->lock);
- charqueue->head = (charqueue->head+1) % alloc_slots;
- if (charqueue->head == charqueue->tail)
- /* overflow; overwrite the oldest entry */
- charqueue->tail = (charqueue->tail+1) % alloc_slots;
- charqueue->buf[charqueue->head] = c;
- spin_unlock(&charqueue->lock);
-}
-EXPORT_SYMBOL_GPL(visor_charqueue_enqueue);
-
-BOOL visor_charqueue_is_empty(struct charqueue *charqueue)
-{
- BOOL b;
-
- spin_lock(&charqueue->lock);
- b = IS_EMPTY(charqueue);
- spin_unlock(&charqueue->lock);
- return b;
-}
-EXPORT_SYMBOL_GPL(visor_charqueue_is_empty);
-
-static int charqueue_dequeue_1(struct charqueue *charqueue)
-{
- int alloc_slots = charqueue->nslots + 1; /* 1 slot is always empty */
-
- if (IS_EMPTY(charqueue))
- return -1;
- charqueue->tail = (charqueue->tail+1) % alloc_slots;
- return charqueue->buf[charqueue->tail];
-}
-
-int charqueue_dequeue(struct charqueue *charqueue)
-{
- int rc;
-
- spin_lock(&charqueue->lock);
- rc = charqueue_dequeue_1(charqueue);
- spin_unlock(&charqueue->lock);
- return rc;
-}
-
-int visor_charqueue_dequeue_n(struct charqueue *charqueue, unsigned char *buf,
- int n)
-{
- int rc, counter = 0, c;
-
- spin_lock(&charqueue->lock);
- for (;;) {
- if (n <= 0)
- break; /* no more buffer space */
- c = charqueue_dequeue_1(charqueue);
- if (c < 0)
- break; /* no more input */
- *buf = (unsigned char)(c);
- buf++;
- n--;
- counter++;
- }
- rc = counter;
- spin_unlock(&charqueue->lock);
- return rc;
-}
-EXPORT_SYMBOL_GPL(visor_charqueue_dequeue_n);
-
-void visor_charqueue_destroy(struct charqueue *charqueue)
-{
- if (charqueue == NULL)
- return;
- kfree(charqueue);
-}
-EXPORT_SYMBOL_GPL(visor_charqueue_destroy);
diff --git a/drivers/staging/unisys/visorutil/charqueue.h b/drivers/staging/unisys/visorutil/charqueue.h
deleted file mode 100644
index f46a776b935b..000000000000
--- a/drivers/staging/unisys/visorutil/charqueue.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* charqueue.h
- *
- * Copyright (C) 2010 - 2013 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 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __CHARQUEUE_H__
-#define __CHARQUEUE_H__
-
-#include "timskmod.h"
-
-/* struct charqueue is an opaque structure to users.
- * Fields are declared only in the implementation .c files.
- */
-struct charqueue;
-
-struct charqueue *visor_charqueue_create(ulong nslots);
-void visor_charqueue_enqueue(struct charqueue *charqueue, unsigned char c);
-int charqueue_dequeue(struct charqueue *charqueue);
-int visor_charqueue_dequeue_n(struct charqueue *charqueue, unsigned char *buf,
- int n);
-BOOL visor_charqueue_is_empty(struct charqueue *charqueue);
-void visor_charqueue_destroy(struct charqueue *charqueue);
-
-#endif
-
diff --git a/drivers/staging/unisys/visorutil/memregion.h b/drivers/staging/unisys/visorutil/memregion.h
deleted file mode 100644
index 0c3eebcf6d50..000000000000
--- a/drivers/staging/unisys/visorutil/memregion.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* memregion.h
- *
- * Copyright (C) 2010 - 2013 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 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __MEMREGION_H__
-#define __MEMREGION_H__
-
-#include "timskmod.h"
-
-/* struct memregion is an opaque structure to users.
- * Fields are declared only in the implementation .c files.
- */
-struct memregion;
-
-struct memregion *visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes);
-struct memregion *visor_memregion_create_overlapped(struct memregion *parent,
- ulong offset, ulong nbytes);
-int visor_memregion_resize(struct memregion *memregion, ulong newsize);
-int visor_memregion_read(struct memregion *memregion,
- ulong offset, void *dest, ulong nbytes);
-int visor_memregion_write(struct memregion *memregion,
- ulong offset, void *src, ulong nbytes);
-void visor_memregion_destroy(struct memregion *memregion);
-HOSTADDRESS visor_memregion_get_physaddr(struct memregion *memregion);
-ulong visor_memregion_get_nbytes(struct memregion *memregion);
-void memregion_dump(struct memregion *memregion, char *s,
- ulong off, ulong len, struct seq_file *seq);
-void __iomem *visor_memregion_get_pointer(struct memregion *memregion);
-
-#endif
diff --git a/drivers/staging/unisys/visorutil/memregion_direct.c b/drivers/staging/unisys/visorutil/memregion_direct.c
deleted file mode 100644
index eb7422fbe20f..000000000000
--- a/drivers/staging/unisys/visorutil/memregion_direct.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* memregion_direct.c
- *
- * Copyright (C) 2010 - 2013 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 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/*
- * This is an implementation of memory regions that can be used to read/write
- * channel memory (in main memory of the host system) from code running in
- * a virtual partition.
- */
-#include "timskmod.h"
-#include "memregion.h"
-
-#define MYDRVNAME "memregion"
-
-struct memregion {
- HOSTADDRESS physaddr;
- ulong nbytes;
- void __iomem *mapped;
- BOOL requested;
- BOOL overlapped;
-};
-
-static BOOL mapit(struct memregion *memregion);
-static void unmapit(struct memregion *memregion);
-
-struct memregion *
-visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes)
-{
- struct memregion *rc = NULL;
- struct memregion *memregion;
-
- memregion = kzalloc(sizeof(*memregion), GFP_KERNEL | __GFP_NORETRY);
- if (memregion == NULL)
- return NULL;
-
- memregion->physaddr = physaddr;
- memregion->nbytes = nbytes;
- memregion->overlapped = FALSE;
- if (!mapit(memregion)) {
- rc = NULL;
- goto cleanup;
- }
- rc = memregion;
-cleanup:
- if (rc == NULL) {
- visor_memregion_destroy(memregion);
- memregion = NULL;
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(visor_memregion_create);
-
-struct memregion *
-visor_memregion_create_overlapped(struct memregion *parent, ulong offset,
- ulong nbytes)
-{
- struct memregion *memregion = NULL;
-
- if (parent == NULL)
- return NULL;
-
- if (parent->mapped == NULL)
- return NULL;
-
- if ((offset >= parent->nbytes) ||
- ((offset + nbytes) >= parent->nbytes))
- return NULL;
-
- memregion = kzalloc(sizeof(*memregion), GFP_KERNEL|__GFP_NORETRY);
- if (memregion == NULL)
- return NULL;
-
- memregion->physaddr = parent->physaddr + offset;
- memregion->nbytes = nbytes;
- memregion->mapped = ((u8 __iomem *)(parent->mapped)) + offset;
- memregion->requested = FALSE;
- memregion->overlapped = TRUE;
- return memregion;
-}
-EXPORT_SYMBOL_GPL(visor_memregion_create_overlapped);
-
-static BOOL
-mapit(struct memregion *memregion)
-{
- ulong physaddr = (ulong)(memregion->physaddr);
- ulong nbytes = memregion->nbytes;
-
- memregion->requested = FALSE;
- if (request_mem_region(physaddr, nbytes, MYDRVNAME))
- memregion->requested = TRUE;
- memregion->mapped = ioremap_cache(physaddr, nbytes);
- if (!memregion->mapped)
- return FALSE;
- return TRUE;
-}
-
-static void
-unmapit(struct memregion *memregion)
-{
- if (memregion->mapped != NULL) {
- iounmap(memregion->mapped);
- memregion->mapped = NULL;
- }
- if (memregion->requested) {
- release_mem_region((ulong)(memregion->physaddr),
- memregion->nbytes);
- memregion->requested = FALSE;
- }
-}
-
-HOSTADDRESS
-visor_memregion_get_physaddr(struct memregion *memregion)
-{
- return memregion->physaddr;
-}
-EXPORT_SYMBOL_GPL(visor_memregion_get_physaddr);
-
-ulong
-visor_memregion_get_nbytes(struct memregion *memregion)
-{
- return memregion->nbytes;
-}
-EXPORT_SYMBOL_GPL(visor_memregion_get_nbytes);
-
-void __iomem *
-visor_memregion_get_pointer(struct memregion *memregion)
-{
- return memregion->mapped;
-}
-EXPORT_SYMBOL_GPL(visor_memregion_get_pointer);
-
-int
-visor_memregion_resize(struct memregion *memregion, ulong newsize)
-{
- if (newsize == memregion->nbytes)
- return 0;
- if (memregion->overlapped)
- /* no error check here - we no longer know the
- * parent's range!
- */
- memregion->nbytes = newsize;
- else {
- unmapit(memregion);
- memregion->nbytes = newsize;
- if (!mapit(memregion))
- return -1;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(visor_memregion_resize);
-
-static int
-memregion_readwrite(BOOL is_write,
- struct memregion *memregion, ulong offset,
- void *local, ulong nbytes)
-{
- if (offset + nbytes > memregion->nbytes)
- return -EIO;
-
- if (is_write)
- memcpy_toio(memregion->mapped + offset, local, nbytes);
- else
- memcpy_fromio(local, memregion->mapped + offset, nbytes);
-
- return 0;
-}
-
-int
-visor_memregion_read(struct memregion *memregion, ulong offset, void *dest,
- ulong nbytes)
-{
- return memregion_readwrite(FALSE, memregion, offset, dest, nbytes);
-}
-EXPORT_SYMBOL_GPL(visor_memregion_read);
-
-int
-visor_memregion_write(struct memregion *memregion, ulong offset, void *src,
- ulong nbytes)
-{
- return memregion_readwrite(TRUE, memregion, offset, src, nbytes);
-}
-EXPORT_SYMBOL_GPL(visor_memregion_write);
-
-void
-visor_memregion_destroy(struct memregion *memregion)
-{
- if (memregion == NULL)
- return;
- if (!memregion->overlapped)
- unmapit(memregion);
- kfree(memregion);
-}
-EXPORT_SYMBOL_GPL(visor_memregion_destroy);
-
diff --git a/drivers/staging/unisys/visorutil/periodic_work.c b/drivers/staging/unisys/visorutil/periodic_work.c
deleted file mode 100644
index abbfb48894f3..000000000000
--- a/drivers/staging/unisys/visorutil/periodic_work.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* periodic_work.c
- *
- * Copyright (C) 2010 - 2013 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 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/*
- * Helper functions to schedule periodic work in Linux kernel mode.
- */
-
-#include "timskmod.h"
-#include "periodic_work.h"
-
-#define MYDRVNAME "periodic_work"
-
-struct periodic_work {
- rwlock_t lock;
- struct delayed_work work;
- void (*workfunc)(void *);
- void *workfuncarg;
- BOOL is_scheduled;
- BOOL want_to_stop;
- ulong jiffy_interval;
- struct workqueue_struct *workqueue;
- const char *devnam;
-};
-
-static void periodic_work_func(struct work_struct *work)
-{
- struct periodic_work *pw;
-
- pw = container_of(work, struct periodic_work, work.work);
- (*pw->workfunc)(pw->workfuncarg);
-}
-
-struct periodic_work *visor_periodic_work_create(ulong jiffy_interval,
- struct workqueue_struct *workqueue,
- void (*workfunc)(void *),
- void *workfuncarg,
- const char *devnam)
-{
- struct periodic_work *pw;
-
- pw = kzalloc(sizeof(*pw), GFP_KERNEL | __GFP_NORETRY);
- if (!pw)
- return NULL;
-
- rwlock_init(&pw->lock);
- pw->jiffy_interval = jiffy_interval;
- pw->workqueue = workqueue;
- pw->workfunc = workfunc;
- pw->workfuncarg = workfuncarg;
- pw->devnam = devnam;
- return pw;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_create);
-
-void visor_periodic_work_destroy(struct periodic_work *pw)
-{
- kfree(pw);
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_destroy);
-
-/** Call this from your periodic work worker function to schedule the next
- * call.
- * If this function returns FALSE, there was a failure and the
- * periodic work is no longer scheduled
- */
-BOOL visor_periodic_work_nextperiod(struct periodic_work *pw)
-{
- BOOL rc = FALSE;
-
- write_lock(&pw->lock);
- if (pw->want_to_stop) {
- pw->is_scheduled = FALSE;
- pw->want_to_stop = FALSE;
- rc = TRUE; /* yes, TRUE; see visor_periodic_work_stop() */
- goto unlock;
- } else if (queue_delayed_work(pw->workqueue, &pw->work,
- pw->jiffy_interval) < 0) {
- pw->is_scheduled = FALSE;
- rc = FALSE;
- goto unlock;
- }
- rc = TRUE;
-unlock:
- write_unlock(&pw->lock);
- return rc;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_nextperiod);
-
-/** This function returns TRUE iff new periodic work was actually started.
- * If this function returns FALSE, then no work was started
- * (either because it was already started, or because of a failure).
- */
-BOOL visor_periodic_work_start(struct periodic_work *pw)
-{
- BOOL rc = FALSE;
-
- write_lock(&pw->lock);
- if (pw->is_scheduled) {
- rc = FALSE;
- goto unlock;
- }
- if (pw->want_to_stop) {
- rc = FALSE;
- goto unlock;
- }
- INIT_DELAYED_WORK(&pw->work, &periodic_work_func);
- if (queue_delayed_work(pw->workqueue, &pw->work,
- pw->jiffy_interval) < 0) {
- rc = FALSE;
- goto unlock;
- }
- pw->is_scheduled = TRUE;
- rc = TRUE;
-unlock:
- write_unlock(&pw->lock);
- return rc;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_start);
-
-/** This function returns TRUE iff your call actually stopped the periodic
- * work.
- *
- * -- PAY ATTENTION... this is important --
- *
- * NO NO #1
- *
- * Do NOT call this function from some function that is running on the
- * same workqueue as the work you are trying to stop might be running
- * on! If you violate this rule, visor_periodic_work_stop() MIGHT work,
- * but it also MIGHT get hung up in an infinite loop saying
- * "waiting for delayed work...". This will happen if the delayed work
- * you are trying to cancel has been put in the workqueue list, but can't
- * run yet because we are running that same workqueue thread right now.
- *
- * Bottom line: If you need to call visor_periodic_work_stop() from a
- * workitem, be sure the workitem is on a DIFFERENT workqueue than the
- * workitem that you are trying to cancel.
- *
- * If I could figure out some way to check for this "no no" condition in
- * the code, I would. It would have saved me the trouble of writing this
- * long comment. And also, don't think this is some "theoretical" race
- * condition. It is REAL, as I have spent the day chasing it.
- *
- * NO NO #2
- *
- * Take close note of the locks that you own when you call this function.
- * You must NOT own any locks that are needed by the periodic work
- * function that is currently installed. If you DO, a deadlock may result,
- * because stopping the periodic work often involves waiting for the last
- * iteration of the periodic work function to complete. Again, if you hit
- * this deadlock, you will get hung up in an infinite loop saying
- * "waiting for delayed work...".
- */
-BOOL visor_periodic_work_stop(struct periodic_work *pw)
-{
- BOOL stopped_something = FALSE;
-
- write_lock(&pw->lock);
- stopped_something = pw->is_scheduled && (!pw->want_to_stop);
- while (pw->is_scheduled) {
- pw->want_to_stop = TRUE;
- if (cancel_delayed_work(&pw->work)) {
- /* We get here if the delayed work was pending as
- * delayed work, but was NOT run.
- */
- WARN_ON(!pw->is_scheduled);
- pw->is_scheduled = FALSE;
- } else {
- /* If we get here, either the delayed work:
- * - was run, OR,
- * - is running RIGHT NOW on another processor, OR,
- * - wasn't even scheduled (there is a miniscule
- * timing window where this could be the case)
- * flush_workqueue() would make sure it is finished
- * executing, but that still isn't very useful, which
- * explains the loop...
- */
- }
- if (pw->is_scheduled) {
- write_unlock(&pw->lock);
- SLEEPJIFFIES(10);
- write_lock(&pw->lock);
- } else {
- pw->want_to_stop = FALSE;
- }
- }
- write_unlock(&pw->lock);
- return stopped_something;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_stop);
diff --git a/drivers/staging/unisys/visorutil/visorkmodutils.c b/drivers/staging/unisys/visorutil/visorkmodutils.c
deleted file mode 100644
index 62f0f7046e17..000000000000
--- a/drivers/staging/unisys/visorutil/visorkmodutils.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* timskmodutils.c
- *
- * Copyright (C) 2010 - 2013 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 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#include "timskmod.h"
-
-#define MYDRVNAME "timskmodutils"
-
-/* s-Par uses the Intel processor's VT-X features to separate groups of
- * processors into partitions. The firmware sets the hypervisor bit and
- * reports an ID in the HV capabilities leaf so that the partition's OS
- * knows s-Par is present and managing the processors.
- */
-
-#define UNISYS_SPAR_LEAF_ID 0x40000000
-
-/* The s-Par leaf ID returns "UnisysSpar64" encoded across ebx, ecx, edx */
-#define UNISYS_SPAR_ID_EBX 0x73696e55
-#define UNISYS_SPAR_ID_ECX 0x70537379
-#define UNISYS_SPAR_ID_EDX 0x34367261
-
-int unisys_spar_platform;
-EXPORT_SYMBOL_GPL(unisys_spar_platform);
-
-static __init uint32_t visorutil_spar_detect(void)
-{
- unsigned int eax, ebx, ecx, edx;
-
- if (cpu_has_hypervisor) {
- /* check the ID */
- cpuid(UNISYS_SPAR_LEAF_ID, &eax, &ebx, &ecx, &edx);
- return (ebx == UNISYS_SPAR_ID_EBX) &&
- (ecx == UNISYS_SPAR_ID_ECX) &&
- (edx == UNISYS_SPAR_ID_EDX);
- } else {
- return 0;
- }
-}
-
-static __init int visorutil_mod_init(void)
-{
- if (visorutil_spar_detect()) {
- unisys_spar_platform = TRUE;
- return 0;
- } else {
- return -ENODEV;
- }
-}
-
-static __exit void
-visorutil_mod_exit(void)
-{
-}
-
-module_init(visorutil_mod_init);
-module_exit(visorutil_mod_exit);
-
-MODULE_LICENSE("GPL");