Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/platform/iris/iris.c
15125 views
1
/*
2
* Eurobraille/Iris power off support.
3
*
4
* Eurobraille's Iris machine is a PC with no APM or ACPI support.
5
* It is shutdown by a special I/O sequence which this module provides.
6
*
7
* Copyright (C) Shérab <[email protected]>
8
*
9
* This program is free software ; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation ; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with the program ; if not, write to the Free Software
21
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
*/
23
24
#include <linux/moduleparam.h>
25
#include <linux/module.h>
26
#include <linux/kernel.h>
27
#include <linux/errno.h>
28
#include <linux/delay.h>
29
#include <linux/init.h>
30
#include <linux/pm.h>
31
#include <asm/io.h>
32
33
#define IRIS_GIO_BASE 0x340
34
#define IRIS_GIO_INPUT IRIS_GIO_BASE
35
#define IRIS_GIO_OUTPUT (IRIS_GIO_BASE + 1)
36
#define IRIS_GIO_PULSE 0x80 /* First byte to send */
37
#define IRIS_GIO_REST 0x00 /* Second byte to send */
38
#define IRIS_GIO_NODEV 0xff /* Likely not an Iris */
39
40
MODULE_LICENSE("GPL");
41
MODULE_AUTHOR("Sébastien Hinderer <[email protected]>");
42
MODULE_DESCRIPTION("A power_off handler for Iris devices from EuroBraille");
43
MODULE_SUPPORTED_DEVICE("Eurobraille/Iris");
44
45
static int force;
46
47
module_param(force, bool, 0);
48
MODULE_PARM_DESC(force, "Set to one to force poweroff handler installation.");
49
50
static void (*old_pm_power_off)(void);
51
52
static void iris_power_off(void)
53
{
54
outb(IRIS_GIO_PULSE, IRIS_GIO_OUTPUT);
55
msleep(850);
56
outb(IRIS_GIO_REST, IRIS_GIO_OUTPUT);
57
}
58
59
/*
60
* Before installing the power_off handler, try to make sure the OS is
61
* running on an Iris. Since Iris does not support DMI, this is done
62
* by reading its input port and seeing whether the read value is
63
* meaningful.
64
*/
65
static int iris_init(void)
66
{
67
unsigned char status;
68
if (force != 1) {
69
printk(KERN_ERR "The force parameter has not been set to 1 so the Iris poweroff handler will not be installed.\n");
70
return -ENODEV;
71
}
72
status = inb(IRIS_GIO_INPUT);
73
if (status == IRIS_GIO_NODEV) {
74
printk(KERN_ERR "This machine does not seem to be an Iris. Power_off handler not installed.\n");
75
return -ENODEV;
76
}
77
old_pm_power_off = pm_power_off;
78
pm_power_off = &iris_power_off;
79
printk(KERN_INFO "Iris power_off handler installed.\n");
80
81
return 0;
82
}
83
84
static void iris_exit(void)
85
{
86
pm_power_off = old_pm_power_off;
87
printk(KERN_INFO "Iris power_off handler uninstalled.\n");
88
}
89
90
module_init(iris_init);
91
module_exit(iris_exit);
92
93