rename patch (v2.6.22.24-op1)
[linux-2.6.22.y-op-patches.git] / backport / i2c-i801-smb / 01-i2c-i801-internal_buff.patch
blobdfe6540656a876acb2be06cac58068ca1a782a02
1 From 7edcb9abb594a8f3b4ca756e03d01c870aeae127 Mon Sep 17 00:00:00 2001
2 From: Oleg Ryjkov <olegr@google.com>
3 Date: Thu, 12 Jul 2007 14:12:31 +0200
4 Subject: [PATCH] i2c-i801: Use the internal 32-byte buffer on ICH4+
6 Add an ability to utilize the internal SRAM buffer on ICH4
7 and newer host controllers to speed up execution of block operations.
9 I've split the code so that it is more clear which block transaction is
10 performed.
12 First of all the host controller's type is identified. isich4 is set when
13 we think that the controller has the internal buffer. Then, before every
14 block transaction, if isich4 is set, we attempt to enable the E32B bit in
15 SMBAUXCTL register.
17 Signed-off-by: Oleg Ryjkov <olegr@google.com>
18 Signed-off-by: Jean Delvare <khali@linux-fr.org>
20 diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801
21 index c34f0db..fe6406f 100644
22 --- a/Documentation/i2c/busses/i2c-i801
23 +++ b/Documentation/i2c/busses/i2c-i801
24 @@ -5,8 +5,8 @@ Supported adapters:
25 '810' and '810E' chipsets)
26 * Intel 82801BA (ICH2 - part of the '815E' chipset)
27 * Intel 82801CA/CAM (ICH3)
28 - * Intel 82801DB (ICH4) (HW PEC supported, 32 byte buffer not supported)
29 - * Intel 82801EB/ER (ICH5) (HW PEC supported, 32 byte buffer not supported)
30 + * Intel 82801DB (ICH4) (HW PEC supported)
31 + * Intel 82801EB/ER (ICH5) (HW PEC supported)
32 * Intel 6300ESB
33 * Intel 82801FB/FR/FW/FRW (ICH6)
34 * Intel 82801G (ICH7)
35 diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
36 index d5e12a4..8f5c686 100644
37 --- a/drivers/i2c/busses/i2c-i801.c
38 +++ b/drivers/i2c/busses/i2c-i801.c
39 @@ -26,8 +26,8 @@
40 82801AB 2423
41 82801BA 2443
42 82801CA/CAM 2483
43 - 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported)
44 - 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
45 + 82801DB 24C3 (HW PEC supported)
46 + 82801EB 24D3 (HW PEC supported)
47 6300ESB 25A4
48 ICH6 266A
49 ICH7 27DA
50 @@ -114,7 +114,7 @@ static struct pci_driver i801_driver;
51 static struct pci_dev *I801_dev;
52 static int isich4;
54 -static int i801_transaction(void)
55 +static int i801_transaction(int xact)
57 int temp;
58 int result = 0;
59 @@ -139,7 +139,9 @@ static int i801_transaction(void)
63 - outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
64 + /* the current contents of SMBHSTCNT can be overwritten, since PEC,
65 + * INTREN, SMBSCMD are passed in xact */
66 + outb_p(xact | I801_START, SMBHSTCNT);
68 /* We will always wait for a fraction of a second! */
69 do {
70 @@ -207,44 +209,52 @@ static void i801_wait_hwpec(void)
71 outb_p(temp, SMBHSTSTS);
74 -/* All-inclusive block transaction function */
75 -static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
76 - int command, int hwpec)
77 +static int i801_block_transaction_by_block(union i2c_smbus_data *data,
78 + char read_write, int hwpec)
80 + int i, len;
82 + inb_p(SMBHSTCNT); /* reset the data buffer index */
84 + /* Use 32-byte buffer to process this transaction */
85 + if (read_write == I2C_SMBUS_WRITE) {
86 + len = data->block[0];
87 + outb_p(len, SMBHSTDAT0);
88 + for (i = 0; i < len; i++)
89 + outb_p(data->block[i+1], SMBBLKDAT);
90 + }
92 + if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
93 + I801_PEC_EN * hwpec))
94 + return -1;
96 + if (read_write == I2C_SMBUS_READ) {
97 + len = inb_p(SMBHSTDAT0);
98 + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
99 + return -1;
101 + data->block[0] = len;
102 + for (i = 0; i < len; i++)
103 + data->block[i + 1] = inb_p(SMBBLKDAT);
105 + return 0;
108 +static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
109 + char read_write, int hwpec)
111 int i, len;
112 int smbcmd;
113 int temp;
114 int result = 0;
115 int timeout;
116 - unsigned char hostc, errmask;
117 + unsigned char errmask;
119 - if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
120 - if (read_write == I2C_SMBUS_WRITE) {
121 - /* set I2C_EN bit in configuration register */
122 - pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
123 - pci_write_config_byte(I801_dev, SMBHSTCFG,
124 - hostc | SMBHSTCFG_I2C_EN);
125 - } else {
126 - dev_err(&I801_dev->dev,
127 - "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
128 - return -1;
131 + len = data->block[0];
133 if (read_write == I2C_SMBUS_WRITE) {
134 - len = data->block[0];
135 - if (len < 1)
136 - len = 1;
137 - if (len > 32)
138 - len = 32;
139 outb_p(len, SMBHSTDAT0);
140 outb_p(data->block[1], SMBBLKDAT);
141 - } else {
142 - len = 32; /* max for reads */
145 - if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
146 - /* set 32 byte buffer */
149 for (i = 1; i <= len; i++) {
150 @@ -277,14 +287,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
151 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
152 dev_err(&I801_dev->dev,
153 "Reset failed! (%02x)\n", temp);
154 - result = -1;
155 - goto END;
156 + return -1;
158 - if (i != 1) {
159 + if (i != 1)
160 /* if die in middle of block transaction, fail */
161 - result = -1;
162 - goto END;
164 + return -1;
167 if (i == 1)
168 @@ -326,10 +333,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
170 if (i == 1 && read_write == I2C_SMBUS_READ) {
171 len = inb_p(SMBHSTDAT0);
172 - if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
173 - result = -1;
174 - goto END;
176 + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
177 + return -1;
178 data->block[0] = len;
181 @@ -352,14 +357,58 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
182 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
184 if (result < 0)
185 - goto END;
186 + return result;
188 + return result;
191 - if (hwpec)
192 +static int i801_set_block_buffer_mode(void)
194 + outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
195 + if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
196 + return -1;
197 + return 0;
200 +/* Block transaction function */
201 +static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
202 + int command, int hwpec)
204 + int result = 0;
205 + unsigned char hostc;
207 + if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
208 + if (read_write == I2C_SMBUS_WRITE) {
209 + /* set I2C_EN bit in configuration register */
210 + pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
211 + pci_write_config_byte(I801_dev, SMBHSTCFG,
212 + hostc | SMBHSTCFG_I2C_EN);
213 + } else {
214 + dev_err(&I801_dev->dev,
215 + "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
216 + return -1;
220 + if (read_write == I2C_SMBUS_WRITE) {
221 + if (data->block[0] < 1)
222 + data->block[0] = 1;
223 + if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
224 + data->block[0] = I2C_SMBUS_BLOCK_MAX;
225 + } else {
226 + data->block[0] = 32; /* max for reads */
229 + if (isich4 && i801_set_block_buffer_mode() == 0 )
230 + result = i801_block_transaction_by_block(data, read_write,
231 + hwpec);
232 + else
233 + result = i801_block_transaction_byte_by_byte(data, read_write,
234 + hwpec);
236 + if (result == 0 && hwpec)
237 i801_wait_hwpec();
239 - result = 0;
240 -END:
241 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
242 /* restore saved configuration register value */
243 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
244 @@ -431,15 +480,15 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
246 if(block)
247 ret = i801_block_transaction(data, read_write, size, hwpec);
248 - else {
249 - outb_p(xact | ENABLE_INT9, SMBHSTCNT);
250 - ret = i801_transaction();
252 + else
253 + ret = i801_transaction(xact | ENABLE_INT9);
255 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
256 - time, so we forcibly disable it after every transaction. */
257 + time, so we forcibly disable it after every transaction. Turn off
258 + E32B for the same reason. */
259 if (hwpec)
260 - outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
261 + outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
262 + SMBAUXCTL);
264 if(block)
265 return ret;