ia64/linux-2.6.18-xen.hg

view drivers/acpi/i2c_ec.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * SMBus driver for ACPI Embedded Controller ($Revision: 1.3 $)
3 *
4 * Copyright (c) 2002, 2005 Ducrot Bruno
5 * Copyright (c) 2005 Rich Townsend (tiny hacks & tweaks)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation version 2.
10 */
12 #include <linux/version.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/kernel.h>
16 #include <linux/stddef.h>
17 #include <linux/sched.h>
18 #include <linux/init.h>
19 #include <linux/i2c.h>
20 #include <linux/acpi.h>
21 #include <linux/delay.h>
23 #include "i2c_ec.h"
25 #define xudelay(t) udelay(t)
26 #define xmsleep(t) msleep(t)
28 #define ACPI_EC_HC_COMPONENT 0x00080000
29 #define ACPI_EC_HC_CLASS "ec_hc_smbus"
30 #define ACPI_EC_HC_HID "ACPI0001"
31 #define ACPI_EC_HC_DRIVER_NAME "ACPI EC HC smbus driver"
32 #define ACPI_EC_HC_DEVICE_NAME "EC HC smbus"
34 #define _COMPONENT ACPI_EC_HC_COMPONENT
36 ACPI_MODULE_NAME("acpi_smbus")
38 static int acpi_ec_hc_add(struct acpi_device *device);
39 static int acpi_ec_hc_remove(struct acpi_device *device, int type);
41 static struct acpi_driver acpi_ec_hc_driver = {
42 .name = ACPI_EC_HC_DRIVER_NAME,
43 .class = ACPI_EC_HC_CLASS,
44 .ids = ACPI_EC_HC_HID,
45 .ops = {
46 .add = acpi_ec_hc_add,
47 .remove = acpi_ec_hc_remove,
48 },
49 };
51 /* Various bit mask for EC_SC (R) */
52 #define OBF 0x01
53 #define IBF 0x02
54 #define CMD 0x08
55 #define BURST 0x10
56 #define SCI_EVT 0x20
57 #define SMI_EVT 0x40
59 /* Commands for EC_SC (W) */
60 #define RD_EC 0x80
61 #define WR_EC 0x81
62 #define BE_EC 0x82
63 #define BD_EC 0x83
64 #define QR_EC 0x84
66 /*
67 * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
68 */
70 #define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */
71 #define ACPI_EC_SMB_STS 0x01 /* status */
72 #define ACPI_EC_SMB_ADDR 0x02 /* address */
73 #define ACPI_EC_SMB_CMD 0x03 /* command */
74 #define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */
75 #define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */
76 #define ACPI_EC_SMB_ALRM_A 0x25 /* alarm address */
77 #define ACPI_EC_SMB_ALRM_D 0x26 /* 2 bytes alarm data */
79 #define ACPI_EC_SMB_STS_DONE 0x80
80 #define ACPI_EC_SMB_STS_ALRM 0x40
81 #define ACPI_EC_SMB_STS_RES 0x20
82 #define ACPI_EC_SMB_STS_STATUS 0x1f
84 #define ACPI_EC_SMB_STATUS_OK 0x00
85 #define ACPI_EC_SMB_STATUS_FAIL 0x07
86 #define ACPI_EC_SMB_STATUS_DNAK 0x10
87 #define ACPI_EC_SMB_STATUS_DERR 0x11
88 #define ACPI_EC_SMB_STATUS_CMD_DENY 0x12
89 #define ACPI_EC_SMB_STATUS_UNKNOWN 0x13
90 #define ACPI_EC_SMB_STATUS_ACC_DENY 0x17
91 #define ACPI_EC_SMB_STATUS_TIMEOUT 0x18
92 #define ACPI_EC_SMB_STATUS_NOTSUP 0x19
93 #define ACPI_EC_SMB_STATUS_BUSY 0x1A
94 #define ACPI_EC_SMB_STATUS_PEC 0x1F
96 #define ACPI_EC_SMB_PRTCL_WRITE 0x00
97 #define ACPI_EC_SMB_PRTCL_READ 0x01
98 #define ACPI_EC_SMB_PRTCL_QUICK 0x02
99 #define ACPI_EC_SMB_PRTCL_BYTE 0x04
100 #define ACPI_EC_SMB_PRTCL_BYTE_DATA 0x06
101 #define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08
102 #define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a
103 #define ACPI_EC_SMB_PRTCL_PROC_CALL 0x0c
104 #define ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
105 #define ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
106 #define ACPI_EC_SMB_PRTCL_PEC 0x80
108 /* Length of pre/post transaction sleep (msec) */
109 #define ACPI_EC_SMB_TRANSACTION_SLEEP 1
110 #define ACPI_EC_SMB_ACCESS_SLEEP1 1
111 #define ACPI_EC_SMB_ACCESS_SLEEP2 10
113 static int acpi_ec_smb_read(struct acpi_ec_smbus *smbus, u8 address, u8 * data)
114 {
115 u8 val;
116 int err;
118 err = ec_read(smbus->base + address, &val);
119 if (!err) {
120 *data = val;
121 }
122 xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
123 return (err);
124 }
126 static int acpi_ec_smb_write(struct acpi_ec_smbus *smbus, u8 address, u8 data)
127 {
128 int err;
130 err = ec_write(smbus->base + address, data);
131 return (err);
132 }
134 static int
135 acpi_ec_smb_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
136 char read_write, u8 command, int size,
137 union i2c_smbus_data *data)
138 {
139 struct acpi_ec_smbus *smbus = adap->algo_data;
140 unsigned char protocol, len = 0, pec, temp[2] = { 0, 0 };
141 int i;
143 if (read_write == I2C_SMBUS_READ) {
144 protocol = ACPI_EC_SMB_PRTCL_READ;
145 } else {
146 protocol = ACPI_EC_SMB_PRTCL_WRITE;
147 }
148 pec = (flags & I2C_CLIENT_PEC) ? ACPI_EC_SMB_PRTCL_PEC : 0;
150 switch (size) {
152 case I2C_SMBUS_QUICK:
153 protocol |= ACPI_EC_SMB_PRTCL_QUICK;
154 read_write = I2C_SMBUS_WRITE;
155 break;
157 case I2C_SMBUS_BYTE:
158 if (read_write == I2C_SMBUS_WRITE) {
159 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte);
160 }
161 protocol |= ACPI_EC_SMB_PRTCL_BYTE;
162 break;
164 case I2C_SMBUS_BYTE_DATA:
165 acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
166 if (read_write == I2C_SMBUS_WRITE) {
167 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte);
168 }
169 protocol |= ACPI_EC_SMB_PRTCL_BYTE_DATA;
170 break;
172 case I2C_SMBUS_WORD_DATA:
173 acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
174 if (read_write == I2C_SMBUS_WRITE) {
175 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word);
176 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1,
177 data->word >> 8);
178 }
179 protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA | pec;
180 break;
182 case I2C_SMBUS_BLOCK_DATA:
183 acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
184 if (read_write == I2C_SMBUS_WRITE) {
185 len = min_t(u8, data->block[0], 32);
186 acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
187 for (i = 0; i < len; i++)
188 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
189 data->block[i + 1]);
190 }
191 protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA | pec;
192 break;
194 case I2C_SMBUS_I2C_BLOCK_DATA:
195 len = min_t(u8, data->block[0], 32);
196 acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
197 acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
198 if (read_write == I2C_SMBUS_WRITE) {
199 for (i = 0; i < len; i++) {
200 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
201 data->block[i + 1]);
202 }
203 }
204 protocol |= ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA;
205 break;
207 case I2C_SMBUS_PROC_CALL:
208 acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
209 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word);
210 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1, data->word >> 8);
211 protocol = ACPI_EC_SMB_PRTCL_PROC_CALL | pec;
212 read_write = I2C_SMBUS_READ;
213 break;
215 case I2C_SMBUS_BLOCK_PROC_CALL:
216 protocol |= pec;
217 len = min_t(u8, data->block[0], 31);
218 acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
219 acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
220 for (i = 0; i < len; i++)
221 acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
222 data->block[i + 1]);
223 protocol = ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL | pec;
224 read_write = I2C_SMBUS_READ;
225 break;
227 default:
228 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "EC SMBus adapter: "
229 "Unsupported transaction %d\n", size));
230 return (-1);
231 }
233 acpi_ec_smb_write(smbus, ACPI_EC_SMB_ADDR, addr << 1);
234 acpi_ec_smb_write(smbus, ACPI_EC_SMB_PRTCL, protocol);
236 acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
238 if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
239 xudelay(500);
240 acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
241 }
242 if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
243 xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
244 acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
245 }
246 if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
247 || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
248 return (-1);
249 }
251 if (read_write == I2C_SMBUS_WRITE) {
252 return (0);
253 }
255 switch (size) {
257 case I2C_SMBUS_BYTE:
258 case I2C_SMBUS_BYTE_DATA:
259 acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, &data->byte);
260 break;
262 case I2C_SMBUS_WORD_DATA:
263 case I2C_SMBUS_PROC_CALL:
264 acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, temp + 0);
265 acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + 1, temp + 1);
266 data->word = (temp[1] << 8) | temp[0];
267 break;
269 case I2C_SMBUS_BLOCK_DATA:
270 case I2C_SMBUS_BLOCK_PROC_CALL:
271 len = 0;
272 acpi_ec_smb_read(smbus, ACPI_EC_SMB_BCNT, &len);
273 len = min_t(u8, len, 32);
274 case I2C_SMBUS_I2C_BLOCK_DATA:
275 for (i = 0; i < len; i++)
276 acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + i,
277 data->block + i + 1);
278 data->block[0] = len;
279 break;
280 }
282 return (0);
283 }
285 static u32 acpi_ec_smb_func(struct i2c_adapter *adapter)
286 {
288 return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
289 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
290 I2C_FUNC_SMBUS_BLOCK_DATA |
291 I2C_FUNC_SMBUS_PROC_CALL |
292 I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
293 I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC);
294 }
296 static struct i2c_algorithm acpi_ec_smbus_algorithm = {
297 .smbus_xfer = acpi_ec_smb_access,
298 .functionality = acpi_ec_smb_func,
299 };
301 static int acpi_ec_hc_add(struct acpi_device *device)
302 {
303 int status;
304 unsigned long val;
305 struct acpi_ec_hc *ec_hc;
306 struct acpi_ec_smbus *smbus;
308 if (!device) {
309 return -EINVAL;
310 }
312 ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
313 if (!ec_hc) {
314 return -ENOMEM;
315 }
316 memset(ec_hc, 0, sizeof(struct acpi_ec_hc));
318 smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
319 if (!smbus) {
320 kfree(ec_hc);
321 return -ENOMEM;
322 }
323 memset(smbus, 0, sizeof(struct acpi_ec_smbus));
325 ec_hc->handle = device->handle;
326 strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME);
327 strcpy(acpi_device_class(device), ACPI_EC_HC_CLASS);
328 acpi_driver_data(device) = ec_hc;
330 status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val);
331 if (ACPI_FAILURE(status)) {
332 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
333 kfree(ec_hc);
334 kfree(smbus);
335 return -EIO;
336 }
338 smbus->ec = acpi_driver_data(device->parent);
339 smbus->base = (val & 0xff00ull) >> 8;
340 smbus->alert = val & 0xffull;
342 smbus->adapter.owner = THIS_MODULE;
343 smbus->adapter.algo = &acpi_ec_smbus_algorithm;
344 smbus->adapter.algo_data = smbus;
346 if (i2c_add_adapter(&smbus->adapter)) {
347 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
348 "EC SMBus adapter: Failed to register adapter\n"));
349 kfree(smbus);
350 kfree(ec_hc);
351 return -EIO;
352 }
354 ec_hc->smbus = smbus;
356 printk(KERN_INFO PREFIX "%s [%s]\n",
357 acpi_device_name(device), acpi_device_bid(device));
359 return AE_OK;
360 }
362 static int acpi_ec_hc_remove(struct acpi_device *device, int type)
363 {
364 struct acpi_ec_hc *ec_hc;
366 if (!device) {
367 return -EINVAL;
368 }
369 ec_hc = acpi_driver_data(device);
371 i2c_del_adapter(&ec_hc->smbus->adapter);
372 kfree(ec_hc->smbus);
373 kfree(ec_hc);
375 return AE_OK;
376 }
378 static int __init acpi_ec_hc_init(void)
379 {
380 int result;
382 result = acpi_bus_register_driver(&acpi_ec_hc_driver);
383 if (result < 0) {
384 return -ENODEV;
385 }
386 return 0;
387 }
389 static void __exit acpi_ec_hc_exit(void)
390 {
391 acpi_bus_unregister_driver(&acpi_ec_hc_driver);
392 }
394 struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device)
395 {
396 return ((struct acpi_ec_hc *)acpi_driver_data(device->parent));
397 }
399 EXPORT_SYMBOL(acpi_get_ec_hc);
401 module_init(acpi_ec_hc_init);
402 module_exit(acpi_ec_hc_exit);
404 MODULE_LICENSE("GPL");
405 MODULE_AUTHOR("Ducrot Bruno");
406 MODULE_DESCRIPTION("ACPI EC SMBus driver");