diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Kconfig | 31 | ||||
-rw-r--r-- | drivers/misc/Makefile | 2 | ||||
-rw-r--r-- | drivers/misc/ibmasm/ibmasm.h | 4 | ||||
-rw-r--r-- | drivers/misc/ibmasm/lowlevel.c | 4 | ||||
-rw-r--r-- | drivers/misc/ibmasm/remote.c | 14 | ||||
-rw-r--r-- | drivers/misc/ioc4.c | 474 | ||||
-rw-r--r-- | drivers/misc/lkdtm.c | 39 | ||||
-rw-r--r-- | drivers/misc/msi-laptop.c | 395 | ||||
-rw-r--r-- | drivers/misc/tifm_7xx1.c | 15 | ||||
-rw-r--r-- | drivers/misc/tifm_core.c | 2 |
10 files changed, 940 insertions, 40 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3df0e7a07c46..00db31c314e0 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -28,6 +28,18 @@ config IBM_ASM | |||
28 | 28 | ||
29 | If unsure, say N. | 29 | If unsure, say N. |
30 | 30 | ||
31 | config SGI_IOC4 | ||
32 | tristate "SGI IOC4 Base IO support" | ||
33 | depends on PCI | ||
34 | ---help--- | ||
35 | This option enables basic support for the IOC4 chip on certain | ||
36 | SGI IO controller cards (IO9, IO10, and PCI-RT). This option | ||
37 | does not enable any specific functions on such a card, but provides | ||
38 | necessary infrastructure for other drivers to utilize. | ||
39 | |||
40 | If you have an SGI Altix with an IOC4-based card say Y. | ||
41 | Otherwise say N. | ||
42 | |||
31 | config TIFM_CORE | 43 | config TIFM_CORE |
32 | tristate "TI Flash Media interface support (EXPERIMENTAL)" | 44 | tristate "TI Flash Media interface support (EXPERIMENTAL)" |
33 | depends on EXPERIMENTAL | 45 | depends on EXPERIMENTAL |
@@ -57,4 +69,23 @@ config TIFM_7XX1 | |||
57 | To compile this driver as a module, choose M here: the module will | 69 | To compile this driver as a module, choose M here: the module will |
58 | be called tifm_7xx1. | 70 | be called tifm_7xx1. |
59 | 71 | ||
72 | config MSI_LAPTOP | ||
73 | tristate "MSI Laptop Extras" | ||
74 | depends on X86 | ||
75 | depends on ACPI_EC | ||
76 | depends on BACKLIGHT_CLASS_DEVICE | ||
77 | ---help--- | ||
78 | This is a driver for laptops built by MSI (MICRO-STAR | ||
79 | INTERNATIONAL): | ||
80 | |||
81 | MSI MegaBook S270 (MS-1013) | ||
82 | Cytron/TCM/Medion/Tchibo MD96100/SAM2000 | ||
83 | |||
84 | It adds support for Bluetooth, WLAN and LCD brightness control. | ||
85 | |||
86 | More information about this driver is available at | ||
87 | <http://0pointer.de/lennart/tchibo.html>. | ||
88 | |||
89 | If you have an MSI S270 laptop, say Y or M here. | ||
90 | |||
60 | endmenu | 91 | endmenu |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index d65ece76095a..c9e98ab021c5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -5,6 +5,8 @@ obj- := misc.o # Dummy rule to force built-in.o to be made | |||
5 | 5 | ||
6 | obj-$(CONFIG_IBM_ASM) += ibmasm/ | 6 | obj-$(CONFIG_IBM_ASM) += ibmasm/ |
7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ | 7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ |
8 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o | ||
8 | obj-$(CONFIG_LKDTM) += lkdtm.o | 9 | obj-$(CONFIG_LKDTM) += lkdtm.o |
9 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o | 10 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o |
10 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o | 11 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o |
12 | obj-$(CONFIG_SGI_IOC4) += ioc4.o | ||
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index 634d538ccd14..48d5abebfc30 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h | |||
@@ -196,10 +196,10 @@ extern int ibmasm_send_os_state(struct service_processor *sp, int os_state); | |||
196 | 196 | ||
197 | /* low level message processing */ | 197 | /* low level message processing */ |
198 | extern int ibmasm_send_i2o_message(struct service_processor *sp); | 198 | extern int ibmasm_send_i2o_message(struct service_processor *sp); |
199 | extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs); | 199 | extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id); |
200 | 200 | ||
201 | /* remote console */ | 201 | /* remote console */ |
202 | extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs); | 202 | extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp); |
203 | extern int ibmasm_init_remote_input_dev(struct service_processor *sp); | 203 | extern int ibmasm_init_remote_input_dev(struct service_processor *sp); |
204 | extern void ibmasm_free_remote_input_dev(struct service_processor *sp); | 204 | extern void ibmasm_free_remote_input_dev(struct service_processor *sp); |
205 | 205 | ||
diff --git a/drivers/misc/ibmasm/lowlevel.c b/drivers/misc/ibmasm/lowlevel.c index 47949a2c7e94..a3c589b7cbfa 100644 --- a/drivers/misc/ibmasm/lowlevel.c +++ b/drivers/misc/ibmasm/lowlevel.c | |||
@@ -54,7 +54,7 @@ int ibmasm_send_i2o_message(struct service_processor *sp) | |||
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs) | 57 | irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id) |
58 | { | 58 | { |
59 | u32 mfa; | 59 | u32 mfa; |
60 | struct service_processor *sp = (struct service_processor *)dev_id; | 60 | struct service_processor *sp = (struct service_processor *)dev_id; |
@@ -67,7 +67,7 @@ irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *reg | |||
67 | dbg("respond to interrupt at %s\n", get_timestamp(tsbuf)); | 67 | dbg("respond to interrupt at %s\n", get_timestamp(tsbuf)); |
68 | 68 | ||
69 | if (mouse_interrupt_pending(sp)) { | 69 | if (mouse_interrupt_pending(sp)) { |
70 | ibmasm_handle_mouse_interrupt(sp, regs); | 70 | ibmasm_handle_mouse_interrupt(sp); |
71 | clear_mouse_interrupt(sp); | 71 | clear_mouse_interrupt(sp); |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c index 0f9e3aa34d07..a40fda6c402c 100644 --- a/drivers/misc/ibmasm/remote.c +++ b/drivers/misc/ibmasm/remote.c | |||
@@ -158,12 +158,10 @@ static void print_input(struct remote_input *input) | |||
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
161 | static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs, | 161 | static void send_mouse_event(struct input_dev *dev, struct remote_input *input) |
162 | struct remote_input *input) | ||
163 | { | 162 | { |
164 | unsigned char buttons = input->mouse_buttons; | 163 | unsigned char buttons = input->mouse_buttons; |
165 | 164 | ||
166 | input_regs(dev, regs); | ||
167 | input_report_abs(dev, ABS_X, input->data.mouse.x); | 165 | input_report_abs(dev, ABS_X, input->data.mouse.x); |
168 | input_report_abs(dev, ABS_Y, input->data.mouse.y); | 166 | input_report_abs(dev, ABS_Y, input->data.mouse.y); |
169 | input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT); | 167 | input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT); |
@@ -172,7 +170,7 @@ static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs, | |||
172 | input_sync(dev); | 170 | input_sync(dev); |
173 | } | 171 | } |
174 | 172 | ||
175 | static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs, | 173 | static void send_keyboard_event(struct input_dev *dev, |
176 | struct remote_input *input) | 174 | struct remote_input *input) |
177 | { | 175 | { |
178 | unsigned int key; | 176 | unsigned int key; |
@@ -182,13 +180,11 @@ static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs, | |||
182 | key = xlate_high[code & 0xff]; | 180 | key = xlate_high[code & 0xff]; |
183 | else | 181 | else |
184 | key = xlate[code]; | 182 | key = xlate[code]; |
185 | input_regs(dev, regs); | ||
186 | input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0); | 183 | input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0); |
187 | input_sync(dev); | 184 | input_sync(dev); |
188 | } | 185 | } |
189 | 186 | ||
190 | void ibmasm_handle_mouse_interrupt(struct service_processor *sp, | 187 | void ibmasm_handle_mouse_interrupt(struct service_processor *sp) |
191 | struct pt_regs *regs) | ||
192 | { | 188 | { |
193 | unsigned long reader; | 189 | unsigned long reader; |
194 | unsigned long writer; | 190 | unsigned long writer; |
@@ -203,9 +199,9 @@ void ibmasm_handle_mouse_interrupt(struct service_processor *sp, | |||
203 | 199 | ||
204 | print_input(&input); | 200 | print_input(&input); |
205 | if (input.type == INPUT_TYPE_MOUSE) { | 201 | if (input.type == INPUT_TYPE_MOUSE) { |
206 | send_mouse_event(sp->remote.mouse_dev, regs, &input); | 202 | send_mouse_event(sp->remote.mouse_dev, &input); |
207 | } else if (input.type == INPUT_TYPE_KEYBOARD) { | 203 | } else if (input.type == INPUT_TYPE_KEYBOARD) { |
208 | send_keyboard_event(sp->remote.keybd_dev, regs, &input); | 204 | send_keyboard_event(sp->remote.keybd_dev, &input); |
209 | } else | 205 | } else |
210 | break; | 206 | break; |
211 | 207 | ||
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c new file mode 100644 index 000000000000..b995a15b7526 --- /dev/null +++ b/drivers/misc/ioc4.c | |||
@@ -0,0 +1,474 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2005-2006 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | /* This file contains the master driver module for use by SGI IOC4 subdrivers. | ||
10 | * | ||
11 | * It allocates any resources shared between multiple subdevices, and | ||
12 | * provides accessor functions (where needed) and the like for those | ||
13 | * resources. It also provides a mechanism for the subdevice modules | ||
14 | * to support loading and unloading. | ||
15 | * | ||
16 | * Non-shared resources (e.g. external interrupt A_INT_OUT register page | ||
17 | * alias, serial port and UART registers) are handled by the subdevice | ||
18 | * modules themselves. | ||
19 | * | ||
20 | * This is all necessary because IOC4 is not implemented as a multi-function | ||
21 | * PCI device, but an amalgamation of disparate registers for several | ||
22 | * types of device (ATA, serial, external interrupts). The normal | ||
23 | * resource management in the kernel doesn't have quite the right interfaces | ||
24 | * to handle this situation (e.g. multiple modules can't claim the same | ||
25 | * PCI ID), thus this IOC4 master module. | ||
26 | */ | ||
27 | |||
28 | #include <linux/errno.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/pci.h> | ||
31 | #include <linux/ioc4.h> | ||
32 | #include <linux/ktime.h> | ||
33 | #include <linux/mutex.h> | ||
34 | #include <linux/time.h> | ||
35 | #include <asm/io.h> | ||
36 | |||
37 | /*************** | ||
38 | * Definitions * | ||
39 | ***************/ | ||
40 | |||
41 | /* Tweakable values */ | ||
42 | |||
43 | /* PCI bus speed detection/calibration */ | ||
44 | #define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ | ||
45 | #define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ | ||
46 | #define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ | ||
47 | #define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ | ||
48 | #define IOC4_CALIBRATE_HIGH_MHZ 75 /* Upper bound on bus speed sanity */ | ||
49 | #define IOC4_CALIBRATE_DEFAULT_MHZ 66 /* Assumed if sanity check fails */ | ||
50 | |||
51 | /************************ | ||
52 | * Submodule management * | ||
53 | ************************/ | ||
54 | |||
55 | static DEFINE_MUTEX(ioc4_mutex); | ||
56 | |||
57 | static LIST_HEAD(ioc4_devices); | ||
58 | static LIST_HEAD(ioc4_submodules); | ||
59 | |||
60 | /* Register an IOC4 submodule */ | ||
61 | int | ||
62 | ioc4_register_submodule(struct ioc4_submodule *is) | ||
63 | { | ||
64 | struct ioc4_driver_data *idd; | ||
65 | |||
66 | mutex_lock(&ioc4_mutex); | ||
67 | list_add(&is->is_list, &ioc4_submodules); | ||
68 | |||
69 | /* Initialize submodule for each IOC4 */ | ||
70 | if (!is->is_probe) | ||
71 | goto out; | ||
72 | |||
73 | list_for_each_entry(idd, &ioc4_devices, idd_list) { | ||
74 | if (is->is_probe(idd)) { | ||
75 | printk(KERN_WARNING | ||
76 | "%s: IOC4 submodule %s probe failed " | ||
77 | "for pci_dev %s", | ||
78 | __FUNCTION__, module_name(is->is_owner), | ||
79 | pci_name(idd->idd_pdev)); | ||
80 | } | ||
81 | } | ||
82 | out: | ||
83 | mutex_unlock(&ioc4_mutex); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* Unregister an IOC4 submodule */ | ||
88 | void | ||
89 | ioc4_unregister_submodule(struct ioc4_submodule *is) | ||
90 | { | ||
91 | struct ioc4_driver_data *idd; | ||
92 | |||
93 | mutex_lock(&ioc4_mutex); | ||
94 | list_del(&is->is_list); | ||
95 | |||
96 | /* Remove submodule for each IOC4 */ | ||
97 | if (!is->is_remove) | ||
98 | goto out; | ||
99 | |||
100 | list_for_each_entry(idd, &ioc4_devices, idd_list) { | ||
101 | if (is->is_remove(idd)) { | ||
102 | printk(KERN_WARNING | ||
103 | "%s: IOC4 submodule %s remove failed " | ||
104 | "for pci_dev %s.\n", | ||
105 | __FUNCTION__, module_name(is->is_owner), | ||
106 | pci_name(idd->idd_pdev)); | ||
107 | } | ||
108 | } | ||
109 | out: | ||
110 | mutex_unlock(&ioc4_mutex); | ||
111 | } | ||
112 | |||
113 | /********************* | ||
114 | * Device management * | ||
115 | *********************/ | ||
116 | |||
117 | #define IOC4_CALIBRATE_LOW_LIMIT \ | ||
118 | (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ) | ||
119 | #define IOC4_CALIBRATE_HIGH_LIMIT \ | ||
120 | (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ) | ||
121 | #define IOC4_CALIBRATE_DEFAULT \ | ||
122 | (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ) | ||
123 | |||
124 | #define IOC4_CALIBRATE_END \ | ||
125 | (IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD) | ||
126 | |||
127 | #define IOC4_INT_OUT_MODE_TOGGLE 0x7 /* Toggle INT_OUT every COUNT+1 ticks */ | ||
128 | |||
129 | /* Determines external interrupt output clock period of the PCI bus an | ||
130 | * IOC4 is attached to. This value can be used to determine the PCI | ||
131 | * bus speed. | ||
132 | * | ||
133 | * IOC4 has a design feature that various internal timers are derived from | ||
134 | * the PCI bus clock. This causes IOC4 device drivers to need to take the | ||
135 | * bus speed into account when setting various register values (e.g. INT_OUT | ||
136 | * register COUNT field, UART divisors, etc). Since this information is | ||
137 | * needed by several subdrivers, it is determined by the main IOC4 driver, | ||
138 | * even though the following code utilizes external interrupt registers | ||
139 | * to perform the speed calculation. | ||
140 | */ | ||
141 | static void | ||
142 | ioc4_clock_calibrate(struct ioc4_driver_data *idd) | ||
143 | { | ||
144 | union ioc4_int_out int_out; | ||
145 | union ioc4_gpcr gpcr; | ||
146 | unsigned int state, last_state = 1; | ||
147 | struct timespec start_ts, end_ts; | ||
148 | uint64_t start, end, period; | ||
149 | unsigned int count = 0; | ||
150 | |||
151 | /* Enable output */ | ||
152 | gpcr.raw = 0; | ||
153 | gpcr.fields.dir = IOC4_GPCR_DIR_0; | ||
154 | gpcr.fields.int_out_en = 1; | ||
155 | writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw); | ||
156 | |||
157 | /* Reset to power-on state */ | ||
158 | writel(0, &idd->idd_misc_regs->int_out.raw); | ||
159 | mmiowb(); | ||
160 | |||
161 | /* Set up square wave */ | ||
162 | int_out.raw = 0; | ||
163 | int_out.fields.count = IOC4_CALIBRATE_COUNT; | ||
164 | int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE; | ||
165 | int_out.fields.diag = 0; | ||
166 | writel(int_out.raw, &idd->idd_misc_regs->int_out.raw); | ||
167 | mmiowb(); | ||
168 | |||
169 | /* Check square wave period averaged over some number of cycles */ | ||
170 | do { | ||
171 | int_out.raw = readl(&idd->idd_misc_regs->int_out.raw); | ||
172 | state = int_out.fields.int_out; | ||
173 | if (!last_state && state) { | ||
174 | count++; | ||
175 | if (count == IOC4_CALIBRATE_END) { | ||
176 | ktime_get_ts(&end_ts); | ||
177 | break; | ||
178 | } else if (count == IOC4_CALIBRATE_DISCARD) | ||
179 | ktime_get_ts(&start_ts); | ||
180 | } | ||
181 | last_state = state; | ||
182 | } while (1); | ||
183 | |||
184 | /* Calculation rearranged to preserve intermediate precision. | ||
185 | * Logically: | ||
186 | * 1. "end - start" gives us the measurement period over all | ||
187 | * the square wave cycles. | ||
188 | * 2. Divide by number of square wave cycles to get the period | ||
189 | * of a square wave cycle. | ||
190 | * 3. Divide by 2*(int_out.fields.count+1), which is the formula | ||
191 | * by which the IOC4 generates the square wave, to get the | ||
192 | * period of an IOC4 INT_OUT count. | ||
193 | */ | ||
194 | end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec; | ||
195 | start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec; | ||
196 | period = (end - start) / | ||
197 | (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1)); | ||
198 | |||
199 | /* Bounds check the result. */ | ||
200 | if (period > IOC4_CALIBRATE_LOW_LIMIT || | ||
201 | period < IOC4_CALIBRATE_HIGH_LIMIT) { | ||
202 | printk(KERN_INFO | ||
203 | "IOC4 %s: Clock calibration failed. Assuming" | ||
204 | "PCI clock is %d ns.\n", | ||
205 | pci_name(idd->idd_pdev), | ||
206 | IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); | ||
207 | period = IOC4_CALIBRATE_DEFAULT; | ||
208 | } else { | ||
209 | u64 ns = period; | ||
210 | |||
211 | do_div(ns, IOC4_EXTINT_COUNT_DIVISOR); | ||
212 | printk(KERN_DEBUG | ||
213 | "IOC4 %s: PCI clock is %llu ns.\n", | ||
214 | pci_name(idd->idd_pdev), (unsigned long long)ns); | ||
215 | } | ||
216 | |||
217 | /* Remember results. We store the extint clock period rather | ||
218 | * than the PCI clock period so that greater precision is | ||
219 | * retained. Divide by IOC4_EXTINT_COUNT_DIVISOR to get | ||
220 | * PCI clock period. | ||
221 | */ | ||
222 | idd->count_period = period; | ||
223 | } | ||
224 | |||
225 | /* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT. | ||
226 | * Each brings out different combinations of IOC4 signals, thus. | ||
227 | * the IOC4 subdrivers need to know to which we're attached. | ||
228 | * | ||
229 | * We look for the presence of a SCSI (IO9) or SATA (IO10) controller | ||
230 | * on the same PCI bus at slot number 3 to differentiate IO9 from IO10. | ||
231 | * If neither is present, it's a PCI-RT. | ||
232 | */ | ||
233 | static unsigned int | ||
234 | ioc4_variant(struct ioc4_driver_data *idd) | ||
235 | { | ||
236 | struct pci_dev *pdev = NULL; | ||
237 | int found = 0; | ||
238 | |||
239 | /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */ | ||
240 | do { | ||
241 | pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC, | ||
242 | PCI_DEVICE_ID_QLOGIC_ISP12160, pdev); | ||
243 | if (pdev && | ||
244 | idd->idd_pdev->bus->number == pdev->bus->number && | ||
245 | 3 == PCI_SLOT(pdev->devfn)) | ||
246 | found = 1; | ||
247 | pci_dev_put(pdev); | ||
248 | } while (pdev && !found); | ||
249 | if (NULL != pdev) | ||
250 | return IOC4_VARIANT_IO9; | ||
251 | |||
252 | /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */ | ||
253 | pdev = NULL; | ||
254 | do { | ||
255 | pdev = pci_get_device(PCI_VENDOR_ID_VITESSE, | ||
256 | PCI_DEVICE_ID_VITESSE_VSC7174, pdev); | ||
257 | if (pdev && | ||
258 | idd->idd_pdev->bus->number == pdev->bus->number && | ||
259 | 3 == PCI_SLOT(pdev->devfn)) | ||
260 | found = 1; | ||
261 | pci_dev_put(pdev); | ||
262 | } while (pdev && !found); | ||
263 | if (NULL != pdev) | ||
264 | return IOC4_VARIANT_IO10; | ||
265 | |||
266 | /* PCI-RT: No SCSI/SATA controller will be present */ | ||
267 | return IOC4_VARIANT_PCI_RT; | ||
268 | } | ||
269 | |||
270 | /* Adds a new instance of an IOC4 card */ | ||
271 | static int | ||
272 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
273 | { | ||
274 | struct ioc4_driver_data *idd; | ||
275 | struct ioc4_submodule *is; | ||
276 | uint32_t pcmd; | ||
277 | int ret; | ||
278 | |||
279 | /* Enable IOC4 and take ownership of it */ | ||
280 | if ((ret = pci_enable_device(pdev))) { | ||
281 | printk(KERN_WARNING | ||
282 | "%s: Failed to enable IOC4 device for pci_dev %s.\n", | ||
283 | __FUNCTION__, pci_name(pdev)); | ||
284 | goto out; | ||
285 | } | ||
286 | pci_set_master(pdev); | ||
287 | |||
288 | /* Set up per-IOC4 data */ | ||
289 | idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL); | ||
290 | if (!idd) { | ||
291 | printk(KERN_WARNING | ||
292 | "%s: Failed to allocate IOC4 data for pci_dev %s.\n", | ||
293 | __FUNCTION__, pci_name(pdev)); | ||
294 | ret = -ENODEV; | ||
295 | goto out_idd; | ||
296 | } | ||
297 | idd->idd_pdev = pdev; | ||
298 | idd->idd_pci_id = pci_id; | ||
299 | |||
300 | /* Map IOC4 misc registers. These are shared between subdevices | ||
301 | * so the main IOC4 module manages them. | ||
302 | */ | ||
303 | idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0); | ||
304 | if (!idd->idd_bar0) { | ||
305 | printk(KERN_WARNING | ||
306 | "%s: Unable to find IOC4 misc resource " | ||
307 | "for pci_dev %s.\n", | ||
308 | __FUNCTION__, pci_name(idd->idd_pdev)); | ||
309 | ret = -ENODEV; | ||
310 | goto out_pci; | ||
311 | } | ||
312 | if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs), | ||
313 | "ioc4_misc")) { | ||
314 | printk(KERN_WARNING | ||
315 | "%s: Unable to request IOC4 misc region " | ||
316 | "for pci_dev %s.\n", | ||
317 | __FUNCTION__, pci_name(idd->idd_pdev)); | ||
318 | ret = -ENODEV; | ||
319 | goto out_pci; | ||
320 | } | ||
321 | idd->idd_misc_regs = ioremap(idd->idd_bar0, | ||
322 | sizeof(struct ioc4_misc_regs)); | ||
323 | if (!idd->idd_misc_regs) { | ||
324 | printk(KERN_WARNING | ||
325 | "%s: Unable to remap IOC4 misc region " | ||
326 | "for pci_dev %s.\n", | ||
327 | __FUNCTION__, pci_name(idd->idd_pdev)); | ||
328 | ret = -ENODEV; | ||
329 | goto out_misc_region; | ||
330 | } | ||
331 | |||
332 | /* Failsafe portion of per-IOC4 initialization */ | ||
333 | |||
334 | /* Detect card variant */ | ||
335 | idd->idd_variant = ioc4_variant(idd); | ||
336 | printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev), | ||
337 | idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" : | ||
338 | idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" : | ||
339 | idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown"); | ||
340 | |||
341 | /* Initialize IOC4 */ | ||
342 | pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd); | ||
343 | pci_write_config_dword(idd->idd_pdev, PCI_COMMAND, | ||
344 | pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | ||
345 | |||
346 | /* Determine PCI clock */ | ||
347 | ioc4_clock_calibrate(idd); | ||
348 | |||
349 | /* Disable/clear all interrupts. Need to do this here lest | ||
350 | * one submodule request the shared IOC4 IRQ, but interrupt | ||
351 | * is generated by a different subdevice. | ||
352 | */ | ||
353 | /* Disable */ | ||
354 | writel(~0, &idd->idd_misc_regs->other_iec.raw); | ||
355 | writel(~0, &idd->idd_misc_regs->sio_iec); | ||
356 | /* Clear (i.e. acknowledge) */ | ||
357 | writel(~0, &idd->idd_misc_regs->other_ir.raw); | ||
358 | writel(~0, &idd->idd_misc_regs->sio_ir); | ||
359 | |||
360 | /* Track PCI-device specific data */ | ||
361 | idd->idd_serial_data = NULL; | ||
362 | pci_set_drvdata(idd->idd_pdev, idd); | ||
363 | |||
364 | mutex_lock(&ioc4_mutex); | ||
365 | list_add_tail(&idd->idd_list, &ioc4_devices); | ||
366 | |||
367 | /* Add this IOC4 to all submodules */ | ||
368 | list_for_each_entry(is, &ioc4_submodules, is_list) { | ||
369 | if (is->is_probe && is->is_probe(idd)) { | ||
370 | printk(KERN_WARNING | ||
371 | "%s: IOC4 submodule 0x%s probe failed " | ||
372 | "for pci_dev %s.\n", | ||
373 | __FUNCTION__, module_name(is->is_owner), | ||
374 | pci_name(idd->idd_pdev)); | ||
375 | } | ||
376 | } | ||
377 | mutex_unlock(&ioc4_mutex); | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | out_misc_region: | ||
382 | release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); | ||
383 | out_pci: | ||
384 | kfree(idd); | ||
385 | out_idd: | ||
386 | pci_disable_device(pdev); | ||
387 | out: | ||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | /* Removes a particular instance of an IOC4 card. */ | ||
392 | static void | ||
393 | ioc4_remove(struct pci_dev *pdev) | ||
394 | { | ||
395 | struct ioc4_submodule *is; | ||
396 | struct ioc4_driver_data *idd; | ||
397 | |||
398 | idd = pci_get_drvdata(pdev); | ||
399 | |||
400 | /* Remove this IOC4 from all submodules */ | ||
401 | mutex_lock(&ioc4_mutex); | ||
402 | list_for_each_entry(is, &ioc4_submodules, is_list) { | ||
403 | if (is->is_remove && is->is_remove(idd)) { | ||
404 | printk(KERN_WARNING | ||
405 | "%s: IOC4 submodule 0x%s remove failed " | ||
406 | "for pci_dev %s.\n", | ||
407 | __FUNCTION__, module_name(is->is_owner), | ||
408 | pci_name(idd->idd_pdev)); | ||
409 | } | ||
410 | } | ||
411 | mutex_unlock(&ioc4_mutex); | ||
412 | |||
413 | /* Release resources */ | ||
414 | iounmap(idd->idd_misc_regs); | ||
415 | if (!idd->idd_bar0) { | ||
416 | printk(KERN_WARNING | ||
417 | "%s: Unable to get IOC4 misc mapping for pci_dev %s. " | ||
418 | "Device removal may be incomplete.\n", | ||
419 | __FUNCTION__, pci_name(idd->idd_pdev)); | ||
420 | } | ||
421 | release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); | ||
422 | |||
423 | /* Disable IOC4 and relinquish */ | ||
424 | pci_disable_device(pdev); | ||
425 | |||
426 | /* Remove and free driver data */ | ||
427 | mutex_lock(&ioc4_mutex); | ||
428 | list_del(&idd->idd_list); | ||
429 | mutex_unlock(&ioc4_mutex); | ||
430 | kfree(idd); | ||
431 | } | ||
432 | |||
433 | static struct pci_device_id ioc4_id_table[] = { | ||
434 | {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID, | ||
435 | PCI_ANY_ID, 0x0b4000, 0xFFFFFF}, | ||
436 | {0} | ||
437 | }; | ||
438 | |||
439 | static struct pci_driver ioc4_driver = { | ||
440 | .name = "IOC4", | ||
441 | .id_table = ioc4_id_table, | ||
442 | .probe = ioc4_probe, | ||
443 | .remove = ioc4_remove, | ||
444 | }; | ||
445 | |||
446 | MODULE_DEVICE_TABLE(pci, ioc4_id_table); | ||
447 | |||
448 | /********************* | ||
449 | * Module management * | ||
450 | *********************/ | ||
451 | |||
452 | /* Module load */ | ||
453 | static int __devinit | ||
454 | ioc4_init(void) | ||
455 | { | ||
456 | return pci_register_driver(&ioc4_driver); | ||
457 | } | ||
458 | |||
459 | /* Module unload */ | ||
460 | static void __devexit | ||
461 | ioc4_exit(void) | ||
462 | { | ||
463 | pci_unregister_driver(&ioc4_driver); | ||
464 | } | ||
465 | |||
466 | module_init(ioc4_init); | ||
467 | module_exit(ioc4_exit); | ||
468 | |||
469 | MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>"); | ||
470 | MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card"); | ||
471 | MODULE_LICENSE("GPL"); | ||
472 | |||
473 | EXPORT_SYMBOL(ioc4_register_submodule); | ||
474 | EXPORT_SYMBOL(ioc4_unregister_submodule); | ||
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index e689ee94ac3d..db9d7df75ae0 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
@@ -44,12 +44,14 @@ | |||
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/fs.h> | ||
47 | #include <linux/module.h> | 48 | #include <linux/module.h> |
49 | #include <linux/buffer_head.h> | ||
48 | #include <linux/kprobes.h> | 50 | #include <linux/kprobes.h> |
49 | #include <linux/kallsyms.h> | 51 | #include <linux/list.h> |
50 | #include <linux/init.h> | 52 | #include <linux/init.h> |
51 | #include <linux/irq.h> | ||
52 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/hrtimer.h> | ||
53 | #include <scsi/scsi_cmnd.h> | 55 | #include <scsi/scsi_cmnd.h> |
54 | 56 | ||
55 | #ifdef CONFIG_IDE | 57 | #ifdef CONFIG_IDE |
@@ -116,26 +118,25 @@ static enum ctype cptype = NONE; | |||
116 | static int count = DEFAULT_COUNT; | 118 | static int count = DEFAULT_COUNT; |
117 | 119 | ||
118 | module_param(recur_count, int, 0644); | 120 | module_param(recur_count, int, 0644); |
119 | MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\ | 121 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ |
120 | default is 10"); | 122 | "default is 10"); |
121 | module_param(cpoint_name, charp, 0644); | 123 | module_param(cpoint_name, charp, 0644); |
122 | MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed"); | 124 | MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); |
123 | module_param(cpoint_type, charp, 06444); | 125 | module_param(cpoint_type, charp, 0644); |
124 | MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\ | 126 | MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ |
125 | hitting the crash point"); | 127 | "hitting the crash point"); |
126 | module_param(cpoint_count, int, 06444); | 128 | module_param(cpoint_count, int, 0644); |
127 | MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \ | 129 | MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ |
128 | crash point is to be hit to trigger action"); | 130 | "crash point is to be hit to trigger action"); |
129 | 131 | ||
130 | unsigned int jp_do_irq(unsigned int irq, struct pt_regs *regs) | 132 | unsigned int jp_do_irq(unsigned int irq) |
131 | { | 133 | { |
132 | lkdtm_handler(); | 134 | lkdtm_handler(); |
133 | jprobe_return(); | 135 | jprobe_return(); |
134 | return 0; | 136 | return 0; |
135 | } | 137 | } |
136 | 138 | ||
137 | irqreturn_t jp_handle_irq_event(unsigned int irq, struct pt_regs *regs, | 139 | irqreturn_t jp_handle_irq_event(unsigned int irq, struct irqaction *action) |
138 | struct irqaction *action) | ||
139 | { | 140 | { |
140 | lkdtm_handler(); | 141 | lkdtm_handler(); |
141 | jprobe_return(); | 142 | jprobe_return(); |
@@ -156,8 +157,8 @@ void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
156 | 157 | ||
157 | struct scan_control; | 158 | struct scan_control; |
158 | 159 | ||
159 | unsigned long jp_shrink_page_list(struct list_head *page_list, | 160 | unsigned long jp_shrink_inactive_list(unsigned long max_scan, |
160 | struct scan_control *sc) | 161 | struct zone *zone, struct scan_control *sc) |
161 | { | 162 | { |
162 | lkdtm_handler(); | 163 | lkdtm_handler(); |
163 | jprobe_return(); | 164 | jprobe_return(); |
@@ -296,8 +297,8 @@ int lkdtm_module_init(void) | |||
296 | lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; | 297 | lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; |
297 | break; | 298 | break; |
298 | case MEM_SWAPOUT: | 299 | case MEM_SWAPOUT: |
299 | lkdtm.kp.symbol_name = "shrink_page_list"; | 300 | lkdtm.kp.symbol_name = "shrink_inactive_list"; |
300 | lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list; | 301 | lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list; |
301 | break; | 302 | break; |
302 | case TIMERADD: | 303 | case TIMERADD: |
303 | lkdtm.kp.symbol_name = "hrtimer_start"; | 304 | lkdtm.kp.symbol_name = "hrtimer_start"; |
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c new file mode 100644 index 000000000000..fdb7153f4426 --- /dev/null +++ b/drivers/misc/msi-laptop.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /*-*-linux-c-*-*/ | ||
2 | |||
3 | /* | ||
4 | Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
19 | 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * msi-laptop.c - MSI S270 laptop support. This laptop is sold under | ||
24 | * various brands, including "Cytron/TCM/Medion/Tchibo MD96100". | ||
25 | * | ||
26 | * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/: | ||
27 | * | ||
28 | * lcd_level - Screen brightness: contains a single integer in the | ||
29 | * range 0..8. (rw) | ||
30 | * | ||
31 | * auto_brightness - Enable automatic brightness control: contains | ||
32 | * either 0 or 1. If set to 1 the hardware adjusts the screen | ||
33 | * brightness automatically when the power cord is | ||
34 | * plugged/unplugged. (rw) | ||
35 | * | ||
36 | * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro) | ||
37 | * | ||
38 | * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1 | ||
39 | * Please note that this file is constantly 0 if no Bluetooth | ||
40 | * hardware is available. (ro) | ||
41 | * | ||
42 | * In addition to these platform device attributes the driver | ||
43 | * registers itself in the Linux backlight control subsystem and is | ||
44 | * available to userspace under /sys/class/backlight/msi-laptop-bl/. | ||
45 | * | ||
46 | * This driver might work on other laptops produced by MSI. If you | ||
47 | * want to try it you can pass force=1 as argument to the module which | ||
48 | * will force it to load even when the DMI data doesn't identify the | ||
49 | * laptop as MSI S270. YMMV. | ||
50 | */ | ||
51 | |||
52 | #include <linux/module.h> | ||
53 | #include <linux/kernel.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/acpi.h> | ||
56 | #include <linux/dmi.h> | ||
57 | #include <linux/backlight.h> | ||
58 | #include <linux/platform_device.h> | ||
59 | #include <linux/autoconf.h> | ||
60 | |||
61 | #define MSI_DRIVER_VERSION "0.5" | ||
62 | |||
63 | #define MSI_LCD_LEVEL_MAX 9 | ||
64 | |||
65 | #define MSI_EC_COMMAND_WIRELESS 0x10 | ||
66 | #define MSI_EC_COMMAND_LCD_LEVEL 0x11 | ||
67 | |||
68 | static int force; | ||
69 | module_param(force, bool, 0); | ||
70 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | ||
71 | |||
72 | static int auto_brightness; | ||
73 | module_param(auto_brightness, int, 0); | ||
74 | MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); | ||
75 | |||
76 | /* Hardware access */ | ||
77 | |||
78 | static int set_lcd_level(int level) | ||
79 | { | ||
80 | u8 buf[2]; | ||
81 | |||
82 | if (level < 0 || level >= MSI_LCD_LEVEL_MAX) | ||
83 | return -EINVAL; | ||
84 | |||
85 | buf[0] = 0x80; | ||
86 | buf[1] = (u8) (level*31); | ||
87 | |||
88 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0); | ||
89 | } | ||
90 | |||
91 | static int get_lcd_level(void) | ||
92 | { | ||
93 | u8 wdata = 0, rdata; | ||
94 | int result; | ||
95 | |||
96 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); | ||
97 | if (result < 0) | ||
98 | return result; | ||
99 | |||
100 | return (int) rdata / 31; | ||
101 | } | ||
102 | |||
103 | static int get_auto_brightness(void) | ||
104 | { | ||
105 | u8 wdata = 4, rdata; | ||
106 | int result; | ||
107 | |||
108 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); | ||
109 | if (result < 0) | ||
110 | return result; | ||
111 | |||
112 | return !!(rdata & 8); | ||
113 | } | ||
114 | |||
115 | static int set_auto_brightness(int enable) | ||
116 | { | ||
117 | u8 wdata[2], rdata; | ||
118 | int result; | ||
119 | |||
120 | wdata[0] = 4; | ||
121 | |||
122 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1); | ||
123 | if (result < 0) | ||
124 | return result; | ||
125 | |||
126 | wdata[0] = 0x84; | ||
127 | wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); | ||
128 | |||
129 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0); | ||
130 | } | ||
131 | |||
132 | static int get_wireless_state(int *wlan, int *bluetooth) | ||
133 | { | ||
134 | u8 wdata = 0, rdata; | ||
135 | int result; | ||
136 | |||
137 | result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); | ||
138 | if (result < 0) | ||
139 | return -1; | ||
140 | |||
141 | if (wlan) | ||
142 | *wlan = !!(rdata & 8); | ||
143 | |||
144 | if (bluetooth) | ||
145 | *bluetooth = !!(rdata & 128); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | /* Backlight device stuff */ | ||
151 | |||
152 | static int bl_get_brightness(struct backlight_device *b) | ||
153 | { | ||
154 | return get_lcd_level(); | ||
155 | } | ||
156 | |||
157 | |||
158 | static int bl_update_status(struct backlight_device *b) | ||
159 | { | ||
160 | return set_lcd_level(b->props->brightness); | ||
161 | } | ||
162 | |||
163 | static struct backlight_properties msibl_props = { | ||
164 | .owner = THIS_MODULE, | ||
165 | .get_brightness = bl_get_brightness, | ||
166 | .update_status = bl_update_status, | ||
167 | .max_brightness = MSI_LCD_LEVEL_MAX-1, | ||
168 | }; | ||
169 | |||
170 | static struct backlight_device *msibl_device; | ||
171 | |||
172 | /* Platform device */ | ||
173 | |||
174 | static ssize_t show_wlan(struct device *dev, | ||
175 | struct device_attribute *attr, char *buf) | ||
176 | { | ||
177 | |||
178 | int ret, enabled; | ||
179 | |||
180 | ret = get_wireless_state(&enabled, NULL); | ||
181 | if (ret < 0) | ||
182 | return ret; | ||
183 | |||
184 | return sprintf(buf, "%i\n", enabled); | ||
185 | } | ||
186 | |||
187 | static ssize_t show_bluetooth(struct device *dev, | ||
188 | struct device_attribute *attr, char *buf) | ||
189 | { | ||
190 | |||
191 | int ret, enabled; | ||
192 | |||
193 | ret = get_wireless_state(NULL, &enabled); | ||
194 | if (ret < 0) | ||
195 | return ret; | ||
196 | |||
197 | return sprintf(buf, "%i\n", enabled); | ||
198 | } | ||
199 | |||
200 | static ssize_t show_lcd_level(struct device *dev, | ||
201 | struct device_attribute *attr, char *buf) | ||
202 | { | ||
203 | |||
204 | int ret; | ||
205 | |||
206 | ret = get_lcd_level(); | ||
207 | if (ret < 0) | ||
208 | return ret; | ||
209 | |||
210 | return sprintf(buf, "%i\n", ret); | ||
211 | } | ||
212 | |||
213 | static ssize_t store_lcd_level(struct device *dev, | ||
214 | struct device_attribute *attr, const char *buf, size_t count) | ||
215 | { | ||
216 | |||
217 | int level, ret; | ||
218 | |||
219 | if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) | ||
220 | return -EINVAL; | ||
221 | |||
222 | ret = set_lcd_level(level); | ||
223 | if (ret < 0) | ||
224 | return ret; | ||
225 | |||
226 | return count; | ||
227 | } | ||
228 | |||
229 | static ssize_t show_auto_brightness(struct device *dev, | ||
230 | struct device_attribute *attr, char *buf) | ||
231 | { | ||
232 | |||
233 | int ret; | ||
234 | |||
235 | ret = get_auto_brightness(); | ||
236 | if (ret < 0) | ||
237 | return ret; | ||
238 | |||
239 | return sprintf(buf, "%i\n", ret); | ||
240 | } | ||
241 | |||
242 | static ssize_t store_auto_brightness(struct device *dev, | ||
243 | struct device_attribute *attr, const char *buf, size_t count) | ||
244 | { | ||
245 | |||
246 | int enable, ret; | ||
247 | |||
248 | if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1))) | ||
249 | return -EINVAL; | ||
250 | |||
251 | ret = set_auto_brightness(enable); | ||
252 | if (ret < 0) | ||
253 | return ret; | ||
254 | |||
255 | return count; | ||
256 | } | ||
257 | |||
258 | static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); | ||
259 | static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); | ||
260 | static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); | ||
261 | static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); | ||
262 | |||
263 | static struct attribute *msipf_attributes[] = { | ||
264 | &dev_attr_lcd_level.attr, | ||
265 | &dev_attr_auto_brightness.attr, | ||
266 | &dev_attr_bluetooth.attr, | ||
267 | &dev_attr_wlan.attr, | ||
268 | NULL | ||
269 | }; | ||
270 | |||
271 | static struct attribute_group msipf_attribute_group = { | ||
272 | .attrs = msipf_attributes | ||
273 | }; | ||
274 | |||
275 | static struct platform_driver msipf_driver = { | ||
276 | .driver = { | ||
277 | .name = "msi-laptop-pf", | ||
278 | .owner = THIS_MODULE, | ||
279 | } | ||
280 | }; | ||
281 | |||
282 | static struct platform_device *msipf_device; | ||
283 | |||
284 | /* Initialization */ | ||
285 | |||
286 | static struct dmi_system_id __initdata msi_dmi_table[] = { | ||
287 | { | ||
288 | .ident = "MSI S270", | ||
289 | .matches = { | ||
290 | DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), | ||
291 | DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), | ||
292 | } | ||
293 | }, | ||
294 | { | ||
295 | .ident = "Medion MD96100", | ||
296 | .matches = { | ||
297 | DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), | ||
298 | DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), | ||
299 | } | ||
300 | }, | ||
301 | { } | ||
302 | }; | ||
303 | |||
304 | |||
305 | static int __init msi_init(void) | ||
306 | { | ||
307 | int ret; | ||
308 | |||
309 | if (acpi_disabled) | ||
310 | return -ENODEV; | ||
311 | |||
312 | if (!force && !dmi_check_system(msi_dmi_table)) | ||
313 | return -ENODEV; | ||
314 | |||
315 | if (auto_brightness < 0 || auto_brightness > 2) | ||
316 | return -EINVAL; | ||
317 | |||
318 | /* Register backlight stuff */ | ||
319 | |||
320 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props); | ||
321 | if (IS_ERR(msibl_device)) | ||
322 | return PTR_ERR(msibl_device); | ||
323 | |||
324 | ret = platform_driver_register(&msipf_driver); | ||
325 | if (ret) | ||
326 | goto fail_backlight; | ||
327 | |||
328 | /* Register platform stuff */ | ||
329 | |||
330 | msipf_device = platform_device_alloc("msi-laptop-pf", -1); | ||
331 | if (!msipf_device) { | ||
332 | ret = -ENOMEM; | ||
333 | goto fail_platform_driver; | ||
334 | } | ||
335 | |||
336 | ret = platform_device_add(msipf_device); | ||
337 | if (ret) | ||
338 | goto fail_platform_device1; | ||
339 | |||
340 | ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); | ||
341 | if (ret) | ||
342 | goto fail_platform_device2; | ||
343 | |||
344 | /* Disable automatic brightness control by default because | ||
345 | * this module was probably loaded to do brightness control in | ||
346 | * software. */ | ||
347 | |||
348 | if (auto_brightness != 2) | ||
349 | set_auto_brightness(auto_brightness); | ||
350 | |||
351 | printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n"); | ||
352 | |||
353 | return 0; | ||
354 | |||
355 | fail_platform_device2: | ||
356 | |||
357 | platform_device_del(msipf_device); | ||
358 | |||
359 | fail_platform_device1: | ||
360 | |||
361 | platform_device_put(msipf_device); | ||
362 | |||
363 | fail_platform_driver: | ||
364 | |||
365 | platform_driver_unregister(&msipf_driver); | ||
366 | |||
367 | fail_backlight: | ||
368 | |||
369 | backlight_device_unregister(msibl_device); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static void __exit msi_cleanup(void) | ||
375 | { | ||
376 | |||
377 | sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); | ||
378 | platform_device_unregister(msipf_device); | ||
379 | platform_driver_unregister(&msipf_driver); | ||
380 | backlight_device_unregister(msibl_device); | ||
381 | |||
382 | /* Enable automatic brightness control again */ | ||
383 | if (auto_brightness != 2) | ||
384 | set_auto_brightness(1); | ||
385 | |||
386 | printk(KERN_INFO "msi-laptop: driver unloaded.\n"); | ||
387 | } | ||
388 | |||
389 | module_init(msi_init); | ||
390 | module_exit(msi_cleanup); | ||
391 | |||
392 | MODULE_AUTHOR("Lennart Poettering"); | ||
393 | MODULE_DESCRIPTION("MSI Laptop Support"); | ||
394 | MODULE_VERSION(MSI_DRIVER_VERSION); | ||
395 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index a7ed30446185..1ba8754e9383 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -48,7 +48,7 @@ static void tifm_7xx1_remove_media(void *adapter) | |||
48 | printk(KERN_INFO DRIVER_NAME | 48 | printk(KERN_INFO DRIVER_NAME |
49 | ": demand removing card from socket %d\n", cnt); | 49 | ": demand removing card from socket %d\n", cnt); |
50 | sock = fm->sockets[cnt]; | 50 | sock = fm->sockets[cnt]; |
51 | fm->sockets[cnt] = 0; | 51 | fm->sockets[cnt] = NULL; |
52 | fm->remove_mask &= ~(1 << cnt); | 52 | fm->remove_mask &= ~(1 << cnt); |
53 | 53 | ||
54 | writel(0x0e00, sock->addr + SOCK_CONTROL); | 54 | writel(0x0e00, sock->addr + SOCK_CONTROL); |
@@ -67,7 +67,7 @@ static void tifm_7xx1_remove_media(void *adapter) | |||
67 | class_device_put(&fm->cdev); | 67 | class_device_put(&fm->cdev); |
68 | } | 68 | } |
69 | 69 | ||
70 | static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs) | 70 | static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) |
71 | { | 71 | { |
72 | struct tifm_adapter *fm = dev_id; | 72 | struct tifm_adapter *fm = dev_id; |
73 | unsigned int irq_status; | 73 | unsigned int irq_status; |
@@ -118,7 +118,7 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
118 | return IRQ_HANDLED; | 118 | return IRQ_HANDLED; |
119 | } | 119 | } |
120 | 120 | ||
121 | static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2) | 121 | static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is_x2) |
122 | { | 122 | { |
123 | unsigned int s_state; | 123 | unsigned int s_state; |
124 | int cnt; | 124 | int cnt; |
@@ -163,7 +163,8 @@ static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2) | |||
163 | return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; | 163 | return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; |
164 | } | 164 | } |
165 | 165 | ||
166 | inline static char *tifm_7xx1_sock_addr(char *base_addr, unsigned int sock_num) | 166 | inline static char __iomem * |
167 | tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) | ||
167 | { | 168 | { |
168 | return base_addr + ((sock_num + 1) << 10); | 169 | return base_addr + ((sock_num + 1) << 10); |
169 | } | 170 | } |
@@ -176,7 +177,7 @@ static void tifm_7xx1_insert_media(void *adapter) | |||
176 | char *card_name = "xx"; | 177 | char *card_name = "xx"; |
177 | int cnt, ok_to_register; | 178 | int cnt, ok_to_register; |
178 | unsigned int insert_mask; | 179 | unsigned int insert_mask; |
179 | struct tifm_dev *new_sock = 0; | 180 | struct tifm_dev *new_sock = NULL; |
180 | 181 | ||
181 | if (!class_device_get(&fm->cdev)) | 182 | if (!class_device_get(&fm->cdev)) |
182 | return; | 183 | return; |
@@ -230,7 +231,7 @@ static void tifm_7xx1_insert_media(void *adapter) | |||
230 | if (!ok_to_register || | 231 | if (!ok_to_register || |
231 | device_register(&new_sock->dev)) { | 232 | device_register(&new_sock->dev)) { |
232 | spin_lock_irqsave(&fm->lock, flags); | 233 | spin_lock_irqsave(&fm->lock, flags); |
233 | fm->sockets[cnt] = 0; | 234 | fm->sockets[cnt] = NULL; |
234 | spin_unlock_irqrestore(&fm->lock, | 235 | spin_unlock_irqrestore(&fm->lock, |
235 | flags); | 236 | flags); |
236 | tifm_free_device(&new_sock->dev); | 237 | tifm_free_device(&new_sock->dev); |
@@ -390,7 +391,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev) | |||
390 | 391 | ||
391 | tifm_remove_adapter(fm); | 392 | tifm_remove_adapter(fm); |
392 | 393 | ||
393 | pci_set_drvdata(dev, 0); | 394 | pci_set_drvdata(dev, NULL); |
394 | 395 | ||
395 | iounmap(fm->addr); | 396 | iounmap(fm->addr); |
396 | pci_intx(dev, 0); | 397 | pci_intx(dev, 0); |
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index cca5f8522469..ee326136d03b 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c | |||
@@ -157,7 +157,7 @@ struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) | |||
157 | dev->wq = create_singlethread_workqueue(dev->wq_name); | 157 | dev->wq = create_singlethread_workqueue(dev->wq_name); |
158 | if (!dev->wq) { | 158 | if (!dev->wq) { |
159 | kfree(dev); | 159 | kfree(dev); |
160 | return 0; | 160 | return NULL; |
161 | } | 161 | } |
162 | dev->dev.parent = fm->dev; | 162 | dev->dev.parent = fm->dev; |
163 | dev->dev.bus = &tifm_bus_type; | 163 | dev->dev.bus = &tifm_bus_type; |