Commit a28d3af2a26c89aaa6470ca36edb212e05143d67
Committed by
Paul Mackerras
1 parent
730745a5c4
Exists in
master
and in
7 other branches
[PATCH] 2/5 powerpc: Rework PowerMac i2c part 2
This is the continuation of the previous patch. This one removes the old PowerMac i2c drivers (i2c-keywest and i2c-pmac-smu) and replaces them both with a single stub driver that uses the new PowerMac low i2c layer. Now that i2c-keywest is gone, the low-i2c code is extended to support interrupt driver transfers. All i2c busses now appear as platform devices. Compatibility with existing drivers should be maintained as the i2c bus names have been kept identical, except for the SMU bus but in that later case, all users has been fixed. With that patch added, matching a device node to an i2c_adapter becomes trivial. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 12 changed files with 563 additions and 1364 deletions Inline Diff
- arch/powerpc/platforms/powermac/low_i2c.c
- arch/powerpc/platforms/powermac/setup.c
- drivers/i2c/busses/Kconfig
- drivers/i2c/busses/Makefile
- drivers/i2c/busses/i2c-keywest.c
- drivers/i2c/busses/i2c-keywest.h
- drivers/i2c/busses/i2c-pmac-smu.c
- drivers/i2c/busses/i2c-powermac.c
- drivers/macintosh/Kconfig
- drivers/macintosh/smu.c
- drivers/macintosh/windfarm_lm75_sensor.c
- include/asm-powerpc/pmac_low_i2c.h
arch/powerpc/platforms/powermac/low_i2c.c
1 | /* | 1 | /* |
2 | * arch/powerpc/platforms/powermac/low_i2c.c | 2 | * arch/powerpc/platforms/powermac/low_i2c.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Ben. Herrenschmidt (benh@kernel.crashing.org) | 4 | * Copyright (C) 2003-2005 Ben. Herrenschmidt (benh@kernel.crashing.org) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * The linux i2c layer isn't completely suitable for our needs for various | 11 | * The linux i2c layer isn't completely suitable for our needs for various |
12 | * reasons ranging from too late initialisation to semantics not perfectly | 12 | * reasons ranging from too late initialisation to semantics not perfectly |
13 | * matching some requirements of the apple platform functions etc... | 13 | * matching some requirements of the apple platform functions etc... |
14 | * | 14 | * |
15 | * This file thus provides a simple low level unified i2c interface for | 15 | * This file thus provides a simple low level unified i2c interface for |
16 | * powermac that covers the various types of i2c busses used in Apple machines. | 16 | * powermac that covers the various types of i2c busses used in Apple machines. |
17 | * For now, keywest, PMU and SMU, though we could add Cuda, or other bit | 17 | * For now, keywest, PMU and SMU, though we could add Cuda, or other bit |
18 | * banging busses found on older chipstes in earlier machines if we ever need | 18 | * banging busses found on older chipstes in earlier machines if we ever need |
19 | * one of them. | 19 | * one of them. |
20 | * | 20 | * |
21 | * The drivers in this file are synchronous/blocking. In addition, the | 21 | * The drivers in this file are synchronous/blocking. In addition, the |
22 | * keywest one is fairly slow due to the use of msleep instead of interrupts | 22 | * keywest one is fairly slow due to the use of msleep instead of interrupts |
23 | * as the interrupt is currently used by i2c-keywest. In the long run, we | 23 | * as the interrupt is currently used by i2c-keywest. In the long run, we |
24 | * might want to get rid of those high-level interfaces to linux i2c layer | 24 | * might want to get rid of those high-level interfaces to linux i2c layer |
25 | * either completely (converting all drivers) or replacing them all with a | 25 | * either completely (converting all drivers) or replacing them all with a |
26 | * single stub driver on top of this one. Once done, the interrupt will be | 26 | * single stub driver on top of this one. Once done, the interrupt will be |
27 | * available for our use. | 27 | * available for our use. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #undef DEBUG | 30 | #undef DEBUG |
31 | #undef DEBUG_LOW | 31 | #undef DEBUG_LOW |
32 | 32 | ||
33 | #include <linux/config.h> | 33 | #include <linux/config.h> |
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/adb.h> | 38 | #include <linux/adb.h> |
39 | #include <linux/pmu.h> | 39 | #include <linux/pmu.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/completion.h> | 41 | #include <linux/completion.h> |
42 | #include <linux/platform_device.h> | ||
43 | #include <linux/interrupt.h> | ||
44 | #include <linux/completion.h> | ||
45 | #include <linux/timer.h> | ||
42 | #include <asm/keylargo.h> | 46 | #include <asm/keylargo.h> |
43 | #include <asm/uninorth.h> | 47 | #include <asm/uninorth.h> |
44 | #include <asm/io.h> | 48 | #include <asm/io.h> |
45 | #include <asm/prom.h> | 49 | #include <asm/prom.h> |
46 | #include <asm/machdep.h> | 50 | #include <asm/machdep.h> |
47 | #include <asm/smu.h> | 51 | #include <asm/smu.h> |
48 | #include <asm/pmac_low_i2c.h> | 52 | #include <asm/pmac_low_i2c.h> |
49 | 53 | ||
50 | #ifdef DEBUG | 54 | #ifdef DEBUG |
51 | #define DBG(x...) do {\ | 55 | #define DBG(x...) do {\ |
52 | printk(KERN_DEBUG "low_i2c:" x); \ | 56 | printk(KERN_DEBUG "low_i2c:" x); \ |
53 | } while(0) | 57 | } while(0) |
54 | #else | 58 | #else |
55 | #define DBG(x...) | 59 | #define DBG(x...) |
56 | #endif | 60 | #endif |
57 | 61 | ||
58 | #ifdef DEBUG_LOW | 62 | #ifdef DEBUG_LOW |
59 | #define DBG_LOW(x...) do {\ | 63 | #define DBG_LOW(x...) do {\ |
60 | printk(KERN_DEBUG "low_i2c:" x); \ | 64 | printk(KERN_DEBUG "low_i2c:" x); \ |
61 | } while(0) | 65 | } while(0) |
62 | #else | 66 | #else |
63 | #define DBG_LOW(x...) | 67 | #define DBG_LOW(x...) |
64 | #endif | 68 | #endif |
65 | 69 | ||
70 | |||
71 | static int pmac_i2c_force_poll = 1; | ||
72 | |||
66 | /* | 73 | /* |
67 | * A bus structure. Each bus in the system has such a structure associated. | 74 | * A bus structure. Each bus in the system has such a structure associated. |
68 | */ | 75 | */ |
69 | struct pmac_i2c_bus | 76 | struct pmac_i2c_bus |
70 | { | 77 | { |
71 | struct list_head link; | 78 | struct list_head link; |
72 | struct device_node *controller; | 79 | struct device_node *controller; |
73 | struct device_node *busnode; | 80 | struct device_node *busnode; |
74 | int type; | 81 | int type; |
75 | int flags; | 82 | int flags; |
76 | struct i2c_adapter *adapter; | 83 | struct i2c_adapter *adapter; |
77 | void *hostdata; | 84 | void *hostdata; |
78 | int channel; /* some hosts have multiple */ | 85 | int channel; /* some hosts have multiple */ |
79 | int mode; /* current mode */ | 86 | int mode; /* current mode */ |
80 | struct semaphore sem; | 87 | struct semaphore sem; |
81 | int opened; | 88 | int opened; |
82 | int polled; /* open mode */ | 89 | int polled; /* open mode */ |
90 | struct platform_device *platform_dev; | ||
83 | 91 | ||
84 | /* ops */ | 92 | /* ops */ |
85 | int (*open)(struct pmac_i2c_bus *bus); | 93 | int (*open)(struct pmac_i2c_bus *bus); |
86 | void (*close)(struct pmac_i2c_bus *bus); | 94 | void (*close)(struct pmac_i2c_bus *bus); |
87 | int (*xfer)(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, | 95 | int (*xfer)(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, |
88 | u32 subaddr, u8 *data, int len); | 96 | u32 subaddr, u8 *data, int len); |
89 | }; | 97 | }; |
90 | 98 | ||
91 | static LIST_HEAD(pmac_i2c_busses); | 99 | static LIST_HEAD(pmac_i2c_busses); |
92 | 100 | ||
93 | /* | 101 | /* |
94 | * Keywest implementation | 102 | * Keywest implementation |
95 | */ | 103 | */ |
96 | 104 | ||
97 | struct pmac_i2c_host_kw | 105 | struct pmac_i2c_host_kw |
98 | { | 106 | { |
99 | struct semaphore mutex; /* Access mutex for use by | 107 | struct semaphore mutex; /* Access mutex for use by |
100 | * i2c-keywest */ | 108 | * i2c-keywest */ |
101 | void __iomem *base; /* register base address */ | 109 | void __iomem *base; /* register base address */ |
102 | int bsteps; /* register stepping */ | 110 | int bsteps; /* register stepping */ |
103 | int speed; /* speed */ | 111 | int speed; /* speed */ |
112 | int irq; | ||
113 | u8 *data; | ||
114 | unsigned len; | ||
115 | int state; | ||
116 | int rw; | ||
117 | int polled; | ||
118 | int result; | ||
119 | struct completion complete; | ||
120 | spinlock_t lock; | ||
121 | struct timer_list timeout_timer; | ||
104 | }; | 122 | }; |
105 | 123 | ||
106 | /* Register indices */ | 124 | /* Register indices */ |
107 | typedef enum { | 125 | typedef enum { |
108 | reg_mode = 0, | 126 | reg_mode = 0, |
109 | reg_control, | 127 | reg_control, |
110 | reg_status, | 128 | reg_status, |
111 | reg_isr, | 129 | reg_isr, |
112 | reg_ier, | 130 | reg_ier, |
113 | reg_addr, | 131 | reg_addr, |
114 | reg_subaddr, | 132 | reg_subaddr, |
115 | reg_data | 133 | reg_data |
116 | } reg_t; | 134 | } reg_t; |
117 | 135 | ||
136 | /* The Tumbler audio equalizer can be really slow sometimes */ | ||
137 | #define KW_POLL_TIMEOUT (2*HZ) | ||
118 | 138 | ||
119 | /* Mode register */ | 139 | /* Mode register */ |
120 | #define KW_I2C_MODE_100KHZ 0x00 | 140 | #define KW_I2C_MODE_100KHZ 0x00 |
121 | #define KW_I2C_MODE_50KHZ 0x01 | 141 | #define KW_I2C_MODE_50KHZ 0x01 |
122 | #define KW_I2C_MODE_25KHZ 0x02 | 142 | #define KW_I2C_MODE_25KHZ 0x02 |
123 | #define KW_I2C_MODE_DUMB 0x00 | 143 | #define KW_I2C_MODE_DUMB 0x00 |
124 | #define KW_I2C_MODE_STANDARD 0x04 | 144 | #define KW_I2C_MODE_STANDARD 0x04 |
125 | #define KW_I2C_MODE_STANDARDSUB 0x08 | 145 | #define KW_I2C_MODE_STANDARDSUB 0x08 |
126 | #define KW_I2C_MODE_COMBINED 0x0C | 146 | #define KW_I2C_MODE_COMBINED 0x0C |
127 | #define KW_I2C_MODE_MODE_MASK 0x0C | 147 | #define KW_I2C_MODE_MODE_MASK 0x0C |
128 | #define KW_I2C_MODE_CHAN_MASK 0xF0 | 148 | #define KW_I2C_MODE_CHAN_MASK 0xF0 |
129 | 149 | ||
130 | /* Control register */ | 150 | /* Control register */ |
131 | #define KW_I2C_CTL_AAK 0x01 | 151 | #define KW_I2C_CTL_AAK 0x01 |
132 | #define KW_I2C_CTL_XADDR 0x02 | 152 | #define KW_I2C_CTL_XADDR 0x02 |
133 | #define KW_I2C_CTL_STOP 0x04 | 153 | #define KW_I2C_CTL_STOP 0x04 |
134 | #define KW_I2C_CTL_START 0x08 | 154 | #define KW_I2C_CTL_START 0x08 |
135 | 155 | ||
136 | /* Status register */ | 156 | /* Status register */ |
137 | #define KW_I2C_STAT_BUSY 0x01 | 157 | #define KW_I2C_STAT_BUSY 0x01 |
138 | #define KW_I2C_STAT_LAST_AAK 0x02 | 158 | #define KW_I2C_STAT_LAST_AAK 0x02 |
139 | #define KW_I2C_STAT_LAST_RW 0x04 | 159 | #define KW_I2C_STAT_LAST_RW 0x04 |
140 | #define KW_I2C_STAT_SDA 0x08 | 160 | #define KW_I2C_STAT_SDA 0x08 |
141 | #define KW_I2C_STAT_SCL 0x10 | 161 | #define KW_I2C_STAT_SCL 0x10 |
142 | 162 | ||
143 | /* IER & ISR registers */ | 163 | /* IER & ISR registers */ |
144 | #define KW_I2C_IRQ_DATA 0x01 | 164 | #define KW_I2C_IRQ_DATA 0x01 |
145 | #define KW_I2C_IRQ_ADDR 0x02 | 165 | #define KW_I2C_IRQ_ADDR 0x02 |
146 | #define KW_I2C_IRQ_STOP 0x04 | 166 | #define KW_I2C_IRQ_STOP 0x04 |
147 | #define KW_I2C_IRQ_START 0x08 | 167 | #define KW_I2C_IRQ_START 0x08 |
148 | #define KW_I2C_IRQ_MASK 0x0F | 168 | #define KW_I2C_IRQ_MASK 0x0F |
149 | 169 | ||
150 | /* State machine states */ | 170 | /* State machine states */ |
151 | enum { | 171 | enum { |
152 | state_idle, | 172 | state_idle, |
153 | state_addr, | 173 | state_addr, |
154 | state_read, | 174 | state_read, |
155 | state_write, | 175 | state_write, |
156 | state_stop, | 176 | state_stop, |
157 | state_dead | 177 | state_dead |
158 | }; | 178 | }; |
159 | 179 | ||
160 | #define WRONG_STATE(name) do {\ | 180 | #define WRONG_STATE(name) do {\ |
161 | printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ | 181 | printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s " \ |
162 | name, __kw_state_names[state], isr); \ | 182 | "(isr: %02x)\n", \ |
183 | name, __kw_state_names[host->state], isr); \ | ||
163 | } while(0) | 184 | } while(0) |
164 | 185 | ||
165 | static const char *__kw_state_names[] = { | 186 | static const char *__kw_state_names[] = { |
166 | "state_idle", | 187 | "state_idle", |
167 | "state_addr", | 188 | "state_addr", |
168 | "state_read", | 189 | "state_read", |
169 | "state_write", | 190 | "state_write", |
170 | "state_stop", | 191 | "state_stop", |
171 | "state_dead" | 192 | "state_dead" |
172 | }; | 193 | }; |
173 | 194 | ||
174 | static inline u8 __kw_read_reg(struct pmac_i2c_bus *bus, reg_t reg) | 195 | static inline u8 __kw_read_reg(struct pmac_i2c_host_kw *host, reg_t reg) |
175 | { | 196 | { |
176 | struct pmac_i2c_host_kw *host = bus->hostdata; | ||
177 | return readb(host->base + (((unsigned int)reg) << host->bsteps)); | 197 | return readb(host->base + (((unsigned int)reg) << host->bsteps)); |
178 | } | 198 | } |
179 | 199 | ||
180 | static inline void __kw_write_reg(struct pmac_i2c_bus *bus, reg_t reg, u8 val) | 200 | static inline void __kw_write_reg(struct pmac_i2c_host_kw *host, |
201 | reg_t reg, u8 val) | ||
181 | { | 202 | { |
182 | struct pmac_i2c_host_kw *host = bus->hostdata; | ||
183 | writeb(val, host->base + (((unsigned)reg) << host->bsteps)); | 203 | writeb(val, host->base + (((unsigned)reg) << host->bsteps)); |
184 | (void)__kw_read_reg(bus, reg_subaddr); | 204 | (void)__kw_read_reg(host, reg_subaddr); |
185 | } | 205 | } |
186 | 206 | ||
187 | #define kw_write_reg(reg, val) __kw_write_reg(bus, reg, val) | 207 | #define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) |
188 | #define kw_read_reg(reg) __kw_read_reg(bus, reg) | 208 | #define kw_read_reg(reg) __kw_read_reg(host, reg) |
189 | 209 | ||
190 | static u8 kw_i2c_wait_interrupt(struct pmac_i2c_bus* bus) | 210 | static u8 kw_i2c_wait_interrupt(struct pmac_i2c_host_kw *host) |
191 | { | 211 | { |
192 | int i, j; | 212 | int i, j; |
193 | u8 isr; | 213 | u8 isr; |
194 | 214 | ||
195 | for (i = 0; i < 1000; i++) { | 215 | for (i = 0; i < 1000; i++) { |
196 | isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; | 216 | isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; |
197 | if (isr != 0) | 217 | if (isr != 0) |
198 | return isr; | 218 | return isr; |
199 | 219 | ||
200 | /* This code is used with the timebase frozen, we cannot rely | 220 | /* This code is used with the timebase frozen, we cannot rely |
201 | * on udelay nor schedule when in polled mode ! | 221 | * on udelay nor schedule when in polled mode ! |
202 | * For now, just use a bogus loop.... | 222 | * For now, just use a bogus loop.... |
203 | */ | 223 | */ |
204 | if (bus->polled) { | 224 | if (host->polled) { |
205 | for (j = 1; j < 1000000; j++) | 225 | for (j = 1; j < 100000; j++) |
206 | mb(); | 226 | mb(); |
207 | } else | 227 | } else |
208 | msleep(1); | 228 | msleep(1); |
209 | } | 229 | } |
210 | return isr; | 230 | return isr; |
211 | } | 231 | } |
212 | 232 | ||
213 | static int kw_i2c_handle_interrupt(struct pmac_i2c_bus *bus, int state, int rw, | 233 | static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) |
214 | int *rc, u8 **data, int *len, u8 isr) | ||
215 | { | 234 | { |
216 | u8 ack; | 235 | u8 ack; |
217 | 236 | ||
218 | DBG_LOW("kw_handle_interrupt(%s, isr: %x)\n", | 237 | DBG_LOW("kw_handle_interrupt(%s, isr: %x)\n", |
219 | __kw_state_names[state], isr); | 238 | __kw_state_names[host->state], isr); |
220 | 239 | ||
240 | if (host->state == state_idle) { | ||
241 | printk(KERN_WARNING "low_i2c: Keywest got an out of state" | ||
242 | " interrupt, ignoring\n"); | ||
243 | kw_write_reg(reg_isr, isr); | ||
244 | return; | ||
245 | } | ||
246 | |||
221 | if (isr == 0) { | 247 | if (isr == 0) { |
222 | if (state != state_stop) { | 248 | if (host->state != state_stop) { |
223 | DBG_LOW("KW: Timeout !\n"); | 249 | DBG_LOW("KW: Timeout !\n"); |
224 | *rc = -EIO; | 250 | host->result = -EIO; |
225 | goto stop; | 251 | goto stop; |
226 | } | 252 | } |
227 | if (state == state_stop) { | 253 | if (host->state == state_stop) { |
228 | ack = kw_read_reg(reg_status); | 254 | ack = kw_read_reg(reg_status); |
229 | if (!(ack & KW_I2C_STAT_BUSY)) { | 255 | if (ack & KW_I2C_STAT_BUSY) |
230 | state = state_idle; | 256 | kw_write_reg(reg_status, 0); |
231 | kw_write_reg(reg_ier, 0x00); | 257 | host->state = state_idle; |
232 | } | 258 | kw_write_reg(reg_ier, 0x00); |
259 | if (!host->polled) | ||
260 | complete(&host->complete); | ||
233 | } | 261 | } |
234 | return state; | 262 | return; |
235 | } | 263 | } |
236 | 264 | ||
237 | if (isr & KW_I2C_IRQ_ADDR) { | 265 | if (isr & KW_I2C_IRQ_ADDR) { |
238 | ack = kw_read_reg(reg_status); | 266 | ack = kw_read_reg(reg_status); |
239 | if (state != state_addr) { | 267 | if (host->state != state_addr) { |
240 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); | 268 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); |
241 | WRONG_STATE("KW_I2C_IRQ_ADDR"); | 269 | WRONG_STATE("KW_I2C_IRQ_ADDR"); |
242 | *rc = -EIO; | 270 | host->result = -EIO; |
243 | goto stop; | 271 | goto stop; |
244 | } | 272 | } |
245 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | 273 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
246 | *rc = -ENODEV; | 274 | host->result = -ENODEV; |
247 | DBG_LOW("KW: NAK on address\n"); | 275 | DBG_LOW("KW: NAK on address\n"); |
248 | return state_stop; | 276 | host->state = state_stop; |
277 | return; | ||
249 | } else { | 278 | } else { |
250 | if (rw) { | 279 | if (host->len == 0) { |
251 | state = state_read; | 280 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); |
252 | if (*len > 1) | 281 | goto stop; |
282 | } | ||
283 | if (host->rw) { | ||
284 | host->state = state_read; | ||
285 | if (host->len > 1) | ||
253 | kw_write_reg(reg_control, | 286 | kw_write_reg(reg_control, |
254 | KW_I2C_CTL_AAK); | 287 | KW_I2C_CTL_AAK); |
255 | } else { | 288 | } else { |
256 | state = state_write; | 289 | host->state = state_write; |
257 | kw_write_reg(reg_data, **data); | 290 | kw_write_reg(reg_data, *(host->data++)); |
258 | (*data)++; (*len)--; | 291 | host->len--; |
259 | } | 292 | } |
260 | } | 293 | } |
261 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); | 294 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); |
262 | } | 295 | } |
263 | 296 | ||
264 | if (isr & KW_I2C_IRQ_DATA) { | 297 | if (isr & KW_I2C_IRQ_DATA) { |
265 | if (state == state_read) { | 298 | if (host->state == state_read) { |
266 | **data = kw_read_reg(reg_data); | 299 | *(host->data++) = kw_read_reg(reg_data); |
267 | (*data)++; (*len)--; | 300 | host->len--; |
268 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | 301 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); |
269 | if ((*len) == 0) | 302 | if (host->len == 0) |
270 | state = state_stop; | 303 | host->state = state_stop; |
271 | else if ((*len) == 1) | 304 | else if (host->len == 1) |
272 | kw_write_reg(reg_control, 0); | 305 | kw_write_reg(reg_control, 0); |
273 | } else if (state == state_write) { | 306 | } else if (host->state == state_write) { |
274 | ack = kw_read_reg(reg_status); | 307 | ack = kw_read_reg(reg_status); |
275 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | 308 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
276 | DBG_LOW("KW: nack on data write\n"); | 309 | DBG_LOW("KW: nack on data write\n"); |
277 | *rc = -EIO; | 310 | host->result = -EIO; |
278 | goto stop; | 311 | goto stop; |
279 | } else if (*len) { | 312 | } else if (host->len) { |
280 | kw_write_reg(reg_data, **data); | 313 | kw_write_reg(reg_data, *(host->data++)); |
281 | (*data)++; (*len)--; | 314 | host->len--; |
282 | } else { | 315 | } else { |
283 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | 316 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); |
284 | state = state_stop; | 317 | host->state = state_stop; |
285 | *rc = 0; | 318 | host->result = 0; |
286 | } | 319 | } |
287 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | 320 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); |
288 | } else { | 321 | } else { |
289 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | 322 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); |
290 | WRONG_STATE("KW_I2C_IRQ_DATA"); | 323 | WRONG_STATE("KW_I2C_IRQ_DATA"); |
291 | if (state != state_stop) { | 324 | if (host->state != state_stop) { |
292 | *rc = -EIO; | 325 | host->result = -EIO; |
293 | goto stop; | 326 | goto stop; |
294 | } | 327 | } |
295 | } | 328 | } |
296 | } | 329 | } |
297 | 330 | ||
298 | if (isr & KW_I2C_IRQ_STOP) { | 331 | if (isr & KW_I2C_IRQ_STOP) { |
299 | kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); | 332 | kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); |
300 | if (state != state_stop) { | 333 | if (host->state != state_stop) { |
301 | WRONG_STATE("KW_I2C_IRQ_STOP"); | 334 | WRONG_STATE("KW_I2C_IRQ_STOP"); |
302 | *rc = -EIO; | 335 | host->result = -EIO; |
303 | } | 336 | } |
304 | return state_idle; | 337 | host->state = state_idle; |
338 | if (!host->polled) | ||
339 | complete(&host->complete); | ||
305 | } | 340 | } |
306 | 341 | ||
307 | if (isr & KW_I2C_IRQ_START) | 342 | if (isr & KW_I2C_IRQ_START) |
308 | kw_write_reg(reg_isr, KW_I2C_IRQ_START); | 343 | kw_write_reg(reg_isr, KW_I2C_IRQ_START); |
309 | 344 | ||
310 | return state; | 345 | return; |
311 | |||
312 | stop: | 346 | stop: |
313 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | 347 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); |
314 | return state_stop; | 348 | host->state = state_stop; |
349 | return; | ||
315 | } | 350 | } |
316 | 351 | ||
352 | /* Interrupt handler */ | ||
353 | static irqreturn_t kw_i2c_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
354 | { | ||
355 | struct pmac_i2c_host_kw *host = dev_id; | ||
356 | unsigned long flags; | ||
357 | |||
358 | spin_lock_irqsave(&host->lock, flags); | ||
359 | del_timer(&host->timeout_timer); | ||
360 | kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); | ||
361 | if (host->state != state_idle) { | ||
362 | host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; | ||
363 | add_timer(&host->timeout_timer); | ||
364 | } | ||
365 | spin_unlock_irqrestore(&host->lock, flags); | ||
366 | return IRQ_HANDLED; | ||
367 | } | ||
368 | |||
369 | static void kw_i2c_timeout(unsigned long data) | ||
370 | { | ||
371 | struct pmac_i2c_host_kw *host = (struct pmac_i2c_host_kw *)data; | ||
372 | unsigned long flags; | ||
373 | |||
374 | spin_lock_irqsave(&host->lock, flags); | ||
375 | kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); | ||
376 | if (host->state != state_idle) { | ||
377 | host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; | ||
378 | add_timer(&host->timeout_timer); | ||
379 | } | ||
380 | spin_unlock_irqrestore(&host->lock, flags); | ||
381 | } | ||
382 | |||
317 | static int kw_i2c_open(struct pmac_i2c_bus *bus) | 383 | static int kw_i2c_open(struct pmac_i2c_bus *bus) |
318 | { | 384 | { |
319 | struct pmac_i2c_host_kw *host = bus->hostdata; | 385 | struct pmac_i2c_host_kw *host = bus->hostdata; |
320 | down(&host->mutex); | 386 | down(&host->mutex); |
321 | return 0; | 387 | return 0; |
322 | } | 388 | } |
323 | 389 | ||
324 | static void kw_i2c_close(struct pmac_i2c_bus *bus) | 390 | static void kw_i2c_close(struct pmac_i2c_bus *bus) |
325 | { | 391 | { |
326 | struct pmac_i2c_host_kw *host = bus->hostdata; | 392 | struct pmac_i2c_host_kw *host = bus->hostdata; |
327 | up(&host->mutex); | 393 | up(&host->mutex); |
328 | } | 394 | } |
329 | 395 | ||
330 | static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, | 396 | static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, |
331 | u32 subaddr, u8 *data, int len) | 397 | u32 subaddr, u8 *data, int len) |
332 | { | 398 | { |
333 | struct pmac_i2c_host_kw *host = bus->hostdata; | 399 | struct pmac_i2c_host_kw *host = bus->hostdata; |
334 | u8 mode_reg = host->speed; | 400 | u8 mode_reg = host->speed; |
335 | int state = state_addr; | 401 | int use_irq = host->irq != NO_IRQ && !bus->polled; |
336 | int rc = 0; | ||
337 | 402 | ||
338 | /* Setup mode & subaddress if any */ | 403 | /* Setup mode & subaddress if any */ |
339 | switch(bus->mode) { | 404 | switch(bus->mode) { |
340 | case pmac_i2c_mode_dumb: | 405 | case pmac_i2c_mode_dumb: |
341 | return -EINVAL; | 406 | return -EINVAL; |
342 | case pmac_i2c_mode_std: | 407 | case pmac_i2c_mode_std: |
343 | mode_reg |= KW_I2C_MODE_STANDARD; | 408 | mode_reg |= KW_I2C_MODE_STANDARD; |
344 | if (subsize != 0) | 409 | if (subsize != 0) |
345 | return -EINVAL; | 410 | return -EINVAL; |
346 | break; | 411 | break; |
347 | case pmac_i2c_mode_stdsub: | 412 | case pmac_i2c_mode_stdsub: |
348 | mode_reg |= KW_I2C_MODE_STANDARDSUB; | 413 | mode_reg |= KW_I2C_MODE_STANDARDSUB; |
349 | if (subsize != 1) | 414 | if (subsize != 1) |
350 | return -EINVAL; | 415 | return -EINVAL; |
351 | break; | 416 | break; |
352 | case pmac_i2c_mode_combined: | 417 | case pmac_i2c_mode_combined: |
353 | mode_reg |= KW_I2C_MODE_COMBINED; | 418 | mode_reg |= KW_I2C_MODE_COMBINED; |
354 | if (subsize != 1) | 419 | if (subsize != 1) |
355 | return -EINVAL; | 420 | return -EINVAL; |
356 | break; | 421 | break; |
357 | } | 422 | } |
358 | 423 | ||
359 | /* Setup channel & clear pending irqs */ | 424 | /* Setup channel & clear pending irqs */ |
360 | kw_write_reg(reg_isr, kw_read_reg(reg_isr)); | 425 | kw_write_reg(reg_isr, kw_read_reg(reg_isr)); |
361 | kw_write_reg(reg_mode, mode_reg | (bus->channel << 4)); | 426 | kw_write_reg(reg_mode, mode_reg | (bus->channel << 4)); |
362 | kw_write_reg(reg_status, 0); | 427 | kw_write_reg(reg_status, 0); |
363 | 428 | ||
364 | /* Set up address and r/w bit, strip possible stale bus number from | 429 | /* Set up address and r/w bit, strip possible stale bus number from |
365 | * address top bits | 430 | * address top bits |
366 | */ | 431 | */ |
367 | kw_write_reg(reg_addr, addrdir & 0xff); | 432 | kw_write_reg(reg_addr, addrdir & 0xff); |
368 | 433 | ||
369 | /* Set up the sub address */ | 434 | /* Set up the sub address */ |
370 | if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB | 435 | if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB |
371 | || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) | 436 | || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) |
372 | kw_write_reg(reg_subaddr, subaddr); | 437 | kw_write_reg(reg_subaddr, subaddr); |
373 | 438 | ||
374 | /* Start sending address & disable interrupt*/ | 439 | /* Prepare for async operations */ |
375 | kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/); | 440 | host->data = data; |
441 | host->len = len; | ||
442 | host->state = state_addr; | ||
443 | host->result = 0; | ||
444 | host->rw = (addrdir & 1); | ||
445 | host->polled = bus->polled; | ||
446 | |||
447 | /* Enable interrupt if not using polled mode and interrupt is | ||
448 | * available | ||
449 | */ | ||
450 | if (use_irq) { | ||
451 | /* Clear completion */ | ||
452 | INIT_COMPLETION(host->complete); | ||
453 | /* Ack stale interrupts */ | ||
454 | kw_write_reg(reg_isr, kw_read_reg(reg_isr)); | ||
455 | /* Arm timeout */ | ||
456 | host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; | ||
457 | add_timer(&host->timeout_timer); | ||
458 | /* Enable emission */ | ||
459 | kw_write_reg(reg_ier, KW_I2C_IRQ_MASK); | ||
460 | } | ||
461 | |||
462 | /* Start sending address */ | ||
376 | kw_write_reg(reg_control, KW_I2C_CTL_XADDR); | 463 | kw_write_reg(reg_control, KW_I2C_CTL_XADDR); |
377 | 464 | ||
378 | /* State machine, to turn into an interrupt handler in the future */ | 465 | /* Wait for completion */ |
379 | while(state != state_idle) { | 466 | if (use_irq) |
380 | u8 isr = kw_i2c_wait_interrupt(bus); | 467 | wait_for_completion(&host->complete); |
381 | state = kw_i2c_handle_interrupt(bus, state, addrdir & 1, &rc, | 468 | else { |
382 | &data, &len, isr); | 469 | while(host->state != state_idle) { |
470 | unsigned long flags; | ||
471 | |||
472 | u8 isr = kw_i2c_wait_interrupt(host); | ||
473 | spin_lock_irqsave(&host->lock, flags); | ||
474 | kw_i2c_handle_interrupt(host, isr); | ||
475 | spin_unlock_irqrestore(&host->lock, flags); | ||
476 | } | ||
383 | } | 477 | } |
384 | 478 | ||
385 | return rc; | 479 | /* Disable emission */ |
480 | kw_write_reg(reg_ier, 0); | ||
481 | |||
482 | return host->result; | ||
386 | } | 483 | } |
387 | 484 | ||
388 | static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) | 485 | static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) |
389 | { | 486 | { |
390 | struct pmac_i2c_host_kw *host; | 487 | struct pmac_i2c_host_kw *host; |
391 | u32 *psteps, *prate, *addrp, steps; | 488 | u32 *psteps, *prate, *addrp, steps; |
392 | 489 | ||
393 | host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); | 490 | host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); |
394 | if (host == NULL) { | 491 | if (host == NULL) { |
395 | printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", | 492 | printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", |
396 | np->full_name); | 493 | np->full_name); |
397 | return NULL; | 494 | return NULL; |
398 | } | 495 | } |
399 | 496 | ||
400 | /* Apple is kind enough to provide a valid AAPL,address property | 497 | /* Apple is kind enough to provide a valid AAPL,address property |
401 | * on all i2c keywest nodes so far ... we would have to fallback | 498 | * on all i2c keywest nodes so far ... we would have to fallback |
402 | * to macio parsing if that wasn't the case | 499 | * to macio parsing if that wasn't the case |
403 | */ | 500 | */ |
404 | addrp = (u32 *)get_property(np, "AAPL,address", NULL); | 501 | addrp = (u32 *)get_property(np, "AAPL,address", NULL); |
405 | if (addrp == NULL) { | 502 | if (addrp == NULL) { |
406 | printk(KERN_ERR "low_i2c: Can't find address for %s\n", | 503 | printk(KERN_ERR "low_i2c: Can't find address for %s\n", |
407 | np->full_name); | 504 | np->full_name); |
408 | kfree(host); | 505 | kfree(host); |
409 | return NULL; | 506 | return NULL; |
410 | } | 507 | } |
411 | init_MUTEX(&host->mutex); | 508 | init_MUTEX(&host->mutex); |
509 | init_completion(&host->complete); | ||
510 | spin_lock_init(&host->lock); | ||
511 | init_timer(&host->timeout_timer); | ||
512 | host->timeout_timer.function = kw_i2c_timeout; | ||
513 | host->timeout_timer.data = (unsigned long)host; | ||
514 | |||
412 | psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); | 515 | psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); |
413 | steps = psteps ? (*psteps) : 0x10; | 516 | steps = psteps ? (*psteps) : 0x10; |
414 | for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) | 517 | for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) |
415 | steps >>= 1; | 518 | steps >>= 1; |
416 | /* Select interface rate */ | 519 | /* Select interface rate */ |
417 | host->speed = KW_I2C_MODE_25KHZ; | 520 | host->speed = KW_I2C_MODE_25KHZ; |
418 | prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); | 521 | prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); |
419 | if (prate) switch(*prate) { | 522 | if (prate) switch(*prate) { |
420 | case 100: | 523 | case 100: |
421 | host->speed = KW_I2C_MODE_100KHZ; | 524 | host->speed = KW_I2C_MODE_100KHZ; |
422 | break; | 525 | break; |
423 | case 50: | 526 | case 50: |
424 | host->speed = KW_I2C_MODE_50KHZ; | 527 | host->speed = KW_I2C_MODE_50KHZ; |
425 | break; | 528 | break; |
426 | case 25: | 529 | case 25: |
427 | host->speed = KW_I2C_MODE_25KHZ; | 530 | host->speed = KW_I2C_MODE_25KHZ; |
428 | break; | 531 | break; |
429 | } | 532 | } |
533 | if (np->n_intrs > 0) | ||
534 | host->irq = np->intrs[0].line; | ||
535 | else | ||
536 | host->irq = NO_IRQ; | ||
430 | 537 | ||
431 | printk(KERN_INFO "KeyWest i2c @0x%08x %s\n", *addrp, np->full_name); | ||
432 | host->base = ioremap((*addrp), 0x1000); | 538 | host->base = ioremap((*addrp), 0x1000); |
539 | if (host->base == NULL) { | ||
540 | printk(KERN_ERR "low_i2c: Can't map registers for %s\n", | ||
541 | np->full_name); | ||
542 | kfree(host); | ||
543 | return NULL; | ||
544 | } | ||
433 | 545 | ||
546 | /* Make sure IRA is disabled */ | ||
547 | kw_write_reg(reg_ier, 0); | ||
548 | |||
549 | /* Request chip interrupt */ | ||
550 | if (request_irq(host->irq, kw_i2c_irq, SA_SHIRQ, "keywest i2c", host)) | ||
551 | host->irq = NO_IRQ; | ||
552 | |||
553 | printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", | ||
554 | *addrp, host->irq, np->full_name); | ||
555 | |||
434 | return host; | 556 | return host; |
435 | } | 557 | } |
436 | 558 | ||
437 | 559 | ||
438 | static void __init kw_i2c_add(struct pmac_i2c_host_kw *host, | 560 | static void __init kw_i2c_add(struct pmac_i2c_host_kw *host, |
439 | struct device_node *controller, | 561 | struct device_node *controller, |
440 | struct device_node *busnode, | 562 | struct device_node *busnode, |
441 | int channel) | 563 | int channel) |
442 | { | 564 | { |
443 | struct pmac_i2c_bus *bus; | 565 | struct pmac_i2c_bus *bus; |
444 | 566 | ||
445 | bus = kzalloc(sizeof(struct pmac_i2c_bus), GFP_KERNEL); | 567 | bus = kzalloc(sizeof(struct pmac_i2c_bus), GFP_KERNEL); |
446 | if (bus == NULL) | 568 | if (bus == NULL) |
447 | return; | 569 | return; |
448 | 570 | ||
449 | bus->controller = of_node_get(controller); | 571 | bus->controller = of_node_get(controller); |
450 | bus->busnode = of_node_get(busnode); | 572 | bus->busnode = of_node_get(busnode); |
451 | bus->type = pmac_i2c_bus_keywest; | 573 | bus->type = pmac_i2c_bus_keywest; |
452 | bus->hostdata = host; | 574 | bus->hostdata = host; |
453 | bus->channel = channel; | 575 | bus->channel = channel; |
454 | bus->mode = pmac_i2c_mode_std; | 576 | bus->mode = pmac_i2c_mode_std; |
455 | bus->open = kw_i2c_open; | 577 | bus->open = kw_i2c_open; |
456 | bus->close = kw_i2c_close; | 578 | bus->close = kw_i2c_close; |
457 | bus->xfer = kw_i2c_xfer; | 579 | bus->xfer = kw_i2c_xfer; |
458 | init_MUTEX(&bus->sem); | 580 | init_MUTEX(&bus->sem); |
459 | if (controller == busnode) | 581 | if (controller == busnode) |
460 | bus->flags = pmac_i2c_multibus; | 582 | bus->flags = pmac_i2c_multibus; |
461 | list_add(&bus->link, &pmac_i2c_busses); | 583 | list_add(&bus->link, &pmac_i2c_busses); |
462 | 584 | ||
463 | printk(KERN_INFO " channel %d bus %s\n", channel, | 585 | printk(KERN_INFO " channel %d bus %s\n", channel, |
464 | (controller == busnode) ? "<multibus>" : busnode->full_name); | 586 | (controller == busnode) ? "<multibus>" : busnode->full_name); |
465 | } | 587 | } |
466 | 588 | ||
467 | static void __init kw_i2c_probe(void) | 589 | static void __init kw_i2c_probe(void) |
468 | { | 590 | { |
469 | struct device_node *np, *child, *parent; | 591 | struct device_node *np, *child, *parent; |
470 | 592 | ||
471 | /* Probe keywest-i2c busses */ | 593 | /* Probe keywest-i2c busses */ |
472 | for (np = NULL; | 594 | for (np = NULL; |
473 | (np = of_find_compatible_node(np, "i2c","keywest-i2c")) != NULL;){ | 595 | (np = of_find_compatible_node(np, "i2c","keywest-i2c")) != NULL;){ |
474 | struct pmac_i2c_host_kw *host; | 596 | struct pmac_i2c_host_kw *host; |
475 | int multibus, chans, i; | 597 | int multibus, chans, i; |
476 | 598 | ||
477 | /* Found one, init a host structure */ | 599 | /* Found one, init a host structure */ |
478 | host = kw_i2c_host_init(np); | 600 | host = kw_i2c_host_init(np); |
479 | if (host == NULL) | 601 | if (host == NULL) |
480 | continue; | 602 | continue; |
481 | 603 | ||
482 | /* Now check if we have a multibus setup (old style) or if we | 604 | /* Now check if we have a multibus setup (old style) or if we |
483 | * have proper bus nodes. Note that the "new" way (proper bus | 605 | * have proper bus nodes. Note that the "new" way (proper bus |
484 | * nodes) might cause us to not create some busses that are | 606 | * nodes) might cause us to not create some busses that are |
485 | * kept hidden in the device-tree. In the future, we might | 607 | * kept hidden in the device-tree. In the future, we might |
486 | * want to work around that by creating busses without a node | 608 | * want to work around that by creating busses without a node |
487 | * but not for now | 609 | * but not for now |
488 | */ | 610 | */ |
489 | child = of_get_next_child(np, NULL); | 611 | child = of_get_next_child(np, NULL); |
490 | multibus = !child || strcmp(child->name, "i2c-bus"); | 612 | multibus = !child || strcmp(child->name, "i2c-bus"); |
491 | of_node_put(child); | 613 | of_node_put(child); |
492 | 614 | ||
493 | /* For a multibus setup, we get the bus count based on the | 615 | /* For a multibus setup, we get the bus count based on the |
494 | * parent type | 616 | * parent type |
495 | */ | 617 | */ |
496 | if (multibus) { | 618 | if (multibus) { |
497 | parent = of_get_parent(np); | 619 | parent = of_get_parent(np); |
498 | if (parent == NULL) | 620 | if (parent == NULL) |
499 | continue; | 621 | continue; |
500 | chans = parent->name[0] == 'u' ? 2 : 1; | 622 | chans = parent->name[0] == 'u' ? 2 : 1; |
501 | for (i = 0; i < chans; i++) | 623 | for (i = 0; i < chans; i++) |
502 | kw_i2c_add(host, np, np, i); | 624 | kw_i2c_add(host, np, np, i); |
503 | } else { | 625 | } else { |
504 | for (child = NULL; | 626 | for (child = NULL; |
505 | (child = of_get_next_child(np, child)) != NULL;) { | 627 | (child = of_get_next_child(np, child)) != NULL;) { |
506 | u32 *reg = | 628 | u32 *reg = |
507 | (u32 *)get_property(child, "reg", NULL); | 629 | (u32 *)get_property(child, "reg", NULL); |
508 | if (reg == NULL) | 630 | if (reg == NULL) |
509 | continue; | 631 | continue; |
510 | kw_i2c_add(host, np, child, *reg); | 632 | kw_i2c_add(host, np, child, *reg); |
511 | } | 633 | } |
512 | } | 634 | } |
513 | } | 635 | } |
514 | } | 636 | } |
515 | 637 | ||
516 | 638 | ||
517 | /* | 639 | /* |
518 | * | 640 | * |
519 | * PMU implementation | 641 | * PMU implementation |
520 | * | 642 | * |
521 | */ | 643 | */ |
522 | 644 | ||
523 | #ifdef CONFIG_ADB_PMU | 645 | #ifdef CONFIG_ADB_PMU |
524 | 646 | ||
525 | /* | 647 | /* |
526 | * i2c command block to the PMU | 648 | * i2c command block to the PMU |
527 | */ | 649 | */ |
528 | struct pmu_i2c_hdr { | 650 | struct pmu_i2c_hdr { |
529 | u8 bus; | 651 | u8 bus; |
530 | u8 mode; | 652 | u8 mode; |
531 | u8 bus2; | 653 | u8 bus2; |
532 | u8 address; | 654 | u8 address; |
533 | u8 sub_addr; | 655 | u8 sub_addr; |
534 | u8 comb_addr; | 656 | u8 comb_addr; |
535 | u8 count; | 657 | u8 count; |
536 | u8 data[]; | 658 | u8 data[]; |
537 | }; | 659 | }; |
538 | 660 | ||
539 | static void pmu_i2c_complete(struct adb_request *req) | 661 | static void pmu_i2c_complete(struct adb_request *req) |
540 | { | 662 | { |
541 | complete(req->arg); | 663 | complete(req->arg); |
542 | } | 664 | } |
543 | 665 | ||
544 | static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, | 666 | static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, |
545 | u32 subaddr, u8 *data, int len) | 667 | u32 subaddr, u8 *data, int len) |
546 | { | 668 | { |
547 | struct adb_request *req = bus->hostdata; | 669 | struct adb_request *req = bus->hostdata; |
548 | struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req->data[1]; | 670 | struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req->data[1]; |
549 | struct completion comp; | 671 | struct completion comp; |
550 | int read = addrdir & 1; | 672 | int read = addrdir & 1; |
551 | int retry; | 673 | int retry; |
552 | int rc = 0; | 674 | int rc = 0; |
553 | 675 | ||
554 | /* For now, limit ourselves to 16 bytes transfers */ | 676 | /* For now, limit ourselves to 16 bytes transfers */ |
555 | if (len > 16) | 677 | if (len > 16) |
556 | return -EINVAL; | 678 | return -EINVAL; |
557 | 679 | ||
558 | init_completion(&comp); | 680 | init_completion(&comp); |
559 | 681 | ||
560 | for (retry = 0; retry < 16; retry++) { | 682 | for (retry = 0; retry < 16; retry++) { |
561 | memset(req, 0, sizeof(struct adb_request)); | 683 | memset(req, 0, sizeof(struct adb_request)); |
562 | hdr->bus = bus->channel; | 684 | hdr->bus = bus->channel; |
563 | hdr->count = len; | 685 | hdr->count = len; |
564 | 686 | ||
565 | switch(bus->mode) { | 687 | switch(bus->mode) { |
566 | case pmac_i2c_mode_std: | 688 | case pmac_i2c_mode_std: |
567 | if (subsize != 0) | 689 | if (subsize != 0) |
568 | return -EINVAL; | 690 | return -EINVAL; |
569 | hdr->address = addrdir; | 691 | hdr->address = addrdir; |
570 | hdr->mode = PMU_I2C_MODE_SIMPLE; | 692 | hdr->mode = PMU_I2C_MODE_SIMPLE; |
571 | break; | 693 | break; |
572 | case pmac_i2c_mode_stdsub: | 694 | case pmac_i2c_mode_stdsub: |
573 | case pmac_i2c_mode_combined: | 695 | case pmac_i2c_mode_combined: |
574 | if (subsize != 1) | 696 | if (subsize != 1) |
575 | return -EINVAL; | 697 | return -EINVAL; |
576 | hdr->address = addrdir & 0xfe; | 698 | hdr->address = addrdir & 0xfe; |
577 | hdr->comb_addr = addrdir; | 699 | hdr->comb_addr = addrdir; |
578 | hdr->sub_addr = subaddr; | 700 | hdr->sub_addr = subaddr; |
579 | if (bus->mode == pmac_i2c_mode_stdsub) | 701 | if (bus->mode == pmac_i2c_mode_stdsub) |
580 | hdr->mode = PMU_I2C_MODE_STDSUB; | 702 | hdr->mode = PMU_I2C_MODE_STDSUB; |
581 | else | 703 | else |
582 | hdr->mode = PMU_I2C_MODE_COMBINED; | 704 | hdr->mode = PMU_I2C_MODE_COMBINED; |
583 | break; | 705 | break; |
584 | default: | 706 | default: |
585 | return -EINVAL; | 707 | return -EINVAL; |
586 | } | 708 | } |
587 | 709 | ||
588 | INIT_COMPLETION(comp); | 710 | INIT_COMPLETION(comp); |
589 | req->data[0] = PMU_I2C_CMD; | 711 | req->data[0] = PMU_I2C_CMD; |
590 | req->reply[0] = 0xff; | 712 | req->reply[0] = 0xff; |
591 | req->nbytes = sizeof(struct pmu_i2c_hdr) + 1; | 713 | req->nbytes = sizeof(struct pmu_i2c_hdr) + 1; |
592 | req->done = pmu_i2c_complete; | 714 | req->done = pmu_i2c_complete; |
593 | req->arg = ∁ | 715 | req->arg = ∁ |
594 | if (!read) { | 716 | if (!read && len) { |
595 | memcpy(hdr->data, data, len); | 717 | memcpy(hdr->data, data, len); |
596 | req->nbytes += len; | 718 | req->nbytes += len; |
597 | } | 719 | } |
598 | rc = pmu_queue_request(req); | 720 | rc = pmu_queue_request(req); |
599 | if (rc) | 721 | if (rc) |
600 | return rc; | 722 | return rc; |
601 | wait_for_completion(&comp); | 723 | wait_for_completion(&comp); |
602 | if (req->reply[0] == PMU_I2C_STATUS_OK) | 724 | if (req->reply[0] == PMU_I2C_STATUS_OK) |
603 | break; | 725 | break; |
604 | msleep(15); | 726 | msleep(15); |
605 | } | 727 | } |
606 | if (req->reply[0] != PMU_I2C_STATUS_OK) | 728 | if (req->reply[0] != PMU_I2C_STATUS_OK) |
607 | return -EIO; | 729 | return -EIO; |
608 | 730 | ||
609 | for (retry = 0; retry < 16; retry++) { | 731 | for (retry = 0; retry < 16; retry++) { |
610 | memset(req, 0, sizeof(struct adb_request)); | 732 | memset(req, 0, sizeof(struct adb_request)); |
611 | 733 | ||
612 | /* I know that looks like a lot, slow as hell, but darwin | 734 | /* I know that looks like a lot, slow as hell, but darwin |
613 | * does it so let's be on the safe side for now | 735 | * does it so let's be on the safe side for now |
614 | */ | 736 | */ |
615 | msleep(15); | 737 | msleep(15); |
616 | 738 | ||
617 | hdr->bus = PMU_I2C_BUS_STATUS; | 739 | hdr->bus = PMU_I2C_BUS_STATUS; |
618 | 740 | ||
619 | INIT_COMPLETION(comp); | 741 | INIT_COMPLETION(comp); |
620 | req->data[0] = PMU_I2C_CMD; | 742 | req->data[0] = PMU_I2C_CMD; |
621 | req->reply[0] = 0xff; | 743 | req->reply[0] = 0xff; |
622 | req->nbytes = 2; | 744 | req->nbytes = 2; |
623 | req->done = pmu_i2c_complete; | 745 | req->done = pmu_i2c_complete; |
624 | req->arg = ∁ | 746 | req->arg = ∁ |
625 | rc = pmu_queue_request(req); | 747 | rc = pmu_queue_request(req); |
626 | if (rc) | 748 | if (rc) |
627 | return rc; | 749 | return rc; |
628 | wait_for_completion(&comp); | 750 | wait_for_completion(&comp); |
629 | 751 | ||
630 | if (req->reply[0] == PMU_I2C_STATUS_OK && !read) | 752 | if (req->reply[0] == PMU_I2C_STATUS_OK && !read) |
631 | return 0; | 753 | return 0; |
632 | if (req->reply[0] == PMU_I2C_STATUS_DATAREAD && read) { | 754 | if (req->reply[0] == PMU_I2C_STATUS_DATAREAD && read) { |
633 | int rlen = req->reply_len - 1; | 755 | int rlen = req->reply_len - 1; |
634 | 756 | ||
635 | if (rlen != len) { | 757 | if (rlen != len) { |
636 | printk(KERN_WARNING "low_i2c: PMU returned %d" | 758 | printk(KERN_WARNING "low_i2c: PMU returned %d" |
637 | " bytes, expected %d !\n", rlen, len); | 759 | " bytes, expected %d !\n", rlen, len); |
638 | return -EIO; | 760 | return -EIO; |
639 | } | 761 | } |
640 | memcpy(data, &req->reply[1], len); | 762 | if (len) |
763 | memcpy(data, &req->reply[1], len); | ||
641 | return 0; | 764 | return 0; |
642 | } | 765 | } |
643 | } | 766 | } |
644 | return -EIO; | 767 | return -EIO; |
645 | } | 768 | } |
646 | 769 | ||
647 | static void __init pmu_i2c_probe(void) | 770 | static void __init pmu_i2c_probe(void) |
648 | { | 771 | { |
649 | struct pmac_i2c_bus *bus; | 772 | struct pmac_i2c_bus *bus; |
650 | struct device_node *busnode; | 773 | struct device_node *busnode; |
651 | int channel, sz; | 774 | int channel, sz; |
652 | 775 | ||
653 | if (!pmu_present()) | 776 | if (!pmu_present()) |
654 | return; | 777 | return; |
655 | 778 | ||
656 | /* There might or might not be a "pmu-i2c" node, we use that | 779 | /* There might or might not be a "pmu-i2c" node, we use that |
657 | * or via-pmu itself, whatever we find. I haven't seen a machine | 780 | * or via-pmu itself, whatever we find. I haven't seen a machine |
658 | * with separate bus nodes, so we assume a multibus setup | 781 | * with separate bus nodes, so we assume a multibus setup |
659 | */ | 782 | */ |
660 | busnode = of_find_node_by_name(NULL, "pmu-i2c"); | 783 | busnode = of_find_node_by_name(NULL, "pmu-i2c"); |
661 | if (busnode == NULL) | 784 | if (busnode == NULL) |
662 | busnode = of_find_node_by_name(NULL, "via-pmu"); | 785 | busnode = of_find_node_by_name(NULL, "via-pmu"); |
663 | if (busnode == NULL) | 786 | if (busnode == NULL) |
664 | return; | 787 | return; |
665 | 788 | ||
666 | printk(KERN_INFO "PMU i2c %s\n", busnode->full_name); | 789 | printk(KERN_INFO "PMU i2c %s\n", busnode->full_name); |
667 | 790 | ||
668 | /* | 791 | /* |
669 | * We add bus 1 and 2 only for now, bus 0 is "special" | 792 | * We add bus 1 and 2 only for now, bus 0 is "special" |
670 | */ | 793 | */ |
671 | for (channel = 1; channel <= 2; channel++) { | 794 | for (channel = 1; channel <= 2; channel++) { |
672 | sz = sizeof(struct pmac_i2c_bus) + sizeof(struct adb_request); | 795 | sz = sizeof(struct pmac_i2c_bus) + sizeof(struct adb_request); |
673 | bus = kzalloc(sz, GFP_KERNEL); | 796 | bus = kzalloc(sz, GFP_KERNEL); |
674 | if (bus == NULL) | 797 | if (bus == NULL) |
675 | return; | 798 | return; |
676 | 799 | ||
677 | bus->controller = busnode; | 800 | bus->controller = busnode; |
678 | bus->busnode = busnode; | 801 | bus->busnode = busnode; |
679 | bus->type = pmac_i2c_bus_pmu; | 802 | bus->type = pmac_i2c_bus_pmu; |
680 | bus->channel = channel; | 803 | bus->channel = channel; |
681 | bus->mode = pmac_i2c_mode_std; | 804 | bus->mode = pmac_i2c_mode_std; |
682 | bus->hostdata = bus + 1; | 805 | bus->hostdata = bus + 1; |
683 | bus->xfer = pmu_i2c_xfer; | 806 | bus->xfer = pmu_i2c_xfer; |
684 | init_MUTEX(&bus->sem); | 807 | init_MUTEX(&bus->sem); |
685 | bus->flags = pmac_i2c_multibus; | 808 | bus->flags = pmac_i2c_multibus; |
686 | list_add(&bus->link, &pmac_i2c_busses); | 809 | list_add(&bus->link, &pmac_i2c_busses); |
687 | 810 | ||
688 | printk(KERN_INFO " channel %d bus <multibus>\n", channel); | 811 | printk(KERN_INFO " channel %d bus <multibus>\n", channel); |
689 | } | 812 | } |
690 | } | 813 | } |
691 | 814 | ||
692 | #endif /* CONFIG_ADB_PMU */ | 815 | #endif /* CONFIG_ADB_PMU */ |
693 | 816 | ||
694 | 817 | ||
695 | /* | 818 | /* |
696 | * | 819 | * |
697 | * SMU implementation | 820 | * SMU implementation |
698 | * | 821 | * |
699 | */ | 822 | */ |
700 | 823 | ||
701 | #ifdef CONFIG_PMAC_SMU | 824 | #ifdef CONFIG_PMAC_SMU |
702 | 825 | ||
703 | static void smu_i2c_complete(struct smu_i2c_cmd *cmd, void *misc) | 826 | static void smu_i2c_complete(struct smu_i2c_cmd *cmd, void *misc) |
704 | { | 827 | { |
705 | complete(misc); | 828 | complete(misc); |
706 | } | 829 | } |
707 | 830 | ||
708 | static int smu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, | 831 | static int smu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, |
709 | u32 subaddr, u8 *data, int len) | 832 | u32 subaddr, u8 *data, int len) |
710 | { | 833 | { |
711 | struct smu_i2c_cmd *cmd = bus->hostdata; | 834 | struct smu_i2c_cmd *cmd = bus->hostdata; |
712 | struct completion comp; | 835 | struct completion comp; |
713 | int read = addrdir & 1; | 836 | int read = addrdir & 1; |
714 | int rc = 0; | 837 | int rc = 0; |
715 | 838 | ||
839 | if ((read && len > SMU_I2C_READ_MAX) || | ||
840 | ((!read) && len > SMU_I2C_WRITE_MAX)) | ||
841 | return -EINVAL; | ||
842 | |||
716 | memset(cmd, 0, sizeof(struct smu_i2c_cmd)); | 843 | memset(cmd, 0, sizeof(struct smu_i2c_cmd)); |
717 | cmd->info.bus = bus->channel; | 844 | cmd->info.bus = bus->channel; |
718 | cmd->info.devaddr = addrdir; | 845 | cmd->info.devaddr = addrdir; |
719 | cmd->info.datalen = len; | 846 | cmd->info.datalen = len; |
720 | 847 | ||
721 | switch(bus->mode) { | 848 | switch(bus->mode) { |
722 | case pmac_i2c_mode_std: | 849 | case pmac_i2c_mode_std: |
723 | if (subsize != 0) | 850 | if (subsize != 0) |
724 | return -EINVAL; | 851 | return -EINVAL; |
725 | cmd->info.type = SMU_I2C_TRANSFER_SIMPLE; | 852 | cmd->info.type = SMU_I2C_TRANSFER_SIMPLE; |
726 | break; | 853 | break; |
727 | case pmac_i2c_mode_stdsub: | 854 | case pmac_i2c_mode_stdsub: |
728 | case pmac_i2c_mode_combined: | 855 | case pmac_i2c_mode_combined: |
729 | if (subsize > 3 || subsize < 1) | 856 | if (subsize > 3 || subsize < 1) |
730 | return -EINVAL; | 857 | return -EINVAL; |
731 | cmd->info.sublen = subsize; | 858 | cmd->info.sublen = subsize; |
732 | /* that's big-endian only but heh ! */ | 859 | /* that's big-endian only but heh ! */ |
733 | memcpy(&cmd->info.subaddr, ((char *)&subaddr) + (4 - subsize), | 860 | memcpy(&cmd->info.subaddr, ((char *)&subaddr) + (4 - subsize), |
734 | subsize); | 861 | subsize); |
735 | if (bus->mode == pmac_i2c_mode_stdsub) | 862 | if (bus->mode == pmac_i2c_mode_stdsub) |
736 | cmd->info.type = SMU_I2C_TRANSFER_STDSUB; | 863 | cmd->info.type = SMU_I2C_TRANSFER_STDSUB; |
737 | else | 864 | else |
738 | cmd->info.type = SMU_I2C_TRANSFER_COMBINED; | 865 | cmd->info.type = SMU_I2C_TRANSFER_COMBINED; |
739 | break; | 866 | break; |
740 | default: | 867 | default: |
741 | return -EINVAL; | 868 | return -EINVAL; |
742 | } | 869 | } |
743 | if (!read) | 870 | if (!read && len) |
744 | memcpy(cmd->info.data, data, len); | 871 | memcpy(cmd->info.data, data, len); |
745 | 872 | ||
746 | init_completion(&comp); | 873 | init_completion(&comp); |
747 | cmd->done = smu_i2c_complete; | 874 | cmd->done = smu_i2c_complete; |
748 | cmd->misc = ∁ | 875 | cmd->misc = ∁ |
749 | rc = smu_queue_i2c(cmd); | 876 | rc = smu_queue_i2c(cmd); |
750 | if (rc < 0) | 877 | if (rc < 0) |
751 | return rc; | 878 | return rc; |
752 | wait_for_completion(&comp); | 879 | wait_for_completion(&comp); |
753 | rc = cmd->status; | 880 | rc = cmd->status; |
754 | 881 | ||
755 | if (read) | 882 | if (read && len) |
756 | memcpy(data, cmd->info.data, len); | 883 | memcpy(data, cmd->info.data, len); |
757 | return rc < 0 ? rc : 0; | 884 | return rc < 0 ? rc : 0; |
758 | } | 885 | } |
759 | 886 | ||
760 | static void __init smu_i2c_probe(void) | 887 | static void __init smu_i2c_probe(void) |
761 | { | 888 | { |
762 | struct device_node *controller, *busnode; | 889 | struct device_node *controller, *busnode; |
763 | struct pmac_i2c_bus *bus; | 890 | struct pmac_i2c_bus *bus; |
764 | u32 *reg; | 891 | u32 *reg; |
765 | int sz; | 892 | int sz; |
766 | 893 | ||
767 | if (!smu_present()) | 894 | if (!smu_present()) |
768 | return; | 895 | return; |
769 | 896 | ||
770 | controller = of_find_node_by_name(NULL, "smu_i2c_control"); | 897 | controller = of_find_node_by_name(NULL, "smu-i2c-control"); |
771 | if (controller == NULL) | 898 | if (controller == NULL) |
772 | controller = of_find_node_by_name(NULL, "smu"); | 899 | controller = of_find_node_by_name(NULL, "smu"); |
773 | if (controller == NULL) | 900 | if (controller == NULL) |
774 | return; | 901 | return; |
775 | 902 | ||
776 | printk(KERN_INFO "SMU i2c %s\n", controller->full_name); | 903 | printk(KERN_INFO "SMU i2c %s\n", controller->full_name); |
777 | 904 | ||
778 | /* Look for childs, note that they might not be of the right | 905 | /* Look for childs, note that they might not be of the right |
779 | * type as older device trees mix i2c busses and other thigns | 906 | * type as older device trees mix i2c busses and other thigns |
780 | * at the same level | 907 | * at the same level |
781 | */ | 908 | */ |
782 | for (busnode = NULL; | 909 | for (busnode = NULL; |
783 | (busnode = of_get_next_child(controller, busnode)) != NULL;) { | 910 | (busnode = of_get_next_child(controller, busnode)) != NULL;) { |
784 | if (strcmp(busnode->type, "i2c") && | 911 | if (strcmp(busnode->type, "i2c") && |
785 | strcmp(busnode->type, "i2c-bus")) | 912 | strcmp(busnode->type, "i2c-bus")) |
786 | continue; | 913 | continue; |
787 | reg = (u32 *)get_property(busnode, "reg", NULL); | 914 | reg = (u32 *)get_property(busnode, "reg", NULL); |
788 | if (reg == NULL) | 915 | if (reg == NULL) |
789 | continue; | 916 | continue; |
790 | 917 | ||
791 | sz = sizeof(struct pmac_i2c_bus) + sizeof(struct smu_i2c_cmd); | 918 | sz = sizeof(struct pmac_i2c_bus) + sizeof(struct smu_i2c_cmd); |
792 | bus = kzalloc(sz, GFP_KERNEL); | 919 | bus = kzalloc(sz, GFP_KERNEL); |
793 | if (bus == NULL) | 920 | if (bus == NULL) |
794 | return; | 921 | return; |
795 | 922 | ||
796 | bus->controller = controller; | 923 | bus->controller = controller; |
797 | bus->busnode = of_node_get(busnode); | 924 | bus->busnode = of_node_get(busnode); |
798 | bus->type = pmac_i2c_bus_smu; | 925 | bus->type = pmac_i2c_bus_smu; |
799 | bus->channel = *reg; | 926 | bus->channel = *reg; |
800 | bus->mode = pmac_i2c_mode_std; | 927 | bus->mode = pmac_i2c_mode_std; |
801 | bus->hostdata = bus + 1; | 928 | bus->hostdata = bus + 1; |
802 | bus->xfer = smu_i2c_xfer; | 929 | bus->xfer = smu_i2c_xfer; |
803 | init_MUTEX(&bus->sem); | 930 | init_MUTEX(&bus->sem); |
804 | bus->flags = 0; | 931 | bus->flags = 0; |
805 | list_add(&bus->link, &pmac_i2c_busses); | 932 | list_add(&bus->link, &pmac_i2c_busses); |
806 | 933 | ||
807 | printk(KERN_INFO " channel %x bus %s\n", | 934 | printk(KERN_INFO " channel %x bus %s\n", |
808 | bus->channel, busnode->full_name); | 935 | bus->channel, busnode->full_name); |
809 | } | 936 | } |
810 | } | 937 | } |
811 | 938 | ||
812 | #endif /* CONFIG_PMAC_SMU */ | 939 | #endif /* CONFIG_PMAC_SMU */ |
813 | 940 | ||
814 | /* | 941 | /* |
815 | * | 942 | * |
816 | * Core code | 943 | * Core code |
817 | * | 944 | * |
818 | */ | 945 | */ |
819 | 946 | ||
820 | 947 | ||
821 | struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node) | 948 | struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node) |
822 | { | 949 | { |
823 | struct device_node *p = of_node_get(node); | 950 | struct device_node *p = of_node_get(node); |
824 | struct device_node *prev = NULL; | 951 | struct device_node *prev = NULL; |
825 | struct pmac_i2c_bus *bus; | 952 | struct pmac_i2c_bus *bus; |
826 | 953 | ||
827 | while(p) { | 954 | while(p) { |
828 | list_for_each_entry(bus, &pmac_i2c_busses, link) { | 955 | list_for_each_entry(bus, &pmac_i2c_busses, link) { |
829 | if (p == bus->busnode) { | 956 | if (p == bus->busnode) { |
830 | if (prev && bus->flags & pmac_i2c_multibus) { | 957 | if (prev && bus->flags & pmac_i2c_multibus) { |
831 | u32 *reg; | 958 | u32 *reg; |
832 | reg = (u32 *)get_property(prev, "reg", | 959 | reg = (u32 *)get_property(prev, "reg", |
833 | NULL); | 960 | NULL); |
834 | if (!reg) | 961 | if (!reg) |
835 | continue; | 962 | continue; |
836 | if (((*reg) >> 8) != bus->channel) | 963 | if (((*reg) >> 8) != bus->channel) |
837 | continue; | 964 | continue; |
838 | } | 965 | } |
839 | of_node_put(p); | 966 | of_node_put(p); |
840 | of_node_put(prev); | 967 | of_node_put(prev); |
841 | return bus; | 968 | return bus; |
842 | } | 969 | } |
843 | } | 970 | } |
844 | of_node_put(prev); | 971 | of_node_put(prev); |
845 | prev = p; | 972 | prev = p; |
846 | p = of_get_parent(p); | 973 | p = of_get_parent(p); |
847 | } | 974 | } |
848 | return NULL; | 975 | return NULL; |
849 | } | 976 | } |
850 | EXPORT_SYMBOL_GPL(pmac_i2c_find_bus); | 977 | EXPORT_SYMBOL_GPL(pmac_i2c_find_bus); |
851 | 978 | ||
852 | u8 pmac_i2c_get_dev_addr(struct device_node *device) | 979 | u8 pmac_i2c_get_dev_addr(struct device_node *device) |
853 | { | 980 | { |
854 | u32 *reg = (u32 *)get_property(device, "reg", NULL); | 981 | u32 *reg = (u32 *)get_property(device, "reg", NULL); |
855 | 982 | ||
856 | if (reg == NULL) | 983 | if (reg == NULL) |
857 | return 0; | 984 | return 0; |
858 | 985 | ||
859 | return (*reg) & 0xff; | 986 | return (*reg) & 0xff; |
860 | } | 987 | } |
861 | EXPORT_SYMBOL_GPL(pmac_i2c_get_dev_addr); | 988 | EXPORT_SYMBOL_GPL(pmac_i2c_get_dev_addr); |
862 | 989 | ||
863 | struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus) | 990 | struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus) |
864 | { | 991 | { |
865 | return bus->controller; | 992 | return bus->controller; |
866 | } | 993 | } |
867 | EXPORT_SYMBOL_GPL(pmac_i2c_get_controller); | 994 | EXPORT_SYMBOL_GPL(pmac_i2c_get_controller); |
868 | 995 | ||
869 | struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus) | 996 | struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus) |
870 | { | 997 | { |
871 | return bus->busnode; | 998 | return bus->busnode; |
872 | } | 999 | } |
873 | EXPORT_SYMBOL_GPL(pmac_i2c_get_bus_node); | 1000 | EXPORT_SYMBOL_GPL(pmac_i2c_get_bus_node); |
874 | 1001 | ||
875 | int pmac_i2c_get_type(struct pmac_i2c_bus *bus) | 1002 | int pmac_i2c_get_type(struct pmac_i2c_bus *bus) |
876 | { | 1003 | { |
877 | return bus->type; | 1004 | return bus->type; |
878 | } | 1005 | } |
879 | EXPORT_SYMBOL_GPL(pmac_i2c_get_type); | 1006 | EXPORT_SYMBOL_GPL(pmac_i2c_get_type); |
880 | 1007 | ||
881 | int pmac_i2c_get_flags(struct pmac_i2c_bus *bus) | 1008 | int pmac_i2c_get_flags(struct pmac_i2c_bus *bus) |
882 | { | 1009 | { |
883 | return bus->flags; | 1010 | return bus->flags; |
884 | } | 1011 | } |
885 | EXPORT_SYMBOL_GPL(pmac_i2c_get_flags); | 1012 | EXPORT_SYMBOL_GPL(pmac_i2c_get_flags); |
886 | 1013 | ||
1014 | int pmac_i2c_get_channel(struct pmac_i2c_bus *bus) | ||
1015 | { | ||
1016 | return bus->channel; | ||
1017 | } | ||
1018 | EXPORT_SYMBOL_GPL(pmac_i2c_get_channel); | ||
1019 | |||
1020 | |||
887 | void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, | 1021 | void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, |
888 | struct i2c_adapter *adapter) | 1022 | struct i2c_adapter *adapter) |
889 | { | 1023 | { |
890 | WARN_ON(bus->adapter != NULL); | 1024 | WARN_ON(bus->adapter != NULL); |
891 | bus->adapter = adapter; | 1025 | bus->adapter = adapter; |
892 | } | 1026 | } |
893 | EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter); | 1027 | EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter); |
894 | 1028 | ||
895 | void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, | 1029 | void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, |
896 | struct i2c_adapter *adapter) | 1030 | struct i2c_adapter *adapter) |
897 | { | 1031 | { |
898 | WARN_ON(bus->adapter != adapter); | 1032 | WARN_ON(bus->adapter != adapter); |
899 | bus->adapter = NULL; | 1033 | bus->adapter = NULL; |
900 | } | 1034 | } |
901 | EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter); | 1035 | EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter); |
902 | 1036 | ||
903 | struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus) | 1037 | struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus) |
904 | { | 1038 | { |
905 | return bus->adapter; | 1039 | return bus->adapter; |
906 | } | 1040 | } |
907 | EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter); | 1041 | EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter); |
908 | 1042 | ||
1043 | struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter) | ||
1044 | { | ||
1045 | struct pmac_i2c_bus *bus; | ||
1046 | |||
1047 | list_for_each_entry(bus, &pmac_i2c_busses, link) | ||
1048 | if (bus->adapter == adapter) | ||
1049 | return bus; | ||
1050 | return NULL; | ||
1051 | } | ||
1052 | EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus); | ||
1053 | |||
909 | extern int pmac_i2c_match_adapter(struct device_node *dev, | 1054 | extern int pmac_i2c_match_adapter(struct device_node *dev, |
910 | struct i2c_adapter *adapter) | 1055 | struct i2c_adapter *adapter) |
911 | { | 1056 | { |
912 | struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev); | 1057 | struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev); |
913 | 1058 | ||
914 | if (bus == NULL) | 1059 | if (bus == NULL) |
915 | return 0; | 1060 | return 0; |
916 | return (bus->adapter == adapter); | 1061 | return (bus->adapter == adapter); |
917 | } | 1062 | } |
918 | EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter); | 1063 | EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter); |
919 | 1064 | ||
920 | int pmac_low_i2c_lock(struct device_node *np) | 1065 | int pmac_low_i2c_lock(struct device_node *np) |
921 | { | 1066 | { |
922 | struct pmac_i2c_bus *bus, *found = NULL; | 1067 | struct pmac_i2c_bus *bus, *found = NULL; |
923 | 1068 | ||
924 | list_for_each_entry(bus, &pmac_i2c_busses, link) { | 1069 | list_for_each_entry(bus, &pmac_i2c_busses, link) { |
925 | if (np == bus->controller) { | 1070 | if (np == bus->controller) { |
926 | found = bus; | 1071 | found = bus; |
927 | break; | 1072 | break; |
928 | } | 1073 | } |
929 | } | 1074 | } |
930 | if (!found) | 1075 | if (!found) |
931 | return -ENODEV; | 1076 | return -ENODEV; |
932 | return pmac_i2c_open(bus, 0); | 1077 | return pmac_i2c_open(bus, 0); |
933 | } | 1078 | } |
934 | EXPORT_SYMBOL_GPL(pmac_low_i2c_lock); | 1079 | EXPORT_SYMBOL_GPL(pmac_low_i2c_lock); |
935 | 1080 | ||
936 | int pmac_low_i2c_unlock(struct device_node *np) | 1081 | int pmac_low_i2c_unlock(struct device_node *np) |
937 | { | 1082 | { |
938 | struct pmac_i2c_bus *bus, *found = NULL; | 1083 | struct pmac_i2c_bus *bus, *found = NULL; |
939 | 1084 | ||
940 | list_for_each_entry(bus, &pmac_i2c_busses, link) { | 1085 | list_for_each_entry(bus, &pmac_i2c_busses, link) { |
941 | if (np == bus->controller) { | 1086 | if (np == bus->controller) { |
942 | found = bus; | 1087 | found = bus; |
943 | break; | 1088 | break; |
944 | } | 1089 | } |
945 | } | 1090 | } |
946 | if (!found) | 1091 | if (!found) |
947 | return -ENODEV; | 1092 | return -ENODEV; |
948 | pmac_i2c_close(bus); | 1093 | pmac_i2c_close(bus); |
949 | return 0; | 1094 | return 0; |
950 | } | 1095 | } |
951 | EXPORT_SYMBOL_GPL(pmac_low_i2c_unlock); | 1096 | EXPORT_SYMBOL_GPL(pmac_low_i2c_unlock); |
952 | 1097 | ||
953 | 1098 | ||
954 | int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled) | 1099 | int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled) |
955 | { | 1100 | { |
956 | int rc; | 1101 | int rc; |
957 | 1102 | ||
958 | down(&bus->sem); | 1103 | down(&bus->sem); |
959 | bus->polled = polled; | 1104 | bus->polled = polled || pmac_i2c_force_poll; |
960 | bus->opened = 1; | 1105 | bus->opened = 1; |
961 | bus->mode = pmac_i2c_mode_std; | 1106 | bus->mode = pmac_i2c_mode_std; |
962 | if (bus->open && (rc = bus->open(bus)) != 0) { | 1107 | if (bus->open && (rc = bus->open(bus)) != 0) { |
963 | bus->opened = 0; | 1108 | bus->opened = 0; |
964 | up(&bus->sem); | 1109 | up(&bus->sem); |
965 | return rc; | 1110 | return rc; |
966 | } | 1111 | } |
967 | return 0; | 1112 | return 0; |
968 | } | 1113 | } |
969 | EXPORT_SYMBOL_GPL(pmac_i2c_open); | 1114 | EXPORT_SYMBOL_GPL(pmac_i2c_open); |
970 | 1115 | ||
971 | void pmac_i2c_close(struct pmac_i2c_bus *bus) | 1116 | void pmac_i2c_close(struct pmac_i2c_bus *bus) |
972 | { | 1117 | { |
973 | WARN_ON(!bus->opened); | 1118 | WARN_ON(!bus->opened); |
974 | if (bus->close) | 1119 | if (bus->close) |
975 | bus->close(bus); | 1120 | bus->close(bus); |
976 | bus->opened = 0; | 1121 | bus->opened = 0; |
977 | up(&bus->sem); | 1122 | up(&bus->sem); |
978 | } | 1123 | } |
979 | EXPORT_SYMBOL_GPL(pmac_i2c_close); | 1124 | EXPORT_SYMBOL_GPL(pmac_i2c_close); |
980 | 1125 | ||
981 | int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode) | 1126 | int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode) |
982 | { | 1127 | { |
983 | WARN_ON(!bus->opened); | 1128 | WARN_ON(!bus->opened); |
984 | 1129 | ||
985 | /* Report me if you see the error below as there might be a new | 1130 | /* Report me if you see the error below as there might be a new |
986 | * "combined4" mode that I need to implement for the SMU bus | 1131 | * "combined4" mode that I need to implement for the SMU bus |
987 | */ | 1132 | */ |
988 | if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) { | 1133 | if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) { |
989 | printk(KERN_ERR "low_i2c: Invalid mode %d requested on" | 1134 | printk(KERN_ERR "low_i2c: Invalid mode %d requested on" |
990 | " bus %s !\n", mode, bus->busnode->full_name); | 1135 | " bus %s !\n", mode, bus->busnode->full_name); |
991 | return -EINVAL; | 1136 | return -EINVAL; |
992 | } | 1137 | } |
993 | bus->mode = mode; | 1138 | bus->mode = mode; |
994 | 1139 | ||
995 | return 0; | 1140 | return 0; |
996 | } | 1141 | } |
997 | EXPORT_SYMBOL_GPL(pmac_i2c_setmode); | 1142 | EXPORT_SYMBOL_GPL(pmac_i2c_setmode); |
998 | 1143 | ||
999 | int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, | 1144 | int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, |
1000 | u32 subaddr, u8 *data, int len) | 1145 | u32 subaddr, u8 *data, int len) |
1001 | { | 1146 | { |
1002 | int rc; | 1147 | int rc; |
1003 | 1148 | ||
1004 | WARN_ON(!bus->opened); | 1149 | WARN_ON(!bus->opened); |
1005 | 1150 | ||
1006 | DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x," | 1151 | DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x," |
1007 | " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize, | 1152 | " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize, |
1008 | subaddr, len, bus->busnode->full_name); | 1153 | subaddr, len, bus->busnode->full_name); |
1009 | 1154 | ||
1010 | rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len); | 1155 | rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len); |
1011 | 1156 | ||
1012 | #ifdef DEBUG | 1157 | #ifdef DEBUG |
1013 | if (rc) | 1158 | if (rc) |
1014 | DBG("xfer error %d\n", rc); | 1159 | DBG("xfer error %d\n", rc); |
1015 | #endif | 1160 | #endif |
1016 | return rc; | 1161 | return rc; |
1017 | } | 1162 | } |
1018 | EXPORT_SYMBOL_GPL(pmac_i2c_xfer); | 1163 | EXPORT_SYMBOL_GPL(pmac_i2c_xfer); |
1019 | 1164 | ||
1020 | /* | 1165 | /* |
1021 | * Initialize us: probe all i2c busses on the machine and instantiate | 1166 | * Initialize us: probe all i2c busses on the machine and instantiate |
1022 | * busses. | 1167 | * busses. |
1023 | */ | 1168 | */ |
1024 | /* This is non-static as it might be called early by smp code */ | 1169 | /* This is non-static as it might be called early by smp code */ |
1025 | int __init pmac_i2c_init(void) | 1170 | int __init pmac_i2c_init(void) |
1026 | { | 1171 | { |
1027 | static int i2c_inited; | 1172 | static int i2c_inited; |
1028 | 1173 | ||
1029 | if (i2c_inited) | 1174 | if (i2c_inited) |
1030 | return 0; | 1175 | return 0; |
1031 | i2c_inited = 1; | 1176 | i2c_inited = 1; |
1032 | 1177 | ||
1033 | /* Probe keywest-i2c busses */ | 1178 | /* Probe keywest-i2c busses */ |
1034 | kw_i2c_probe(); | 1179 | kw_i2c_probe(); |
1035 | 1180 | ||
1036 | #ifdef CONFIG_ADB_PMU | 1181 | #ifdef CONFIG_ADB_PMU |
1182 | /* Probe PMU i2c busses */ | ||
1037 | pmu_i2c_probe(); | 1183 | pmu_i2c_probe(); |
1038 | #endif | 1184 | #endif |
1039 | 1185 | ||
1040 | #ifdef CONFIG_PMAC_SMU | 1186 | #ifdef CONFIG_PMAC_SMU |
1187 | /* Probe SMU i2c busses */ | ||
1041 | smu_i2c_probe(); | 1188 | smu_i2c_probe(); |
1042 | #endif | 1189 | #endif |
1043 | |||
1044 | return 0; | 1190 | return 0; |
1045 | } | 1191 | } |
1046 | arch_initcall(pmac_i2c_init); | 1192 | arch_initcall(pmac_i2c_init); |
1193 | |||
1194 | /* Since pmac_i2c_init can be called too early for the platform device | ||
1195 | * registration, we need to do it at a later time. In our case, subsys | ||
1196 | * happens to fit well, though I agree it's a bit of a hack... | ||
1197 | */ | ||
1198 | static int __init pmac_i2c_create_platform_devices(void) | ||
1199 | { | ||
1200 | struct pmac_i2c_bus *bus; | ||
1201 | int i = 0; | ||
1202 | |||
1203 | /* In the case where we are initialized from smp_init(), we must | ||
1204 | * not use the timer (and thus the irq). It's safe from now on | ||
1205 | * though | ||
1206 | */ | ||
1207 | pmac_i2c_force_poll = 0; | ||
1208 | |||
1209 | /* Create platform devices */ | ||
1210 | list_for_each_entry(bus, &pmac_i2c_busses, link) { | ||
1211 | bus->platform_dev = | ||
1212 | platform_device_alloc("i2c-powermac", i++); | ||
1213 | if (bus->platform_dev == NULL) | ||
1214 | return -ENOMEM; | ||
1215 | bus->platform_dev->dev.platform_data = bus; |
arch/powerpc/platforms/powermac/setup.c
1 | /* | 1 | /* |
2 | * Powermac setup and early boot code plus other random bits. | 2 | * Powermac setup and early boot code plus other random bits. |
3 | * | 3 | * |
4 | * PowerPC version | 4 | * PowerPC version |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
6 | * | 6 | * |
7 | * Adapted for Power Macintosh by Paul Mackerras | 7 | * Adapted for Power Macintosh by Paul Mackerras |
8 | * Copyright (C) 1996 Paul Mackerras (paulus@samba.org) | 8 | * Copyright (C) 1996 Paul Mackerras (paulus@samba.org) |
9 | * | 9 | * |
10 | * Derived from "arch/alpha/kernel/setup.c" | 10 | * Derived from "arch/alpha/kernel/setup.c" |
11 | * Copyright (C) 1995 Linus Torvalds | 11 | * Copyright (C) 1995 Linus Torvalds |
12 | * | 12 | * |
13 | * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) | 13 | * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or | 15 | * This program is free software; you can redistribute it and/or |
16 | * modify it under the terms of the GNU General Public License | 16 | * modify it under the terms of the GNU General Public License |
17 | * as published by the Free Software Foundation; either version | 17 | * as published by the Free Software Foundation; either version |
18 | * 2 of the License, or (at your option) any later version. | 18 | * 2 of the License, or (at your option) any later version. |
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * bootup setup stuff.. | 23 | * bootup setup stuff.. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/stddef.h> | 32 | #include <linux/stddef.h> |
33 | #include <linux/unistd.h> | 33 | #include <linux/unistd.h> |
34 | #include <linux/ptrace.h> | 34 | #include <linux/ptrace.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/user.h> | 36 | #include <linux/user.h> |
37 | #include <linux/a.out.h> | 37 | #include <linux/a.out.h> |
38 | #include <linux/tty.h> | 38 | #include <linux/tty.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/ioport.h> | 41 | #include <linux/ioport.h> |
42 | #include <linux/major.h> | 42 | #include <linux/major.h> |
43 | #include <linux/initrd.h> | 43 | #include <linux/initrd.h> |
44 | #include <linux/vt_kern.h> | 44 | #include <linux/vt_kern.h> |
45 | #include <linux/console.h> | 45 | #include <linux/console.h> |
46 | #include <linux/ide.h> | 46 | #include <linux/ide.h> |
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/adb.h> | 48 | #include <linux/adb.h> |
49 | #include <linux/cuda.h> | 49 | #include <linux/cuda.h> |
50 | #include <linux/pmu.h> | 50 | #include <linux/pmu.h> |
51 | #include <linux/irq.h> | 51 | #include <linux/irq.h> |
52 | #include <linux/seq_file.h> | 52 | #include <linux/seq_file.h> |
53 | #include <linux/root_dev.h> | 53 | #include <linux/root_dev.h> |
54 | #include <linux/bitops.h> | 54 | #include <linux/bitops.h> |
55 | #include <linux/suspend.h> | 55 | #include <linux/suspend.h> |
56 | 56 | ||
57 | #include <asm/reg.h> | 57 | #include <asm/reg.h> |
58 | #include <asm/sections.h> | 58 | #include <asm/sections.h> |
59 | #include <asm/prom.h> | 59 | #include <asm/prom.h> |
60 | #include <asm/system.h> | 60 | #include <asm/system.h> |
61 | #include <asm/pgtable.h> | 61 | #include <asm/pgtable.h> |
62 | #include <asm/io.h> | 62 | #include <asm/io.h> |
63 | #include <asm/kexec.h> | 63 | #include <asm/kexec.h> |
64 | #include <asm/pci-bridge.h> | 64 | #include <asm/pci-bridge.h> |
65 | #include <asm/ohare.h> | 65 | #include <asm/ohare.h> |
66 | #include <asm/mediabay.h> | 66 | #include <asm/mediabay.h> |
67 | #include <asm/machdep.h> | 67 | #include <asm/machdep.h> |
68 | #include <asm/dma.h> | 68 | #include <asm/dma.h> |
69 | #include <asm/cputable.h> | 69 | #include <asm/cputable.h> |
70 | #include <asm/btext.h> | 70 | #include <asm/btext.h> |
71 | #include <asm/pmac_feature.h> | 71 | #include <asm/pmac_feature.h> |
72 | #include <asm/time.h> | 72 | #include <asm/time.h> |
73 | #include <asm/of_device.h> | 73 | #include <asm/of_device.h> |
74 | #include <asm/mmu_context.h> | 74 | #include <asm/mmu_context.h> |
75 | #include <asm/iommu.h> | 75 | #include <asm/iommu.h> |
76 | #include <asm/smu.h> | 76 | #include <asm/smu.h> |
77 | #include <asm/pmc.h> | 77 | #include <asm/pmc.h> |
78 | #include <asm/lmb.h> | 78 | #include <asm/lmb.h> |
79 | #include <asm/udbg.h> | 79 | #include <asm/udbg.h> |
80 | 80 | ||
81 | #include "pmac.h" | 81 | #include "pmac.h" |
82 | 82 | ||
83 | #undef SHOW_GATWICK_IRQS | 83 | #undef SHOW_GATWICK_IRQS |
84 | 84 | ||
85 | unsigned char drive_info; | 85 | unsigned char drive_info; |
86 | 86 | ||
87 | int ppc_override_l2cr = 0; | 87 | int ppc_override_l2cr = 0; |
88 | int ppc_override_l2cr_value; | 88 | int ppc_override_l2cr_value; |
89 | int has_l2cache = 0; | 89 | int has_l2cache = 0; |
90 | 90 | ||
91 | int pmac_newworld = 1; | 91 | int pmac_newworld = 1; |
92 | 92 | ||
93 | static int current_root_goodness = -1; | 93 | static int current_root_goodness = -1; |
94 | 94 | ||
95 | extern int pmac_newworld; | 95 | extern int pmac_newworld; |
96 | extern struct machdep_calls pmac_md; | 96 | extern struct machdep_calls pmac_md; |
97 | 97 | ||
98 | #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ | 98 | #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ |
99 | 99 | ||
100 | #ifdef CONFIG_PPC64 | 100 | #ifdef CONFIG_PPC64 |
101 | #include <asm/udbg.h> | 101 | #include <asm/udbg.h> |
102 | int sccdbg; | 102 | int sccdbg; |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | extern void zs_kgdb_hook(int tty_num); | 105 | extern void zs_kgdb_hook(int tty_num); |
106 | 106 | ||
107 | sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; | 107 | sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; |
108 | EXPORT_SYMBOL(sys_ctrler); | 108 | EXPORT_SYMBOL(sys_ctrler); |
109 | 109 | ||
110 | #ifdef CONFIG_PMAC_SMU | 110 | #ifdef CONFIG_PMAC_SMU |
111 | unsigned long smu_cmdbuf_abs; | 111 | unsigned long smu_cmdbuf_abs; |
112 | EXPORT_SYMBOL(smu_cmdbuf_abs); | 112 | EXPORT_SYMBOL(smu_cmdbuf_abs); |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | #ifdef CONFIG_SMP | 115 | #ifdef CONFIG_SMP |
116 | extern struct smp_ops_t psurge_smp_ops; | 116 | extern struct smp_ops_t psurge_smp_ops; |
117 | extern struct smp_ops_t core99_smp_ops; | 117 | extern struct smp_ops_t core99_smp_ops; |
118 | #endif /* CONFIG_SMP */ | 118 | #endif /* CONFIG_SMP */ |
119 | 119 | ||
120 | static void pmac_show_cpuinfo(struct seq_file *m) | 120 | static void pmac_show_cpuinfo(struct seq_file *m) |
121 | { | 121 | { |
122 | struct device_node *np; | 122 | struct device_node *np; |
123 | char *pp; | 123 | char *pp; |
124 | int plen; | 124 | int plen; |
125 | int mbmodel; | 125 | int mbmodel; |
126 | unsigned int mbflags; | 126 | unsigned int mbflags; |
127 | char* mbname; | 127 | char* mbname; |
128 | 128 | ||
129 | mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, | 129 | mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, |
130 | PMAC_MB_INFO_MODEL, 0); | 130 | PMAC_MB_INFO_MODEL, 0); |
131 | mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, | 131 | mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, |
132 | PMAC_MB_INFO_FLAGS, 0); | 132 | PMAC_MB_INFO_FLAGS, 0); |
133 | if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, | 133 | if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, |
134 | (long) &mbname) != 0) | 134 | (long) &mbname) != 0) |
135 | mbname = "Unknown"; | 135 | mbname = "Unknown"; |
136 | 136 | ||
137 | /* find motherboard type */ | 137 | /* find motherboard type */ |
138 | seq_printf(m, "machine\t\t: "); | 138 | seq_printf(m, "machine\t\t: "); |
139 | np = of_find_node_by_path("/"); | 139 | np = of_find_node_by_path("/"); |
140 | if (np != NULL) { | 140 | if (np != NULL) { |
141 | pp = (char *) get_property(np, "model", NULL); | 141 | pp = (char *) get_property(np, "model", NULL); |
142 | if (pp != NULL) | 142 | if (pp != NULL) |
143 | seq_printf(m, "%s\n", pp); | 143 | seq_printf(m, "%s\n", pp); |
144 | else | 144 | else |
145 | seq_printf(m, "PowerMac\n"); | 145 | seq_printf(m, "PowerMac\n"); |
146 | pp = (char *) get_property(np, "compatible", &plen); | 146 | pp = (char *) get_property(np, "compatible", &plen); |
147 | if (pp != NULL) { | 147 | if (pp != NULL) { |
148 | seq_printf(m, "motherboard\t:"); | 148 | seq_printf(m, "motherboard\t:"); |
149 | while (plen > 0) { | 149 | while (plen > 0) { |
150 | int l = strlen(pp) + 1; | 150 | int l = strlen(pp) + 1; |
151 | seq_printf(m, " %s", pp); | 151 | seq_printf(m, " %s", pp); |
152 | plen -= l; | 152 | plen -= l; |
153 | pp += l; | 153 | pp += l; |
154 | } | 154 | } |
155 | seq_printf(m, "\n"); | 155 | seq_printf(m, "\n"); |
156 | } | 156 | } |
157 | of_node_put(np); | 157 | of_node_put(np); |
158 | } else | 158 | } else |
159 | seq_printf(m, "PowerMac\n"); | 159 | seq_printf(m, "PowerMac\n"); |
160 | 160 | ||
161 | /* print parsed model */ | 161 | /* print parsed model */ |
162 | seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); | 162 | seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); |
163 | seq_printf(m, "pmac flags\t: %08x\n", mbflags); | 163 | seq_printf(m, "pmac flags\t: %08x\n", mbflags); |
164 | 164 | ||
165 | /* find l2 cache info */ | 165 | /* find l2 cache info */ |
166 | np = of_find_node_by_name(NULL, "l2-cache"); | 166 | np = of_find_node_by_name(NULL, "l2-cache"); |
167 | if (np == NULL) | 167 | if (np == NULL) |
168 | np = of_find_node_by_type(NULL, "cache"); | 168 | np = of_find_node_by_type(NULL, "cache"); |
169 | if (np != NULL) { | 169 | if (np != NULL) { |
170 | unsigned int *ic = (unsigned int *) | 170 | unsigned int *ic = (unsigned int *) |
171 | get_property(np, "i-cache-size", NULL); | 171 | get_property(np, "i-cache-size", NULL); |
172 | unsigned int *dc = (unsigned int *) | 172 | unsigned int *dc = (unsigned int *) |
173 | get_property(np, "d-cache-size", NULL); | 173 | get_property(np, "d-cache-size", NULL); |
174 | seq_printf(m, "L2 cache\t:"); | 174 | seq_printf(m, "L2 cache\t:"); |
175 | has_l2cache = 1; | 175 | has_l2cache = 1; |
176 | if (get_property(np, "cache-unified", NULL) != 0 && dc) { | 176 | if (get_property(np, "cache-unified", NULL) != 0 && dc) { |
177 | seq_printf(m, " %dK unified", *dc / 1024); | 177 | seq_printf(m, " %dK unified", *dc / 1024); |
178 | } else { | 178 | } else { |
179 | if (ic) | 179 | if (ic) |
180 | seq_printf(m, " %dK instruction", *ic / 1024); | 180 | seq_printf(m, " %dK instruction", *ic / 1024); |
181 | if (dc) | 181 | if (dc) |
182 | seq_printf(m, "%s %dK data", | 182 | seq_printf(m, "%s %dK data", |
183 | (ic? " +": ""), *dc / 1024); | 183 | (ic? " +": ""), *dc / 1024); |
184 | } | 184 | } |
185 | pp = get_property(np, "ram-type", NULL); | 185 | pp = get_property(np, "ram-type", NULL); |
186 | if (pp) | 186 | if (pp) |
187 | seq_printf(m, " %s", pp); | 187 | seq_printf(m, " %s", pp); |
188 | seq_printf(m, "\n"); | 188 | seq_printf(m, "\n"); |
189 | of_node_put(np); | 189 | of_node_put(np); |
190 | } | 190 | } |
191 | 191 | ||
192 | /* Indicate newworld/oldworld */ | 192 | /* Indicate newworld/oldworld */ |
193 | seq_printf(m, "pmac-generation\t: %s\n", | 193 | seq_printf(m, "pmac-generation\t: %s\n", |
194 | pmac_newworld ? "NewWorld" : "OldWorld"); | 194 | pmac_newworld ? "NewWorld" : "OldWorld"); |
195 | } | 195 | } |
196 | 196 | ||
197 | #ifndef CONFIG_ADB_CUDA | 197 | #ifndef CONFIG_ADB_CUDA |
198 | int find_via_cuda(void) | 198 | int find_via_cuda(void) |
199 | { | 199 | { |
200 | if (!find_devices("via-cuda")) | 200 | if (!find_devices("via-cuda")) |
201 | return 0; | 201 | return 0; |
202 | printk("WARNING ! Your machine is CUDA-based but your kernel\n"); | 202 | printk("WARNING ! Your machine is CUDA-based but your kernel\n"); |
203 | printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); | 203 | printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); |
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | #ifndef CONFIG_ADB_PMU | 208 | #ifndef CONFIG_ADB_PMU |
209 | int find_via_pmu(void) | 209 | int find_via_pmu(void) |
210 | { | 210 | { |
211 | if (!find_devices("via-pmu")) | 211 | if (!find_devices("via-pmu")) |
212 | return 0; | 212 | return 0; |
213 | printk("WARNING ! Your machine is PMU-based but your kernel\n"); | 213 | printk("WARNING ! Your machine is PMU-based but your kernel\n"); |
214 | printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); | 214 | printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); |
215 | return 0; | 215 | return 0; |
216 | } | 216 | } |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | #ifndef CONFIG_PMAC_SMU | 219 | #ifndef CONFIG_PMAC_SMU |
220 | int smu_init(void) | 220 | int smu_init(void) |
221 | { | 221 | { |
222 | /* should check and warn if SMU is present */ | 222 | /* should check and warn if SMU is present */ |
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | #endif | 225 | #endif |
226 | 226 | ||
227 | #ifdef CONFIG_PPC32 | 227 | #ifdef CONFIG_PPC32 |
228 | static volatile u32 *sysctrl_regs; | 228 | static volatile u32 *sysctrl_regs; |
229 | 229 | ||
230 | static void __init ohare_init(void) | 230 | static void __init ohare_init(void) |
231 | { | 231 | { |
232 | /* this area has the CPU identification register | 232 | /* this area has the CPU identification register |
233 | and some registers used by smp boards */ | 233 | and some registers used by smp boards */ |
234 | sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); | 234 | sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); |
235 | 235 | ||
236 | /* | 236 | /* |
237 | * Turn on the L2 cache. | 237 | * Turn on the L2 cache. |
238 | * We assume that we have a PSX memory controller iff | 238 | * We assume that we have a PSX memory controller iff |
239 | * we have an ohare I/O controller. | 239 | * we have an ohare I/O controller. |
240 | */ | 240 | */ |
241 | if (find_devices("ohare") != NULL) { | 241 | if (find_devices("ohare") != NULL) { |
242 | if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { | 242 | if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { |
243 | if (sysctrl_regs[4] & 0x10) | 243 | if (sysctrl_regs[4] & 0x10) |
244 | sysctrl_regs[4] |= 0x04000020; | 244 | sysctrl_regs[4] |= 0x04000020; |
245 | else | 245 | else |
246 | sysctrl_regs[4] |= 0x04000000; | 246 | sysctrl_regs[4] |= 0x04000000; |
247 | if(has_l2cache) | 247 | if(has_l2cache) |
248 | printk(KERN_INFO "Level 2 cache enabled\n"); | 248 | printk(KERN_INFO "Level 2 cache enabled\n"); |
249 | } | 249 | } |
250 | } | 250 | } |
251 | } | 251 | } |
252 | 252 | ||
253 | static void __init l2cr_init(void) | 253 | static void __init l2cr_init(void) |
254 | { | 254 | { |
255 | /* Checks "l2cr-value" property in the registry */ | 255 | /* Checks "l2cr-value" property in the registry */ |
256 | if (cpu_has_feature(CPU_FTR_L2CR)) { | 256 | if (cpu_has_feature(CPU_FTR_L2CR)) { |
257 | struct device_node *np = find_devices("cpus"); | 257 | struct device_node *np = find_devices("cpus"); |
258 | if (np == 0) | 258 | if (np == 0) |
259 | np = find_type_devices("cpu"); | 259 | np = find_type_devices("cpu"); |
260 | if (np != 0) { | 260 | if (np != 0) { |
261 | unsigned int *l2cr = (unsigned int *) | 261 | unsigned int *l2cr = (unsigned int *) |
262 | get_property(np, "l2cr-value", NULL); | 262 | get_property(np, "l2cr-value", NULL); |
263 | if (l2cr != 0) { | 263 | if (l2cr != 0) { |
264 | ppc_override_l2cr = 1; | 264 | ppc_override_l2cr = 1; |
265 | ppc_override_l2cr_value = *l2cr; | 265 | ppc_override_l2cr_value = *l2cr; |
266 | _set_L2CR(0); | 266 | _set_L2CR(0); |
267 | _set_L2CR(ppc_override_l2cr_value); | 267 | _set_L2CR(ppc_override_l2cr_value); |
268 | } | 268 | } |
269 | } | 269 | } |
270 | } | 270 | } |
271 | 271 | ||
272 | if (ppc_override_l2cr) | 272 | if (ppc_override_l2cr) |
273 | printk(KERN_INFO "L2CR overridden (0x%x), " | 273 | printk(KERN_INFO "L2CR overridden (0x%x), " |
274 | "backside cache is %s\n", | 274 | "backside cache is %s\n", |
275 | ppc_override_l2cr_value, | 275 | ppc_override_l2cr_value, |
276 | (ppc_override_l2cr_value & 0x80000000) | 276 | (ppc_override_l2cr_value & 0x80000000) |
277 | ? "enabled" : "disabled"); | 277 | ? "enabled" : "disabled"); |
278 | } | 278 | } |
279 | #endif | 279 | #endif |
280 | 280 | ||
281 | void __init pmac_setup_arch(void) | 281 | void __init pmac_setup_arch(void) |
282 | { | 282 | { |
283 | struct device_node *cpu, *ic; | 283 | struct device_node *cpu, *ic; |
284 | int *fp; | 284 | int *fp; |
285 | unsigned long pvr; | 285 | unsigned long pvr; |
286 | 286 | ||
287 | pvr = PVR_VER(mfspr(SPRN_PVR)); | 287 | pvr = PVR_VER(mfspr(SPRN_PVR)); |
288 | 288 | ||
289 | /* Set loops_per_jiffy to a half-way reasonable value, | 289 | /* Set loops_per_jiffy to a half-way reasonable value, |
290 | for use until calibrate_delay gets called. */ | 290 | for use until calibrate_delay gets called. */ |
291 | loops_per_jiffy = 50000000 / HZ; | 291 | loops_per_jiffy = 50000000 / HZ; |
292 | cpu = of_find_node_by_type(NULL, "cpu"); | 292 | cpu = of_find_node_by_type(NULL, "cpu"); |
293 | if (cpu != NULL) { | 293 | if (cpu != NULL) { |
294 | fp = (int *) get_property(cpu, "clock-frequency", NULL); | 294 | fp = (int *) get_property(cpu, "clock-frequency", NULL); |
295 | if (fp != NULL) { | 295 | if (fp != NULL) { |
296 | if (pvr >= 0x30 && pvr < 0x80) | 296 | if (pvr >= 0x30 && pvr < 0x80) |
297 | /* PPC970 etc. */ | 297 | /* PPC970 etc. */ |
298 | loops_per_jiffy = *fp / (3 * HZ); | 298 | loops_per_jiffy = *fp / (3 * HZ); |
299 | else if (pvr == 4 || pvr >= 8) | 299 | else if (pvr == 4 || pvr >= 8) |
300 | /* 604, G3, G4 etc. */ | 300 | /* 604, G3, G4 etc. */ |
301 | loops_per_jiffy = *fp / HZ; | 301 | loops_per_jiffy = *fp / HZ; |
302 | else | 302 | else |
303 | /* 601, 603, etc. */ | 303 | /* 601, 603, etc. */ |
304 | loops_per_jiffy = *fp / (2 * HZ); | 304 | loops_per_jiffy = *fp / (2 * HZ); |
305 | } | 305 | } |
306 | of_node_put(cpu); | 306 | of_node_put(cpu); |
307 | } | 307 | } |
308 | 308 | ||
309 | /* See if newworld or oldworld */ | 309 | /* See if newworld or oldworld */ |
310 | for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) | 310 | for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) |
311 | if (get_property(ic, "interrupt-controller", NULL)) | 311 | if (get_property(ic, "interrupt-controller", NULL)) |
312 | break; | 312 | break; |
313 | pmac_newworld = (ic != NULL); | 313 | pmac_newworld = (ic != NULL); |
314 | if (ic) | 314 | if (ic) |
315 | of_node_put(ic); | 315 | of_node_put(ic); |
316 | 316 | ||
317 | /* Lookup PCI hosts */ | 317 | /* Lookup PCI hosts */ |
318 | pmac_pci_init(); | 318 | pmac_pci_init(); |
319 | 319 | ||
320 | #ifdef CONFIG_PPC32 | 320 | #ifdef CONFIG_PPC32 |
321 | ohare_init(); | 321 | ohare_init(); |
322 | l2cr_init(); | 322 | l2cr_init(); |
323 | #endif /* CONFIG_PPC32 */ | 323 | #endif /* CONFIG_PPC32 */ |
324 | 324 | ||
325 | #ifdef CONFIG_KGDB | 325 | #ifdef CONFIG_KGDB |
326 | zs_kgdb_hook(0); | 326 | zs_kgdb_hook(0); |
327 | #endif | 327 | #endif |
328 | 328 | ||
329 | find_via_cuda(); | 329 | find_via_cuda(); |
330 | find_via_pmu(); | 330 | find_via_pmu(); |
331 | smu_init(); | 331 | smu_init(); |
332 | 332 | ||
333 | #if defined(CONFIG_NVRAM) || defined(CONFIG_PPC64) | 333 | #if defined(CONFIG_NVRAM) || defined(CONFIG_PPC64) |
334 | pmac_nvram_init(); | 334 | pmac_nvram_init(); |
335 | #endif | 335 | #endif |
336 | 336 | ||
337 | #ifdef CONFIG_PPC32 | 337 | #ifdef CONFIG_PPC32 |
338 | #ifdef CONFIG_BLK_DEV_INITRD | 338 | #ifdef CONFIG_BLK_DEV_INITRD |
339 | if (initrd_start) | 339 | if (initrd_start) |
340 | ROOT_DEV = Root_RAM0; | 340 | ROOT_DEV = Root_RAM0; |
341 | else | 341 | else |
342 | #endif | 342 | #endif |
343 | ROOT_DEV = DEFAULT_ROOT_DEVICE; | 343 | ROOT_DEV = DEFAULT_ROOT_DEVICE; |
344 | #endif | 344 | #endif |
345 | 345 | ||
346 | #ifdef CONFIG_SMP | 346 | #ifdef CONFIG_SMP |
347 | /* Check for Core99 */ | 347 | /* Check for Core99 */ |
348 | if (find_devices("uni-n") || find_devices("u3") || find_devices("u4")) | 348 | if (find_devices("uni-n") || find_devices("u3") || find_devices("u4")) |
349 | smp_ops = &core99_smp_ops; | 349 | smp_ops = &core99_smp_ops; |
350 | #ifdef CONFIG_PPC32 | 350 | #ifdef CONFIG_PPC32 |
351 | else | 351 | else |
352 | smp_ops = &psurge_smp_ops; | 352 | smp_ops = &psurge_smp_ops; |
353 | #endif | 353 | #endif |
354 | #endif /* CONFIG_SMP */ | 354 | #endif /* CONFIG_SMP */ |
355 | } | 355 | } |
356 | 356 | ||
357 | char *bootpath; | 357 | char *bootpath; |
358 | char *bootdevice; | 358 | char *bootdevice; |
359 | void *boot_host; | 359 | void *boot_host; |
360 | int boot_target; | 360 | int boot_target; |
361 | int boot_part; | 361 | int boot_part; |
362 | extern dev_t boot_dev; | 362 | extern dev_t boot_dev; |
363 | 363 | ||
364 | #ifdef CONFIG_SCSI | 364 | #ifdef CONFIG_SCSI |
365 | void __init note_scsi_host(struct device_node *node, void *host) | 365 | void __init note_scsi_host(struct device_node *node, void *host) |
366 | { | 366 | { |
367 | int l; | 367 | int l; |
368 | char *p; | 368 | char *p; |
369 | 369 | ||
370 | l = strlen(node->full_name); | 370 | l = strlen(node->full_name); |
371 | if (bootpath != NULL && bootdevice != NULL | 371 | if (bootpath != NULL && bootdevice != NULL |
372 | && strncmp(node->full_name, bootdevice, l) == 0 | 372 | && strncmp(node->full_name, bootdevice, l) == 0 |
373 | && (bootdevice[l] == '/' || bootdevice[l] == 0)) { | 373 | && (bootdevice[l] == '/' || bootdevice[l] == 0)) { |
374 | boot_host = host; | 374 | boot_host = host; |
375 | /* | 375 | /* |
376 | * There's a bug in OF 1.0.5. (Why am I not surprised.) | 376 | * There's a bug in OF 1.0.5. (Why am I not surprised.) |
377 | * If you pass a path like scsi/sd@1:0 to canon, it returns | 377 | * If you pass a path like scsi/sd@1:0 to canon, it returns |
378 | * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0 | 378 | * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0 |
379 | * That is, the scsi target number doesn't get preserved. | 379 | * That is, the scsi target number doesn't get preserved. |
380 | * So we pick the target number out of bootpath and use that. | 380 | * So we pick the target number out of bootpath and use that. |
381 | */ | 381 | */ |
382 | p = strstr(bootpath, "/sd@"); | 382 | p = strstr(bootpath, "/sd@"); |
383 | if (p != NULL) { | 383 | if (p != NULL) { |
384 | p += 4; | 384 | p += 4; |
385 | boot_target = simple_strtoul(p, NULL, 10); | 385 | boot_target = simple_strtoul(p, NULL, 10); |
386 | p = strchr(p, ':'); | 386 | p = strchr(p, ':'); |
387 | if (p != NULL) | 387 | if (p != NULL) |
388 | boot_part = simple_strtoul(p + 1, NULL, 10); | 388 | boot_part = simple_strtoul(p + 1, NULL, 10); |
389 | } | 389 | } |
390 | } | 390 | } |
391 | } | 391 | } |
392 | EXPORT_SYMBOL(note_scsi_host); | 392 | EXPORT_SYMBOL(note_scsi_host); |
393 | #endif | 393 | #endif |
394 | 394 | ||
395 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | 395 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) |
396 | static dev_t __init find_ide_boot(void) | 396 | static dev_t __init find_ide_boot(void) |
397 | { | 397 | { |
398 | char *p; | 398 | char *p; |
399 | int n; | 399 | int n; |
400 | dev_t __init pmac_find_ide_boot(char *bootdevice, int n); | 400 | dev_t __init pmac_find_ide_boot(char *bootdevice, int n); |
401 | 401 | ||
402 | if (bootdevice == NULL) | 402 | if (bootdevice == NULL) |
403 | return 0; | 403 | return 0; |
404 | p = strrchr(bootdevice, '/'); | 404 | p = strrchr(bootdevice, '/'); |
405 | if (p == NULL) | 405 | if (p == NULL) |
406 | return 0; | 406 | return 0; |
407 | n = p - bootdevice; | 407 | n = p - bootdevice; |
408 | 408 | ||
409 | return pmac_find_ide_boot(bootdevice, n); | 409 | return pmac_find_ide_boot(bootdevice, n); |
410 | } | 410 | } |
411 | #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ | 411 | #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ |
412 | 412 | ||
413 | static void __init find_boot_device(void) | 413 | static void __init find_boot_device(void) |
414 | { | 414 | { |
415 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | 415 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) |
416 | boot_dev = find_ide_boot(); | 416 | boot_dev = find_ide_boot(); |
417 | #endif | 417 | #endif |
418 | } | 418 | } |
419 | 419 | ||
420 | /* TODO: Merge the suspend-to-ram with the common code !!! | 420 | /* TODO: Merge the suspend-to-ram with the common code !!! |
421 | * currently, this is a stub implementation for suspend-to-disk | 421 | * currently, this is a stub implementation for suspend-to-disk |
422 | * only | 422 | * only |
423 | */ | 423 | */ |
424 | 424 | ||
425 | #ifdef CONFIG_SOFTWARE_SUSPEND | 425 | #ifdef CONFIG_SOFTWARE_SUSPEND |
426 | 426 | ||
427 | static int pmac_pm_prepare(suspend_state_t state) | 427 | static int pmac_pm_prepare(suspend_state_t state) |
428 | { | 428 | { |
429 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | 429 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); |
430 | 430 | ||
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
433 | 433 | ||
434 | static int pmac_pm_enter(suspend_state_t state) | 434 | static int pmac_pm_enter(suspend_state_t state) |
435 | { | 435 | { |
436 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | 436 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); |
437 | 437 | ||
438 | /* Giveup the lazy FPU & vec so we don't have to back them | 438 | /* Giveup the lazy FPU & vec so we don't have to back them |
439 | * up from the low level code | 439 | * up from the low level code |
440 | */ | 440 | */ |
441 | enable_kernel_fp(); | 441 | enable_kernel_fp(); |
442 | 442 | ||
443 | #ifdef CONFIG_ALTIVEC | 443 | #ifdef CONFIG_ALTIVEC |
444 | if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) | 444 | if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) |
445 | enable_kernel_altivec(); | 445 | enable_kernel_altivec(); |
446 | #endif /* CONFIG_ALTIVEC */ | 446 | #endif /* CONFIG_ALTIVEC */ |
447 | 447 | ||
448 | return 0; | 448 | return 0; |
449 | } | 449 | } |
450 | 450 | ||
451 | static int pmac_pm_finish(suspend_state_t state) | 451 | static int pmac_pm_finish(suspend_state_t state) |
452 | { | 452 | { |
453 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | 453 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); |
454 | 454 | ||
455 | /* Restore userland MMU context */ | 455 | /* Restore userland MMU context */ |
456 | set_context(current->active_mm->context, current->active_mm->pgd); | 456 | set_context(current->active_mm->context, current->active_mm->pgd); |
457 | 457 | ||
458 | return 0; | 458 | return 0; |
459 | } | 459 | } |
460 | 460 | ||
461 | static struct pm_ops pmac_pm_ops = { | 461 | static struct pm_ops pmac_pm_ops = { |
462 | .pm_disk_mode = PM_DISK_SHUTDOWN, | 462 | .pm_disk_mode = PM_DISK_SHUTDOWN, |
463 | .prepare = pmac_pm_prepare, | 463 | .prepare = pmac_pm_prepare, |
464 | .enter = pmac_pm_enter, | 464 | .enter = pmac_pm_enter, |
465 | .finish = pmac_pm_finish, | 465 | .finish = pmac_pm_finish, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | 468 | #endif /* CONFIG_SOFTWARE_SUSPEND */ |
469 | 469 | ||
470 | static int initializing = 1; | 470 | static int initializing = 1; |
471 | 471 | ||
472 | static int pmac_late_init(void) | 472 | static int pmac_late_init(void) |
473 | { | 473 | { |
474 | initializing = 0; | 474 | initializing = 0; |
475 | #ifdef CONFIG_SOFTWARE_SUSPEND | 475 | #ifdef CONFIG_SOFTWARE_SUSPEND |
476 | pm_set_ops(&pmac_pm_ops); | 476 | pm_set_ops(&pmac_pm_ops); |
477 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | 477 | #endif /* CONFIG_SOFTWARE_SUSPEND */ |
478 | return 0; | 478 | return 0; |
479 | } | 479 | } |
480 | 480 | ||
481 | late_initcall(pmac_late_init); | 481 | late_initcall(pmac_late_init); |
482 | 482 | ||
483 | /* can't be __init - can be called whenever a disk is first accessed */ | 483 | /* can't be __init - can be called whenever a disk is first accessed */ |
484 | void note_bootable_part(dev_t dev, int part, int goodness) | 484 | void note_bootable_part(dev_t dev, int part, int goodness) |
485 | { | 485 | { |
486 | static int found_boot = 0; | 486 | static int found_boot = 0; |
487 | char *p; | 487 | char *p; |
488 | 488 | ||
489 | if (!initializing) | 489 | if (!initializing) |
490 | return; | 490 | return; |
491 | if ((goodness <= current_root_goodness) && | 491 | if ((goodness <= current_root_goodness) && |
492 | ROOT_DEV != DEFAULT_ROOT_DEVICE) | 492 | ROOT_DEV != DEFAULT_ROOT_DEVICE) |
493 | return; | 493 | return; |
494 | p = strstr(saved_command_line, "root="); | 494 | p = strstr(saved_command_line, "root="); |
495 | if (p != NULL && (p == saved_command_line || p[-1] == ' ')) | 495 | if (p != NULL && (p == saved_command_line || p[-1] == ' ')) |
496 | return; | 496 | return; |
497 | 497 | ||
498 | if (!found_boot) { | 498 | if (!found_boot) { |
499 | find_boot_device(); | 499 | find_boot_device(); |
500 | found_boot = 1; | 500 | found_boot = 1; |
501 | } | 501 | } |
502 | if (!boot_dev || dev == boot_dev) { | 502 | if (!boot_dev || dev == boot_dev) { |
503 | ROOT_DEV = dev + part; | 503 | ROOT_DEV = dev + part; |
504 | boot_dev = 0; | 504 | boot_dev = 0; |
505 | current_root_goodness = goodness; | 505 | current_root_goodness = goodness; |
506 | } | 506 | } |
507 | } | 507 | } |
508 | 508 | ||
509 | #ifdef CONFIG_ADB_CUDA | 509 | #ifdef CONFIG_ADB_CUDA |
510 | static void cuda_restart(void) | 510 | static void cuda_restart(void) |
511 | { | 511 | { |
512 | struct adb_request req; | 512 | struct adb_request req; |
513 | 513 | ||
514 | cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); | 514 | cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); |
515 | for (;;) | 515 | for (;;) |
516 | cuda_poll(); | 516 | cuda_poll(); |
517 | } | 517 | } |
518 | 518 | ||
519 | static void cuda_shutdown(void) | 519 | static void cuda_shutdown(void) |
520 | { | 520 | { |
521 | struct adb_request req; | 521 | struct adb_request req; |
522 | 522 | ||
523 | cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); | 523 | cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); |
524 | for (;;) | 524 | for (;;) |
525 | cuda_poll(); | 525 | cuda_poll(); |
526 | } | 526 | } |
527 | 527 | ||
528 | #else | 528 | #else |
529 | #define cuda_restart() | 529 | #define cuda_restart() |
530 | #define cuda_shutdown() | 530 | #define cuda_shutdown() |
531 | #endif | 531 | #endif |
532 | 532 | ||
533 | #ifndef CONFIG_ADB_PMU | 533 | #ifndef CONFIG_ADB_PMU |
534 | #define pmu_restart() | 534 | #define pmu_restart() |
535 | #define pmu_shutdown() | 535 | #define pmu_shutdown() |
536 | #endif | 536 | #endif |
537 | 537 | ||
538 | #ifndef CONFIG_PMAC_SMU | 538 | #ifndef CONFIG_PMAC_SMU |
539 | #define smu_restart() | 539 | #define smu_restart() |
540 | #define smu_shutdown() | 540 | #define smu_shutdown() |
541 | #endif | 541 | #endif |
542 | 542 | ||
543 | static void pmac_restart(char *cmd) | 543 | static void pmac_restart(char *cmd) |
544 | { | 544 | { |
545 | switch (sys_ctrler) { | 545 | switch (sys_ctrler) { |
546 | case SYS_CTRLER_CUDA: | 546 | case SYS_CTRLER_CUDA: |
547 | cuda_restart(); | 547 | cuda_restart(); |
548 | break; | 548 | break; |
549 | case SYS_CTRLER_PMU: | 549 | case SYS_CTRLER_PMU: |
550 | pmu_restart(); | 550 | pmu_restart(); |
551 | break; | 551 | break; |
552 | case SYS_CTRLER_SMU: | 552 | case SYS_CTRLER_SMU: |
553 | smu_restart(); | 553 | smu_restart(); |
554 | break; | 554 | break; |
555 | default: ; | 555 | default: ; |
556 | } | 556 | } |
557 | } | 557 | } |
558 | 558 | ||
559 | static void pmac_power_off(void) | 559 | static void pmac_power_off(void) |
560 | { | 560 | { |
561 | switch (sys_ctrler) { | 561 | switch (sys_ctrler) { |
562 | case SYS_CTRLER_CUDA: | 562 | case SYS_CTRLER_CUDA: |
563 | cuda_shutdown(); | 563 | cuda_shutdown(); |
564 | break; | 564 | break; |
565 | case SYS_CTRLER_PMU: | 565 | case SYS_CTRLER_PMU: |
566 | pmu_shutdown(); | 566 | pmu_shutdown(); |
567 | break; | 567 | break; |
568 | case SYS_CTRLER_SMU: | 568 | case SYS_CTRLER_SMU: |
569 | smu_shutdown(); | 569 | smu_shutdown(); |
570 | break; | 570 | break; |
571 | default: ; | 571 | default: ; |
572 | } | 572 | } |
573 | } | 573 | } |
574 | 574 | ||
575 | static void | 575 | static void |
576 | pmac_halt(void) | 576 | pmac_halt(void) |
577 | { | 577 | { |
578 | pmac_power_off(); | 578 | pmac_power_off(); |
579 | } | 579 | } |
580 | 580 | ||
581 | #ifdef CONFIG_PPC32 | 581 | #ifdef CONFIG_PPC32 |
582 | void __init pmac_init(void) | 582 | void __init pmac_init(void) |
583 | { | 583 | { |
584 | /* isa_io_base gets set in pmac_pci_init */ | 584 | /* isa_io_base gets set in pmac_pci_init */ |
585 | isa_mem_base = PMAC_ISA_MEM_BASE; | 585 | isa_mem_base = PMAC_ISA_MEM_BASE; |
586 | pci_dram_offset = PMAC_PCI_DRAM_OFFSET; | 586 | pci_dram_offset = PMAC_PCI_DRAM_OFFSET; |
587 | ISA_DMA_THRESHOLD = ~0L; | 587 | ISA_DMA_THRESHOLD = ~0L; |
588 | DMA_MODE_READ = 1; | 588 | DMA_MODE_READ = 1; |
589 | DMA_MODE_WRITE = 2; | 589 | DMA_MODE_WRITE = 2; |
590 | 590 | ||
591 | ppc_md = pmac_md; | 591 | ppc_md = pmac_md; |
592 | 592 | ||
593 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) | 593 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) |
594 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | 594 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
595 | ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; | 595 | ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; |
596 | ppc_ide_md.default_io_base = pmac_ide_get_base; | 596 | ppc_ide_md.default_io_base = pmac_ide_get_base; |
597 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | 597 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ |
598 | #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ | 598 | #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ |
599 | 599 | ||
600 | if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); | 600 | if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); |
601 | 601 | ||
602 | } | 602 | } |
603 | #endif | 603 | #endif |
604 | 604 | ||
605 | /* | 605 | /* |
606 | * Early initialization. | 606 | * Early initialization. |
607 | */ | 607 | */ |
608 | static void __init pmac_init_early(void) | 608 | static void __init pmac_init_early(void) |
609 | { | 609 | { |
610 | #ifdef CONFIG_PPC64 | 610 | #ifdef CONFIG_PPC64 |
611 | /* Initialize hash table, from now on, we can take hash faults | 611 | /* Initialize hash table, from now on, we can take hash faults |
612 | * and call ioremap | 612 | * and call ioremap |
613 | */ | 613 | */ |
614 | hpte_init_native(); | 614 | hpte_init_native(); |
615 | #endif | 615 | #endif |
616 | 616 | ||
617 | /* Enable early btext debug if requested */ | 617 | /* Enable early btext debug if requested */ |
618 | if (strstr(cmd_line, "btextdbg")) { | 618 | if (strstr(cmd_line, "btextdbg")) { |
619 | udbg_adb_init_early(); | 619 | udbg_adb_init_early(); |
620 | register_early_udbg_console(); | 620 | register_early_udbg_console(); |
621 | } | 621 | } |
622 | 622 | ||
623 | /* Probe motherboard chipset */ | 623 | /* Probe motherboard chipset */ |
624 | pmac_feature_init(); | 624 | pmac_feature_init(); |
625 | 625 | ||
626 | /* We can NAP */ | 626 | /* We can NAP */ |
627 | powersave_nap = 1; | 627 | powersave_nap = 1; |
628 | printk(KERN_INFO "Using native/NAP idle loop\n"); | 628 | printk(KERN_INFO "Using native/NAP idle loop\n"); |
629 | 629 | ||
630 | /* Initialize debug stuff */ | 630 | /* Initialize debug stuff */ |
631 | udbg_scc_init(!!strstr(cmd_line, "sccdbg")); | 631 | udbg_scc_init(!!strstr(cmd_line, "sccdbg")); |
632 | udbg_adb_init(!!strstr(cmd_line, "btextdbg")); | 632 | udbg_adb_init(!!strstr(cmd_line, "btextdbg")); |
633 | 633 | ||
634 | #ifdef CONFIG_PPC64 | 634 | #ifdef CONFIG_PPC64 |
635 | /* Setup interrupt mapping options */ | 635 | /* Setup interrupt mapping options */ |
636 | ppc64_interrupt_controller = IC_OPEN_PIC; | 636 | ppc64_interrupt_controller = IC_OPEN_PIC; |
637 | 637 | ||
638 | iommu_init_early_dart(); | 638 | iommu_init_early_dart(); |
639 | #endif | 639 | #endif |
640 | } | 640 | } |
641 | 641 | ||
642 | /* | 642 | /* |
643 | * pmac has no legacy IO, anything calling this function has to | 643 | * pmac has no legacy IO, anything calling this function has to |
644 | * fail or bad things will happen | 644 | * fail or bad things will happen |
645 | */ | 645 | */ |
646 | static int pmac_check_legacy_ioport(unsigned int baseport) | 646 | static int pmac_check_legacy_ioport(unsigned int baseport) |
647 | { | 647 | { |
648 | return -ENODEV; | 648 | return -ENODEV; |
649 | } | 649 | } |
650 | 650 | ||
651 | static int __init pmac_declare_of_platform_devices(void) | 651 | static int __init pmac_declare_of_platform_devices(void) |
652 | { | 652 | { |
653 | struct device_node *np, *npp; | 653 | struct device_node *np; |
654 | 654 | ||
655 | np = of_find_node_by_name(NULL, "valkyrie"); | 655 | np = of_find_node_by_name(NULL, "valkyrie"); |
656 | if (np) | 656 | if (np) |
657 | of_platform_device_create(np, "valkyrie", NULL); | 657 | of_platform_device_create(np, "valkyrie", NULL); |
658 | np = of_find_node_by_name(NULL, "platinum"); | 658 | np = of_find_node_by_name(NULL, "platinum"); |
659 | if (np) | 659 | if (np) |
660 | of_platform_device_create(np, "platinum", NULL); | 660 | of_platform_device_create(np, "platinum", NULL); |
661 | npp = of_find_node_by_name(NULL, "uni-n"); | ||
662 | if (npp == NULL) | ||
663 | npp = of_find_node_by_name(NULL, "u3"); | ||
664 | if (npp == NULL) | ||
665 | npp = of_find_node_by_name(NULL, "u4"); | ||
666 | if (npp) { | ||
667 | for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) { | ||
668 | if (strncmp(np->name, "i2c", 3) == 0) { | ||
669 | of_platform_device_create(np, "uni-n-i2c", | ||
670 | NULL); | ||
671 | of_node_put(np); | ||
672 | break; | ||
673 | } | ||
674 | } | ||
675 | of_node_put(npp); | ||
676 | } | ||
677 | np = of_find_node_by_type(NULL, "smu"); | 661 | np = of_find_node_by_type(NULL, "smu"); |
678 | if (np) { | 662 | if (np) { |
679 | of_platform_device_create(np, "smu", NULL); | 663 | of_platform_device_create(np, "smu", NULL); |
680 | of_node_put(np); | 664 | of_node_put(np); |
681 | } | 665 | } |
682 | 666 | ||
683 | return 0; | 667 | return 0; |
684 | } | 668 | } |
685 | 669 | ||
686 | device_initcall(pmac_declare_of_platform_devices); | 670 | device_initcall(pmac_declare_of_platform_devices); |
687 | 671 | ||
688 | /* | 672 | /* |
689 | * Called very early, MMU is off, device-tree isn't unflattened | 673 | * Called very early, MMU is off, device-tree isn't unflattened |
690 | */ | 674 | */ |
691 | static int __init pmac_probe(int platform) | 675 | static int __init pmac_probe(int platform) |
692 | { | 676 | { |
693 | #ifdef CONFIG_PPC64 | 677 | #ifdef CONFIG_PPC64 |
694 | if (platform != PLATFORM_POWERMAC) | 678 | if (platform != PLATFORM_POWERMAC) |
695 | return 0; | 679 | return 0; |
696 | 680 | ||
697 | /* | 681 | /* |
698 | * On U3, the DART (iommu) must be allocated now since it | 682 | * On U3, the DART (iommu) must be allocated now since it |
699 | * has an impact on htab_initialize (due to the large page it | 683 | * has an impact on htab_initialize (due to the large page it |
700 | * occupies having to be broken up so the DART itself is not | 684 | * occupies having to be broken up so the DART itself is not |
701 | * part of the cacheable linar mapping | 685 | * part of the cacheable linar mapping |
702 | */ | 686 | */ |
703 | alloc_dart_table(); | 687 | alloc_dart_table(); |
704 | #endif | 688 | #endif |
705 | 689 | ||
706 | #ifdef CONFIG_PMAC_SMU | 690 | #ifdef CONFIG_PMAC_SMU |
707 | /* | 691 | /* |
708 | * SMU based G5s need some memory below 2Gb, at least the current | 692 | * SMU based G5s need some memory below 2Gb, at least the current |
709 | * driver needs that. We have to allocate it now. We allocate 4k | 693 | * driver needs that. We have to allocate it now. We allocate 4k |
710 | * (1 small page) for now. | 694 | * (1 small page) for now. |
711 | */ | 695 | */ |
712 | smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL); | 696 | smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL); |
713 | #endif /* CONFIG_PMAC_SMU */ | 697 | #endif /* CONFIG_PMAC_SMU */ |
714 | 698 | ||
715 | return 1; | 699 | return 1; |
716 | } | 700 | } |
717 | 701 | ||
718 | #ifdef CONFIG_PPC64 | 702 | #ifdef CONFIG_PPC64 |
719 | /* Move that to pci.c */ | 703 | /* Move that to pci.c */ |
720 | static int pmac_pci_probe_mode(struct pci_bus *bus) | 704 | static int pmac_pci_probe_mode(struct pci_bus *bus) |
721 | { | 705 | { |
722 | struct device_node *node = bus->sysdata; | 706 | struct device_node *node = bus->sysdata; |
723 | 707 | ||
724 | /* We need to use normal PCI probing for the AGP bus, | 708 | /* We need to use normal PCI probing for the AGP bus, |
725 | * since the device for the AGP bridge isn't in the tree. | 709 | * since the device for the AGP bridge isn't in the tree. |
726 | */ | 710 | */ |
727 | if (bus->self == NULL && (device_is_compatible(node, "u3-agp") || | 711 | if (bus->self == NULL && (device_is_compatible(node, "u3-agp") || |
728 | device_is_compatible(node, "u4-pcie"))) | 712 | device_is_compatible(node, "u4-pcie"))) |
729 | return PCI_PROBE_NORMAL; | 713 | return PCI_PROBE_NORMAL; |
730 | return PCI_PROBE_DEVTREE; | 714 | return PCI_PROBE_DEVTREE; |
731 | } | 715 | } |
732 | #endif | 716 | #endif |
733 | 717 | ||
734 | struct machdep_calls __initdata pmac_md = { | 718 | struct machdep_calls __initdata pmac_md = { |
735 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) | 719 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) |
736 | .cpu_die = generic_mach_cpu_die, | 720 | .cpu_die = generic_mach_cpu_die, |
737 | #endif | 721 | #endif |
738 | .probe = pmac_probe, | 722 | .probe = pmac_probe, |
739 | .setup_arch = pmac_setup_arch, | 723 | .setup_arch = pmac_setup_arch, |
740 | .init_early = pmac_init_early, | 724 | .init_early = pmac_init_early, |
741 | .show_cpuinfo = pmac_show_cpuinfo, | 725 | .show_cpuinfo = pmac_show_cpuinfo, |
742 | .init_IRQ = pmac_pic_init, | 726 | .init_IRQ = pmac_pic_init, |
743 | .get_irq = NULL, /* changed later */ | 727 | .get_irq = NULL, /* changed later */ |
744 | .pcibios_fixup = pmac_pcibios_fixup, | 728 | .pcibios_fixup = pmac_pcibios_fixup, |
745 | .restart = pmac_restart, | 729 | .restart = pmac_restart, |
746 | .power_off = pmac_power_off, | 730 | .power_off = pmac_power_off, |
747 | .halt = pmac_halt, | 731 | .halt = pmac_halt, |
748 | .time_init = pmac_time_init, | 732 | .time_init = pmac_time_init, |
749 | .get_boot_time = pmac_get_boot_time, | 733 | .get_boot_time = pmac_get_boot_time, |
750 | .set_rtc_time = pmac_set_rtc_time, | 734 | .set_rtc_time = pmac_set_rtc_time, |
751 | .get_rtc_time = pmac_get_rtc_time, | 735 | .get_rtc_time = pmac_get_rtc_time, |
752 | .calibrate_decr = pmac_calibrate_decr, | 736 | .calibrate_decr = pmac_calibrate_decr, |
753 | .feature_call = pmac_do_feature_call, | 737 | .feature_call = pmac_do_feature_call, |
754 | .check_legacy_ioport = pmac_check_legacy_ioport, | 738 | .check_legacy_ioport = pmac_check_legacy_ioport, |
755 | .progress = udbg_progress, | 739 | .progress = udbg_progress, |
756 | #ifdef CONFIG_PPC64 | 740 | #ifdef CONFIG_PPC64 |
757 | .pci_probe_mode = pmac_pci_probe_mode, | 741 | .pci_probe_mode = pmac_pci_probe_mode, |
758 | .idle_loop = native_idle, | 742 | .idle_loop = native_idle, |
759 | .enable_pmcs = power4_enable_pmcs, | 743 | .enable_pmcs = power4_enable_pmcs, |
760 | #ifdef CONFIG_KEXEC | 744 | #ifdef CONFIG_KEXEC |
761 | .machine_kexec = default_machine_kexec, | 745 | .machine_kexec = default_machine_kexec, |
762 | .machine_kexec_prepare = default_machine_kexec_prepare, | 746 | .machine_kexec_prepare = default_machine_kexec_prepare, |
763 | .machine_crash_shutdown = default_machine_crash_shutdown, | 747 | .machine_crash_shutdown = default_machine_crash_shutdown, |
764 | #endif | 748 | #endif |
765 | #endif /* CONFIG_PPC64 */ | 749 | #endif /* CONFIG_PPC64 */ |
766 | #ifdef CONFIG_PPC32 | 750 | #ifdef CONFIG_PPC32 |
767 | .pcibios_enable_device_hook = pmac_pci_enable_device_hook, | 751 | .pcibios_enable_device_hook = pmac_pci_enable_device_hook, |
768 | .pcibios_after_init = pmac_pcibios_after_init, | 752 | .pcibios_after_init = pmac_pcibios_after_init, |
769 | .phys_mem_access_prot = pci_phys_mem_access_prot, | 753 | .phys_mem_access_prot = pci_phys_mem_access_prot, |
770 | #endif | 754 | #endif |
771 | }; | 755 | }; |
772 | 756 |
drivers/i2c/busses/Kconfig
1 | # | 1 | # |
2 | # Sensor device configuration | 2 | # Sensor device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "I2C Hardware Bus support" | 5 | menu "I2C Hardware Bus support" |
6 | depends on I2C | 6 | depends on I2C |
7 | 7 | ||
8 | config I2C_ALI1535 | 8 | config I2C_ALI1535 |
9 | tristate "ALI 1535" | 9 | tristate "ALI 1535" |
10 | depends on I2C && PCI | 10 | depends on I2C && PCI |
11 | help | 11 | help |
12 | If you say yes to this option, support will be included for the SMB | 12 | If you say yes to this option, support will be included for the SMB |
13 | Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB | 13 | Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB |
14 | controller is part of the 7101 device, which is an ACPI-compliant | 14 | controller is part of the 7101 device, which is an ACPI-compliant |
15 | Power Management Unit (PMU). | 15 | Power Management Unit (PMU). |
16 | 16 | ||
17 | This driver can also be built as a module. If so, the module | 17 | This driver can also be built as a module. If so, the module |
18 | will be called i2c-ali1535. | 18 | will be called i2c-ali1535. |
19 | 19 | ||
20 | config I2C_ALI1563 | 20 | config I2C_ALI1563 |
21 | tristate "ALI 1563" | 21 | tristate "ALI 1563" |
22 | depends on I2C && PCI && EXPERIMENTAL | 22 | depends on I2C && PCI && EXPERIMENTAL |
23 | help | 23 | help |
24 | If you say yes to this option, support will be included for the SMB | 24 | If you say yes to this option, support will be included for the SMB |
25 | Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB | 25 | Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB |
26 | controller is part of the 7101 device, which is an ACPI-compliant | 26 | controller is part of the 7101 device, which is an ACPI-compliant |
27 | Power Management Unit (PMU). | 27 | Power Management Unit (PMU). |
28 | 28 | ||
29 | This driver can also be built as a module. If so, the module | 29 | This driver can also be built as a module. If so, the module |
30 | will be called i2c-ali1563. | 30 | will be called i2c-ali1563. |
31 | 31 | ||
32 | config I2C_ALI15X3 | 32 | config I2C_ALI15X3 |
33 | tristate "ALI 15x3" | 33 | tristate "ALI 15x3" |
34 | depends on I2C && PCI | 34 | depends on I2C && PCI |
35 | help | 35 | help |
36 | If you say yes to this option, support will be included for the | 36 | If you say yes to this option, support will be included for the |
37 | Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces. | 37 | Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces. |
38 | 38 | ||
39 | This driver can also be built as a module. If so, the module | 39 | This driver can also be built as a module. If so, the module |
40 | will be called i2c-ali15x3. | 40 | will be called i2c-ali15x3. |
41 | 41 | ||
42 | config I2C_AMD756 | 42 | config I2C_AMD756 |
43 | tristate "AMD 756/766/768/8111 and nVidia nForce" | 43 | tristate "AMD 756/766/768/8111 and nVidia nForce" |
44 | depends on I2C && PCI | 44 | depends on I2C && PCI |
45 | help | 45 | help |
46 | If you say yes to this option, support will be included for the AMD | 46 | If you say yes to this option, support will be included for the AMD |
47 | 756/766/768 mainboard I2C interfaces. The driver also includes | 47 | 756/766/768 mainboard I2C interfaces. The driver also includes |
48 | support for the first (SMBus 1.0) I2C interface of the AMD 8111 and | 48 | support for the first (SMBus 1.0) I2C interface of the AMD 8111 and |
49 | the nVidia nForce I2C interface. | 49 | the nVidia nForce I2C interface. |
50 | 50 | ||
51 | This driver can also be built as a module. If so, the module | 51 | This driver can also be built as a module. If so, the module |
52 | will be called i2c-amd756. | 52 | will be called i2c-amd756. |
53 | 53 | ||
54 | config I2C_AMD756_S4882 | 54 | config I2C_AMD756_S4882 |
55 | tristate "SMBus multiplexing on the Tyan S4882" | 55 | tristate "SMBus multiplexing on the Tyan S4882" |
56 | depends on I2C_AMD756 && EXPERIMENTAL | 56 | depends on I2C_AMD756 && EXPERIMENTAL |
57 | help | 57 | help |
58 | Enabling this option will add specific SMBus support for the Tyan | 58 | Enabling this option will add specific SMBus support for the Tyan |
59 | S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed | 59 | S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed |
60 | over 8 different channels, where the various memory module EEPROMs | 60 | over 8 different channels, where the various memory module EEPROMs |
61 | and temperature sensors live. Saying yes here will give you access | 61 | and temperature sensors live. Saying yes here will give you access |
62 | to these in addition to the trunk. | 62 | to these in addition to the trunk. |
63 | 63 | ||
64 | This driver can also be built as a module. If so, the module | 64 | This driver can also be built as a module. If so, the module |
65 | will be called i2c-amd756-s4882. | 65 | will be called i2c-amd756-s4882. |
66 | 66 | ||
67 | config I2C_AMD8111 | 67 | config I2C_AMD8111 |
68 | tristate "AMD 8111" | 68 | tristate "AMD 8111" |
69 | depends on I2C && PCI | 69 | depends on I2C && PCI |
70 | help | 70 | help |
71 | If you say yes to this option, support will be included for the | 71 | If you say yes to this option, support will be included for the |
72 | second (SMBus 2.0) AMD 8111 mainboard I2C interface. | 72 | second (SMBus 2.0) AMD 8111 mainboard I2C interface. |
73 | 73 | ||
74 | This driver can also be built as a module. If so, the module | 74 | This driver can also be built as a module. If so, the module |
75 | will be called i2c-amd8111. | 75 | will be called i2c-amd8111. |
76 | 76 | ||
77 | config I2C_AU1550 | 77 | config I2C_AU1550 |
78 | tristate "Au1550 SMBus interface" | 78 | tristate "Au1550 SMBus interface" |
79 | depends on I2C && SOC_AU1550 | 79 | depends on I2C && SOC_AU1550 |
80 | help | 80 | help |
81 | If you say yes to this option, support will be included for the | 81 | If you say yes to this option, support will be included for the |
82 | Au1550 SMBus interface. | 82 | Au1550 SMBus interface. |
83 | 83 | ||
84 | This driver can also be built as a module. If so, the module | 84 | This driver can also be built as a module. If so, the module |
85 | will be called i2c-au1550. | 85 | will be called i2c-au1550. |
86 | 86 | ||
87 | config I2C_ELEKTOR | 87 | config I2C_ELEKTOR |
88 | tristate "Elektor ISA card" | 88 | tristate "Elektor ISA card" |
89 | depends on I2C && ISA && BROKEN_ON_SMP | 89 | depends on I2C && ISA && BROKEN_ON_SMP |
90 | select I2C_ALGOPCF | 90 | select I2C_ALGOPCF |
91 | help | 91 | help |
92 | This supports the PCF8584 ISA bus I2C adapter. Say Y if you own | 92 | This supports the PCF8584 ISA bus I2C adapter. Say Y if you own |
93 | such an adapter. | 93 | such an adapter. |
94 | 94 | ||
95 | This support is also available as a module. If so, the module | 95 | This support is also available as a module. If so, the module |
96 | will be called i2c-elektor. | 96 | will be called i2c-elektor. |
97 | 97 | ||
98 | config I2C_HYDRA | 98 | config I2C_HYDRA |
99 | tristate "CHRP Apple Hydra Mac I/O I2C interface" | 99 | tristate "CHRP Apple Hydra Mac I/O I2C interface" |
100 | depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL | 100 | depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL |
101 | select I2C_ALGOBIT | 101 | select I2C_ALGOBIT |
102 | help | 102 | help |
103 | This supports the use of the I2C interface in the Apple Hydra Mac | 103 | This supports the use of the I2C interface in the Apple Hydra Mac |
104 | I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you | 104 | I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you |
105 | have such a machine. | 105 | have such a machine. |
106 | 106 | ||
107 | This support is also available as a module. If so, the module | 107 | This support is also available as a module. If so, the module |
108 | will be called i2c-hydra. | 108 | will be called i2c-hydra. |
109 | 109 | ||
110 | config I2C_I801 | 110 | config I2C_I801 |
111 | tristate "Intel 82801 (ICH)" | 111 | tristate "Intel 82801 (ICH)" |
112 | depends on I2C && PCI | 112 | depends on I2C && PCI |
113 | help | 113 | help |
114 | If you say yes to this option, support will be included for the Intel | 114 | If you say yes to this option, support will be included for the Intel |
115 | 801 family of mainboard I2C interfaces. Specifically, the following | 115 | 801 family of mainboard I2C interfaces. Specifically, the following |
116 | versions of the chipset are supported: | 116 | versions of the chipset are supported: |
117 | 82801AA | 117 | 82801AA |
118 | 82801AB | 118 | 82801AB |
119 | 82801BA | 119 | 82801BA |
120 | 82801CA/CAM | 120 | 82801CA/CAM |
121 | 82801DB | 121 | 82801DB |
122 | 82801EB/ER (ICH5/ICH5R) | 122 | 82801EB/ER (ICH5/ICH5R) |
123 | 6300ESB | 123 | 6300ESB |
124 | ICH6 | 124 | ICH6 |
125 | ICH7 | 125 | ICH7 |
126 | ESB2 | 126 | ESB2 |
127 | 127 | ||
128 | This driver can also be built as a module. If so, the module | 128 | This driver can also be built as a module. If so, the module |
129 | will be called i2c-i801. | 129 | will be called i2c-i801. |
130 | 130 | ||
131 | config I2C_I810 | 131 | config I2C_I810 |
132 | tristate "Intel 810/815" | 132 | tristate "Intel 810/815" |
133 | depends on I2C && PCI | 133 | depends on I2C && PCI |
134 | select I2C_ALGOBIT | 134 | select I2C_ALGOBIT |
135 | help | 135 | help |
136 | If you say yes to this option, support will be included for the Intel | 136 | If you say yes to this option, support will be included for the Intel |
137 | 810/815 family of mainboard I2C interfaces. Specifically, the | 137 | 810/815 family of mainboard I2C interfaces. Specifically, the |
138 | following versions of the chipset are supported: | 138 | following versions of the chipset are supported: |
139 | i810AA | 139 | i810AA |
140 | i810AB | 140 | i810AB |
141 | i810E | 141 | i810E |
142 | i815 | 142 | i815 |
143 | i845G | 143 | i845G |
144 | 144 | ||
145 | This driver can also be built as a module. If so, the module | 145 | This driver can also be built as a module. If so, the module |
146 | will be called i2c-i810. | 146 | will be called i2c-i810. |
147 | 147 | ||
148 | config I2C_PXA | 148 | config I2C_PXA |
149 | tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" | 149 | tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" |
150 | depends on I2C && EXPERIMENTAL && ARCH_PXA | 150 | depends on I2C && EXPERIMENTAL && ARCH_PXA |
151 | help | 151 | help |
152 | If you have devices in the PXA I2C bus, say yes to this option. | 152 | If you have devices in the PXA I2C bus, say yes to this option. |
153 | This driver can also be built as a module. If so, the module | 153 | This driver can also be built as a module. If so, the module |
154 | will be called i2c-pxa. | 154 | will be called i2c-pxa. |
155 | 155 | ||
156 | config I2C_PXA_SLAVE | 156 | config I2C_PXA_SLAVE |
157 | bool "Intel PXA2XX I2C Slave comms support" | 157 | bool "Intel PXA2XX I2C Slave comms support" |
158 | depends on I2C_PXA | 158 | depends on I2C_PXA |
159 | help | 159 | help |
160 | Support I2C slave mode communications on the PXA I2C bus. This | 160 | Support I2C slave mode communications on the PXA I2C bus. This |
161 | is necessary for systems where the PXA may be a target on the | 161 | is necessary for systems where the PXA may be a target on the |
162 | I2C bus. | 162 | I2C bus. |
163 | 163 | ||
164 | config I2C_PIIX4 | 164 | config I2C_PIIX4 |
165 | tristate "Intel PIIX4" | 165 | tristate "Intel PIIX4" |
166 | depends on I2C && PCI | 166 | depends on I2C && PCI |
167 | help | 167 | help |
168 | If you say yes to this option, support will be included for the Intel | 168 | If you say yes to this option, support will be included for the Intel |
169 | PIIX4 family of mainboard I2C interfaces. Specifically, the following | 169 | PIIX4 family of mainboard I2C interfaces. Specifically, the following |
170 | versions of the chipset are supported: | 170 | versions of the chipset are supported: |
171 | Intel PIIX4 | 171 | Intel PIIX4 |
172 | Intel 440MX | 172 | Intel 440MX |
173 | Serverworks OSB4 | 173 | Serverworks OSB4 |
174 | Serverworks CSB5 | 174 | Serverworks CSB5 |
175 | Serverworks CSB6 | 175 | Serverworks CSB6 |
176 | SMSC Victory66 | 176 | SMSC Victory66 |
177 | 177 | ||
178 | This driver can also be built as a module. If so, the module | 178 | This driver can also be built as a module. If so, the module |
179 | will be called i2c-piix4. | 179 | will be called i2c-piix4. |
180 | 180 | ||
181 | config I2C_IBM_IIC | 181 | config I2C_IBM_IIC |
182 | tristate "IBM PPC 4xx on-chip I2C interface" | 182 | tristate "IBM PPC 4xx on-chip I2C interface" |
183 | depends on IBM_OCP && I2C | 183 | depends on IBM_OCP && I2C |
184 | help | 184 | help |
185 | Say Y here if you want to use IIC peripheral found on | 185 | Say Y here if you want to use IIC peripheral found on |
186 | embedded IBM PPC 4xx based systems. | 186 | embedded IBM PPC 4xx based systems. |
187 | 187 | ||
188 | This driver can also be built as a module. If so, the module | 188 | This driver can also be built as a module. If so, the module |
189 | will be called i2c-ibm_iic. | 189 | will be called i2c-ibm_iic. |
190 | 190 | ||
191 | config I2C_IOP3XX | 191 | config I2C_IOP3XX |
192 | tristate "Intel IOP3xx and IXP4xx on-chip I2C interface" | 192 | tristate "Intel IOP3xx and IXP4xx on-chip I2C interface" |
193 | depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C | 193 | depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C |
194 | help | 194 | help |
195 | Say Y here if you want to use the IIC bus controller on | 195 | Say Y here if you want to use the IIC bus controller on |
196 | the Intel IOP3xx I/O Processors or IXP4xx Network Processors. | 196 | the Intel IOP3xx I/O Processors or IXP4xx Network Processors. |
197 | 197 | ||
198 | This driver can also be built as a module. If so, the module | 198 | This driver can also be built as a module. If so, the module |
199 | will be called i2c-iop3xx. | 199 | will be called i2c-iop3xx. |
200 | 200 | ||
201 | config I2C_ISA | 201 | config I2C_ISA |
202 | tristate | 202 | tristate |
203 | depends on I2C | 203 | depends on I2C |
204 | 204 | ||
205 | config I2C_ITE | 205 | config I2C_ITE |
206 | tristate "ITE I2C Adapter" | 206 | tristate "ITE I2C Adapter" |
207 | depends on I2C && MIPS_ITE8172 | 207 | depends on I2C && MIPS_ITE8172 |
208 | select I2C_ALGOITE | 208 | select I2C_ALGOITE |
209 | help | 209 | help |
210 | This supports the ITE8172 I2C peripheral found on some MIPS | 210 | This supports the ITE8172 I2C peripheral found on some MIPS |
211 | systems. Say Y if you have one of these. You should also say Y for | 211 | systems. Say Y if you have one of these. You should also say Y for |
212 | the ITE I2C driver algorithm support above. | 212 | the ITE I2C driver algorithm support above. |
213 | 213 | ||
214 | This support is also available as a module. If so, the module | 214 | This support is also available as a module. If so, the module |
215 | will be called i2c-ite. | 215 | will be called i2c-ite. |
216 | 216 | ||
217 | config I2C_IXP4XX | 217 | config I2C_IXP4XX |
218 | tristate "IXP4xx GPIO-Based I2C Interface" | 218 | tristate "IXP4xx GPIO-Based I2C Interface" |
219 | depends on I2C && ARCH_IXP4XX | 219 | depends on I2C && ARCH_IXP4XX |
220 | select I2C_ALGOBIT | 220 | select I2C_ALGOBIT |
221 | help | 221 | help |
222 | Say Y here if you have an Intel IXP4xx(420,421,422,425) based | 222 | Say Y here if you have an Intel IXP4xx(420,421,422,425) based |
223 | system and are using GPIO lines for an I2C bus. | 223 | system and are using GPIO lines for an I2C bus. |
224 | 224 | ||
225 | This support is also available as a module. If so, the module | 225 | This support is also available as a module. If so, the module |
226 | will be called i2c-ixp4xx. | 226 | will be called i2c-ixp4xx. |
227 | 227 | ||
228 | config I2C_IXP2000 | 228 | config I2C_IXP2000 |
229 | tristate "IXP2000 GPIO-Based I2C Interface" | 229 | tristate "IXP2000 GPIO-Based I2C Interface" |
230 | depends on I2C && ARCH_IXP2000 | 230 | depends on I2C && ARCH_IXP2000 |
231 | select I2C_ALGOBIT | 231 | select I2C_ALGOBIT |
232 | help | 232 | help |
233 | Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based | 233 | Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based |
234 | system and are using GPIO lines for an I2C bus. | 234 | system and are using GPIO lines for an I2C bus. |
235 | 235 | ||
236 | This support is also available as a module. If so, the module | 236 | This support is also available as a module. If so, the module |
237 | will be called i2c-ixp2000. | 237 | will be called i2c-ixp2000. |
238 | 238 | ||
239 | config I2C_KEYWEST | 239 | config I2C_POWERMAC |
240 | tristate "Powermac Keywest I2C interface" | 240 | tristate "Powermac I2C interface" |
241 | depends on I2C && PPC_PMAC | 241 | depends on I2C && PPC_PMAC |
242 | default y | ||
242 | help | 243 | help |
243 | This supports the use of the I2C interface in the combo-I/O | 244 | This exposes the various PowerMac i2c interfaces to the linux i2c |
244 | chip on recent Apple machines. Say Y if you have such a machine. | 245 | layer and to userland. It is used by various drivers on the powemac |
246 | platform, thus should generally be enabled. | ||
245 | 247 | ||
246 | This support is also available as a module. If so, the module | ||
247 | will be called i2c-keywest. | ||
248 | |||
249 | config I2C_PMAC_SMU | ||
250 | tristate "Powermac SMU I2C interface" | ||
251 | depends on I2C && PMAC_SMU | ||
252 | help | ||
253 | This supports the use of the I2C interface in the SMU | ||
254 | chip on recent Apple machines like the iMac G5. It is used | ||
255 | among others by the thermal control driver for those machines. | ||
256 | Say Y if you have such a machine. | ||
257 | |||
258 | This support is also available as a module. If so, the module | 248 | This support is also available as a module. If so, the module |
259 | will be called i2c-pmac-smu. | 249 | will be called i2c-powermac. |
260 | 250 | ||
261 | config I2C_MPC | 251 | config I2C_MPC |
262 | tristate "MPC107/824x/85xx/52xx" | 252 | tristate "MPC107/824x/85xx/52xx" |
263 | depends on I2C && PPC32 | 253 | depends on I2C && PPC32 |
264 | help | 254 | help |
265 | If you say yes to this option, support will be included for the | 255 | If you say yes to this option, support will be included for the |
266 | built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and | 256 | built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and |
267 | MPC85xx family processors. The driver may also work on 52xx | 257 | MPC85xx family processors. The driver may also work on 52xx |
268 | family processors, though interrupts are known not to work. | 258 | family processors, though interrupts are known not to work. |
269 | 259 | ||
270 | This driver can also be built as a module. If so, the module | 260 | This driver can also be built as a module. If so, the module |
271 | will be called i2c-mpc. | 261 | will be called i2c-mpc. |
272 | 262 | ||
273 | config I2C_NFORCE2 | 263 | config I2C_NFORCE2 |
274 | tristate "Nvidia nForce2, nForce3 and nForce4" | 264 | tristate "Nvidia nForce2, nForce3 and nForce4" |
275 | depends on I2C && PCI | 265 | depends on I2C && PCI |
276 | help | 266 | help |
277 | If you say yes to this option, support will be included for the Nvidia | 267 | If you say yes to this option, support will be included for the Nvidia |
278 | nForce2, nForce3 and nForce4 families of mainboard I2C interfaces. | 268 | nForce2, nForce3 and nForce4 families of mainboard I2C interfaces. |
279 | 269 | ||
280 | This driver can also be built as a module. If so, the module | 270 | This driver can also be built as a module. If so, the module |
281 | will be called i2c-nforce2. | 271 | will be called i2c-nforce2. |
282 | 272 | ||
283 | config I2C_PARPORT | 273 | config I2C_PARPORT |
284 | tristate "Parallel port adapter" | 274 | tristate "Parallel port adapter" |
285 | depends on I2C && PARPORT | 275 | depends on I2C && PARPORT |
286 | select I2C_ALGOBIT | 276 | select I2C_ALGOBIT |
287 | help | 277 | help |
288 | This supports parallel port I2C adapters such as the ones made by | 278 | This supports parallel port I2C adapters such as the ones made by |
289 | Philips or Velleman, Analog Devices evaluation boards, and more. | 279 | Philips or Velleman, Analog Devices evaluation boards, and more. |
290 | Basically any adapter using the parallel port as an I2C bus with | 280 | Basically any adapter using the parallel port as an I2C bus with |
291 | no extra chipset is supported by this driver, or could be. | 281 | no extra chipset is supported by this driver, or could be. |
292 | 282 | ||
293 | This driver is a replacement for (and was inspired by) an older | 283 | This driver is a replacement for (and was inspired by) an older |
294 | driver named i2c-philips-par. The new driver supports more devices, | 284 | driver named i2c-philips-par. The new driver supports more devices, |
295 | and makes it easier to add support for new devices. | 285 | and makes it easier to add support for new devices. |
296 | 286 | ||
297 | Another driver exists, named i2c-parport-light, which doesn't depend | 287 | Another driver exists, named i2c-parport-light, which doesn't depend |
298 | on the parport driver. This is meant for embedded systems. Don't say | 288 | on the parport driver. This is meant for embedded systems. Don't say |
299 | Y here if you intend to say Y or M there. | 289 | Y here if you intend to say Y or M there. |
300 | 290 | ||
301 | This support is also available as a module. If so, the module | 291 | This support is also available as a module. If so, the module |
302 | will be called i2c-parport. | 292 | will be called i2c-parport. |
303 | 293 | ||
304 | config I2C_PARPORT_LIGHT | 294 | config I2C_PARPORT_LIGHT |
305 | tristate "Parallel port adapter (light)" | 295 | tristate "Parallel port adapter (light)" |
306 | depends on I2C | 296 | depends on I2C |
307 | select I2C_ALGOBIT | 297 | select I2C_ALGOBIT |
308 | help | 298 | help |
309 | This supports parallel port I2C adapters such as the ones made by | 299 | This supports parallel port I2C adapters such as the ones made by |
310 | Philips or Velleman, Analog Devices evaluation boards, and more. | 300 | Philips or Velleman, Analog Devices evaluation boards, and more. |
311 | Basically any adapter using the parallel port as an I2C bus with | 301 | Basically any adapter using the parallel port as an I2C bus with |
312 | no extra chipset is supported by this driver, or could be. | 302 | no extra chipset is supported by this driver, or could be. |
313 | 303 | ||
314 | This driver is a light version of i2c-parport. It doesn't depend | 304 | This driver is a light version of i2c-parport. It doesn't depend |
315 | on the parport driver, and uses direct I/O access instead. This | 305 | on the parport driver, and uses direct I/O access instead. This |
316 | might be prefered on embedded systems where wasting memory for | 306 | might be prefered on embedded systems where wasting memory for |
317 | the clean but heavy parport handling is not an option. The | 307 | the clean but heavy parport handling is not an option. The |
318 | drawback is a reduced portability and the impossibility to | 308 | drawback is a reduced portability and the impossibility to |
319 | dasiy-chain other parallel port devices. | 309 | dasiy-chain other parallel port devices. |
320 | 310 | ||
321 | Don't say Y here if you said Y or M to i2c-parport. Saying M to | 311 | Don't say Y here if you said Y or M to i2c-parport. Saying M to |
322 | both is possible but both modules should not be loaded at the same | 312 | both is possible but both modules should not be loaded at the same |
323 | time. | 313 | time. |
324 | 314 | ||
325 | This support is also available as a module. If so, the module | 315 | This support is also available as a module. If so, the module |
326 | will be called i2c-parport-light. | 316 | will be called i2c-parport-light. |
327 | 317 | ||
328 | config I2C_PROSAVAGE | 318 | config I2C_PROSAVAGE |
329 | tristate "S3/VIA (Pro)Savage" | 319 | tristate "S3/VIA (Pro)Savage" |
330 | depends on I2C && PCI | 320 | depends on I2C && PCI |
331 | select I2C_ALGOBIT | 321 | select I2C_ALGOBIT |
332 | help | 322 | help |
333 | If you say yes to this option, support will be included for the | 323 | If you say yes to this option, support will be included for the |
334 | I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8 | 324 | I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8 |
335 | graphics processors. | 325 | graphics processors. |
336 | chipsets supported: | 326 | chipsets supported: |
337 | S3/VIA KM266/VT8375 aka ProSavage8 | 327 | S3/VIA KM266/VT8375 aka ProSavage8 |
338 | S3/VIA KM133/VT8365 aka Savage4 | 328 | S3/VIA KM133/VT8365 aka Savage4 |
339 | 329 | ||
340 | This support is also available as a module. If so, the module | 330 | This support is also available as a module. If so, the module |
341 | will be called i2c-prosavage. | 331 | will be called i2c-prosavage. |
342 | 332 | ||
343 | config I2C_RPXLITE | 333 | config I2C_RPXLITE |
344 | tristate "Embedded Planet RPX Lite/Classic support" | 334 | tristate "Embedded Planet RPX Lite/Classic support" |
345 | depends on (RPXLITE || RPXCLASSIC) && I2C | 335 | depends on (RPXLITE || RPXCLASSIC) && I2C |
346 | select I2C_ALGO8XX | 336 | select I2C_ALGO8XX |
347 | 337 | ||
348 | config I2C_S3C2410 | 338 | config I2C_S3C2410 |
349 | tristate "S3C2410 I2C Driver" | 339 | tristate "S3C2410 I2C Driver" |
350 | depends on I2C && ARCH_S3C2410 | 340 | depends on I2C && ARCH_S3C2410 |
351 | help | 341 | help |
352 | Say Y here to include support for I2C controller in the | 342 | Say Y here to include support for I2C controller in the |
353 | Samsung S3C2410 based System-on-Chip devices. | 343 | Samsung S3C2410 based System-on-Chip devices. |
354 | 344 | ||
355 | config I2C_SAVAGE4 | 345 | config I2C_SAVAGE4 |
356 | tristate "S3 Savage 4" | 346 | tristate "S3 Savage 4" |
357 | depends on I2C && PCI && EXPERIMENTAL | 347 | depends on I2C && PCI && EXPERIMENTAL |
358 | select I2C_ALGOBIT | 348 | select I2C_ALGOBIT |
359 | help | 349 | help |
360 | If you say yes to this option, support will be included for the | 350 | If you say yes to this option, support will be included for the |
361 | S3 Savage 4 I2C interface. | 351 | S3 Savage 4 I2C interface. |
362 | 352 | ||
363 | This driver can also be built as a module. If so, the module | 353 | This driver can also be built as a module. If so, the module |
364 | will be called i2c-savage4. | 354 | will be called i2c-savage4. |
365 | 355 | ||
366 | config I2C_SIBYTE | 356 | config I2C_SIBYTE |
367 | tristate "SiByte SMBus interface" | 357 | tristate "SiByte SMBus interface" |
368 | depends on SIBYTE_SB1xxx_SOC && I2C | 358 | depends on SIBYTE_SB1xxx_SOC && I2C |
369 | help | 359 | help |
370 | Supports the SiByte SOC on-chip I2C interfaces (2 channels). | 360 | Supports the SiByte SOC on-chip I2C interfaces (2 channels). |
371 | 361 | ||
372 | config SCx200_I2C | 362 | config SCx200_I2C |
373 | tristate "NatSemi SCx200 I2C using GPIO pins" | 363 | tristate "NatSemi SCx200 I2C using GPIO pins" |
374 | depends on SCx200_GPIO && I2C | 364 | depends on SCx200_GPIO && I2C |
375 | select I2C_ALGOBIT | 365 | select I2C_ALGOBIT |
376 | help | 366 | help |
377 | Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. | 367 | Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. |
378 | 368 | ||
379 | If you don't know what to do here, say N. | 369 | If you don't know what to do here, say N. |
380 | 370 | ||
381 | This support is also available as a module. If so, the module | 371 | This support is also available as a module. If so, the module |
382 | will be called scx200_i2c. | 372 | will be called scx200_i2c. |
383 | 373 | ||
384 | config SCx200_I2C_SCL | 374 | config SCx200_I2C_SCL |
385 | int "GPIO pin used for SCL" | 375 | int "GPIO pin used for SCL" |
386 | depends on SCx200_I2C | 376 | depends on SCx200_I2C |
387 | default "12" | 377 | default "12" |
388 | help | 378 | help |
389 | Enter the GPIO pin number used for the SCL signal. This value can | 379 | Enter the GPIO pin number used for the SCL signal. This value can |
390 | also be specified with a module parameter. | 380 | also be specified with a module parameter. |
391 | 381 | ||
392 | config SCx200_I2C_SDA | 382 | config SCx200_I2C_SDA |
393 | int "GPIO pin used for SDA" | 383 | int "GPIO pin used for SDA" |
394 | depends on SCx200_I2C | 384 | depends on SCx200_I2C |
395 | default "13" | 385 | default "13" |
396 | help | 386 | help |
397 | Enter the GPIO pin number used for the SSA signal. This value can | 387 | Enter the GPIO pin number used for the SSA signal. This value can |
398 | also be specified with a module parameter. | 388 | also be specified with a module parameter. |
399 | 389 | ||
400 | config SCx200_ACB | 390 | config SCx200_ACB |
401 | tristate "NatSemi SCx200 ACCESS.bus" | 391 | tristate "NatSemi SCx200 ACCESS.bus" |
402 | depends on I2C && PCI | 392 | depends on I2C && PCI |
403 | help | 393 | help |
404 | Enable the use of the ACCESS.bus controllers of a SCx200 processor. | 394 | Enable the use of the ACCESS.bus controllers of a SCx200 processor. |
405 | 395 | ||
406 | If you don't know what to do here, say N. | 396 | If you don't know what to do here, say N. |
407 | 397 | ||
408 | This support is also available as a module. If so, the module | 398 | This support is also available as a module. If so, the module |
409 | will be called scx200_acb. | 399 | will be called scx200_acb. |
410 | 400 | ||
411 | config I2C_SIS5595 | 401 | config I2C_SIS5595 |
412 | tristate "SiS 5595" | 402 | tristate "SiS 5595" |
413 | depends on I2C && PCI | 403 | depends on I2C && PCI |
414 | help | 404 | help |
415 | If you say yes to this option, support will be included for the | 405 | If you say yes to this option, support will be included for the |
416 | SiS5595 SMBus (a subset of I2C) interface. | 406 | SiS5595 SMBus (a subset of I2C) interface. |
417 | 407 | ||
418 | This driver can also be built as a module. If so, the module | 408 | This driver can also be built as a module. If so, the module |
419 | will be called i2c-sis5595. | 409 | will be called i2c-sis5595. |
420 | 410 | ||
421 | config I2C_SIS630 | 411 | config I2C_SIS630 |
422 | tristate "SiS 630/730" | 412 | tristate "SiS 630/730" |
423 | depends on I2C && PCI | 413 | depends on I2C && PCI |
424 | help | 414 | help |
425 | If you say yes to this option, support will be included for the | 415 | If you say yes to this option, support will be included for the |
426 | SiS630 and SiS730 SMBus (a subset of I2C) interface. | 416 | SiS630 and SiS730 SMBus (a subset of I2C) interface. |
427 | 417 | ||
428 | This driver can also be built as a module. If so, the module | 418 | This driver can also be built as a module. If so, the module |
429 | will be called i2c-sis630. | 419 | will be called i2c-sis630. |
430 | 420 | ||
431 | config I2C_SIS96X | 421 | config I2C_SIS96X |
432 | tristate "SiS 96x" | 422 | tristate "SiS 96x" |
433 | depends on I2C && PCI | 423 | depends on I2C && PCI |
434 | help | 424 | help |
435 | If you say yes to this option, support will be included for the SiS | 425 | If you say yes to this option, support will be included for the SiS |
436 | 96x SMBus (a subset of I2C) interfaces. Specifically, the following | 426 | 96x SMBus (a subset of I2C) interfaces. Specifically, the following |
437 | chipsets are supported: | 427 | chipsets are supported: |
438 | 645/961 | 428 | 645/961 |
439 | 645DX/961 | 429 | 645DX/961 |
440 | 645DX/962 | 430 | 645DX/962 |
441 | 648/961 | 431 | 648/961 |
442 | 650/961 | 432 | 650/961 |
443 | 735 | 433 | 735 |
444 | 745 | 434 | 745 |
445 | 435 | ||
446 | This driver can also be built as a module. If so, the module | 436 | This driver can also be built as a module. If so, the module |
447 | will be called i2c-sis96x. | 437 | will be called i2c-sis96x. |
448 | 438 | ||
449 | config I2C_STUB | 439 | config I2C_STUB |
450 | tristate "I2C/SMBus Test Stub" | 440 | tristate "I2C/SMBus Test Stub" |
451 | depends on I2C && EXPERIMENTAL && 'm' | 441 | depends on I2C && EXPERIMENTAL && 'm' |
452 | default 'n' | 442 | default 'n' |
453 | help | 443 | help |
454 | This module may be useful to developers of SMBus client drivers, | 444 | This module may be useful to developers of SMBus client drivers, |
455 | especially for certain kinds of sensor chips. | 445 | especially for certain kinds of sensor chips. |
456 | 446 | ||
457 | If you do build this module, be sure to read the notes and warnings | 447 | If you do build this module, be sure to read the notes and warnings |
458 | in <file:Documentation/i2c/i2c-stub>. | 448 | in <file:Documentation/i2c/i2c-stub>. |
459 | 449 | ||
460 | If you don't know what to do here, definitely say N. | 450 | If you don't know what to do here, definitely say N. |
461 | 451 | ||
462 | config I2C_VIA | 452 | config I2C_VIA |
463 | tristate "VIA 82C586B" | 453 | tristate "VIA 82C586B" |
464 | depends on I2C && PCI && EXPERIMENTAL | 454 | depends on I2C && PCI && EXPERIMENTAL |
465 | select I2C_ALGOBIT | 455 | select I2C_ALGOBIT |
466 | help | 456 | help |
467 | If you say yes to this option, support will be included for the VIA | 457 | If you say yes to this option, support will be included for the VIA |
468 | 82C586B I2C interface | 458 | 82C586B I2C interface |
469 | 459 | ||
470 | This driver can also be built as a module. If so, the module | 460 | This driver can also be built as a module. If so, the module |
471 | will be called i2c-via. | 461 | will be called i2c-via. |
472 | 462 | ||
473 | config I2C_VIAPRO | 463 | config I2C_VIAPRO |
474 | tristate "VIA 82C596/82C686/823x" | 464 | tristate "VIA 82C596/82C686/823x" |
475 | depends on I2C && PCI | 465 | depends on I2C && PCI |
476 | help | 466 | help |
477 | If you say yes to this option, support will be included for the VIA | 467 | If you say yes to this option, support will be included for the VIA |
478 | 82C596/82C686/823x I2C interfaces. Specifically, the following | 468 | 82C596/82C686/823x I2C interfaces. Specifically, the following |
479 | chipsets are supported: | 469 | chipsets are supported: |
480 | 82C596A/B | 470 | 82C596A/B |
481 | 82C686A/B | 471 | 82C686A/B |
482 | 8231 | 472 | 8231 |
483 | 8233 | 473 | 8233 |
484 | 8233A | 474 | 8233A |
485 | 8235 | 475 | 8235 |
486 | 8237 | 476 | 8237 |
487 | 477 | ||
488 | This driver can also be built as a module. If so, the module | 478 | This driver can also be built as a module. If so, the module |
489 | will be called i2c-viapro. | 479 | will be called i2c-viapro. |
490 | 480 | ||
491 | config I2C_VOODOO3 | 481 | config I2C_VOODOO3 |
492 | tristate "Voodoo 3" | 482 | tristate "Voodoo 3" |
493 | depends on I2C && PCI | 483 | depends on I2C && PCI |
494 | select I2C_ALGOBIT | 484 | select I2C_ALGOBIT |
495 | help | 485 | help |
496 | If you say yes to this option, support will be included for the | 486 | If you say yes to this option, support will be included for the |
497 | Voodoo 3 I2C interface. | 487 | Voodoo 3 I2C interface. |
498 | 488 | ||
499 | This driver can also be built as a module. If so, the module | 489 | This driver can also be built as a module. If so, the module |
500 | will be called i2c-voodoo3. | 490 | will be called i2c-voodoo3. |
501 | 491 | ||
502 | config I2C_PCA_ISA | 492 | config I2C_PCA_ISA |
503 | tristate "PCA9564 on an ISA bus" | 493 | tristate "PCA9564 on an ISA bus" |
504 | depends on I2C | 494 | depends on I2C |
505 | select I2C_ALGOPCA | 495 | select I2C_ALGOPCA |
506 | help | 496 | help |
507 | This driver supports ISA boards using the Philips PCA 9564 | 497 | This driver supports ISA boards using the Philips PCA 9564 |
508 | Parallel bus to I2C bus controller | 498 | Parallel bus to I2C bus controller |
509 | 499 | ||
510 | This driver can also be built as a module. If so, the module | 500 | This driver can also be built as a module. If so, the module |
511 | will be called i2c-pca-isa. | 501 | will be called i2c-pca-isa. |
512 | 502 | ||
513 | config I2C_MV64XXX | 503 | config I2C_MV64XXX |
514 | tristate "Marvell mv64xxx I2C Controller" | 504 | tristate "Marvell mv64xxx I2C Controller" |
515 | depends on I2C && MV64X60 && EXPERIMENTAL | 505 | depends on I2C && MV64X60 && EXPERIMENTAL |
516 | help | 506 | help |
517 | If you say yes to this option, support will be included for the | 507 | If you say yes to this option, support will be included for the |
518 | built-in I2C interface on the Marvell 64xxx line of host bridges. | 508 | built-in I2C interface on the Marvell 64xxx line of host bridges. |
519 | 509 | ||
520 | This driver can also be built as a module. If so, the module | 510 | This driver can also be built as a module. If so, the module |
521 | will be called i2c-mv64xxx. | 511 | will be called i2c-mv64xxx. |
522 | 512 |
drivers/i2c/busses/Makefile
1 | # | 1 | # |
2 | # Makefile for the i2c bus drivers. | 2 | # Makefile for the i2c bus drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o | 5 | obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o |
6 | obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o | 6 | obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o |
7 | obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o | 7 | obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o |
8 | obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o | 8 | obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o |
9 | obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o | 9 | obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o |
10 | obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o | 10 | obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o |
11 | obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o | 11 | obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o |
12 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o | 12 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o |
13 | obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o | 13 | obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o |
14 | obj-$(CONFIG_I2C_I801) += i2c-i801.o | 14 | obj-$(CONFIG_I2C_I801) += i2c-i801.o |
15 | obj-$(CONFIG_I2C_I810) += i2c-i810.o | 15 | obj-$(CONFIG_I2C_I810) += i2c-i810.o |
16 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o | 16 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o |
17 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o | 17 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o |
18 | obj-$(CONFIG_I2C_ISA) += i2c-isa.o | 18 | obj-$(CONFIG_I2C_ISA) += i2c-isa.o |
19 | obj-$(CONFIG_I2C_ITE) += i2c-ite.o | 19 | obj-$(CONFIG_I2C_ITE) += i2c-ite.o |
20 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o | 20 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o |
21 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o | 21 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o |
22 | obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o | 22 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o |
23 | obj-$(CONFIG_I2C_PMAC_SMU) += i2c-pmac-smu.o | ||
24 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o | 23 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o |
25 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o | 24 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o |
26 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o | 25 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o |
27 | obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o | 26 | obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o |
28 | obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o | 27 | obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o |
29 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o | 28 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o |
30 | obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o | 29 | obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o |
31 | obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o | 30 | obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o |
32 | obj-$(CONFIG_I2C_PXA) += i2c-pxa.o | 31 | obj-$(CONFIG_I2C_PXA) += i2c-pxa.o |
33 | obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o | 32 | obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o |
34 | obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o | 33 | obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o |
35 | obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o | 34 | obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o |
36 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o | 35 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o |
37 | obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o | 36 | obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o |
38 | obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o | 37 | obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o |
39 | obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o | 38 | obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o |
40 | obj-$(CONFIG_I2C_STUB) += i2c-stub.o | 39 | obj-$(CONFIG_I2C_STUB) += i2c-stub.o |
41 | obj-$(CONFIG_I2C_VIA) += i2c-via.o | 40 | obj-$(CONFIG_I2C_VIA) += i2c-via.o |
42 | obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o | 41 | obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o |
43 | obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o | 42 | obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o |
44 | obj-$(CONFIG_SCx200_ACB) += scx200_acb.o | 43 | obj-$(CONFIG_SCx200_ACB) += scx200_acb.o |
45 | obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o | 44 | obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o |
46 | 45 | ||
47 | ifeq ($(CONFIG_I2C_DEBUG_BUS),y) | 46 | ifeq ($(CONFIG_I2C_DEBUG_BUS),y) |
48 | EXTRA_CFLAGS += -DDEBUG | 47 | EXTRA_CFLAGS += -DDEBUG |
49 | endif | 48 | endif |
50 | 49 |
drivers/i2c/busses/i2c-keywest.c
1 | /* | File was deleted | |
2 | i2c Support for Apple Keywest I2C Bus Controller | ||
3 | |||
4 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
5 | |||
6 | Original work by | ||
7 | |||
8 | Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | |||
24 | Changes: | ||
25 | |||
26 | 2001/12/13 BenH New implementation | ||
27 | 2001/12/15 BenH Add support for "byte" and "quick" | ||
28 | transfers. Add i2c_xfer routine. | ||
29 | 2003/09/21 BenH Rework state machine with Paulus help | ||
30 | 2004/01/21 BenH Merge in Greg KH changes, polled mode is back | ||
31 | 2004/02/05 BenH Merge 64 bits fixes from the g5 ppc64 tree | ||
32 | |||
33 | My understanding of the various modes supported by keywest are: | ||
34 | |||
35 | - Dumb mode : not implemented, probably direct tweaking of lines | ||
36 | - Standard mode : simple i2c transaction of type | ||
37 | S Addr R/W A Data A Data ... T | ||
38 | - Standard sub mode : combined 8 bit subaddr write with data read | ||
39 | S Addr R/W A SubAddr A Data A Data ... T | ||
40 | - Combined mode : Subaddress and Data sequences appended with no stop | ||
41 | S Addr R/W A SubAddr S Addr R/W A Data A Data ... T | ||
42 | |||
43 | Currently, this driver uses only Standard mode for i2c xfer, and | ||
44 | smbus byte & quick transfers ; and uses StandardSub mode for | ||
45 | other smbus transfers instead of combined as we need that for the | ||
46 | sound driver to be happy | ||
47 | */ | ||
48 | |||
49 | #include <linux/module.h> | ||
50 | #include <linux/kernel.h> | ||
51 | #include <linux/ioport.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/types.h> | ||
54 | #include <linux/delay.h> | ||
55 | #include <linux/i2c.h> | ||
56 | #include <linux/init.h> | ||
57 | #include <linux/mm.h> | ||
58 | #include <linux/timer.h> | ||
59 | #include <linux/spinlock.h> | ||
60 | #include <linux/completion.h> | ||
61 | #include <linux/interrupt.h> | ||
62 | |||
63 | #include <asm/io.h> | ||
64 | #include <asm/prom.h> | ||
65 | #include <asm/machdep.h> | ||
66 | #include <asm/pmac_feature.h> | ||
67 | #include <asm/pmac_low_i2c.h> | ||
68 | |||
69 | #include "i2c-keywest.h" | ||
70 | |||
71 | #undef POLLED_MODE | ||
72 | |||
73 | /* Some debug macros */ | ||
74 | #define WRONG_STATE(name) do {\ | ||
75 | pr_debug("KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ | ||
76 | name, __kw_state_names[iface->state], isr); \ | ||
77 | } while(0) | ||
78 | |||
79 | #ifdef DEBUG | ||
80 | static const char *__kw_state_names[] = { | ||
81 | "state_idle", | ||
82 | "state_addr", | ||
83 | "state_read", | ||
84 | "state_write", | ||
85 | "state_stop", | ||
86 | "state_dead" | ||
87 | }; | ||
88 | #endif /* DEBUG */ | ||
89 | |||
90 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
91 | MODULE_DESCRIPTION("I2C driver for Apple's Keywest"); | ||
92 | MODULE_LICENSE("GPL"); | ||
93 | |||
94 | #ifdef POLLED_MODE | ||
95 | /* Don't schedule, the g5 fan controller is too | ||
96 | * timing sensitive | ||
97 | */ | ||
98 | static u8 | ||
99 | wait_interrupt(struct keywest_iface* iface) | ||
100 | { | ||
101 | int i; | ||
102 | u8 isr; | ||
103 | |||
104 | for (i = 0; i < 200000; i++) { | ||
105 | isr = read_reg(reg_isr) & KW_I2C_IRQ_MASK; | ||
106 | if (isr != 0) | ||
107 | return isr; | ||
108 | udelay(10); | ||
109 | } | ||
110 | return isr; | ||
111 | } | ||
112 | #endif /* POLLED_MODE */ | ||
113 | |||
114 | static void | ||
115 | do_stop(struct keywest_iface* iface, int result) | ||
116 | { | ||
117 | write_reg(reg_control, KW_I2C_CTL_STOP); | ||
118 | iface->state = state_stop; | ||
119 | iface->result = result; | ||
120 | } | ||
121 | |||
122 | /* Main state machine for standard & standard sub mode */ | ||
123 | static void | ||
124 | handle_interrupt(struct keywest_iface *iface, u8 isr) | ||
125 | { | ||
126 | int ack; | ||
127 | |||
128 | if (isr == 0) { | ||
129 | if (iface->state != state_stop) { | ||
130 | pr_debug("KW: Timeout !\n"); | ||
131 | do_stop(iface, -EIO); | ||
132 | } | ||
133 | if (iface->state == state_stop) { | ||
134 | ack = read_reg(reg_status); | ||
135 | if (!(ack & KW_I2C_STAT_BUSY)) { | ||
136 | iface->state = state_idle; | ||
137 | write_reg(reg_ier, 0x00); | ||
138 | #ifndef POLLED_MODE | ||
139 | complete(&iface->complete); | ||
140 | #endif /* POLLED_MODE */ | ||
141 | } | ||
142 | } | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | if (isr & KW_I2C_IRQ_ADDR) { | ||
147 | ack = read_reg(reg_status); | ||
148 | if (iface->state != state_addr) { | ||
149 | write_reg(reg_isr, KW_I2C_IRQ_ADDR); | ||
150 | WRONG_STATE("KW_I2C_IRQ_ADDR"); | ||
151 | do_stop(iface, -EIO); | ||
152 | return; | ||
153 | } | ||
154 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | ||
155 | iface->state = state_stop; | ||
156 | iface->result = -ENODEV; | ||
157 | pr_debug("KW: NAK on address\n"); | ||
158 | } else { | ||
159 | /* Handle rw "quick" mode */ | ||
160 | if (iface->datalen == 0) { | ||
161 | do_stop(iface, 0); | ||
162 | } else if (iface->read_write == I2C_SMBUS_READ) { | ||
163 | iface->state = state_read; | ||
164 | if (iface->datalen > 1) | ||
165 | write_reg(reg_control, KW_I2C_CTL_AAK); | ||
166 | } else { | ||
167 | iface->state = state_write; | ||
168 | write_reg(reg_data, *(iface->data++)); | ||
169 | iface->datalen--; | ||
170 | } | ||
171 | } | ||
172 | write_reg(reg_isr, KW_I2C_IRQ_ADDR); | ||
173 | } | ||
174 | |||
175 | if (isr & KW_I2C_IRQ_DATA) { | ||
176 | if (iface->state == state_read) { | ||
177 | *(iface->data++) = read_reg(reg_data); | ||
178 | write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
179 | iface->datalen--; | ||
180 | if (iface->datalen == 0) | ||
181 | iface->state = state_stop; | ||
182 | else if (iface->datalen == 1) | ||
183 | write_reg(reg_control, 0); | ||
184 | } else if (iface->state == state_write) { | ||
185 | /* Check ack status */ | ||
186 | ack = read_reg(reg_status); | ||
187 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | ||
188 | pr_debug("KW: nack on data write (%x): %x\n", | ||
189 | iface->data[-1], ack); | ||
190 | do_stop(iface, -EIO); | ||
191 | } else if (iface->datalen) { | ||
192 | write_reg(reg_data, *(iface->data++)); | ||
193 | iface->datalen--; | ||
194 | } else { | ||
195 | write_reg(reg_control, KW_I2C_CTL_STOP); | ||
196 | iface->state = state_stop; | ||
197 | iface->result = 0; | ||
198 | } | ||
199 | write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
200 | } else { | ||
201 | write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
202 | WRONG_STATE("KW_I2C_IRQ_DATA"); | ||
203 | if (iface->state != state_stop) | ||
204 | do_stop(iface, -EIO); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | if (isr & KW_I2C_IRQ_STOP) { | ||
209 | write_reg(reg_isr, KW_I2C_IRQ_STOP); | ||
210 | if (iface->state != state_stop) { | ||
211 | WRONG_STATE("KW_I2C_IRQ_STOP"); | ||
212 | iface->result = -EIO; | ||
213 | } | ||
214 | iface->state = state_idle; | ||
215 | write_reg(reg_ier, 0x00); | ||
216 | #ifndef POLLED_MODE | ||
217 | complete(&iface->complete); | ||
218 | #endif /* POLLED_MODE */ | ||
219 | } | ||
220 | |||
221 | if (isr & KW_I2C_IRQ_START) | ||
222 | write_reg(reg_isr, KW_I2C_IRQ_START); | ||
223 | } | ||
224 | |||
225 | #ifndef POLLED_MODE | ||
226 | |||
227 | /* Interrupt handler */ | ||
228 | static irqreturn_t | ||
229 | keywest_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
230 | { | ||
231 | struct keywest_iface *iface = (struct keywest_iface *)dev_id; | ||
232 | unsigned long flags; | ||
233 | |||
234 | spin_lock_irqsave(&iface->lock, flags); | ||
235 | del_timer(&iface->timeout_timer); | ||
236 | handle_interrupt(iface, read_reg(reg_isr)); | ||
237 | if (iface->state != state_idle) { | ||
238 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; | ||
239 | add_timer(&iface->timeout_timer); | ||
240 | } | ||
241 | spin_unlock_irqrestore(&iface->lock, flags); | ||
242 | return IRQ_HANDLED; | ||
243 | } | ||
244 | |||
245 | static void | ||
246 | keywest_timeout(unsigned long data) | ||
247 | { | ||
248 | struct keywest_iface *iface = (struct keywest_iface *)data; | ||
249 | unsigned long flags; | ||
250 | |||
251 | pr_debug("timeout !\n"); | ||
252 | spin_lock_irqsave(&iface->lock, flags); | ||
253 | handle_interrupt(iface, read_reg(reg_isr)); | ||
254 | if (iface->state != state_idle) { | ||
255 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; | ||
256 | add_timer(&iface->timeout_timer); | ||
257 | } | ||
258 | spin_unlock_irqrestore(&iface->lock, flags); | ||
259 | } | ||
260 | |||
261 | #endif /* POLLED_MODE */ | ||
262 | |||
263 | /* | ||
264 | * SMBUS-type transfer entrypoint | ||
265 | */ | ||
266 | static s32 | ||
267 | keywest_smbus_xfer( struct i2c_adapter* adap, | ||
268 | u16 addr, | ||
269 | unsigned short flags, | ||
270 | char read_write, | ||
271 | u8 command, | ||
272 | int size, | ||
273 | union i2c_smbus_data* data) | ||
274 | { | ||
275 | struct keywest_chan* chan = i2c_get_adapdata(adap); | ||
276 | struct keywest_iface* iface = chan->iface; | ||
277 | int len; | ||
278 | u8* buffer; | ||
279 | u16 cur_word; | ||
280 | int rc = 0; | ||
281 | |||
282 | if (iface->state == state_dead) | ||
283 | return -ENXIO; | ||
284 | |||
285 | /* Prepare datas & select mode */ | ||
286 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; | ||
287 | switch (size) { | ||
288 | case I2C_SMBUS_QUICK: | ||
289 | len = 0; | ||
290 | buffer = NULL; | ||
291 | iface->cur_mode |= KW_I2C_MODE_STANDARD; | ||
292 | break; | ||
293 | case I2C_SMBUS_BYTE: | ||
294 | len = 1; | ||
295 | buffer = &data->byte; | ||
296 | iface->cur_mode |= KW_I2C_MODE_STANDARD; | ||
297 | break; | ||
298 | case I2C_SMBUS_BYTE_DATA: | ||
299 | len = 1; | ||
300 | buffer = &data->byte; | ||
301 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; | ||
302 | break; | ||
303 | case I2C_SMBUS_WORD_DATA: | ||
304 | len = 2; | ||
305 | cur_word = cpu_to_le16(data->word); | ||
306 | buffer = (u8 *)&cur_word; | ||
307 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; | ||
308 | break; | ||
309 | case I2C_SMBUS_BLOCK_DATA: | ||
310 | len = data->block[0]; | ||
311 | buffer = &data->block[1]; | ||
312 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; | ||
313 | break; | ||
314 | default: | ||
315 | return -1; | ||
316 | } | ||
317 | |||
318 | /* Turn a standardsub read into a combined mode access */ | ||
319 | if (read_write == I2C_SMBUS_READ | ||
320 | && (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB) { | ||
321 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; | ||
322 | iface->cur_mode |= KW_I2C_MODE_COMBINED; | ||
323 | } | ||
324 | |||
325 | /* Original driver had this limitation */ | ||
326 | if (len > 32) | ||
327 | len = 32; | ||
328 | |||
329 | if (pmac_low_i2c_lock(iface->node)) | ||
330 | return -ENXIO; | ||
331 | |||
332 | pr_debug("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n", | ||
333 | chan->chan_no, addr, len, read_write == I2C_SMBUS_READ); | ||
334 | |||
335 | iface->data = buffer; | ||
336 | iface->datalen = len; | ||
337 | iface->state = state_addr; | ||
338 | iface->result = 0; | ||
339 | iface->read_write = read_write; | ||
340 | |||
341 | /* Setup channel & clear pending irqs */ | ||
342 | write_reg(reg_isr, read_reg(reg_isr)); | ||
343 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); | ||
344 | write_reg(reg_status, 0); | ||
345 | |||
346 | /* Set up address and r/w bit */ | ||
347 | write_reg(reg_addr, | ||
348 | (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); | ||
349 | |||
350 | /* Set up the sub address */ | ||
351 | if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB | ||
352 | || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) | ||
353 | write_reg(reg_subaddr, command); | ||
354 | |||
355 | #ifndef POLLED_MODE | ||
356 | /* Arm timeout */ | ||
357 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; | ||
358 | add_timer(&iface->timeout_timer); | ||
359 | #endif | ||
360 | |||
361 | /* Start sending address & enable interrupt*/ | ||
362 | write_reg(reg_control, KW_I2C_CTL_XADDR); | ||
363 | write_reg(reg_ier, KW_I2C_IRQ_MASK); | ||
364 | |||
365 | #ifdef POLLED_MODE | ||
366 | pr_debug("using polled mode...\n"); | ||
367 | /* State machine, to turn into an interrupt handler */ | ||
368 | while(iface->state != state_idle) { | ||
369 | unsigned long flags; | ||
370 | |||
371 | u8 isr = wait_interrupt(iface); | ||
372 | spin_lock_irqsave(&iface->lock, flags); | ||
373 | handle_interrupt(iface, isr); | ||
374 | spin_unlock_irqrestore(&iface->lock, flags); | ||
375 | } | ||
376 | #else /* POLLED_MODE */ | ||
377 | pr_debug("using interrupt mode...\n"); | ||
378 | wait_for_completion(&iface->complete); | ||
379 | #endif /* POLLED_MODE */ | ||
380 | |||
381 | rc = iface->result; | ||
382 | pr_debug("transfer done, result: %d\n", rc); | ||
383 | |||
384 | if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ) | ||
385 | data->word = le16_to_cpu(cur_word); | ||
386 | |||
387 | /* Release sem */ | ||
388 | pmac_low_i2c_unlock(iface->node); | ||
389 | |||
390 | return rc; | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * Generic i2c master transfer entrypoint | ||
395 | */ | ||
396 | static int | ||
397 | keywest_xfer( struct i2c_adapter *adap, | ||
398 | struct i2c_msg *msgs, | ||
399 | int num) | ||
400 | { | ||
401 | struct keywest_chan* chan = i2c_get_adapdata(adap); | ||
402 | struct keywest_iface* iface = chan->iface; | ||
403 | struct i2c_msg *pmsg; | ||
404 | int i, completed; | ||
405 | int rc = 0; | ||
406 | |||
407 | if (iface->state == state_dead) | ||
408 | return -ENXIO; | ||
409 | |||
410 | if (pmac_low_i2c_lock(iface->node)) | ||
411 | return -ENXIO; | ||
412 | |||
413 | /* Set adapter to standard mode */ | ||
414 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; | ||
415 | iface->cur_mode |= KW_I2C_MODE_STANDARD; | ||
416 | |||
417 | completed = 0; | ||
418 | for (i = 0; rc >= 0 && i < num;) { | ||
419 | u8 addr; | ||
420 | |||
421 | pmsg = &msgs[i++]; | ||
422 | addr = pmsg->addr; | ||
423 | if (pmsg->flags & I2C_M_TEN) { | ||
424 | printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n"); | ||
425 | rc = -EINVAL; | ||
426 | break; | ||
427 | } | ||
428 | pr_debug("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n", | ||
429 | chan->chan_no, | ||
430 | pmsg->flags & I2C_M_RD ? "read" : "write", | ||
431 | pmsg->len, addr, i, num); | ||
432 | |||
433 | /* Setup channel & clear pending irqs */ | ||
434 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); | ||
435 | write_reg(reg_isr, read_reg(reg_isr)); | ||
436 | write_reg(reg_status, 0); | ||
437 | |||
438 | iface->data = pmsg->buf; | ||
439 | iface->datalen = pmsg->len; | ||
440 | iface->state = state_addr; | ||
441 | iface->result = 0; | ||
442 | if (pmsg->flags & I2C_M_RD) | ||
443 | iface->read_write = I2C_SMBUS_READ; | ||
444 | else | ||
445 | iface->read_write = I2C_SMBUS_WRITE; | ||
446 | |||
447 | /* Set up address and r/w bit */ | ||
448 | if (pmsg->flags & I2C_M_REV_DIR_ADDR) | ||
449 | addr ^= 1; | ||
450 | write_reg(reg_addr, | ||
451 | (addr << 1) | | ||
452 | ((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); | ||
453 | |||
454 | #ifndef POLLED_MODE | ||
455 | /* Arm timeout */ | ||
456 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; | ||
457 | add_timer(&iface->timeout_timer); | ||
458 | #endif | ||
459 | |||
460 | /* Start sending address & enable interrupt*/ | ||
461 | write_reg(reg_ier, KW_I2C_IRQ_MASK); | ||
462 | write_reg(reg_control, KW_I2C_CTL_XADDR); | ||
463 | |||
464 | #ifdef POLLED_MODE | ||
465 | pr_debug("using polled mode...\n"); | ||
466 | /* State machine, to turn into an interrupt handler */ | ||
467 | while(iface->state != state_idle) { | ||
468 | u8 isr = wait_interrupt(iface); | ||
469 | handle_interrupt(iface, isr); | ||
470 | } | ||
471 | #else /* POLLED_MODE */ | ||
472 | pr_debug("using interrupt mode...\n"); | ||
473 | wait_for_completion(&iface->complete); | ||
474 | #endif /* POLLED_MODE */ | ||
475 | |||
476 | rc = iface->result; | ||
477 | if (rc == 0) | ||
478 | completed++; | ||
479 | pr_debug("transfer done, result: %d\n", rc); | ||
480 | } | ||
481 | |||
482 | /* Release sem */ | ||
483 | pmac_low_i2c_unlock(iface->node); | ||
484 | |||
485 | return completed; | ||
486 | } | ||
487 | |||
488 | static u32 | ||
489 | keywest_func(struct i2c_adapter * adapter) | ||
490 | { | ||
491 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | ||
492 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | ||
493 | I2C_FUNC_SMBUS_BLOCK_DATA; | ||
494 | } | ||
495 | |||
496 | /* For now, we only handle combined mode (smbus) */ | ||
497 | static struct i2c_algorithm keywest_algorithm = { | ||
498 | .smbus_xfer = keywest_smbus_xfer, | ||
499 | .master_xfer = keywest_xfer, | ||
500 | .functionality = keywest_func, | ||
501 | }; | ||
502 | |||
503 | |||
504 | static int | ||
505 | create_iface(struct device_node *np, struct device *dev) | ||
506 | { | ||
507 | unsigned long steps; | ||
508 | unsigned bsteps, tsize, i, nchan; | ||
509 | struct keywest_iface* iface; | ||
510 | u32 *psteps, *prate, *addrp; | ||
511 | int rc; | ||
512 | |||
513 | if (np->n_intrs < 1) { | ||
514 | printk(KERN_ERR "%s: Missing interrupt !\n", | ||
515 | np->full_name); | ||
516 | return -ENODEV; | ||
517 | } | ||
518 | addrp = (u32 *)get_property(np, "AAPL,address", NULL); | ||
519 | if (addrp == NULL) { | ||
520 | printk(KERN_ERR "%s: Can't find address !\n", | ||
521 | np->full_name); | ||
522 | return -ENODEV; | ||
523 | } | ||
524 | |||
525 | if (pmac_low_i2c_lock(np)) | ||
526 | return -ENODEV; | ||
527 | |||
528 | psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); | ||
529 | steps = psteps ? (*psteps) : 0x10; | ||
530 | |||
531 | /* Hrm... maybe we can be smarter here */ | ||
532 | for (bsteps = 0; (steps & 0x01) == 0; bsteps++) | ||
533 | steps >>= 1; | ||
534 | |||
535 | if (np->parent->name[0] == 'u') | ||
536 | nchan = 2; | ||
537 | else | ||
538 | nchan = 1; | ||
539 | |||
540 | tsize = sizeof(struct keywest_iface) + | ||
541 | (sizeof(struct keywest_chan) + 4) * nchan; | ||
542 | iface = kzalloc(tsize, GFP_KERNEL); | ||
543 | if (iface == NULL) { | ||
544 | printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); | ||
545 | pmac_low_i2c_unlock(np); | ||
546 | return -ENOMEM; | ||
547 | } | ||
548 | spin_lock_init(&iface->lock); | ||
549 | init_completion(&iface->complete); | ||
550 | iface->node = of_node_get(np); | ||
551 | iface->bsteps = bsteps; | ||
552 | iface->chan_count = nchan; | ||
553 | iface->state = state_idle; | ||
554 | iface->irq = np->intrs[0].line; | ||
555 | iface->channels = (struct keywest_chan *) | ||
556 | (((unsigned long)(iface + 1) + 3UL) & ~3UL); | ||
557 | iface->base = ioremap(*addrp, 0x1000); | ||
558 | if (!iface->base) { | ||
559 | printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); | ||
560 | kfree(iface); | ||
561 | pmac_low_i2c_unlock(np); | ||
562 | return -ENOMEM; | ||
563 | } | ||
564 | |||
565 | #ifndef POLLED_MODE | ||
566 | init_timer(&iface->timeout_timer); | ||
567 | iface->timeout_timer.function = keywest_timeout; | ||
568 | iface->timeout_timer.data = (unsigned long)iface; | ||
569 | #endif | ||
570 | |||
571 | /* Select interface rate */ | ||
572 | iface->cur_mode = KW_I2C_MODE_100KHZ; | ||
573 | prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); | ||
574 | if (prate) switch(*prate) { | ||
575 | case 100: | ||
576 | iface->cur_mode = KW_I2C_MODE_100KHZ; | ||
577 | break; | ||
578 | case 50: | ||
579 | iface->cur_mode = KW_I2C_MODE_50KHZ; | ||
580 | break; | ||
581 | case 25: | ||
582 | iface->cur_mode = KW_I2C_MODE_25KHZ; | ||
583 | break; | ||
584 | default: | ||
585 | printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n", | ||
586 | (long)*prate); | ||
587 | } | ||
588 | |||
589 | /* Select standard mode by default */ | ||
590 | iface->cur_mode |= KW_I2C_MODE_STANDARD; | ||
591 | |||
592 | /* Write mode */ | ||
593 | write_reg(reg_mode, iface->cur_mode); | ||
594 | |||
595 | /* Switch interrupts off & clear them*/ | ||
596 | write_reg(reg_ier, 0x00); | ||
597 | write_reg(reg_isr, KW_I2C_IRQ_MASK); | ||
598 | |||
599 | #ifndef POLLED_MODE | ||
600 | /* Request chip interrupt */ | ||
601 | rc = request_irq(iface->irq, keywest_irq, SA_INTERRUPT, "keywest i2c", iface); | ||
602 | if (rc) { | ||
603 | printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq); | ||
604 | iounmap(iface->base); | ||
605 | kfree(iface); | ||
606 | pmac_low_i2c_unlock(np); | ||
607 | return -ENODEV; | ||
608 | } | ||
609 | #endif /* POLLED_MODE */ | ||
610 | |||
611 | pmac_low_i2c_unlock(np); | ||
612 | dev_set_drvdata(dev, iface); | ||
613 | |||
614 | for (i=0; i<nchan; i++) { | ||
615 | struct keywest_chan* chan = &iface->channels[i]; | ||
616 | |||
617 | sprintf(chan->adapter.name, "%s %d", np->parent->name, i); | ||
618 | chan->iface = iface; | ||
619 | chan->chan_no = i; | ||
620 | chan->adapter.algo = &keywest_algorithm; | ||
621 | chan->adapter.algo_data = NULL; | ||
622 | chan->adapter.client_register = NULL; | ||
623 | chan->adapter.client_unregister = NULL; | ||
624 | i2c_set_adapdata(&chan->adapter, chan); | ||
625 | chan->adapter.dev.parent = dev; | ||
626 | |||
627 | rc = i2c_add_adapter(&chan->adapter); | ||
628 | if (rc) { | ||
629 | printk("i2c-keywest.c: Adapter %s registration failed\n", | ||
630 | chan->adapter.name); | ||
631 | i2c_set_adapdata(&chan->adapter, NULL); | ||
632 | } | ||
633 | } | ||
634 | |||
635 | printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", | ||
636 | np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | static int | ||
642 | dispose_iface(struct device *dev) | ||
643 | { | ||
644 | struct keywest_iface *iface = dev_get_drvdata(dev); | ||
645 | int i, rc; | ||
646 | |||
647 | /* Make sure we stop all activity */ | ||
648 | if (pmac_low_i2c_lock(iface->node)) | ||
649 | return -ENODEV; | ||
650 | |||
651 | #ifndef POLLED_MODE | ||
652 | spin_lock_irq(&iface->lock); | ||
653 | while (iface->state != state_idle) { | ||
654 | spin_unlock_irq(&iface->lock); | ||
655 | msleep(100); | ||
656 | spin_lock_irq(&iface->lock); | ||
657 | } | ||
658 | #endif /* POLLED_MODE */ | ||
659 | iface->state = state_dead; | ||
660 | #ifndef POLLED_MODE | ||
661 | spin_unlock_irq(&iface->lock); | ||
662 | free_irq(iface->irq, iface); | ||
663 | #endif /* POLLED_MODE */ | ||
664 | |||
665 | pmac_low_i2c_unlock(iface->node); | ||
666 | |||
667 | /* Release all channels */ | ||
668 | for (i=0; i<iface->chan_count; i++) { | ||
669 | struct keywest_chan* chan = &iface->channels[i]; | ||
670 | if (i2c_get_adapdata(&chan->adapter) == NULL) | ||
671 | continue; | ||
672 | rc = i2c_del_adapter(&chan->adapter); | ||
673 | i2c_set_adapdata(&chan->adapter, NULL); | ||
674 | /* We aren't that prepared to deal with this... */ | ||
675 | if (rc) | ||
676 | printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n"); | ||
677 | } | ||
678 | iounmap(iface->base); | ||
679 | dev_set_drvdata(dev, NULL); | ||
680 | of_node_put(iface->node); | ||
681 | kfree(iface); | ||
682 | |||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | static int | ||
687 | create_iface_macio(struct macio_dev* dev, const struct of_device_id *match) | ||
688 | { | ||
689 | return create_iface(dev->ofdev.node, &dev->ofdev.dev); | ||
690 | } | ||
691 | |||
692 | static int | ||
693 | dispose_iface_macio(struct macio_dev* dev) | ||
694 | { | ||
695 | return dispose_iface(&dev->ofdev.dev); | ||
696 | } | ||
697 | |||
698 | static int | ||
699 | create_iface_of_platform(struct of_device* dev, const struct of_device_id *match) | ||
700 | { | ||
701 | return create_iface(dev->node, &dev->dev); | ||
702 | } | ||
703 | |||
704 | static int | ||
705 | dispose_iface_of_platform(struct of_device* dev) | ||
706 | { | ||
707 | return dispose_iface(&dev->dev); | ||
708 | } | ||
709 | |||
710 | static struct of_device_id i2c_keywest_match[] = | ||
711 | { | ||
712 | { | ||
713 | .type = "i2c", | ||
714 | .compatible = "keywest" | ||
715 | }, | ||
716 | {}, | ||
717 | }; | ||
718 | |||
719 | static struct macio_driver i2c_keywest_macio_driver = | ||
720 | { | ||
721 | .owner = THIS_MODULE, | ||
722 | .name = "i2c-keywest", | ||
723 | .match_table = i2c_keywest_match, | ||
724 | .probe = create_iface_macio, | ||
725 | .remove = dispose_iface_macio | ||
726 | }; | ||
727 | |||
728 | static struct of_platform_driver i2c_keywest_of_platform_driver = | ||
729 | { | ||
730 | .owner = THIS_MODULE, | ||
731 | .name = "i2c-keywest", | ||
732 | .match_table = i2c_keywest_match, | ||
733 | .probe = create_iface_of_platform, | ||
734 | .remove = dispose_iface_of_platform | ||
735 | }; | ||
736 | |||
737 | static int __init | ||
738 | i2c_keywest_init(void) | ||
739 | { | ||
740 | of_register_driver(&i2c_keywest_of_platform_driver); | ||
741 | macio_register_driver(&i2c_keywest_macio_driver); | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | static void __exit | ||
747 | i2c_keywest_cleanup(void) | ||
748 | { | ||
749 | of_unregister_driver(&i2c_keywest_of_platform_driver); | ||
750 | macio_unregister_driver(&i2c_keywest_macio_driver); | ||
751 | } | ||
752 | |||
753 | module_init(i2c_keywest_init); | ||
754 | module_exit(i2c_keywest_cleanup); | ||
755 | 1 | /* |
drivers/i2c/busses/i2c-keywest.h
1 | #ifndef __I2C_KEYWEST_H__ | File was deleted | |
2 | #define __I2C_KEYWEST_H__ | ||
3 | |||
4 | /* The Tumbler audio equalizer can be really slow sometimes */ | ||
5 | #define POLL_TIMEOUT (2*HZ) | ||
6 | |||
7 | /* Register indices */ | ||
8 | typedef enum { | ||
9 | reg_mode = 0, | ||
10 | reg_control, | ||
11 | reg_status, | ||
12 | reg_isr, | ||
13 | reg_ier, | ||
14 | reg_addr, | ||
15 | reg_subaddr, | ||
16 | reg_data | ||
17 | } reg_t; | ||
18 | |||
19 | |||
20 | /* Mode register */ | ||
21 | #define KW_I2C_MODE_100KHZ 0x00 | ||
22 | #define KW_I2C_MODE_50KHZ 0x01 | ||
23 | #define KW_I2C_MODE_25KHZ 0x02 | ||
24 | #define KW_I2C_MODE_DUMB 0x00 | ||
25 | #define KW_I2C_MODE_STANDARD 0x04 | ||
26 | #define KW_I2C_MODE_STANDARDSUB 0x08 | ||
27 | #define KW_I2C_MODE_COMBINED 0x0C | ||
28 | #define KW_I2C_MODE_MODE_MASK 0x0C | ||
29 | #define KW_I2C_MODE_CHAN_MASK 0xF0 | ||
30 | |||
31 | /* Control register */ | ||
32 | #define KW_I2C_CTL_AAK 0x01 | ||
33 | #define KW_I2C_CTL_XADDR 0x02 | ||
34 | #define KW_I2C_CTL_STOP 0x04 | ||
35 | #define KW_I2C_CTL_START 0x08 | ||
36 | |||
37 | /* Status register */ | ||
38 | #define KW_I2C_STAT_BUSY 0x01 | ||
39 | #define KW_I2C_STAT_LAST_AAK 0x02 | ||
40 | #define KW_I2C_STAT_LAST_RW 0x04 | ||
41 | #define KW_I2C_STAT_SDA 0x08 | ||
42 | #define KW_I2C_STAT_SCL 0x10 | ||
43 | |||
44 | /* IER & ISR registers */ | ||
45 | #define KW_I2C_IRQ_DATA 0x01 | ||
46 | #define KW_I2C_IRQ_ADDR 0x02 | ||
47 | #define KW_I2C_IRQ_STOP 0x04 | ||
48 | #define KW_I2C_IRQ_START 0x08 | ||
49 | #define KW_I2C_IRQ_MASK 0x0F | ||
50 | |||
51 | /* Physical interface */ | ||
52 | struct keywest_iface | ||
53 | { | ||
54 | struct device_node *node; | ||
55 | void __iomem * base; | ||
56 | unsigned bsteps; | ||
57 | int irq; | ||
58 | spinlock_t lock; | ||
59 | struct keywest_chan *channels; | ||
60 | unsigned chan_count; | ||
61 | u8 cur_mode; | ||
62 | char read_write; | ||
63 | u8 *data; | ||
64 | unsigned datalen; | ||
65 | int state; | ||
66 | int result; | ||
67 | struct timer_list timeout_timer; | ||
68 | struct completion complete; | ||
69 | }; | ||
70 | |||
71 | enum { | ||
72 | state_idle, | ||
73 | state_addr, | ||
74 | state_read, | ||
75 | state_write, | ||
76 | state_stop, | ||
77 | state_dead | ||
78 | }; | ||
79 | |||
80 | /* Channel on an interface */ | ||
81 | struct keywest_chan | ||
82 | { | ||
83 | struct i2c_adapter adapter; | ||
84 | struct keywest_iface* iface; | ||
85 | unsigned chan_no; | ||
86 | }; | ||
87 | |||
88 | /* Register access */ | ||
89 | |||
90 | static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg) | ||
91 | { | ||
92 | return in_8(iface->base | ||
93 | + (((unsigned)reg) << iface->bsteps)); | ||
94 | } | ||
95 | |||
96 | static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val) | ||
97 | { | ||
98 | out_8(iface->base | ||
99 | + (((unsigned)reg) << iface->bsteps), val); | ||
100 | (void)__read_reg(iface, reg_subaddr); | ||
101 | } | ||
102 | |||
103 | #define write_reg(reg, val) __write_reg(iface, reg, val) | ||
104 | #define read_reg(reg) __read_reg(iface, reg) | ||
105 | |||
106 | |||
107 | |||
108 | #endif /* __I2C_KEYWEST_H__ */ | ||
109 | 1 | #ifndef __I2C_KEYWEST_H__ |
drivers/i2c/busses/i2c-pmac-smu.c
1 | /* | File was deleted | |
2 | i2c Support for Apple SMU Controller | ||
3 | |||
4 | Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp. | ||
5 | <benh@kernel.crashing.org> | ||
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; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/completion.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <asm/prom.h> | ||
32 | #include <asm/of_device.h> | ||
33 | #include <asm/smu.h> | ||
34 | |||
35 | static int probe; | ||
36 | |||
37 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
38 | MODULE_DESCRIPTION("I2C driver for Apple's SMU"); | ||
39 | MODULE_LICENSE("GPL"); | ||
40 | module_param(probe, bool, 0); | ||
41 | |||
42 | |||
43 | /* Physical interface */ | ||
44 | struct smu_iface | ||
45 | { | ||
46 | struct i2c_adapter adapter; | ||
47 | struct completion complete; | ||
48 | u32 busid; | ||
49 | }; | ||
50 | |||
51 | static void smu_i2c_done(struct smu_i2c_cmd *cmd, void *misc) | ||
52 | { | ||
53 | struct smu_iface *iface = misc; | ||
54 | complete(&iface->complete); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * SMBUS-type transfer entrypoint | ||
59 | */ | ||
60 | static s32 smu_smbus_xfer( struct i2c_adapter* adap, | ||
61 | u16 addr, | ||
62 | unsigned short flags, | ||
63 | char read_write, | ||
64 | u8 command, | ||
65 | int size, | ||
66 | union i2c_smbus_data* data) | ||
67 | { | ||
68 | struct smu_iface *iface = i2c_get_adapdata(adap); | ||
69 | struct smu_i2c_cmd cmd; | ||
70 | int rc = 0; | ||
71 | int read = (read_write == I2C_SMBUS_READ); | ||
72 | |||
73 | cmd.info.bus = iface->busid; | ||
74 | cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00); | ||
75 | |||
76 | /* Prepare datas & select mode */ | ||
77 | switch (size) { | ||
78 | case I2C_SMBUS_QUICK: | ||
79 | cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; | ||
80 | cmd.info.datalen = 0; | ||
81 | break; | ||
82 | case I2C_SMBUS_BYTE: | ||
83 | cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; | ||
84 | cmd.info.datalen = 1; | ||
85 | if (!read) | ||
86 | cmd.info.data[0] = data->byte; | ||
87 | break; | ||
88 | case I2C_SMBUS_BYTE_DATA: | ||
89 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
90 | cmd.info.datalen = 1; | ||
91 | cmd.info.sublen = 1; | ||
92 | cmd.info.subaddr[0] = command; | ||
93 | cmd.info.subaddr[1] = 0; | ||
94 | cmd.info.subaddr[2] = 0; | ||
95 | if (!read) | ||
96 | cmd.info.data[0] = data->byte; | ||
97 | break; | ||
98 | case I2C_SMBUS_WORD_DATA: | ||
99 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
100 | cmd.info.datalen = 2; | ||
101 | cmd.info.sublen = 1; | ||
102 | cmd.info.subaddr[0] = command; | ||
103 | cmd.info.subaddr[1] = 0; | ||
104 | cmd.info.subaddr[2] = 0; | ||
105 | if (!read) { | ||
106 | cmd.info.data[0] = data->word & 0xff; | ||
107 | cmd.info.data[1] = (data->word >> 8) & 0xff; | ||
108 | } | ||
109 | break; | ||
110 | /* Note that these are broken vs. the expected smbus API where | ||
111 | * on reads, the lenght is actually returned from the function, | ||
112 | * but I think the current API makes no sense and I don't want | ||
113 | * any driver that I haven't verified for correctness to go | ||
114 | * anywhere near a pmac i2c bus anyway ... | ||
115 | */ | ||
116 | case I2C_SMBUS_BLOCK_DATA: | ||
117 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
118 | cmd.info.datalen = data->block[0] + 1; | ||
119 | if (cmd.info.datalen > (SMU_I2C_WRITE_MAX + 1)) | ||
120 | return -EINVAL; | ||
121 | if (!read) | ||
122 | memcpy(cmd.info.data, data->block, cmd.info.datalen); | ||
123 | cmd.info.sublen = 1; | ||
124 | cmd.info.subaddr[0] = command; | ||
125 | cmd.info.subaddr[1] = 0; | ||
126 | cmd.info.subaddr[2] = 0; | ||
127 | break; | ||
128 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
129 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
130 | cmd.info.datalen = data->block[0]; | ||
131 | if (cmd.info.datalen > 7) | ||
132 | return -EINVAL; | ||
133 | if (!read) | ||
134 | memcpy(cmd.info.data, &data->block[1], | ||
135 | cmd.info.datalen); | ||
136 | cmd.info.sublen = 1; | ||
137 | cmd.info.subaddr[0] = command; | ||
138 | cmd.info.subaddr[1] = 0; | ||
139 | cmd.info.subaddr[2] = 0; | ||
140 | break; | ||
141 | |||
142 | default: | ||
143 | return -EINVAL; | ||
144 | } | ||
145 | |||
146 | /* Turn a standardsub read into a combined mode access */ | ||
147 | if (read_write == I2C_SMBUS_READ && | ||
148 | cmd.info.type == SMU_I2C_TRANSFER_STDSUB) | ||
149 | cmd.info.type = SMU_I2C_TRANSFER_COMBINED; | ||
150 | |||
151 | /* Finish filling command and submit it */ | ||
152 | cmd.done = smu_i2c_done; | ||
153 | cmd.misc = iface; | ||
154 | rc = smu_queue_i2c(&cmd); | ||
155 | if (rc < 0) | ||
156 | return rc; | ||
157 | wait_for_completion(&iface->complete); | ||
158 | rc = cmd.status; | ||
159 | |||
160 | if (!read || rc < 0) | ||
161 | return rc; | ||
162 | |||
163 | switch (size) { | ||
164 | case I2C_SMBUS_BYTE: | ||
165 | case I2C_SMBUS_BYTE_DATA: | ||
166 | data->byte = cmd.info.data[0]; | ||
167 | break; | ||
168 | case I2C_SMBUS_WORD_DATA: | ||
169 | data->word = ((u16)cmd.info.data[1]) << 8; | ||
170 | data->word |= cmd.info.data[0]; | ||
171 | break; | ||
172 | /* Note that these are broken vs. the expected smbus API where | ||
173 | * on reads, the lenght is actually returned from the function, | ||
174 | * but I think the current API makes no sense and I don't want | ||
175 | * any driver that I haven't verified for correctness to go | ||
176 | * anywhere near a pmac i2c bus anyway ... | ||
177 | */ | ||
178 | case I2C_SMBUS_BLOCK_DATA: | ||
179 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
180 | memcpy(&data->block[0], cmd.info.data, cmd.info.datalen); | ||
181 | break; | ||
182 | } | ||
183 | |||
184 | return rc; | ||
185 | } | ||
186 | |||
187 | static u32 | ||
188 | smu_smbus_func(struct i2c_adapter * adapter) | ||
189 | { | ||
190 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | ||
191 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | ||
192 | I2C_FUNC_SMBUS_BLOCK_DATA; | ||
193 | } | ||
194 | |||
195 | /* For now, we only handle combined mode (smbus) */ | ||
196 | static struct i2c_algorithm smu_algorithm = { | ||
197 | .smbus_xfer = smu_smbus_xfer, | ||
198 | .functionality = smu_smbus_func, | ||
199 | }; | ||
200 | |||
201 | static int create_iface(struct device_node *np, struct device *dev) | ||
202 | { | ||
203 | struct smu_iface* iface; | ||
204 | u32 *reg, busid; | ||
205 | int rc; | ||
206 | |||
207 | reg = (u32 *)get_property(np, "reg", NULL); | ||
208 | if (reg == NULL) { | ||
209 | printk(KERN_ERR "i2c-pmac-smu: can't find bus number !\n"); | ||
210 | return -ENXIO; | ||
211 | } | ||
212 | busid = *reg; | ||
213 | |||
214 | iface = kzalloc(sizeof(struct smu_iface), GFP_KERNEL); | ||
215 | if (iface == NULL) { | ||
216 | printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n"); | ||
217 | return -ENOMEM; | ||
218 | } | ||
219 | init_completion(&iface->complete); | ||
220 | iface->busid = busid; | ||
221 | |||
222 | dev_set_drvdata(dev, iface); | ||
223 | |||
224 | sprintf(iface->adapter.name, "smu-i2c-%02x", busid); | ||
225 | iface->adapter.algo = &smu_algorithm; | ||
226 | iface->adapter.algo_data = NULL; | ||
227 | iface->adapter.client_register = NULL; | ||
228 | iface->adapter.client_unregister = NULL; | ||
229 | i2c_set_adapdata(&iface->adapter, iface); | ||
230 | iface->adapter.dev.parent = dev; | ||
231 | |||
232 | rc = i2c_add_adapter(&iface->adapter); | ||
233 | if (rc) { | ||
234 | printk(KERN_ERR "i2c-pamc-smu.c: Adapter %s registration " | ||
235 | "failed\n", iface->adapter.name); | ||
236 | i2c_set_adapdata(&iface->adapter, NULL); | ||
237 | } | ||
238 | |||
239 | if (probe) { | ||
240 | unsigned char addr; | ||
241 | printk("Probe: "); | ||
242 | for (addr = 0x00; addr <= 0x7f; addr++) { | ||
243 | if (i2c_smbus_xfer(&iface->adapter,addr, | ||
244 | 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) | ||
245 | printk("%02x ", addr); | ||
246 | } | ||
247 | printk("\n"); | ||
248 | } | ||
249 | |||
250 | printk(KERN_INFO "SMU i2c bus %x registered\n", busid); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int dispose_iface(struct device *dev) | ||
256 | { | ||
257 | struct smu_iface *iface = dev_get_drvdata(dev); | ||
258 | int rc; | ||
259 | |||
260 | rc = i2c_del_adapter(&iface->adapter); | ||
261 | i2c_set_adapdata(&iface->adapter, NULL); | ||
262 | /* We aren't that prepared to deal with this... */ | ||
263 | if (rc) | ||
264 | printk("i2c-pmac-smu.c: Failed to remove bus %s !\n", | ||
265 | iface->adapter.name); | ||
266 | dev_set_drvdata(dev, NULL); | ||
267 | kfree(iface); | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | |||
273 | static int create_iface_of_platform(struct of_device* dev, | ||
274 | const struct of_device_id *match) | ||
275 | { | ||
276 | struct device_node *node = dev->node; | ||
277 | |||
278 | if (device_is_compatible(node, "smu-i2c") || | ||
279 | (node->parent != NULL && | ||
280 | device_is_compatible(node->parent, "smu-i2c-control"))) | ||
281 | return create_iface(node, &dev->dev); | ||
282 | return -ENODEV; | ||
283 | } | ||
284 | |||
285 | |||
286 | static int dispose_iface_of_platform(struct of_device* dev) | ||
287 | { | ||
288 | return dispose_iface(&dev->dev); | ||
289 | } | ||
290 | |||
291 | |||
292 | static struct of_device_id i2c_smu_match[] = | ||
293 | { | ||
294 | { | ||
295 | .compatible = "smu-i2c", | ||
296 | }, | ||
297 | { | ||
298 | .compatible = "i2c-bus", | ||
299 | }, | ||
300 | {}, | ||
301 | }; | ||
302 | static struct of_platform_driver i2c_smu_of_platform_driver = | ||
303 | { | ||
304 | .name = "i2c-smu", | ||
305 | .match_table = i2c_smu_match, | ||
306 | .probe = create_iface_of_platform, | ||
307 | .remove = dispose_iface_of_platform | ||
308 | }; | ||
309 | |||
310 | |||
311 | static int __init i2c_pmac_smu_init(void) | ||
312 | { | ||
313 | of_register_driver(&i2c_smu_of_platform_driver); | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | |||
318 | static void __exit i2c_pmac_smu_cleanup(void) | ||
319 | { | ||
320 | of_unregister_driver(&i2c_smu_of_platform_driver); | ||
321 | } | ||
322 | |||
323 | module_init(i2c_pmac_smu_init); | ||
324 | module_exit(i2c_pmac_smu_cleanup); | ||
325 | 1 | /* |
drivers/i2c/busses/i2c-powermac.c
File was created | 1 | /* | |
2 | i2c Support for Apple SMU Controller | ||
3 | |||
4 | Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp. | ||
5 | <benh@kernel.crashing.org> | ||
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; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/completion.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <asm/prom.h> | ||
33 | #include <asm/pmac_low_i2c.h> | ||
34 | |||
35 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
36 | MODULE_DESCRIPTION("I2C driver for Apple PowerMac"); | ||
37 | MODULE_LICENSE("GPL"); | ||
38 | |||
39 | /* | ||
40 | * SMBUS-type transfer entrypoint | ||
41 | */ | ||
42 | static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap, | ||
43 | u16 addr, | ||
44 | unsigned short flags, | ||
45 | char read_write, | ||
46 | u8 command, | ||
47 | int size, | ||
48 | union i2c_smbus_data* data) | ||
49 | { | ||
50 | struct pmac_i2c_bus *bus = i2c_get_adapdata(adap); | ||
51 | int rc = 0; | ||
52 | int read = (read_write == I2C_SMBUS_READ); | ||
53 | int addrdir = (addr << 1) | read; | ||
54 | u8 local[2]; | ||
55 | |||
56 | rc = pmac_i2c_open(bus, 0); | ||
57 | if (rc) | ||
58 | return rc; | ||
59 | |||
60 | switch (size) { | ||
61 | case I2C_SMBUS_QUICK: | ||
62 | rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); | ||
63 | if (rc) | ||
64 | goto bail; | ||
65 | rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0); | ||
66 | break; | ||
67 | case I2C_SMBUS_BYTE: | ||
68 | rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); | ||
69 | if (rc) | ||
70 | goto bail; | ||
71 | rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1); | ||
72 | break; | ||
73 | case I2C_SMBUS_BYTE_DATA: | ||
74 | rc = pmac_i2c_setmode(bus, read ? | ||
75 | pmac_i2c_mode_combined : | ||
76 | pmac_i2c_mode_stdsub); | ||
77 | if (rc) | ||
78 | goto bail; | ||
79 | rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1); | ||
80 | break; | ||
81 | case I2C_SMBUS_WORD_DATA: | ||
82 | rc = pmac_i2c_setmode(bus, read ? | ||
83 | pmac_i2c_mode_combined : | ||
84 | pmac_i2c_mode_stdsub); | ||
85 | if (rc) | ||
86 | goto bail; | ||
87 | if (!read) { | ||
88 | local[0] = data->word & 0xff; | ||
89 | local[1] = (data->word >> 8) & 0xff; | ||
90 | } | ||
91 | rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2); | ||
92 | if (rc == 0 && read) { | ||
93 | data->word = ((u16)local[1]) << 8; | ||
94 | data->word |= local[0]; | ||
95 | } | ||
96 | break; | ||
97 | |||
98 | /* Note that these are broken vs. the expected smbus API where | ||
99 | * on reads, the lenght is actually returned from the function, | ||
100 | * but I think the current API makes no sense and I don't want | ||
101 | * any driver that I haven't verified for correctness to go | ||
102 | * anywhere near a pmac i2c bus anyway ... | ||
103 | * | ||
104 | * I'm also not completely sure what kind of phases to do between | ||
105 | * the actual command and the data (what I am _supposed_ to do that | ||
106 | * is). For now, I assume writes are a single stream and reads have | ||
107 | * a repeat start/addr phase (but not stop in between) | ||
108 | */ | ||
109 | case I2C_SMBUS_BLOCK_DATA: | ||
110 | rc = pmac_i2c_setmode(bus, read ? | ||
111 | pmac_i2c_mode_combined : | ||
112 | pmac_i2c_mode_stdsub); | ||
113 | if (rc) | ||
114 | goto bail; | ||
115 | rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block, | ||
116 | data->block[0] + 1); | ||
117 | |||
118 | break; | ||
119 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
120 | rc = pmac_i2c_setmode(bus, read ? | ||
121 | pmac_i2c_mode_combined : | ||
122 | pmac_i2c_mode_stdsub); | ||
123 | if (rc) | ||
124 | goto bail; | ||
125 | rc = pmac_i2c_xfer(bus, addrdir, 1, command, | ||
126 | read ? data->block : &data->block[1], | ||
127 | data->block[0]); | ||
128 | break; | ||
129 | |||
130 | default: | ||
131 | rc = -EINVAL; | ||
132 | } | ||
133 | bail: | ||
134 | pmac_i2c_close(bus); | ||
135 | return rc; | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * Generic i2c master transfer entrypoint. This driver only support single | ||
140 | * messages (for "lame i2c" transfers). Anything else should use the smbus | ||
141 | * entry point | ||
142 | */ | ||
143 | static int i2c_powermac_master_xfer( struct i2c_adapter *adap, | ||
144 | struct i2c_msg *msgs, | ||
145 | int num) | ||
146 | { | ||
147 | struct pmac_i2c_bus *bus = i2c_get_adapdata(adap); | ||
148 | int rc = 0; | ||
149 | int read; | ||
150 | int addrdir; | ||
151 | |||
152 | if (num != 1) | ||
153 | return -EINVAL; | ||
154 | if (msgs->flags & I2C_M_TEN) | ||
155 | return -EINVAL; | ||
156 | read = (msgs->flags & I2C_M_RD) != 0; | ||
157 | addrdir = (msgs->addr << 1) | read; | ||
158 | if (msgs->flags & I2C_M_REV_DIR_ADDR) | ||
159 | addrdir ^= 1; | ||
160 | |||
161 | rc = pmac_i2c_open(bus, 0); | ||
162 | if (rc) | ||
163 | return rc; | ||
164 | rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); | ||
165 | if (rc) | ||
166 | goto bail; | ||
167 | rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); | ||
168 | bail: | ||
169 | pmac_i2c_close(bus); | ||
170 | return rc < 0 ? rc : msgs->len; | ||
171 | } | ||
172 | |||
173 | static u32 i2c_powermac_func(struct i2c_adapter * adapter) | ||
174 | { | ||
175 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | ||
176 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | ||
177 | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C; | ||
178 | } | ||
179 | |||
180 | /* For now, we only handle smbus */ | ||
181 | static struct i2c_algorithm i2c_powermac_algorithm = { | ||
182 | .smbus_xfer = i2c_powermac_smbus_xfer, | ||
183 | .master_xfer = i2c_powermac_master_xfer, | ||
184 | .functionality = i2c_powermac_func, | ||
185 | }; | ||
186 | |||
187 | |||
188 | static int i2c_powermac_remove(struct device *dev) | ||
189 | { | ||
190 | struct i2c_adapter *adapter = dev_get_drvdata(dev); | ||
191 | struct pmac_i2c_bus *bus = i2c_get_adapdata(adapter); | ||
192 | int rc; | ||
193 | |||
194 | rc = i2c_del_adapter(adapter); | ||
195 | pmac_i2c_detach_adapter(bus, adapter); | ||
196 | i2c_set_adapdata(adapter, NULL); | ||
197 | /* We aren't that prepared to deal with this... */ | ||
198 | if (rc) | ||
199 | printk("i2c-powermac.c: Failed to remove bus %s !\n", | ||
200 | adapter->name); | ||
201 | dev_set_drvdata(dev, NULL); | ||
202 | kfree(adapter); | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | |||
208 | static int i2c_powermac_probe(struct device *dev) | ||
209 | { | ||
210 | struct pmac_i2c_bus *bus = dev->platform_data; | ||
211 | struct device_node *parent = NULL; | ||
212 | struct i2c_adapter *adapter; | ||
213 | char name[32], *basename; | ||
214 | int rc; | ||
215 | |||
216 | if (bus == NULL) | ||
217 | return -EINVAL; | ||
218 | |||
219 | /* Ok, now we need to make up a name for the interface that will | ||
220 | * match what we used to do in the past, that is basically the | ||
221 | * controller's parent device node for keywest. PMU didn't have a | ||
222 | * naming convention and SMU has a different one | ||
223 | */ | ||
224 | switch(pmac_i2c_get_type(bus)) { | ||
225 | case pmac_i2c_bus_keywest: | ||
226 | parent = of_get_parent(pmac_i2c_get_controller(bus)); | ||
227 | if (parent == NULL) | ||
228 | return -EINVAL; | ||
229 | basename = parent->name; | ||
230 | break; | ||
231 | case pmac_i2c_bus_pmu: | ||
232 | basename = "pmu"; | ||
233 | break; | ||
234 | case pmac_i2c_bus_smu: | ||
235 | /* This is not what we used to do but I'm fixing drivers at | ||
236 | * the same time as this change | ||
237 | */ | ||
238 | basename = "smu"; | ||
239 | break; | ||
240 | default: | ||
241 | return -EINVAL; | ||
242 | } | ||
243 | snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus)); | ||
244 | of_node_put(parent); | ||
245 | |||
246 | adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); | ||
247 | if (adapter == NULL) { | ||
248 | printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n"); | ||
249 | return -ENOMEM; | ||
250 | } | ||
251 | dev_set_drvdata(dev, adapter); | ||
252 | strcpy(adapter->name, name); | ||
253 | adapter->algo = &i2c_powermac_algorithm; | ||
254 | i2c_set_adapdata(adapter, bus); | ||
255 | adapter->dev.parent = dev; | ||
256 | pmac_i2c_attach_adapter(bus, adapter); | ||
257 | rc = i2c_add_adapter(adapter); | ||
258 | if (rc) { | ||
259 | printk(KERN_ERR "i2c-powermac: Adapter %s registration " | ||
260 | "failed\n", name); | ||
261 | i2c_set_adapdata(adapter, NULL); | ||
262 | pmac_i2c_detach_adapter(bus, adapter); | ||
263 | } | ||
264 | |||
265 | printk(KERN_INFO "PowerMac i2c bus %s registered\n", name); | ||
266 | return rc; | ||
267 | } | ||
268 | |||
269 | |||
270 | static struct device_driver i2c_powermac_driver = { | ||
271 | .name = "i2c-powermac", | ||
272 | .bus = &platform_bus_type, | ||
273 | .probe = i2c_powermac_probe, | ||
274 | .remove = i2c_powermac_remove, | ||
275 | }; | ||
276 | |||
277 | static int __init i2c_powermac_init(void) | ||
278 | { | ||
279 | driver_register(&i2c_powermac_driver); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | |||
284 | static void __exit i2c_powermac_cleanup(void) | ||
285 | { | ||
286 | driver_unregister(&i2c_powermac_driver); | ||
287 | } | ||
288 | |||
289 | module_init(i2c_powermac_init); | ||
290 | module_exit(i2c_powermac_cleanup); | ||
291 |
drivers/macintosh/Kconfig
1 | 1 | ||
2 | menu "Macintosh device drivers" | 2 | menu "Macintosh device drivers" |
3 | depends on PPC || MAC | 3 | depends on PPC || MAC |
4 | 4 | ||
5 | config ADB | 5 | config ADB |
6 | bool "Apple Desktop Bus (ADB) support" | 6 | bool "Apple Desktop Bus (ADB) support" |
7 | depends on MAC || (PPC_PMAC && PPC32) | 7 | depends on MAC || (PPC_PMAC && PPC32) |
8 | help | 8 | help |
9 | Apple Desktop Bus (ADB) support is for support of devices which | 9 | Apple Desktop Bus (ADB) support is for support of devices which |
10 | are connected to an ADB port. ADB devices tend to have 4 pins. | 10 | are connected to an ADB port. ADB devices tend to have 4 pins. |
11 | If you have an Apple Macintosh prior to the iMac, an iBook or | 11 | If you have an Apple Macintosh prior to the iMac, an iBook or |
12 | PowerBook, or a "Blue and White G3", you probably want to say Y | 12 | PowerBook, or a "Blue and White G3", you probably want to say Y |
13 | here. Otherwise say N. | 13 | here. Otherwise say N. |
14 | 14 | ||
15 | config ADB_MACII | 15 | config ADB_MACII |
16 | bool "Include Mac II ADB driver" | 16 | bool "Include Mac II ADB driver" |
17 | depends on ADB && MAC | 17 | depends on ADB && MAC |
18 | help | 18 | help |
19 | Say Y here if want your kernel to support Macintosh systems that use | 19 | Say Y here if want your kernel to support Macintosh systems that use |
20 | the Mac II style ADB. This includes the II, IIx, IIcx, SE/30, IIci, | 20 | the Mac II style ADB. This includes the II, IIx, IIcx, SE/30, IIci, |
21 | Quadra 610, Quadra 650, Quadra 700, Quadra 800, Centris 610 and | 21 | Quadra 610, Quadra 650, Quadra 700, Quadra 800, Centris 610 and |
22 | Centris 650. | 22 | Centris 650. |
23 | 23 | ||
24 | config ADB_MACIISI | 24 | config ADB_MACIISI |
25 | bool "Include Mac IIsi ADB driver" | 25 | bool "Include Mac IIsi ADB driver" |
26 | depends on ADB && MAC | 26 | depends on ADB && MAC |
27 | help | 27 | help |
28 | Say Y here if want your kernel to support Macintosh systems that use | 28 | Say Y here if want your kernel to support Macintosh systems that use |
29 | the Mac IIsi style ADB. This includes the IIsi, IIvi, IIvx, Classic | 29 | the Mac IIsi style ADB. This includes the IIsi, IIvi, IIvx, Classic |
30 | II, LC, LC II, LC III, Performa 460, and the Performa 600. | 30 | II, LC, LC II, LC III, Performa 460, and the Performa 600. |
31 | 31 | ||
32 | config ADB_IOP | 32 | config ADB_IOP |
33 | bool "Include IOP (IIfx/Quadra 9x0) ADB driver" | 33 | bool "Include IOP (IIfx/Quadra 9x0) ADB driver" |
34 | depends on ADB && MAC | 34 | depends on ADB && MAC |
35 | help | 35 | help |
36 | The I/O Processor (IOP) is an Apple custom IC designed to provide | 36 | The I/O Processor (IOP) is an Apple custom IC designed to provide |
37 | intelligent support for I/O controllers. It is described at | 37 | intelligent support for I/O controllers. It is described at |
38 | <http://www.angelfire.com/ca2/dev68k/iopdesc.html> to enable direct | 38 | <http://www.angelfire.com/ca2/dev68k/iopdesc.html> to enable direct |
39 | support for it, say 'Y' here. | 39 | support for it, say 'Y' here. |
40 | 40 | ||
41 | config ADB_PMU68K | 41 | config ADB_PMU68K |
42 | bool "Include PMU (Powerbook) ADB driver" | 42 | bool "Include PMU (Powerbook) ADB driver" |
43 | depends on ADB && MAC | 43 | depends on ADB && MAC |
44 | help | 44 | help |
45 | Say Y here if want your kernel to support the m68k based Powerbooks. | 45 | Say Y here if want your kernel to support the m68k based Powerbooks. |
46 | This includes the PowerBook 140, PowerBook 145, PowerBook 150, | 46 | This includes the PowerBook 140, PowerBook 145, PowerBook 150, |
47 | PowerBook 160, PowerBook 165, PowerBook 165c, PowerBook 170, | 47 | PowerBook 160, PowerBook 165, PowerBook 165c, PowerBook 170, |
48 | PowerBook 180, PowerBook, 180c, PowerBook 190cs, PowerBook 520, | 48 | PowerBook 180, PowerBook, 180c, PowerBook 190cs, PowerBook 520, |
49 | PowerBook Duo 210, PowerBook Duo 230, PowerBook Duo 250, | 49 | PowerBook Duo 210, PowerBook Duo 230, PowerBook Duo 250, |
50 | PowerBook Duo 270c, PowerBook Duo 280 and PowerBook Duo 280c. | 50 | PowerBook Duo 270c, PowerBook Duo 280 and PowerBook Duo 280c. |
51 | 51 | ||
52 | # we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU | 52 | # we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU |
53 | config ADB_CUDA | 53 | config ADB_CUDA |
54 | bool "Support for CUDA based Macs and PowerMacs" | 54 | bool "Support for CUDA based Macs and PowerMacs" |
55 | depends on (ADB || PPC_PMAC) && !PPC_PMAC64 | 55 | depends on (ADB || PPC_PMAC) && !PPC_PMAC64 |
56 | help | 56 | help |
57 | This provides support for CUDA based Macintosh and Power Macintosh | 57 | This provides support for CUDA based Macintosh and Power Macintosh |
58 | systems. This includes many m68k based Macs (Color Classic, Mac TV, | 58 | systems. This includes many m68k based Macs (Color Classic, Mac TV, |
59 | Performa 475, Performa 520, Performa 550, Performa 575, | 59 | Performa 475, Performa 520, Performa 550, Performa 575, |
60 | Performa 588, Quadra 605, Quadra 630, Quadra/Centris 660AV, and | 60 | Performa 588, Quadra 605, Quadra 630, Quadra/Centris 660AV, and |
61 | Quadra 840AV), most OldWorld PowerMacs, the first generation iMacs, | 61 | Quadra 840AV), most OldWorld PowerMacs, the first generation iMacs, |
62 | the Blue&White G3 and the "Yikes" G4 (PCI Graphics). All later | 62 | the Blue&White G3 and the "Yikes" G4 (PCI Graphics). All later |
63 | models should use CONFIG_ADB_PMU instead. It is safe to say Y here | 63 | models should use CONFIG_ADB_PMU instead. It is safe to say Y here |
64 | even if your machine doesn't have a CUDA. | 64 | even if your machine doesn't have a CUDA. |
65 | 65 | ||
66 | If unsure say Y. | 66 | If unsure say Y. |
67 | 67 | ||
68 | config ADB_PMU | 68 | config ADB_PMU |
69 | bool "Support for PMU based PowerMacs" | 69 | bool "Support for PMU based PowerMacs" |
70 | depends on PPC_PMAC | 70 | depends on PPC_PMAC |
71 | help | 71 | help |
72 | On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the | 72 | On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the |
73 | PMU is an embedded microprocessor whose primary function is to | 73 | PMU is an embedded microprocessor whose primary function is to |
74 | control system power, and battery charging on the portable models. | 74 | control system power, and battery charging on the portable models. |
75 | The PMU also controls the ADB (Apple Desktop Bus) which connects to | 75 | The PMU also controls the ADB (Apple Desktop Bus) which connects to |
76 | the keyboard and mouse on some machines, as well as the non-volatile | 76 | the keyboard and mouse on some machines, as well as the non-volatile |
77 | RAM and the RTC (real time clock) chip. Say Y to enable support for | 77 | RAM and the RTC (real time clock) chip. Say Y to enable support for |
78 | this device; you should do so if your machine is one of those | 78 | this device; you should do so if your machine is one of those |
79 | mentioned above. | 79 | mentioned above. |
80 | 80 | ||
81 | config PMAC_SMU | 81 | config PMAC_SMU |
82 | bool "Support for SMU based PowerMacs" | 82 | bool "Support for SMU based PowerMacs" |
83 | depends on PPC_PMAC64 | 83 | depends on PPC_PMAC64 |
84 | help | 84 | help |
85 | This option adds support for the newer G5 iMacs and PowerMacs based | 85 | This option adds support for the newer G5 iMacs and PowerMacs based |
86 | on the "SMU" system control chip which replaces the old PMU. | 86 | on the "SMU" system control chip which replaces the old PMU. |
87 | If you don't know, say Y. | 87 | If you don't know, say Y. |
88 | 88 | ||
89 | config PMAC_APM_EMU | 89 | config PMAC_APM_EMU |
90 | tristate "APM emulation" | 90 | tristate "APM emulation" |
91 | depends on PPC_PMAC && PPC32 && PM | 91 | depends on PPC_PMAC && PPC32 && PM |
92 | 92 | ||
93 | config PMAC_MEDIABAY | 93 | config PMAC_MEDIABAY |
94 | bool "Support PowerBook hotswap media bay" | 94 | bool "Support PowerBook hotswap media bay" |
95 | depends on PPC_PMAC && PPC32 | 95 | depends on PPC_PMAC && PPC32 |
96 | help | 96 | help |
97 | This option adds support for older PowerBook's hotswap media bay | 97 | This option adds support for older PowerBook's hotswap media bay |
98 | that can contains batteries, floppy drives, or IDE devices. PCI | 98 | that can contains batteries, floppy drives, or IDE devices. PCI |
99 | devices are not fully supported in the bay as I never had one to | 99 | devices are not fully supported in the bay as I never had one to |
100 | try with | 100 | try with |
101 | 101 | ||
102 | # made a separate option since backlight may end up beeing used | 102 | # made a separate option since backlight may end up beeing used |
103 | # on non-powerbook machines (but only on PMU based ones AFAIK) | 103 | # on non-powerbook machines (but only on PMU based ones AFAIK) |
104 | config PMAC_BACKLIGHT | 104 | config PMAC_BACKLIGHT |
105 | bool "Backlight control for LCD screens" | 105 | bool "Backlight control for LCD screens" |
106 | depends on ADB_PMU && (BROKEN || !PPC64) | 106 | depends on ADB_PMU && (BROKEN || !PPC64) |
107 | help | 107 | help |
108 | Say Y here to build in code to manage the LCD backlight on a | 108 | Say Y here to build in code to manage the LCD backlight on a |
109 | Macintosh PowerBook. With this code, the backlight will be turned | 109 | Macintosh PowerBook. With this code, the backlight will be turned |
110 | on and off appropriately on power-management and lid-open/lid-closed | 110 | on and off appropriately on power-management and lid-open/lid-closed |
111 | events; also, the PowerBook button device will be enabled so you can | 111 | events; also, the PowerBook button device will be enabled so you can |
112 | change the screen brightness. | 112 | change the screen brightness. |
113 | 113 | ||
114 | config ADB_MACIO | 114 | config ADB_MACIO |
115 | bool "Include MacIO (CHRP) ADB driver" | 115 | bool "Include MacIO (CHRP) ADB driver" |
116 | depends on ADB && PPC_CHRP && !PPC_PMAC64 | 116 | depends on ADB && PPC_CHRP && !PPC_PMAC64 |
117 | help | 117 | help |
118 | Say Y here to include direct support for the ADB controller in the | 118 | Say Y here to include direct support for the ADB controller in the |
119 | Hydra chip used on PowerPC Macintoshes of the CHRP type. (The Hydra | 119 | Hydra chip used on PowerPC Macintoshes of the CHRP type. (The Hydra |
120 | also includes a MESH II SCSI controller, DBDMA controller, VIA chip, | 120 | also includes a MESH II SCSI controller, DBDMA controller, VIA chip, |
121 | OpenPIC controller and two RS422/Geoports.) | 121 | OpenPIC controller and two RS422/Geoports.) |
122 | 122 | ||
123 | config INPUT_ADBHID | 123 | config INPUT_ADBHID |
124 | bool "Support for ADB input devices (keyboard, mice, ...)" | 124 | bool "Support for ADB input devices (keyboard, mice, ...)" |
125 | depends on ADB && INPUT=y | 125 | depends on ADB && INPUT=y |
126 | help | 126 | help |
127 | Say Y here if you want to have ADB (Apple Desktop Bus) HID devices | 127 | Say Y here if you want to have ADB (Apple Desktop Bus) HID devices |
128 | such as keyboards, mice, joysticks, trackpads or graphic tablets | 128 | such as keyboards, mice, joysticks, trackpads or graphic tablets |
129 | handled by the input layer. If you say Y here, make sure to say Y to | 129 | handled by the input layer. If you say Y here, make sure to say Y to |
130 | the corresponding drivers "Keyboard support" (CONFIG_INPUT_KEYBDEV), | 130 | the corresponding drivers "Keyboard support" (CONFIG_INPUT_KEYBDEV), |
131 | "Mouse Support" (CONFIG_INPUT_MOUSEDEV) and "Event interface | 131 | "Mouse Support" (CONFIG_INPUT_MOUSEDEV) and "Event interface |
132 | support" (CONFIG_INPUT_EVDEV) as well. | 132 | support" (CONFIG_INPUT_EVDEV) as well. |
133 | 133 | ||
134 | If unsure, say Y. | 134 | If unsure, say Y. |
135 | 135 | ||
136 | config MAC_EMUMOUSEBTN | 136 | config MAC_EMUMOUSEBTN |
137 | bool "Support for mouse button 2+3 emulation" | 137 | bool "Support for mouse button 2+3 emulation" |
138 | depends on INPUT_ADBHID | 138 | depends on INPUT_ADBHID |
139 | help | 139 | help |
140 | This provides generic support for emulating the 2nd and 3rd mouse | 140 | This provides generic support for emulating the 2nd and 3rd mouse |
141 | button with keypresses. If you say Y here, the emulation is still | 141 | button with keypresses. If you say Y here, the emulation is still |
142 | disabled by default. The emulation is controlled by these sysctl | 142 | disabled by default. The emulation is controlled by these sysctl |
143 | entries: | 143 | entries: |
144 | /proc/sys/dev/mac_hid/mouse_button_emulation | 144 | /proc/sys/dev/mac_hid/mouse_button_emulation |
145 | /proc/sys/dev/mac_hid/mouse_button2_keycode | 145 | /proc/sys/dev/mac_hid/mouse_button2_keycode |
146 | /proc/sys/dev/mac_hid/mouse_button3_keycode | 146 | /proc/sys/dev/mac_hid/mouse_button3_keycode |
147 | 147 | ||
148 | If you have an Apple machine with a 1-button mouse, say Y here. | 148 | If you have an Apple machine with a 1-button mouse, say Y here. |
149 | 149 | ||
150 | config THERM_WINDTUNNEL | 150 | config THERM_WINDTUNNEL |
151 | tristate "Support for thermal management on Windtunnel G4s" | 151 | tristate "Support for thermal management on Windtunnel G4s" |
152 | depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64 | 152 | depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 |
153 | help | 153 | help |
154 | This driver provides some thermostat and fan control for the desktop | 154 | This driver provides some thermostat and fan control for the desktop |
155 | G4 "Windtunnel" | 155 | G4 "Windtunnel" |
156 | 156 | ||
157 | config THERM_ADT746X | 157 | config THERM_ADT746X |
158 | tristate "Support for thermal mgmnt on laptops with ADT 746x chipset" | 158 | tristate "Support for thermal mgmnt on laptops with ADT 746x chipset" |
159 | depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64 | 159 | depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 |
160 | help | 160 | help |
161 | This driver provides some thermostat and fan control for the | 161 | This driver provides some thermostat and fan control for the |
162 | iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty | 162 | iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty |
163 | better fan behaviour by default, and some manual control. | 163 | better fan behaviour by default, and some manual control. |
164 | 164 | ||
165 | config THERM_PM72 | 165 | config THERM_PM72 |
166 | tristate "Support for thermal management on PowerMac G5" | 166 | tristate "Support for thermal management on PowerMac G5" |
167 | depends on I2C && I2C_KEYWEST && PPC_PMAC64 | 167 | depends on I2C && I2C_POWERMAC && PPC_PMAC64 |
168 | help | 168 | help |
169 | This driver provides thermostat and fan control for the desktop | 169 | This driver provides thermostat and fan control for the desktop |
170 | G5 machines. | 170 | G5 machines. |
171 | 171 | ||
172 | config WINDFARM | 172 | config WINDFARM |
173 | tristate "New PowerMac thermal control infrastructure" | 173 | tristate "New PowerMac thermal control infrastructure" |
174 | 174 | ||
175 | config WINDFARM_PM81 | 175 | config WINDFARM_PM81 |
176 | tristate "Support for thermal management on iMac G5" | 176 | tristate "Support for thermal management on iMac G5" |
177 | depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU | 177 | depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU |
178 | select I2C_PMAC_SMU | 178 | select I2C_POWERMAC |
179 | help | 179 | help |
180 | This driver provides thermal control for the iMacG5 | 180 | This driver provides thermal control for the iMacG5 |
181 | 181 | ||
182 | config WINDFARM_PM91 | 182 | config WINDFARM_PM91 |
183 | tristate "Support for thermal management on PowerMac9,1" | 183 | tristate "Support for thermal management on PowerMac9,1" |
184 | depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU | 184 | depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU |
185 | select I2C_PMAC_SMU | 185 | select I2C_POWERMAC |
186 | help | 186 | help |
187 | This driver provides thermal control for the PowerMac9,1 | 187 | This driver provides thermal control for the PowerMac9,1 |
188 | which is the recent (SMU based) single CPU desktop G5 | 188 | which is the recent (SMU based) single CPU desktop G5 |
189 | 189 | ||
190 | 190 | ||
191 | config ANSLCD | 191 | config ANSLCD |
192 | tristate "Support for ANS LCD display" | 192 | tristate "Support for ANS LCD display" |
193 | depends on ADB_CUDA && PPC_PMAC | 193 | depends on ADB_CUDA && PPC_PMAC |
194 | 194 | ||
195 | endmenu | 195 | endmenu |
196 | 196 |
drivers/macintosh/smu.c
1 | /* | 1 | /* |
2 | * PowerMac G5 SMU driver | 2 | * PowerMac G5 SMU driver |
3 | * | 3 | * |
4 | * Copyright 2004 J. Mayer <l_indien@magic.fr> | 4 | * Copyright 2004 J. Mayer <l_indien@magic.fr> |
5 | * Copyright 2005 Benjamin Herrenschmidt, IBM Corp. | 5 | * Copyright 2005 Benjamin Herrenschmidt, IBM Corp. |
6 | * | 6 | * |
7 | * Released under the term of the GNU GPL v2. | 7 | * Released under the term of the GNU GPL v2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * TODO: | 11 | * TODO: |
12 | * - maybe add timeout to commands ? | 12 | * - maybe add timeout to commands ? |
13 | * - blocking version of time functions | 13 | * - blocking version of time functions |
14 | * - polling version of i2c commands (including timer that works with | 14 | * - polling version of i2c commands (including timer that works with |
15 | * interrutps off) | 15 | * interrutps off) |
16 | * - maybe avoid some data copies with i2c by directly using the smu cmd | 16 | * - maybe avoid some data copies with i2c by directly using the smu cmd |
17 | * buffer and a lower level internal interface | 17 | * buffer and a lower level internal interface |
18 | * - understand SMU -> CPU events and implement reception of them via | 18 | * - understand SMU -> CPU events and implement reception of them via |
19 | * the userland interface | 19 | * the userland interface |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/config.h> | 22 | #include <linux/config.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/dmapool.h> | 26 | #include <linux/dmapool.h> |
27 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/jiffies.h> | 30 | #include <linux/jiffies.h> |
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/rtc.h> | 32 | #include <linux/rtc.h> |
33 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
34 | #include <linux/miscdevice.h> | 34 | #include <linux/miscdevice.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/sysdev.h> | 36 | #include <linux/sysdev.h> |
37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
38 | 38 | ||
39 | #include <asm/byteorder.h> | 39 | #include <asm/byteorder.h> |
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <asm/prom.h> | 41 | #include <asm/prom.h> |
42 | #include <asm/machdep.h> | 42 | #include <asm/machdep.h> |
43 | #include <asm/pmac_feature.h> | 43 | #include <asm/pmac_feature.h> |
44 | #include <asm/smu.h> | 44 | #include <asm/smu.h> |
45 | #include <asm/sections.h> | 45 | #include <asm/sections.h> |
46 | #include <asm/abs_addr.h> | 46 | #include <asm/abs_addr.h> |
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | #include <asm/of_device.h> | 48 | #include <asm/of_device.h> |
49 | 49 | ||
50 | #define VERSION "0.7" | 50 | #define VERSION "0.7" |
51 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." | 51 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." |
52 | 52 | ||
53 | #undef DEBUG_SMU | 53 | #undef DEBUG_SMU |
54 | 54 | ||
55 | #ifdef DEBUG_SMU | 55 | #ifdef DEBUG_SMU |
56 | #define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) | 56 | #define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) |
57 | #else | 57 | #else |
58 | #define DPRINTK(fmt, args...) do { } while (0) | 58 | #define DPRINTK(fmt, args...) do { } while (0) |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * This is the command buffer passed to the SMU hardware | 62 | * This is the command buffer passed to the SMU hardware |
63 | */ | 63 | */ |
64 | #define SMU_MAX_DATA 254 | 64 | #define SMU_MAX_DATA 254 |
65 | 65 | ||
66 | struct smu_cmd_buf { | 66 | struct smu_cmd_buf { |
67 | u8 cmd; | 67 | u8 cmd; |
68 | u8 length; | 68 | u8 length; |
69 | u8 data[SMU_MAX_DATA]; | 69 | u8 data[SMU_MAX_DATA]; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct smu_device { | 72 | struct smu_device { |
73 | spinlock_t lock; | 73 | spinlock_t lock; |
74 | struct device_node *of_node; | 74 | struct device_node *of_node; |
75 | struct of_device *of_dev; | 75 | struct of_device *of_dev; |
76 | int doorbell; /* doorbell gpio */ | 76 | int doorbell; /* doorbell gpio */ |
77 | u32 __iomem *db_buf; /* doorbell buffer */ | 77 | u32 __iomem *db_buf; /* doorbell buffer */ |
78 | int db_irq; | 78 | int db_irq; |
79 | int msg; | 79 | int msg; |
80 | int msg_irq; | 80 | int msg_irq; |
81 | struct smu_cmd_buf *cmd_buf; /* command buffer virtual */ | 81 | struct smu_cmd_buf *cmd_buf; /* command buffer virtual */ |
82 | u32 cmd_buf_abs; /* command buffer absolute */ | 82 | u32 cmd_buf_abs; /* command buffer absolute */ |
83 | struct list_head cmd_list; | 83 | struct list_head cmd_list; |
84 | struct smu_cmd *cmd_cur; /* pending command */ | 84 | struct smu_cmd *cmd_cur; /* pending command */ |
85 | struct list_head cmd_i2c_list; | 85 | struct list_head cmd_i2c_list; |
86 | struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ | 86 | struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ |
87 | struct timer_list i2c_timer; | 87 | struct timer_list i2c_timer; |
88 | }; | 88 | }; |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * I don't think there will ever be more than one SMU, so | 91 | * I don't think there will ever be more than one SMU, so |
92 | * for now, just hard code that | 92 | * for now, just hard code that |
93 | */ | 93 | */ |
94 | static struct smu_device *smu; | 94 | static struct smu_device *smu; |
95 | static DECLARE_MUTEX(smu_part_access); | 95 | static DECLARE_MUTEX(smu_part_access); |
96 | 96 | ||
97 | static void smu_i2c_retry(unsigned long data); | 97 | static void smu_i2c_retry(unsigned long data); |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * SMU driver low level stuff | 100 | * SMU driver low level stuff |
101 | */ | 101 | */ |
102 | 102 | ||
103 | static void smu_start_cmd(void) | 103 | static void smu_start_cmd(void) |
104 | { | 104 | { |
105 | unsigned long faddr, fend; | 105 | unsigned long faddr, fend; |
106 | struct smu_cmd *cmd; | 106 | struct smu_cmd *cmd; |
107 | 107 | ||
108 | if (list_empty(&smu->cmd_list)) | 108 | if (list_empty(&smu->cmd_list)) |
109 | return; | 109 | return; |
110 | 110 | ||
111 | /* Fetch first command in queue */ | 111 | /* Fetch first command in queue */ |
112 | cmd = list_entry(smu->cmd_list.next, struct smu_cmd, link); | 112 | cmd = list_entry(smu->cmd_list.next, struct smu_cmd, link); |
113 | smu->cmd_cur = cmd; | 113 | smu->cmd_cur = cmd; |
114 | list_del(&cmd->link); | 114 | list_del(&cmd->link); |
115 | 115 | ||
116 | DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd, | 116 | DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd, |
117 | cmd->data_len); | 117 | cmd->data_len); |
118 | DPRINTK("SMU: data buffer: %02x %02x %02x %02x %02x %02x %02x %02x\n", | 118 | DPRINTK("SMU: data buffer: %02x %02x %02x %02x %02x %02x %02x %02x\n", |
119 | ((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1], | 119 | ((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1], |
120 | ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3], | 120 | ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3], |
121 | ((u8 *)cmd->data_buf)[4], ((u8 *)cmd->data_buf)[5], | 121 | ((u8 *)cmd->data_buf)[4], ((u8 *)cmd->data_buf)[5], |
122 | ((u8 *)cmd->data_buf)[6], ((u8 *)cmd->data_buf)[7]); | 122 | ((u8 *)cmd->data_buf)[6], ((u8 *)cmd->data_buf)[7]); |
123 | 123 | ||
124 | /* Fill the SMU command buffer */ | 124 | /* Fill the SMU command buffer */ |
125 | smu->cmd_buf->cmd = cmd->cmd; | 125 | smu->cmd_buf->cmd = cmd->cmd; |
126 | smu->cmd_buf->length = cmd->data_len; | 126 | smu->cmd_buf->length = cmd->data_len; |
127 | memcpy(smu->cmd_buf->data, cmd->data_buf, cmd->data_len); | 127 | memcpy(smu->cmd_buf->data, cmd->data_buf, cmd->data_len); |
128 | 128 | ||
129 | /* Flush command and data to RAM */ | 129 | /* Flush command and data to RAM */ |
130 | faddr = (unsigned long)smu->cmd_buf; | 130 | faddr = (unsigned long)smu->cmd_buf; |
131 | fend = faddr + smu->cmd_buf->length + 2; | 131 | fend = faddr + smu->cmd_buf->length + 2; |
132 | flush_inval_dcache_range(faddr, fend); | 132 | flush_inval_dcache_range(faddr, fend); |
133 | 133 | ||
134 | /* This isn't exactly a DMA mapping here, I suspect | 134 | /* This isn't exactly a DMA mapping here, I suspect |
135 | * the SMU is actually communicating with us via i2c to the | 135 | * the SMU is actually communicating with us via i2c to the |
136 | * northbridge or the CPU to access RAM. | 136 | * northbridge or the CPU to access RAM. |
137 | */ | 137 | */ |
138 | writel(smu->cmd_buf_abs, smu->db_buf); | 138 | writel(smu->cmd_buf_abs, smu->db_buf); |
139 | 139 | ||
140 | /* Ring the SMU doorbell */ | 140 | /* Ring the SMU doorbell */ |
141 | pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, smu->doorbell, 4); | 141 | pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, smu->doorbell, 4); |
142 | } | 142 | } |
143 | 143 | ||
144 | 144 | ||
145 | static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs) | 145 | static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs) |
146 | { | 146 | { |
147 | unsigned long flags; | 147 | unsigned long flags; |
148 | struct smu_cmd *cmd; | 148 | struct smu_cmd *cmd; |
149 | void (*done)(struct smu_cmd *cmd, void *misc) = NULL; | 149 | void (*done)(struct smu_cmd *cmd, void *misc) = NULL; |
150 | void *misc = NULL; | 150 | void *misc = NULL; |
151 | u8 gpio; | 151 | u8 gpio; |
152 | int rc = 0; | 152 | int rc = 0; |
153 | 153 | ||
154 | /* SMU completed the command, well, we hope, let's make sure | 154 | /* SMU completed the command, well, we hope, let's make sure |
155 | * of it | 155 | * of it |
156 | */ | 156 | */ |
157 | spin_lock_irqsave(&smu->lock, flags); | 157 | spin_lock_irqsave(&smu->lock, flags); |
158 | 158 | ||
159 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); | 159 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); |
160 | if ((gpio & 7) != 7) { | 160 | if ((gpio & 7) != 7) { |
161 | spin_unlock_irqrestore(&smu->lock, flags); | 161 | spin_unlock_irqrestore(&smu->lock, flags); |
162 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
163 | } | 163 | } |
164 | 164 | ||
165 | cmd = smu->cmd_cur; | 165 | cmd = smu->cmd_cur; |
166 | smu->cmd_cur = NULL; | 166 | smu->cmd_cur = NULL; |
167 | if (cmd == NULL) | 167 | if (cmd == NULL) |
168 | goto bail; | 168 | goto bail; |
169 | 169 | ||
170 | if (rc == 0) { | 170 | if (rc == 0) { |
171 | unsigned long faddr; | 171 | unsigned long faddr; |
172 | int reply_len; | 172 | int reply_len; |
173 | u8 ack; | 173 | u8 ack; |
174 | 174 | ||
175 | /* CPU might have brought back the cache line, so we need | 175 | /* CPU might have brought back the cache line, so we need |
176 | * to flush again before peeking at the SMU response. We | 176 | * to flush again before peeking at the SMU response. We |
177 | * flush the entire buffer for now as we haven't read the | 177 | * flush the entire buffer for now as we haven't read the |
178 | * reply lenght (it's only 2 cache lines anyway) | 178 | * reply lenght (it's only 2 cache lines anyway) |
179 | */ | 179 | */ |
180 | faddr = (unsigned long)smu->cmd_buf; | 180 | faddr = (unsigned long)smu->cmd_buf; |
181 | flush_inval_dcache_range(faddr, faddr + 256); | 181 | flush_inval_dcache_range(faddr, faddr + 256); |
182 | 182 | ||
183 | /* Now check ack */ | 183 | /* Now check ack */ |
184 | ack = (~cmd->cmd) & 0xff; | 184 | ack = (~cmd->cmd) & 0xff; |
185 | if (ack != smu->cmd_buf->cmd) { | 185 | if (ack != smu->cmd_buf->cmd) { |
186 | DPRINTK("SMU: incorrect ack, want %x got %x\n", | 186 | DPRINTK("SMU: incorrect ack, want %x got %x\n", |
187 | ack, smu->cmd_buf->cmd); | 187 | ack, smu->cmd_buf->cmd); |
188 | rc = -EIO; | 188 | rc = -EIO; |
189 | } | 189 | } |
190 | reply_len = rc == 0 ? smu->cmd_buf->length : 0; | 190 | reply_len = rc == 0 ? smu->cmd_buf->length : 0; |
191 | DPRINTK("SMU: reply len: %d\n", reply_len); | 191 | DPRINTK("SMU: reply len: %d\n", reply_len); |
192 | if (reply_len > cmd->reply_len) { | 192 | if (reply_len > cmd->reply_len) { |
193 | printk(KERN_WARNING "SMU: reply buffer too small," | 193 | printk(KERN_WARNING "SMU: reply buffer too small," |
194 | "got %d bytes for a %d bytes buffer\n", | 194 | "got %d bytes for a %d bytes buffer\n", |
195 | reply_len, cmd->reply_len); | 195 | reply_len, cmd->reply_len); |
196 | reply_len = cmd->reply_len; | 196 | reply_len = cmd->reply_len; |
197 | } | 197 | } |
198 | cmd->reply_len = reply_len; | 198 | cmd->reply_len = reply_len; |
199 | if (cmd->reply_buf && reply_len) | 199 | if (cmd->reply_buf && reply_len) |
200 | memcpy(cmd->reply_buf, smu->cmd_buf->data, reply_len); | 200 | memcpy(cmd->reply_buf, smu->cmd_buf->data, reply_len); |
201 | } | 201 | } |
202 | 202 | ||
203 | /* Now complete the command. Write status last in order as we lost | 203 | /* Now complete the command. Write status last in order as we lost |
204 | * ownership of the command structure as soon as it's no longer -1 | 204 | * ownership of the command structure as soon as it's no longer -1 |
205 | */ | 205 | */ |
206 | done = cmd->done; | 206 | done = cmd->done; |
207 | misc = cmd->misc; | 207 | misc = cmd->misc; |
208 | mb(); | 208 | mb(); |
209 | cmd->status = rc; | 209 | cmd->status = rc; |
210 | bail: | 210 | bail: |
211 | /* Start next command if any */ | 211 | /* Start next command if any */ |
212 | smu_start_cmd(); | 212 | smu_start_cmd(); |
213 | spin_unlock_irqrestore(&smu->lock, flags); | 213 | spin_unlock_irqrestore(&smu->lock, flags); |
214 | 214 | ||
215 | /* Call command completion handler if any */ | 215 | /* Call command completion handler if any */ |
216 | if (done) | 216 | if (done) |
217 | done(cmd, misc); | 217 | done(cmd, misc); |
218 | 218 | ||
219 | /* It's an edge interrupt, nothing to do */ | 219 | /* It's an edge interrupt, nothing to do */ |
220 | return IRQ_HANDLED; | 220 | return IRQ_HANDLED; |
221 | } | 221 | } |
222 | 222 | ||
223 | 223 | ||
224 | static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs) | 224 | static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs) |
225 | { | 225 | { |
226 | /* I don't quite know what to do with this one, we seem to never | 226 | /* I don't quite know what to do with this one, we seem to never |
227 | * receive it, so I suspect we have to arm it someway in the SMU | 227 | * receive it, so I suspect we have to arm it someway in the SMU |
228 | * to start getting events that way. | 228 | * to start getting events that way. |
229 | */ | 229 | */ |
230 | 230 | ||
231 | printk(KERN_INFO "SMU: message interrupt !\n"); | 231 | printk(KERN_INFO "SMU: message interrupt !\n"); |
232 | 232 | ||
233 | /* It's an edge interrupt, nothing to do */ | 233 | /* It's an edge interrupt, nothing to do */ |
234 | return IRQ_HANDLED; | 234 | return IRQ_HANDLED; |
235 | } | 235 | } |
236 | 236 | ||
237 | 237 | ||
238 | /* | 238 | /* |
239 | * Queued command management. | 239 | * Queued command management. |
240 | * | 240 | * |
241 | */ | 241 | */ |
242 | 242 | ||
243 | int smu_queue_cmd(struct smu_cmd *cmd) | 243 | int smu_queue_cmd(struct smu_cmd *cmd) |
244 | { | 244 | { |
245 | unsigned long flags; | 245 | unsigned long flags; |
246 | 246 | ||
247 | if (smu == NULL) | 247 | if (smu == NULL) |
248 | return -ENODEV; | 248 | return -ENODEV; |
249 | if (cmd->data_len > SMU_MAX_DATA || | 249 | if (cmd->data_len > SMU_MAX_DATA || |
250 | cmd->reply_len > SMU_MAX_DATA) | 250 | cmd->reply_len > SMU_MAX_DATA) |
251 | return -EINVAL; | 251 | return -EINVAL; |
252 | 252 | ||
253 | cmd->status = 1; | 253 | cmd->status = 1; |
254 | spin_lock_irqsave(&smu->lock, flags); | 254 | spin_lock_irqsave(&smu->lock, flags); |
255 | list_add_tail(&cmd->link, &smu->cmd_list); | 255 | list_add_tail(&cmd->link, &smu->cmd_list); |
256 | if (smu->cmd_cur == NULL) | 256 | if (smu->cmd_cur == NULL) |
257 | smu_start_cmd(); | 257 | smu_start_cmd(); |
258 | spin_unlock_irqrestore(&smu->lock, flags); | 258 | spin_unlock_irqrestore(&smu->lock, flags); |
259 | 259 | ||
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
262 | EXPORT_SYMBOL(smu_queue_cmd); | 262 | EXPORT_SYMBOL(smu_queue_cmd); |
263 | 263 | ||
264 | 264 | ||
265 | int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command, | 265 | int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command, |
266 | unsigned int data_len, | 266 | unsigned int data_len, |
267 | void (*done)(struct smu_cmd *cmd, void *misc), | 267 | void (*done)(struct smu_cmd *cmd, void *misc), |
268 | void *misc, ...) | 268 | void *misc, ...) |
269 | { | 269 | { |
270 | struct smu_cmd *cmd = &scmd->cmd; | 270 | struct smu_cmd *cmd = &scmd->cmd; |
271 | va_list list; | 271 | va_list list; |
272 | int i; | 272 | int i; |
273 | 273 | ||
274 | if (data_len > sizeof(scmd->buffer)) | 274 | if (data_len > sizeof(scmd->buffer)) |
275 | return -EINVAL; | 275 | return -EINVAL; |
276 | 276 | ||
277 | memset(scmd, 0, sizeof(*scmd)); | 277 | memset(scmd, 0, sizeof(*scmd)); |
278 | cmd->cmd = command; | 278 | cmd->cmd = command; |
279 | cmd->data_len = data_len; | 279 | cmd->data_len = data_len; |
280 | cmd->data_buf = scmd->buffer; | 280 | cmd->data_buf = scmd->buffer; |
281 | cmd->reply_len = sizeof(scmd->buffer); | 281 | cmd->reply_len = sizeof(scmd->buffer); |
282 | cmd->reply_buf = scmd->buffer; | 282 | cmd->reply_buf = scmd->buffer; |
283 | cmd->done = done; | 283 | cmd->done = done; |
284 | cmd->misc = misc; | 284 | cmd->misc = misc; |
285 | 285 | ||
286 | va_start(list, misc); | 286 | va_start(list, misc); |
287 | for (i = 0; i < data_len; ++i) | 287 | for (i = 0; i < data_len; ++i) |
288 | scmd->buffer[i] = (u8)va_arg(list, int); | 288 | scmd->buffer[i] = (u8)va_arg(list, int); |
289 | va_end(list); | 289 | va_end(list); |
290 | 290 | ||
291 | return smu_queue_cmd(cmd); | 291 | return smu_queue_cmd(cmd); |
292 | } | 292 | } |
293 | EXPORT_SYMBOL(smu_queue_simple); | 293 | EXPORT_SYMBOL(smu_queue_simple); |
294 | 294 | ||
295 | 295 | ||
296 | void smu_poll(void) | 296 | void smu_poll(void) |
297 | { | 297 | { |
298 | u8 gpio; | 298 | u8 gpio; |
299 | 299 | ||
300 | if (smu == NULL) | 300 | if (smu == NULL) |
301 | return; | 301 | return; |
302 | 302 | ||
303 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); | 303 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); |
304 | if ((gpio & 7) == 7) | 304 | if ((gpio & 7) == 7) |
305 | smu_db_intr(smu->db_irq, smu, NULL); | 305 | smu_db_intr(smu->db_irq, smu, NULL); |
306 | } | 306 | } |
307 | EXPORT_SYMBOL(smu_poll); | 307 | EXPORT_SYMBOL(smu_poll); |
308 | 308 | ||
309 | 309 | ||
310 | void smu_done_complete(struct smu_cmd *cmd, void *misc) | 310 | void smu_done_complete(struct smu_cmd *cmd, void *misc) |
311 | { | 311 | { |
312 | struct completion *comp = misc; | 312 | struct completion *comp = misc; |
313 | 313 | ||
314 | complete(comp); | 314 | complete(comp); |
315 | } | 315 | } |
316 | EXPORT_SYMBOL(smu_done_complete); | 316 | EXPORT_SYMBOL(smu_done_complete); |
317 | 317 | ||
318 | 318 | ||
319 | void smu_spinwait_cmd(struct smu_cmd *cmd) | 319 | void smu_spinwait_cmd(struct smu_cmd *cmd) |
320 | { | 320 | { |
321 | while(cmd->status == 1) | 321 | while(cmd->status == 1) |
322 | smu_poll(); | 322 | smu_poll(); |
323 | } | 323 | } |
324 | EXPORT_SYMBOL(smu_spinwait_cmd); | 324 | EXPORT_SYMBOL(smu_spinwait_cmd); |
325 | 325 | ||
326 | 326 | ||
327 | /* RTC low level commands */ | 327 | /* RTC low level commands */ |
328 | static inline int bcd2hex (int n) | 328 | static inline int bcd2hex (int n) |
329 | { | 329 | { |
330 | return (((n & 0xf0) >> 4) * 10) + (n & 0xf); | 330 | return (((n & 0xf0) >> 4) * 10) + (n & 0xf); |
331 | } | 331 | } |
332 | 332 | ||
333 | 333 | ||
334 | static inline int hex2bcd (int n) | 334 | static inline int hex2bcd (int n) |
335 | { | 335 | { |
336 | return ((n / 10) << 4) + (n % 10); | 336 | return ((n / 10) << 4) + (n % 10); |
337 | } | 337 | } |
338 | 338 | ||
339 | 339 | ||
340 | static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf, | 340 | static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf, |
341 | struct rtc_time *time) | 341 | struct rtc_time *time) |
342 | { | 342 | { |
343 | cmd_buf->cmd = 0x8e; | 343 | cmd_buf->cmd = 0x8e; |
344 | cmd_buf->length = 8; | 344 | cmd_buf->length = 8; |
345 | cmd_buf->data[0] = 0x80; | 345 | cmd_buf->data[0] = 0x80; |
346 | cmd_buf->data[1] = hex2bcd(time->tm_sec); | 346 | cmd_buf->data[1] = hex2bcd(time->tm_sec); |
347 | cmd_buf->data[2] = hex2bcd(time->tm_min); | 347 | cmd_buf->data[2] = hex2bcd(time->tm_min); |
348 | cmd_buf->data[3] = hex2bcd(time->tm_hour); | 348 | cmd_buf->data[3] = hex2bcd(time->tm_hour); |
349 | cmd_buf->data[4] = time->tm_wday; | 349 | cmd_buf->data[4] = time->tm_wday; |
350 | cmd_buf->data[5] = hex2bcd(time->tm_mday); | 350 | cmd_buf->data[5] = hex2bcd(time->tm_mday); |
351 | cmd_buf->data[6] = hex2bcd(time->tm_mon) + 1; | 351 | cmd_buf->data[6] = hex2bcd(time->tm_mon) + 1; |
352 | cmd_buf->data[7] = hex2bcd(time->tm_year - 100); | 352 | cmd_buf->data[7] = hex2bcd(time->tm_year - 100); |
353 | } | 353 | } |
354 | 354 | ||
355 | 355 | ||
356 | int smu_get_rtc_time(struct rtc_time *time, int spinwait) | 356 | int smu_get_rtc_time(struct rtc_time *time, int spinwait) |
357 | { | 357 | { |
358 | struct smu_simple_cmd cmd; | 358 | struct smu_simple_cmd cmd; |
359 | int rc; | 359 | int rc; |
360 | 360 | ||
361 | if (smu == NULL) | 361 | if (smu == NULL) |
362 | return -ENODEV; | 362 | return -ENODEV; |
363 | 363 | ||
364 | memset(time, 0, sizeof(struct rtc_time)); | 364 | memset(time, 0, sizeof(struct rtc_time)); |
365 | rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 1, NULL, NULL, | 365 | rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 1, NULL, NULL, |
366 | SMU_CMD_RTC_GET_DATETIME); | 366 | SMU_CMD_RTC_GET_DATETIME); |
367 | if (rc) | 367 | if (rc) |
368 | return rc; | 368 | return rc; |
369 | smu_spinwait_simple(&cmd); | 369 | smu_spinwait_simple(&cmd); |
370 | 370 | ||
371 | time->tm_sec = bcd2hex(cmd.buffer[0]); | 371 | time->tm_sec = bcd2hex(cmd.buffer[0]); |
372 | time->tm_min = bcd2hex(cmd.buffer[1]); | 372 | time->tm_min = bcd2hex(cmd.buffer[1]); |
373 | time->tm_hour = bcd2hex(cmd.buffer[2]); | 373 | time->tm_hour = bcd2hex(cmd.buffer[2]); |
374 | time->tm_wday = bcd2hex(cmd.buffer[3]); | 374 | time->tm_wday = bcd2hex(cmd.buffer[3]); |
375 | time->tm_mday = bcd2hex(cmd.buffer[4]); | 375 | time->tm_mday = bcd2hex(cmd.buffer[4]); |
376 | time->tm_mon = bcd2hex(cmd.buffer[5]) - 1; | 376 | time->tm_mon = bcd2hex(cmd.buffer[5]) - 1; |
377 | time->tm_year = bcd2hex(cmd.buffer[6]) + 100; | 377 | time->tm_year = bcd2hex(cmd.buffer[6]) + 100; |
378 | 378 | ||
379 | return 0; | 379 | return 0; |
380 | } | 380 | } |
381 | 381 | ||
382 | 382 | ||
383 | int smu_set_rtc_time(struct rtc_time *time, int spinwait) | 383 | int smu_set_rtc_time(struct rtc_time *time, int spinwait) |
384 | { | 384 | { |
385 | struct smu_simple_cmd cmd; | 385 | struct smu_simple_cmd cmd; |
386 | int rc; | 386 | int rc; |
387 | 387 | ||
388 | if (smu == NULL) | 388 | if (smu == NULL) |
389 | return -ENODEV; | 389 | return -ENODEV; |
390 | 390 | ||
391 | rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 8, NULL, NULL, | 391 | rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 8, NULL, NULL, |
392 | SMU_CMD_RTC_SET_DATETIME, | 392 | SMU_CMD_RTC_SET_DATETIME, |
393 | hex2bcd(time->tm_sec), | 393 | hex2bcd(time->tm_sec), |
394 | hex2bcd(time->tm_min), | 394 | hex2bcd(time->tm_min), |
395 | hex2bcd(time->tm_hour), | 395 | hex2bcd(time->tm_hour), |
396 | time->tm_wday, | 396 | time->tm_wday, |
397 | hex2bcd(time->tm_mday), | 397 | hex2bcd(time->tm_mday), |
398 | hex2bcd(time->tm_mon) + 1, | 398 | hex2bcd(time->tm_mon) + 1, |
399 | hex2bcd(time->tm_year - 100)); | 399 | hex2bcd(time->tm_year - 100)); |
400 | if (rc) | 400 | if (rc) |
401 | return rc; | 401 | return rc; |
402 | smu_spinwait_simple(&cmd); | 402 | smu_spinwait_simple(&cmd); |
403 | 403 | ||
404 | return 0; | 404 | return 0; |
405 | } | 405 | } |
406 | 406 | ||
407 | 407 | ||
408 | void smu_shutdown(void) | 408 | void smu_shutdown(void) |
409 | { | 409 | { |
410 | struct smu_simple_cmd cmd; | 410 | struct smu_simple_cmd cmd; |
411 | 411 | ||
412 | if (smu == NULL) | 412 | if (smu == NULL) |
413 | return; | 413 | return; |
414 | 414 | ||
415 | if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 9, NULL, NULL, | 415 | if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 9, NULL, NULL, |
416 | 'S', 'H', 'U', 'T', 'D', 'O', 'W', 'N', 0)) | 416 | 'S', 'H', 'U', 'T', 'D', 'O', 'W', 'N', 0)) |
417 | return; | 417 | return; |
418 | smu_spinwait_simple(&cmd); | 418 | smu_spinwait_simple(&cmd); |
419 | for (;;) | 419 | for (;;) |
420 | ; | 420 | ; |
421 | } | 421 | } |
422 | 422 | ||
423 | 423 | ||
424 | void smu_restart(void) | 424 | void smu_restart(void) |
425 | { | 425 | { |
426 | struct smu_simple_cmd cmd; | 426 | struct smu_simple_cmd cmd; |
427 | 427 | ||
428 | if (smu == NULL) | 428 | if (smu == NULL) |
429 | return; | 429 | return; |
430 | 430 | ||
431 | if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, NULL, NULL, | 431 | if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, NULL, NULL, |
432 | 'R', 'E', 'S', 'T', 'A', 'R', 'T', 0)) | 432 | 'R', 'E', 'S', 'T', 'A', 'R', 'T', 0)) |
433 | return; | 433 | return; |
434 | smu_spinwait_simple(&cmd); | 434 | smu_spinwait_simple(&cmd); |
435 | for (;;) | 435 | for (;;) |
436 | ; | 436 | ; |
437 | } | 437 | } |
438 | 438 | ||
439 | 439 | ||
440 | int smu_present(void) | 440 | int smu_present(void) |
441 | { | 441 | { |
442 | return smu != NULL; | 442 | return smu != NULL; |
443 | } | 443 | } |
444 | EXPORT_SYMBOL(smu_present); | 444 | EXPORT_SYMBOL(smu_present); |
445 | 445 | ||
446 | 446 | ||
447 | int __init smu_init (void) | 447 | int __init smu_init (void) |
448 | { | 448 | { |
449 | struct device_node *np; | 449 | struct device_node *np; |
450 | u32 *data; | 450 | u32 *data; |
451 | 451 | ||
452 | np = of_find_node_by_type(NULL, "smu"); | 452 | np = of_find_node_by_type(NULL, "smu"); |
453 | if (np == NULL) | 453 | if (np == NULL) |
454 | return -ENODEV; | 454 | return -ENODEV; |
455 | 455 | ||
456 | printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); | 456 | printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); |
457 | 457 | ||
458 | if (smu_cmdbuf_abs == 0) { | 458 | if (smu_cmdbuf_abs == 0) { |
459 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); | 459 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
460 | return -EINVAL; | 460 | return -EINVAL; |
461 | } | 461 | } |
462 | 462 | ||
463 | smu = alloc_bootmem(sizeof(struct smu_device)); | 463 | smu = alloc_bootmem(sizeof(struct smu_device)); |
464 | if (smu == NULL) | 464 | if (smu == NULL) |
465 | return -ENOMEM; | 465 | return -ENOMEM; |
466 | memset(smu, 0, sizeof(*smu)); | 466 | memset(smu, 0, sizeof(*smu)); |
467 | 467 | ||
468 | spin_lock_init(&smu->lock); | 468 | spin_lock_init(&smu->lock); |
469 | INIT_LIST_HEAD(&smu->cmd_list); | 469 | INIT_LIST_HEAD(&smu->cmd_list); |
470 | INIT_LIST_HEAD(&smu->cmd_i2c_list); | 470 | INIT_LIST_HEAD(&smu->cmd_i2c_list); |
471 | smu->of_node = np; | 471 | smu->of_node = np; |
472 | smu->db_irq = NO_IRQ; | 472 | smu->db_irq = NO_IRQ; |
473 | smu->msg_irq = NO_IRQ; | 473 | smu->msg_irq = NO_IRQ; |
474 | 474 | ||
475 | /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a | 475 | /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a |
476 | * 32 bits value safely | 476 | * 32 bits value safely |
477 | */ | 477 | */ |
478 | smu->cmd_buf_abs = (u32)smu_cmdbuf_abs; | 478 | smu->cmd_buf_abs = (u32)smu_cmdbuf_abs; |
479 | smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs); | 479 | smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs); |
480 | 480 | ||
481 | np = of_find_node_by_name(NULL, "smu-doorbell"); | 481 | np = of_find_node_by_name(NULL, "smu-doorbell"); |
482 | if (np == NULL) { | 482 | if (np == NULL) { |
483 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); | 483 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); |
484 | goto fail; | 484 | goto fail; |
485 | } | 485 | } |
486 | data = (u32 *)get_property(np, "reg", NULL); | 486 | data = (u32 *)get_property(np, "reg", NULL); |
487 | if (data == NULL) { | 487 | if (data == NULL) { |
488 | of_node_put(np); | 488 | of_node_put(np); |
489 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); | 489 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); |
490 | goto fail; | 490 | goto fail; |
491 | } | 491 | } |
492 | 492 | ||
493 | /* Current setup has one doorbell GPIO that does both doorbell | 493 | /* Current setup has one doorbell GPIO that does both doorbell |
494 | * and ack. GPIOs are at 0x50, best would be to find that out | 494 | * and ack. GPIOs are at 0x50, best would be to find that out |
495 | * in the device-tree though. | 495 | * in the device-tree though. |
496 | */ | 496 | */ |
497 | smu->doorbell = *data; | 497 | smu->doorbell = *data; |
498 | if (smu->doorbell < 0x50) | 498 | if (smu->doorbell < 0x50) |
499 | smu->doorbell += 0x50; | 499 | smu->doorbell += 0x50; |
500 | if (np->n_intrs > 0) | 500 | if (np->n_intrs > 0) |
501 | smu->db_irq = np->intrs[0].line; | 501 | smu->db_irq = np->intrs[0].line; |
502 | 502 | ||
503 | of_node_put(np); | 503 | of_node_put(np); |
504 | 504 | ||
505 | /* Now look for the smu-interrupt GPIO */ | 505 | /* Now look for the smu-interrupt GPIO */ |
506 | do { | 506 | do { |
507 | np = of_find_node_by_name(NULL, "smu-interrupt"); | 507 | np = of_find_node_by_name(NULL, "smu-interrupt"); |
508 | if (np == NULL) | 508 | if (np == NULL) |
509 | break; | 509 | break; |
510 | data = (u32 *)get_property(np, "reg", NULL); | 510 | data = (u32 *)get_property(np, "reg", NULL); |
511 | if (data == NULL) { | 511 | if (data == NULL) { |
512 | of_node_put(np); | 512 | of_node_put(np); |
513 | break; | 513 | break; |
514 | } | 514 | } |
515 | smu->msg = *data; | 515 | smu->msg = *data; |
516 | if (smu->msg < 0x50) | 516 | if (smu->msg < 0x50) |
517 | smu->msg += 0x50; | 517 | smu->msg += 0x50; |
518 | if (np->n_intrs > 0) | 518 | if (np->n_intrs > 0) |
519 | smu->msg_irq = np->intrs[0].line; | 519 | smu->msg_irq = np->intrs[0].line; |
520 | of_node_put(np); | 520 | of_node_put(np); |
521 | } while(0); | 521 | } while(0); |
522 | 522 | ||
523 | /* Doorbell buffer is currently hard-coded, I didn't find a proper | 523 | /* Doorbell buffer is currently hard-coded, I didn't find a proper |
524 | * device-tree entry giving the address. Best would probably to use | 524 | * device-tree entry giving the address. Best would probably to use |
525 | * an offset for K2 base though, but let's do it that way for now. | 525 | * an offset for K2 base though, but let's do it that way for now. |
526 | */ | 526 | */ |
527 | smu->db_buf = ioremap(0x8000860c, 0x1000); | 527 | smu->db_buf = ioremap(0x8000860c, 0x1000); |
528 | if (smu->db_buf == NULL) { | 528 | if (smu->db_buf == NULL) { |
529 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); | 529 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); |
530 | goto fail; | 530 | goto fail; |
531 | } | 531 | } |
532 | 532 | ||
533 | sys_ctrler = SYS_CTRLER_SMU; | 533 | sys_ctrler = SYS_CTRLER_SMU; |
534 | return 0; | 534 | return 0; |
535 | 535 | ||
536 | fail: | 536 | fail: |
537 | smu = NULL; | 537 | smu = NULL; |
538 | return -ENXIO; | 538 | return -ENXIO; |
539 | 539 | ||
540 | } | 540 | } |
541 | 541 | ||
542 | 542 | ||
543 | static int smu_late_init(void) | 543 | static int smu_late_init(void) |
544 | { | 544 | { |
545 | if (!smu) | 545 | if (!smu) |
546 | return 0; | 546 | return 0; |
547 | 547 | ||
548 | init_timer(&smu->i2c_timer); | 548 | init_timer(&smu->i2c_timer); |
549 | smu->i2c_timer.function = smu_i2c_retry; | 549 | smu->i2c_timer.function = smu_i2c_retry; |
550 | smu->i2c_timer.data = (unsigned long)smu; | 550 | smu->i2c_timer.data = (unsigned long)smu; |
551 | 551 | ||
552 | /* | 552 | /* |
553 | * Try to request the interrupts | 553 | * Try to request the interrupts |
554 | */ | 554 | */ |
555 | 555 | ||
556 | if (smu->db_irq != NO_IRQ) { | 556 | if (smu->db_irq != NO_IRQ) { |
557 | if (request_irq(smu->db_irq, smu_db_intr, | 557 | if (request_irq(smu->db_irq, smu_db_intr, |
558 | SA_SHIRQ, "SMU doorbell", smu) < 0) { | 558 | SA_SHIRQ, "SMU doorbell", smu) < 0) { |
559 | printk(KERN_WARNING "SMU: can't " | 559 | printk(KERN_WARNING "SMU: can't " |
560 | "request interrupt %d\n", | 560 | "request interrupt %d\n", |
561 | smu->db_irq); | 561 | smu->db_irq); |
562 | smu->db_irq = NO_IRQ; | 562 | smu->db_irq = NO_IRQ; |
563 | } | 563 | } |
564 | } | 564 | } |
565 | 565 | ||
566 | if (smu->msg_irq != NO_IRQ) { | 566 | if (smu->msg_irq != NO_IRQ) { |
567 | if (request_irq(smu->msg_irq, smu_msg_intr, | 567 | if (request_irq(smu->msg_irq, smu_msg_intr, |
568 | SA_SHIRQ, "SMU message", smu) < 0) { | 568 | SA_SHIRQ, "SMU message", smu) < 0) { |
569 | printk(KERN_WARNING "SMU: can't " | 569 | printk(KERN_WARNING "SMU: can't " |
570 | "request interrupt %d\n", | 570 | "request interrupt %d\n", |
571 | smu->msg_irq); | 571 | smu->msg_irq); |
572 | smu->msg_irq = NO_IRQ; | 572 | smu->msg_irq = NO_IRQ; |
573 | } | 573 | } |
574 | } | 574 | } |
575 | 575 | ||
576 | return 0; | 576 | return 0; |
577 | } | 577 | } |
578 | /* This has to be before arch_initcall as the low i2c stuff relies on the | 578 | /* This has to be before arch_initcall as the low i2c stuff relies on the |
579 | * above having been done before we reach arch_initcalls | 579 | * above having been done before we reach arch_initcalls |
580 | */ | 580 | */ |
581 | core_initcall(smu_late_init); | 581 | core_initcall(smu_late_init); |
582 | 582 | ||
583 | /* | 583 | /* |
584 | * sysfs visibility | 584 | * sysfs visibility |
585 | */ | 585 | */ |
586 | 586 | ||
587 | static void smu_create_i2c(struct device_node *np) | ||
588 | { | ||
589 | char name[32]; | ||
590 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | ||
591 | |||
592 | if (reg != NULL) { | ||
593 | sprintf(name, "smu-i2c-%02x", *reg); | ||
594 | of_platform_device_create(np, name, &smu->of_dev->dev); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | static void smu_expose_childs(void *unused) | 587 | static void smu_expose_childs(void *unused) |
599 | { | 588 | { |
600 | struct device_node *np, *gp; | 589 | struct device_node *np; |
601 | 590 | ||
602 | for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) { | 591 | for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) |
603 | if (device_is_compatible(np, "smu-i2c-control")) { | ||
604 | gp = NULL; | ||
605 | while ((gp = of_get_next_child(np, gp)) != NULL) | ||
606 | if (device_is_compatible(gp, "i2c-bus")) | ||
607 | smu_create_i2c(gp); | ||
608 | } else if (device_is_compatible(np, "smu-i2c")) | ||
609 | smu_create_i2c(np); | ||
610 | if (device_is_compatible(np, "smu-sensors")) | 592 | if (device_is_compatible(np, "smu-sensors")) |
611 | of_platform_device_create(np, "smu-sensors", | 593 | of_platform_device_create(np, "smu-sensors", |
612 | &smu->of_dev->dev); | 594 | &smu->of_dev->dev); |
613 | } | ||
614 | |||
615 | } | 595 | } |
616 | 596 | ||
617 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); | 597 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); |
618 | 598 | ||
619 | static int smu_platform_probe(struct of_device* dev, | 599 | static int smu_platform_probe(struct of_device* dev, |
620 | const struct of_device_id *match) | 600 | const struct of_device_id *match) |
621 | { | 601 | { |
622 | if (!smu) | 602 | if (!smu) |
623 | return -ENODEV; | 603 | return -ENODEV; |
624 | smu->of_dev = dev; | 604 | smu->of_dev = dev; |
625 | 605 | ||
626 | /* | 606 | /* |
627 | * Ok, we are matched, now expose all i2c busses. We have to defer | 607 | * Ok, we are matched, now expose all i2c busses. We have to defer |
628 | * that unfortunately or it would deadlock inside the device model | 608 | * that unfortunately or it would deadlock inside the device model |
629 | */ | 609 | */ |
630 | schedule_work(&smu_expose_childs_work); | 610 | schedule_work(&smu_expose_childs_work); |
631 | 611 | ||
632 | return 0; | 612 | return 0; |
633 | } | 613 | } |
634 | 614 | ||
635 | static struct of_device_id smu_platform_match[] = | 615 | static struct of_device_id smu_platform_match[] = |
636 | { | 616 | { |
637 | { | 617 | { |
638 | .type = "smu", | 618 | .type = "smu", |
639 | }, | 619 | }, |
640 | {}, | 620 | {}, |
641 | }; | 621 | }; |
642 | 622 | ||
643 | static struct of_platform_driver smu_of_platform_driver = | 623 | static struct of_platform_driver smu_of_platform_driver = |
644 | { | 624 | { |
645 | .name = "smu", | 625 | .name = "smu", |
646 | .match_table = smu_platform_match, | 626 | .match_table = smu_platform_match, |
647 | .probe = smu_platform_probe, | 627 | .probe = smu_platform_probe, |
648 | }; | 628 | }; |
649 | 629 | ||
650 | static int __init smu_init_sysfs(void) | 630 | static int __init smu_init_sysfs(void) |
651 | { | 631 | { |
652 | int rc; | 632 | int rc; |
653 | 633 | ||
654 | /* | 634 | /* |
655 | * Due to sysfs bogosity, a sysdev is not a real device, so | 635 | * Due to sysfs bogosity, a sysdev is not a real device, so |
656 | * we should in fact create both if we want sysdev semantics | 636 | * we should in fact create both if we want sysdev semantics |
657 | * for power management. | 637 | * for power management. |
658 | * For now, we don't power manage machines with an SMU chip, | 638 | * For now, we don't power manage machines with an SMU chip, |
659 | * I'm a bit too far from figuring out how that works with those | 639 | * I'm a bit too far from figuring out how that works with those |
660 | * new chipsets, but that will come back and bite us | 640 | * new chipsets, but that will come back and bite us |
661 | */ | 641 | */ |
662 | rc = of_register_driver(&smu_of_platform_driver); | 642 | rc = of_register_driver(&smu_of_platform_driver); |
663 | return 0; | 643 | return 0; |
664 | } | 644 | } |
665 | 645 | ||
666 | device_initcall(smu_init_sysfs); | 646 | device_initcall(smu_init_sysfs); |
667 | 647 | ||
668 | struct of_device *smu_get_ofdev(void) | 648 | struct of_device *smu_get_ofdev(void) |
669 | { | 649 | { |
670 | if (!smu) | 650 | if (!smu) |
671 | return NULL; | 651 | return NULL; |
672 | return smu->of_dev; | 652 | return smu->of_dev; |
673 | } | 653 | } |
674 | 654 | ||
675 | EXPORT_SYMBOL_GPL(smu_get_ofdev); | 655 | EXPORT_SYMBOL_GPL(smu_get_ofdev); |
676 | 656 | ||
677 | /* | 657 | /* |
678 | * i2c interface | 658 | * i2c interface |
679 | */ | 659 | */ |
680 | 660 | ||
681 | static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail) | 661 | static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail) |
682 | { | 662 | { |
683 | void (*done)(struct smu_i2c_cmd *cmd, void *misc) = cmd->done; | 663 | void (*done)(struct smu_i2c_cmd *cmd, void *misc) = cmd->done; |
684 | void *misc = cmd->misc; | 664 | void *misc = cmd->misc; |
685 | unsigned long flags; | 665 | unsigned long flags; |
686 | 666 | ||
687 | /* Check for read case */ | 667 | /* Check for read case */ |
688 | if (!fail && cmd->read) { | 668 | if (!fail && cmd->read) { |
689 | if (cmd->pdata[0] < 1) | 669 | if (cmd->pdata[0] < 1) |
690 | fail = 1; | 670 | fail = 1; |
691 | else | 671 | else |
692 | memcpy(cmd->info.data, &cmd->pdata[1], | 672 | memcpy(cmd->info.data, &cmd->pdata[1], |
693 | cmd->info.datalen); | 673 | cmd->info.datalen); |
694 | } | 674 | } |
695 | 675 | ||
696 | DPRINTK("SMU: completing, success: %d\n", !fail); | 676 | DPRINTK("SMU: completing, success: %d\n", !fail); |
697 | 677 | ||
698 | /* Update status and mark no pending i2c command with lock | 678 | /* Update status and mark no pending i2c command with lock |
699 | * held so nobody comes in while we dequeue an eventual | 679 | * held so nobody comes in while we dequeue an eventual |
700 | * pending next i2c command | 680 | * pending next i2c command |
701 | */ | 681 | */ |
702 | spin_lock_irqsave(&smu->lock, flags); | 682 | spin_lock_irqsave(&smu->lock, flags); |
703 | smu->cmd_i2c_cur = NULL; | 683 | smu->cmd_i2c_cur = NULL; |
704 | wmb(); | 684 | wmb(); |
705 | cmd->status = fail ? -EIO : 0; | 685 | cmd->status = fail ? -EIO : 0; |
706 | 686 | ||
707 | /* Is there another i2c command waiting ? */ | 687 | /* Is there another i2c command waiting ? */ |
708 | if (!list_empty(&smu->cmd_i2c_list)) { | 688 | if (!list_empty(&smu->cmd_i2c_list)) { |
709 | struct smu_i2c_cmd *newcmd; | 689 | struct smu_i2c_cmd *newcmd; |
710 | 690 | ||
711 | /* Fetch it, new current, remove from list */ | 691 | /* Fetch it, new current, remove from list */ |
712 | newcmd = list_entry(smu->cmd_i2c_list.next, | 692 | newcmd = list_entry(smu->cmd_i2c_list.next, |
713 | struct smu_i2c_cmd, link); | 693 | struct smu_i2c_cmd, link); |
714 | smu->cmd_i2c_cur = newcmd; | 694 | smu->cmd_i2c_cur = newcmd; |
715 | list_del(&cmd->link); | 695 | list_del(&cmd->link); |
716 | 696 | ||
717 | /* Queue with low level smu */ | 697 | /* Queue with low level smu */ |
718 | list_add_tail(&cmd->scmd.link, &smu->cmd_list); | 698 | list_add_tail(&cmd->scmd.link, &smu->cmd_list); |
719 | if (smu->cmd_cur == NULL) | 699 | if (smu->cmd_cur == NULL) |
720 | smu_start_cmd(); | 700 | smu_start_cmd(); |
721 | } | 701 | } |
722 | spin_unlock_irqrestore(&smu->lock, flags); | 702 | spin_unlock_irqrestore(&smu->lock, flags); |
723 | 703 | ||
724 | /* Call command completion handler if any */ | 704 | /* Call command completion handler if any */ |
725 | if (done) | 705 | if (done) |
726 | done(cmd, misc); | 706 | done(cmd, misc); |
727 | 707 | ||
728 | } | 708 | } |
729 | 709 | ||
730 | 710 | ||
731 | static void smu_i2c_retry(unsigned long data) | 711 | static void smu_i2c_retry(unsigned long data) |
732 | { | 712 | { |
733 | struct smu_i2c_cmd *cmd = smu->cmd_i2c_cur; | 713 | struct smu_i2c_cmd *cmd = smu->cmd_i2c_cur; |
734 | 714 | ||
735 | DPRINTK("SMU: i2c failure, requeuing...\n"); | 715 | DPRINTK("SMU: i2c failure, requeuing...\n"); |
736 | 716 | ||
737 | /* requeue command simply by resetting reply_len */ | 717 | /* requeue command simply by resetting reply_len */ |
738 | cmd->pdata[0] = 0xff; | 718 | cmd->pdata[0] = 0xff; |
739 | cmd->scmd.reply_len = sizeof(cmd->pdata); | 719 | cmd->scmd.reply_len = sizeof(cmd->pdata); |
740 | smu_queue_cmd(&cmd->scmd); | 720 | smu_queue_cmd(&cmd->scmd); |
741 | } | 721 | } |
742 | 722 | ||
743 | 723 | ||
744 | static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) | 724 | static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) |
745 | { | 725 | { |
746 | struct smu_i2c_cmd *cmd = misc; | 726 | struct smu_i2c_cmd *cmd = misc; |
747 | int fail = 0; | 727 | int fail = 0; |
748 | 728 | ||
749 | DPRINTK("SMU: i2c compl. stage=%d status=%x pdata[0]=%x rlen: %x\n", | 729 | DPRINTK("SMU: i2c compl. stage=%d status=%x pdata[0]=%x rlen: %x\n", |
750 | cmd->stage, scmd->status, cmd->pdata[0], scmd->reply_len); | 730 | cmd->stage, scmd->status, cmd->pdata[0], scmd->reply_len); |
751 | 731 | ||
752 | /* Check for possible status */ | 732 | /* Check for possible status */ |
753 | if (scmd->status < 0) | 733 | if (scmd->status < 0) |
754 | fail = 1; | 734 | fail = 1; |
755 | else if (cmd->read) { | 735 | else if (cmd->read) { |
756 | if (cmd->stage == 0) | 736 | if (cmd->stage == 0) |
757 | fail = cmd->pdata[0] != 0; | 737 | fail = cmd->pdata[0] != 0; |
758 | else | 738 | else |
759 | fail = cmd->pdata[0] >= 0x80; | 739 | fail = cmd->pdata[0] >= 0x80; |
760 | } else { | 740 | } else { |
761 | fail = cmd->pdata[0] != 0; | 741 | fail = cmd->pdata[0] != 0; |
762 | } | 742 | } |
763 | 743 | ||
764 | /* Handle failures by requeuing command, after 5ms interval | 744 | /* Handle failures by requeuing command, after 5ms interval |
765 | */ | 745 | */ |
766 | if (fail && --cmd->retries > 0) { | 746 | if (fail && --cmd->retries > 0) { |
767 | DPRINTK("SMU: i2c failure, starting timer...\n"); | 747 | DPRINTK("SMU: i2c failure, starting timer...\n"); |
768 | BUG_ON(cmd != smu->cmd_i2c_cur); | 748 | BUG_ON(cmd != smu->cmd_i2c_cur); |
769 | mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5)); | 749 | mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5)); |
770 | return; | 750 | return; |
771 | } | 751 | } |
772 | 752 | ||
773 | /* If failure or stage 1, command is complete */ | 753 | /* If failure or stage 1, command is complete */ |
774 | if (fail || cmd->stage != 0) { | 754 | if (fail || cmd->stage != 0) { |
775 | smu_i2c_complete_command(cmd, fail); | 755 | smu_i2c_complete_command(cmd, fail); |
776 | return; | 756 | return; |
777 | } | 757 | } |
778 | 758 | ||
779 | DPRINTK("SMU: going to stage 1\n"); | 759 | DPRINTK("SMU: going to stage 1\n"); |
780 | 760 | ||
781 | /* Ok, initial command complete, now poll status */ | 761 | /* Ok, initial command complete, now poll status */ |
782 | scmd->reply_buf = cmd->pdata; | 762 | scmd->reply_buf = cmd->pdata; |
783 | scmd->reply_len = sizeof(cmd->pdata); | 763 | scmd->reply_len = sizeof(cmd->pdata); |
784 | scmd->data_buf = cmd->pdata; | 764 | scmd->data_buf = cmd->pdata; |
785 | scmd->data_len = 1; | 765 | scmd->data_len = 1; |
786 | cmd->pdata[0] = 0; | 766 | cmd->pdata[0] = 0; |
787 | cmd->stage = 1; | 767 | cmd->stage = 1; |
788 | cmd->retries = 20; | 768 | cmd->retries = 20; |
789 | smu_queue_cmd(scmd); | 769 | smu_queue_cmd(scmd); |
790 | } | 770 | } |
791 | 771 | ||
792 | 772 | ||
793 | int smu_queue_i2c(struct smu_i2c_cmd *cmd) | 773 | int smu_queue_i2c(struct smu_i2c_cmd *cmd) |
794 | { | 774 | { |
795 | unsigned long flags; | 775 | unsigned long flags; |
796 | 776 | ||
797 | if (smu == NULL) | 777 | if (smu == NULL) |
798 | return -ENODEV; | 778 | return -ENODEV; |
799 | 779 | ||
800 | /* Fill most fields of scmd */ | 780 | /* Fill most fields of scmd */ |
801 | cmd->scmd.cmd = SMU_CMD_I2C_COMMAND; | 781 | cmd->scmd.cmd = SMU_CMD_I2C_COMMAND; |
802 | cmd->scmd.done = smu_i2c_low_completion; | 782 | cmd->scmd.done = smu_i2c_low_completion; |
803 | cmd->scmd.misc = cmd; | 783 | cmd->scmd.misc = cmd; |
804 | cmd->scmd.reply_buf = cmd->pdata; | 784 | cmd->scmd.reply_buf = cmd->pdata; |
805 | cmd->scmd.reply_len = sizeof(cmd->pdata); | 785 | cmd->scmd.reply_len = sizeof(cmd->pdata); |
806 | cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; | 786 | cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; |
807 | cmd->scmd.status = 1; | 787 | cmd->scmd.status = 1; |
808 | cmd->stage = 0; | 788 | cmd->stage = 0; |
809 | cmd->pdata[0] = 0xff; | 789 | cmd->pdata[0] = 0xff; |
810 | cmd->retries = 20; | 790 | cmd->retries = 20; |
811 | cmd->status = 1; | 791 | cmd->status = 1; |
812 | 792 | ||
813 | /* Check transfer type, sanitize some "info" fields | 793 | /* Check transfer type, sanitize some "info" fields |
814 | * based on transfer type and do more checking | 794 | * based on transfer type and do more checking |
815 | */ | 795 | */ |
816 | cmd->info.caddr = cmd->info.devaddr; | 796 | cmd->info.caddr = cmd->info.devaddr; |
817 | cmd->read = cmd->info.devaddr & 0x01; | 797 | cmd->read = cmd->info.devaddr & 0x01; |
818 | switch(cmd->info.type) { | 798 | switch(cmd->info.type) { |
819 | case SMU_I2C_TRANSFER_SIMPLE: | 799 | case SMU_I2C_TRANSFER_SIMPLE: |
820 | memset(&cmd->info.sublen, 0, 4); | 800 | memset(&cmd->info.sublen, 0, 4); |
821 | break; | 801 | break; |
822 | case SMU_I2C_TRANSFER_COMBINED: | 802 | case SMU_I2C_TRANSFER_COMBINED: |
823 | cmd->info.devaddr &= 0xfe; | 803 | cmd->info.devaddr &= 0xfe; |
824 | case SMU_I2C_TRANSFER_STDSUB: | 804 | case SMU_I2C_TRANSFER_STDSUB: |
825 | if (cmd->info.sublen > 3) | 805 | if (cmd->info.sublen > 3) |
826 | return -EINVAL; | 806 | return -EINVAL; |
827 | break; | 807 | break; |
828 | default: | 808 | default: |
829 | return -EINVAL; | 809 | return -EINVAL; |
830 | } | 810 | } |
831 | 811 | ||
832 | /* Finish setting up command based on transfer direction | 812 | /* Finish setting up command based on transfer direction |
833 | */ | 813 | */ |
834 | if (cmd->read) { | 814 | if (cmd->read) { |
835 | if (cmd->info.datalen > SMU_I2C_READ_MAX) | 815 | if (cmd->info.datalen > SMU_I2C_READ_MAX) |
836 | return -EINVAL; | 816 | return -EINVAL; |
837 | memset(cmd->info.data, 0xff, cmd->info.datalen); | 817 | memset(cmd->info.data, 0xff, cmd->info.datalen); |
838 | cmd->scmd.data_len = 9; | 818 | cmd->scmd.data_len = 9; |
839 | } else { | 819 | } else { |
840 | if (cmd->info.datalen > SMU_I2C_WRITE_MAX) | 820 | if (cmd->info.datalen > SMU_I2C_WRITE_MAX) |
841 | return -EINVAL; | 821 | return -EINVAL; |
842 | cmd->scmd.data_len = 9 + cmd->info.datalen; | 822 | cmd->scmd.data_len = 9 + cmd->info.datalen; |
843 | } | 823 | } |
844 | 824 | ||
845 | DPRINTK("SMU: i2c enqueuing command\n"); | 825 | DPRINTK("SMU: i2c enqueuing command\n"); |
846 | DPRINTK("SMU: %s, len=%d bus=%x addr=%x sub0=%x type=%x\n", | 826 | DPRINTK("SMU: %s, len=%d bus=%x addr=%x sub0=%x type=%x\n", |
847 | cmd->read ? "read" : "write", cmd->info.datalen, | 827 | cmd->read ? "read" : "write", cmd->info.datalen, |
848 | cmd->info.bus, cmd->info.caddr, | 828 | cmd->info.bus, cmd->info.caddr, |
849 | cmd->info.subaddr[0], cmd->info.type); | 829 | cmd->info.subaddr[0], cmd->info.type); |
850 | 830 | ||
851 | 831 | ||
852 | /* Enqueue command in i2c list, and if empty, enqueue also in | 832 | /* Enqueue command in i2c list, and if empty, enqueue also in |
853 | * main command list | 833 | * main command list |
854 | */ | 834 | */ |
855 | spin_lock_irqsave(&smu->lock, flags); | 835 | spin_lock_irqsave(&smu->lock, flags); |
856 | if (smu->cmd_i2c_cur == NULL) { | 836 | if (smu->cmd_i2c_cur == NULL) { |
857 | smu->cmd_i2c_cur = cmd; | 837 | smu->cmd_i2c_cur = cmd; |
858 | list_add_tail(&cmd->scmd.link, &smu->cmd_list); | 838 | list_add_tail(&cmd->scmd.link, &smu->cmd_list); |
859 | if (smu->cmd_cur == NULL) | 839 | if (smu->cmd_cur == NULL) |
860 | smu_start_cmd(); | 840 | smu_start_cmd(); |
861 | } else | 841 | } else |
862 | list_add_tail(&cmd->link, &smu->cmd_i2c_list); | 842 | list_add_tail(&cmd->link, &smu->cmd_i2c_list); |
863 | spin_unlock_irqrestore(&smu->lock, flags); | 843 | spin_unlock_irqrestore(&smu->lock, flags); |
864 | 844 | ||
865 | return 0; | 845 | return 0; |
866 | } | 846 | } |
867 | 847 | ||
868 | /* | 848 | /* |
869 | * Handling of "partitions" | 849 | * Handling of "partitions" |
870 | */ | 850 | */ |
871 | 851 | ||
872 | static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len) | 852 | static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len) |
873 | { | 853 | { |
874 | DECLARE_COMPLETION(comp); | 854 | DECLARE_COMPLETION(comp); |
875 | unsigned int chunk; | 855 | unsigned int chunk; |
876 | struct smu_cmd cmd; | 856 | struct smu_cmd cmd; |
877 | int rc; | 857 | int rc; |
878 | u8 params[8]; | 858 | u8 params[8]; |
879 | 859 | ||
880 | /* We currently use a chunk size of 0xe. We could check the | 860 | /* We currently use a chunk size of 0xe. We could check the |
881 | * SMU firmware version and use bigger sizes though | 861 | * SMU firmware version and use bigger sizes though |
882 | */ | 862 | */ |
883 | chunk = 0xe; | 863 | chunk = 0xe; |
884 | 864 | ||
885 | while (len) { | 865 | while (len) { |
886 | unsigned int clen = min(len, chunk); | 866 | unsigned int clen = min(len, chunk); |
887 | 867 | ||
888 | cmd.cmd = SMU_CMD_MISC_ee_COMMAND; | 868 | cmd.cmd = SMU_CMD_MISC_ee_COMMAND; |
889 | cmd.data_len = 7; | 869 | cmd.data_len = 7; |
890 | cmd.data_buf = params; | 870 | cmd.data_buf = params; |
891 | cmd.reply_len = chunk; | 871 | cmd.reply_len = chunk; |
892 | cmd.reply_buf = dest; | 872 | cmd.reply_buf = dest; |
893 | cmd.done = smu_done_complete; | 873 | cmd.done = smu_done_complete; |
894 | cmd.misc = ∁ | 874 | cmd.misc = ∁ |
895 | params[0] = SMU_CMD_MISC_ee_GET_DATABLOCK_REC; | 875 | params[0] = SMU_CMD_MISC_ee_GET_DATABLOCK_REC; |
896 | params[1] = 0x4; | 876 | params[1] = 0x4; |
897 | *((u32 *)¶ms[2]) = addr; | 877 | *((u32 *)¶ms[2]) = addr; |
898 | params[6] = clen; | 878 | params[6] = clen; |
899 | 879 | ||
900 | rc = smu_queue_cmd(&cmd); | 880 | rc = smu_queue_cmd(&cmd); |
901 | if (rc) | 881 | if (rc) |
902 | return rc; | 882 | return rc; |
903 | wait_for_completion(&comp); | 883 | wait_for_completion(&comp); |
904 | if (cmd.status != 0) | 884 | if (cmd.status != 0) |
905 | return rc; | 885 | return rc; |
906 | if (cmd.reply_len != clen) { | 886 | if (cmd.reply_len != clen) { |
907 | printk(KERN_DEBUG "SMU: short read in " | 887 | printk(KERN_DEBUG "SMU: short read in " |
908 | "smu_read_datablock, got: %d, want: %d\n", | 888 | "smu_read_datablock, got: %d, want: %d\n", |
909 | cmd.reply_len, clen); | 889 | cmd.reply_len, clen); |
910 | return -EIO; | 890 | return -EIO; |
911 | } | 891 | } |
912 | len -= clen; | 892 | len -= clen; |
913 | addr += clen; | 893 | addr += clen; |
914 | dest += clen; | 894 | dest += clen; |
915 | } | 895 | } |
916 | return 0; | 896 | return 0; |
917 | } | 897 | } |
918 | 898 | ||
919 | static struct smu_sdbp_header *smu_create_sdb_partition(int id) | 899 | static struct smu_sdbp_header *smu_create_sdb_partition(int id) |
920 | { | 900 | { |
921 | DECLARE_COMPLETION(comp); | 901 | DECLARE_COMPLETION(comp); |
922 | struct smu_simple_cmd cmd; | 902 | struct smu_simple_cmd cmd; |
923 | unsigned int addr, len, tlen; | 903 | unsigned int addr, len, tlen; |
924 | struct smu_sdbp_header *hdr; | 904 | struct smu_sdbp_header *hdr; |
925 | struct property *prop; | 905 | struct property *prop; |
926 | 906 | ||
927 | /* First query the partition info */ | 907 | /* First query the partition info */ |
928 | DPRINTK("SMU: Query partition infos ... (irq=%d)\n", smu->db_irq); | 908 | DPRINTK("SMU: Query partition infos ... (irq=%d)\n", smu->db_irq); |
929 | smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2, | 909 | smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2, |
930 | smu_done_complete, &comp, | 910 | smu_done_complete, &comp, |
931 | SMU_CMD_PARTITION_LATEST, id); | 911 | SMU_CMD_PARTITION_LATEST, id); |
932 | wait_for_completion(&comp); | 912 | wait_for_completion(&comp); |
933 | DPRINTK("SMU: done, status: %d, reply_len: %d\n", | 913 | DPRINTK("SMU: done, status: %d, reply_len: %d\n", |
934 | cmd.cmd.status, cmd.cmd.reply_len); | 914 | cmd.cmd.status, cmd.cmd.reply_len); |
935 | 915 | ||
936 | /* Partition doesn't exist (or other error) */ | 916 | /* Partition doesn't exist (or other error) */ |
937 | if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6) | 917 | if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6) |
938 | return NULL; | 918 | return NULL; |
939 | 919 | ||
940 | /* Fetch address and length from reply */ | 920 | /* Fetch address and length from reply */ |
941 | addr = *((u16 *)cmd.buffer); | 921 | addr = *((u16 *)cmd.buffer); |
942 | len = cmd.buffer[3] << 2; | 922 | len = cmd.buffer[3] << 2; |
943 | /* Calucluate total length to allocate, including the 17 bytes | 923 | /* Calucluate total length to allocate, including the 17 bytes |
944 | * for "sdb-partition-XX" that we append at the end of the buffer | 924 | * for "sdb-partition-XX" that we append at the end of the buffer |
945 | */ | 925 | */ |
946 | tlen = sizeof(struct property) + len + 18; | 926 | tlen = sizeof(struct property) + len + 18; |
947 | 927 | ||
948 | prop = kcalloc(tlen, 1, GFP_KERNEL); | 928 | prop = kcalloc(tlen, 1, GFP_KERNEL); |
949 | if (prop == NULL) | 929 | if (prop == NULL) |
950 | return NULL; | 930 | return NULL; |
951 | hdr = (struct smu_sdbp_header *)(prop + 1); | 931 | hdr = (struct smu_sdbp_header *)(prop + 1); |
952 | prop->name = ((char *)prop) + tlen - 18; | 932 | prop->name = ((char *)prop) + tlen - 18; |
953 | sprintf(prop->name, "sdb-partition-%02x", id); | 933 | sprintf(prop->name, "sdb-partition-%02x", id); |
954 | prop->length = len; | 934 | prop->length = len; |
955 | prop->value = (unsigned char *)hdr; | 935 | prop->value = (unsigned char *)hdr; |
956 | prop->next = NULL; | 936 | prop->next = NULL; |
957 | 937 | ||
958 | /* Read the datablock */ | 938 | /* Read the datablock */ |
959 | if (smu_read_datablock((u8 *)hdr, addr, len)) { | 939 | if (smu_read_datablock((u8 *)hdr, addr, len)) { |
960 | printk(KERN_DEBUG "SMU: datablock read failed while reading " | 940 | printk(KERN_DEBUG "SMU: datablock read failed while reading " |
961 | "partition %02x !\n", id); | 941 | "partition %02x !\n", id); |
962 | goto failure; | 942 | goto failure; |
963 | } | 943 | } |
964 | 944 | ||
965 | /* Got it, check a few things and create the property */ | 945 | /* Got it, check a few things and create the property */ |
966 | if (hdr->id != id) { | 946 | if (hdr->id != id) { |
967 | printk(KERN_DEBUG "SMU: Reading partition %02x and got " | 947 | printk(KERN_DEBUG "SMU: Reading partition %02x and got " |
968 | "%02x !\n", id, hdr->id); | 948 | "%02x !\n", id, hdr->id); |
969 | goto failure; | 949 | goto failure; |
970 | } | 950 | } |
971 | if (prom_add_property(smu->of_node, prop)) { | 951 | if (prom_add_property(smu->of_node, prop)) { |
972 | printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x " | 952 | printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x " |
973 | "property !\n", id); | 953 | "property !\n", id); |
974 | goto failure; | 954 | goto failure; |
975 | } | 955 | } |
976 | 956 | ||
977 | return hdr; | 957 | return hdr; |
978 | failure: | 958 | failure: |
979 | kfree(prop); | 959 | kfree(prop); |
980 | return NULL; | 960 | return NULL; |
981 | } | 961 | } |
982 | 962 | ||
983 | /* Note: Only allowed to return error code in pointers (using ERR_PTR) | 963 | /* Note: Only allowed to return error code in pointers (using ERR_PTR) |
984 | * when interruptible is 1 | 964 | * when interruptible is 1 |
985 | */ | 965 | */ |
986 | struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, | 966 | struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, |
987 | int interruptible) | 967 | int interruptible) |
988 | { | 968 | { |
989 | char pname[32]; | 969 | char pname[32]; |
990 | struct smu_sdbp_header *part; | 970 | struct smu_sdbp_header *part; |
991 | 971 | ||
992 | if (!smu) | 972 | if (!smu) |
993 | return NULL; | 973 | return NULL; |
994 | 974 | ||
995 | sprintf(pname, "sdb-partition-%02x", id); | 975 | sprintf(pname, "sdb-partition-%02x", id); |
996 | 976 | ||
997 | DPRINTK("smu_get_sdb_partition(%02x)\n", id); | 977 | DPRINTK("smu_get_sdb_partition(%02x)\n", id); |
998 | 978 | ||
999 | if (interruptible) { | 979 | if (interruptible) { |
1000 | int rc; | 980 | int rc; |
1001 | rc = down_interruptible(&smu_part_access); | 981 | rc = down_interruptible(&smu_part_access); |
1002 | if (rc) | 982 | if (rc) |
1003 | return ERR_PTR(rc); | 983 | return ERR_PTR(rc); |
1004 | } else | 984 | } else |
1005 | down(&smu_part_access); | 985 | down(&smu_part_access); |
1006 | 986 | ||
1007 | part = (struct smu_sdbp_header *)get_property(smu->of_node, | 987 | part = (struct smu_sdbp_header *)get_property(smu->of_node, |
1008 | pname, size); | 988 | pname, size); |
1009 | if (part == NULL) { | 989 | if (part == NULL) { |
1010 | DPRINTK("trying to extract from SMU ...\n"); | 990 | DPRINTK("trying to extract from SMU ...\n"); |
1011 | part = smu_create_sdb_partition(id); | 991 | part = smu_create_sdb_partition(id); |
1012 | if (part != NULL && size) | 992 | if (part != NULL && size) |
1013 | *size = part->len << 2; | 993 | *size = part->len << 2; |
1014 | } | 994 | } |
1015 | up(&smu_part_access); | 995 | up(&smu_part_access); |
1016 | return part; | 996 | return part; |
1017 | } | 997 | } |
1018 | 998 | ||
1019 | struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size) | 999 | struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size) |
1020 | { | 1000 | { |
1021 | return __smu_get_sdb_partition(id, size, 0); | 1001 | return __smu_get_sdb_partition(id, size, 0); |
1022 | } | 1002 | } |
1023 | EXPORT_SYMBOL(smu_get_sdb_partition); | 1003 | EXPORT_SYMBOL(smu_get_sdb_partition); |
1024 | 1004 | ||
1025 | 1005 | ||
1026 | /* | 1006 | /* |
1027 | * Userland driver interface | 1007 | * Userland driver interface |
1028 | */ | 1008 | */ |
1029 | 1009 | ||
1030 | 1010 | ||
1031 | static LIST_HEAD(smu_clist); | 1011 | static LIST_HEAD(smu_clist); |
1032 | static DEFINE_SPINLOCK(smu_clist_lock); | 1012 | static DEFINE_SPINLOCK(smu_clist_lock); |
1033 | 1013 | ||
1034 | enum smu_file_mode { | 1014 | enum smu_file_mode { |
1035 | smu_file_commands, | 1015 | smu_file_commands, |
1036 | smu_file_events, | 1016 | smu_file_events, |
1037 | smu_file_closing | 1017 | smu_file_closing |
1038 | }; | 1018 | }; |
1039 | 1019 | ||
1040 | struct smu_private | 1020 | struct smu_private |
1041 | { | 1021 | { |
1042 | struct list_head list; | 1022 | struct list_head list; |
1043 | enum smu_file_mode mode; | 1023 | enum smu_file_mode mode; |
1044 | int busy; | 1024 | int busy; |
1045 | struct smu_cmd cmd; | 1025 | struct smu_cmd cmd; |
1046 | spinlock_t lock; | 1026 | spinlock_t lock; |
1047 | wait_queue_head_t wait; | 1027 | wait_queue_head_t wait; |
1048 | u8 buffer[SMU_MAX_DATA]; | 1028 | u8 buffer[SMU_MAX_DATA]; |
1049 | }; | 1029 | }; |
1050 | 1030 | ||
1051 | 1031 | ||
1052 | static int smu_open(struct inode *inode, struct file *file) | 1032 | static int smu_open(struct inode *inode, struct file *file) |
1053 | { | 1033 | { |
1054 | struct smu_private *pp; | 1034 | struct smu_private *pp; |
1055 | unsigned long flags; | 1035 | unsigned long flags; |
1056 | 1036 | ||
1057 | pp = kmalloc(sizeof(struct smu_private), GFP_KERNEL); | 1037 | pp = kmalloc(sizeof(struct smu_private), GFP_KERNEL); |
1058 | if (pp == 0) | 1038 | if (pp == 0) |
1059 | return -ENOMEM; | 1039 | return -ENOMEM; |
1060 | memset(pp, 0, sizeof(struct smu_private)); | 1040 | memset(pp, 0, sizeof(struct smu_private)); |
1061 | spin_lock_init(&pp->lock); | 1041 | spin_lock_init(&pp->lock); |
1062 | pp->mode = smu_file_commands; | 1042 | pp->mode = smu_file_commands; |
1063 | init_waitqueue_head(&pp->wait); | 1043 | init_waitqueue_head(&pp->wait); |
1064 | 1044 | ||
1065 | spin_lock_irqsave(&smu_clist_lock, flags); | 1045 | spin_lock_irqsave(&smu_clist_lock, flags); |
1066 | list_add(&pp->list, &smu_clist); | 1046 | list_add(&pp->list, &smu_clist); |
1067 | spin_unlock_irqrestore(&smu_clist_lock, flags); | 1047 | spin_unlock_irqrestore(&smu_clist_lock, flags); |
1068 | file->private_data = pp; | 1048 | file->private_data = pp; |
1069 | 1049 | ||
1070 | return 0; | 1050 | return 0; |
1071 | } | 1051 | } |
1072 | 1052 | ||
1073 | 1053 | ||
1074 | static void smu_user_cmd_done(struct smu_cmd *cmd, void *misc) | 1054 | static void smu_user_cmd_done(struct smu_cmd *cmd, void *misc) |
1075 | { | 1055 | { |
1076 | struct smu_private *pp = misc; | 1056 | struct smu_private *pp = misc; |
1077 | 1057 | ||
1078 | wake_up_all(&pp->wait); | 1058 | wake_up_all(&pp->wait); |
1079 | } | 1059 | } |
1080 | 1060 | ||
1081 | 1061 | ||
1082 | static ssize_t smu_write(struct file *file, const char __user *buf, | 1062 | static ssize_t smu_write(struct file *file, const char __user *buf, |
1083 | size_t count, loff_t *ppos) | 1063 | size_t count, loff_t *ppos) |
1084 | { | 1064 | { |
1085 | struct smu_private *pp = file->private_data; | 1065 | struct smu_private *pp = file->private_data; |
1086 | unsigned long flags; | 1066 | unsigned long flags; |
1087 | struct smu_user_cmd_hdr hdr; | 1067 | struct smu_user_cmd_hdr hdr; |
1088 | int rc = 0; | 1068 | int rc = 0; |
1089 | 1069 | ||
1090 | if (pp->busy) | 1070 | if (pp->busy) |
1091 | return -EBUSY; | 1071 | return -EBUSY; |
1092 | else if (copy_from_user(&hdr, buf, sizeof(hdr))) | 1072 | else if (copy_from_user(&hdr, buf, sizeof(hdr))) |
1093 | return -EFAULT; | 1073 | return -EFAULT; |
1094 | else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) { | 1074 | else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) { |
1095 | pp->mode = smu_file_events; | 1075 | pp->mode = smu_file_events; |
1096 | return 0; | 1076 | return 0; |
1097 | } else if (hdr.cmdtype == SMU_CMDTYPE_GET_PARTITION) { | 1077 | } else if (hdr.cmdtype == SMU_CMDTYPE_GET_PARTITION) { |
1098 | struct smu_sdbp_header *part; | 1078 | struct smu_sdbp_header *part; |
1099 | part = __smu_get_sdb_partition(hdr.cmd, NULL, 1); | 1079 | part = __smu_get_sdb_partition(hdr.cmd, NULL, 1); |
1100 | if (part == NULL) | 1080 | if (part == NULL) |
1101 | return -EINVAL; | 1081 | return -EINVAL; |
1102 | else if (IS_ERR(part)) | 1082 | else if (IS_ERR(part)) |
1103 | return PTR_ERR(part); | 1083 | return PTR_ERR(part); |
1104 | return 0; | 1084 | return 0; |
1105 | } else if (hdr.cmdtype != SMU_CMDTYPE_SMU) | 1085 | } else if (hdr.cmdtype != SMU_CMDTYPE_SMU) |
1106 | return -EINVAL; | 1086 | return -EINVAL; |
1107 | else if (pp->mode != smu_file_commands) | 1087 | else if (pp->mode != smu_file_commands) |
1108 | return -EBADFD; | 1088 | return -EBADFD; |
1109 | else if (hdr.data_len > SMU_MAX_DATA) | 1089 | else if (hdr.data_len > SMU_MAX_DATA) |
1110 | return -EINVAL; | 1090 | return -EINVAL; |
1111 | 1091 | ||
1112 | spin_lock_irqsave(&pp->lock, flags); | 1092 | spin_lock_irqsave(&pp->lock, flags); |
1113 | if (pp->busy) { | 1093 | if (pp->busy) { |
1114 | spin_unlock_irqrestore(&pp->lock, flags); | 1094 | spin_unlock_irqrestore(&pp->lock, flags); |
1115 | return -EBUSY; | 1095 | return -EBUSY; |
1116 | } | 1096 | } |
1117 | pp->busy = 1; | 1097 | pp->busy = 1; |
1118 | pp->cmd.status = 1; | 1098 | pp->cmd.status = 1; |
1119 | spin_unlock_irqrestore(&pp->lock, flags); | 1099 | spin_unlock_irqrestore(&pp->lock, flags); |
1120 | 1100 | ||
1121 | if (copy_from_user(pp->buffer, buf + sizeof(hdr), hdr.data_len)) { | 1101 | if (copy_from_user(pp->buffer, buf + sizeof(hdr), hdr.data_len)) { |
1122 | pp->busy = 0; | 1102 | pp->busy = 0; |
1123 | return -EFAULT; | 1103 | return -EFAULT; |
1124 | } | 1104 | } |
1125 | 1105 | ||
1126 | pp->cmd.cmd = hdr.cmd; | 1106 | pp->cmd.cmd = hdr.cmd; |
1127 | pp->cmd.data_len = hdr.data_len; | 1107 | pp->cmd.data_len = hdr.data_len; |
1128 | pp->cmd.reply_len = SMU_MAX_DATA; | 1108 | pp->cmd.reply_len = SMU_MAX_DATA; |
1129 | pp->cmd.data_buf = pp->buffer; | 1109 | pp->cmd.data_buf = pp->buffer; |
1130 | pp->cmd.reply_buf = pp->buffer; | 1110 | pp->cmd.reply_buf = pp->buffer; |
1131 | pp->cmd.done = smu_user_cmd_done; | 1111 | pp->cmd.done = smu_user_cmd_done; |
1132 | pp->cmd.misc = pp; | 1112 | pp->cmd.misc = pp; |
1133 | rc = smu_queue_cmd(&pp->cmd); | 1113 | rc = smu_queue_cmd(&pp->cmd); |
1134 | if (rc < 0) | 1114 | if (rc < 0) |
1135 | return rc; | 1115 | return rc; |
1136 | return count; | 1116 | return count; |
1137 | } | 1117 | } |
1138 | 1118 | ||
1139 | 1119 | ||
1140 | static ssize_t smu_read_command(struct file *file, struct smu_private *pp, | 1120 | static ssize_t smu_read_command(struct file *file, struct smu_private *pp, |
1141 | char __user *buf, size_t count) | 1121 | char __user *buf, size_t count) |
1142 | { | 1122 | { |
1143 | DECLARE_WAITQUEUE(wait, current); | 1123 | DECLARE_WAITQUEUE(wait, current); |
1144 | struct smu_user_reply_hdr hdr; | 1124 | struct smu_user_reply_hdr hdr; |
1145 | unsigned long flags; | 1125 | unsigned long flags; |
1146 | int size, rc = 0; | 1126 | int size, rc = 0; |
1147 | 1127 | ||
1148 | if (!pp->busy) | 1128 | if (!pp->busy) |
1149 | return 0; | 1129 | return 0; |
1150 | if (count < sizeof(struct smu_user_reply_hdr)) | 1130 | if (count < sizeof(struct smu_user_reply_hdr)) |
1151 | return -EOVERFLOW; | 1131 | return -EOVERFLOW; |
1152 | spin_lock_irqsave(&pp->lock, flags); | 1132 | spin_lock_irqsave(&pp->lock, flags); |
1153 | if (pp->cmd.status == 1) { | 1133 | if (pp->cmd.status == 1) { |
1154 | if (file->f_flags & O_NONBLOCK) | 1134 | if (file->f_flags & O_NONBLOCK) |
1155 | return -EAGAIN; | 1135 | return -EAGAIN; |
1156 | add_wait_queue(&pp->wait, &wait); | 1136 | add_wait_queue(&pp->wait, &wait); |
1157 | for (;;) { | 1137 | for (;;) { |
1158 | set_current_state(TASK_INTERRUPTIBLE); | 1138 | set_current_state(TASK_INTERRUPTIBLE); |
1159 | rc = 0; | 1139 | rc = 0; |
1160 | if (pp->cmd.status != 1) | 1140 | if (pp->cmd.status != 1) |
1161 | break; | 1141 | break; |
1162 | rc = -ERESTARTSYS; | 1142 | rc = -ERESTARTSYS; |
1163 | if (signal_pending(current)) | 1143 | if (signal_pending(current)) |
1164 | break; | 1144 | break; |
1165 | spin_unlock_irqrestore(&pp->lock, flags); | 1145 | spin_unlock_irqrestore(&pp->lock, flags); |
1166 | schedule(); | 1146 | schedule(); |
1167 | spin_lock_irqsave(&pp->lock, flags); | 1147 | spin_lock_irqsave(&pp->lock, flags); |
1168 | } | 1148 | } |
1169 | set_current_state(TASK_RUNNING); | 1149 | set_current_state(TASK_RUNNING); |
1170 | remove_wait_queue(&pp->wait, &wait); | 1150 | remove_wait_queue(&pp->wait, &wait); |
1171 | } | 1151 | } |
1172 | spin_unlock_irqrestore(&pp->lock, flags); | 1152 | spin_unlock_irqrestore(&pp->lock, flags); |
1173 | if (rc) | 1153 | if (rc) |
1174 | return rc; | 1154 | return rc; |
1175 | if (pp->cmd.status != 0) | 1155 | if (pp->cmd.status != 0) |
1176 | pp->cmd.reply_len = 0; | 1156 | pp->cmd.reply_len = 0; |
1177 | size = sizeof(hdr) + pp->cmd.reply_len; | 1157 | size = sizeof(hdr) + pp->cmd.reply_len; |
1178 | if (count < size) | 1158 | if (count < size) |
1179 | size = count; | 1159 | size = count; |
1180 | rc = size; | 1160 | rc = size; |
1181 | hdr.status = pp->cmd.status; | 1161 | hdr.status = pp->cmd.status; |
1182 | hdr.reply_len = pp->cmd.reply_len; | 1162 | hdr.reply_len = pp->cmd.reply_len; |
1183 | if (copy_to_user(buf, &hdr, sizeof(hdr))) | 1163 | if (copy_to_user(buf, &hdr, sizeof(hdr))) |
1184 | return -EFAULT; | 1164 | return -EFAULT; |
1185 | size -= sizeof(hdr); | 1165 | size -= sizeof(hdr); |
1186 | if (size && copy_to_user(buf + sizeof(hdr), pp->buffer, size)) | 1166 | if (size && copy_to_user(buf + sizeof(hdr), pp->buffer, size)) |
1187 | return -EFAULT; | 1167 | return -EFAULT; |
1188 | pp->busy = 0; | 1168 | pp->busy = 0; |
1189 | 1169 | ||
1190 | return rc; | 1170 | return rc; |
1191 | } | 1171 | } |
1192 | 1172 | ||
1193 | 1173 | ||
1194 | static ssize_t smu_read_events(struct file *file, struct smu_private *pp, | 1174 | static ssize_t smu_read_events(struct file *file, struct smu_private *pp, |
1195 | char __user *buf, size_t count) | 1175 | char __user *buf, size_t count) |
1196 | { | 1176 | { |
1197 | /* Not implemented */ | 1177 | /* Not implemented */ |
1198 | msleep_interruptible(1000); | 1178 | msleep_interruptible(1000); |
1199 | return 0; | 1179 | return 0; |
1200 | } | 1180 | } |
1201 | 1181 | ||
1202 | 1182 | ||
1203 | static ssize_t smu_read(struct file *file, char __user *buf, | 1183 | static ssize_t smu_read(struct file *file, char __user *buf, |
1204 | size_t count, loff_t *ppos) | 1184 | size_t count, loff_t *ppos) |
1205 | { | 1185 | { |
1206 | struct smu_private *pp = file->private_data; | 1186 | struct smu_private *pp = file->private_data; |
1207 | 1187 | ||
1208 | if (pp->mode == smu_file_commands) | 1188 | if (pp->mode == smu_file_commands) |
1209 | return smu_read_command(file, pp, buf, count); | 1189 | return smu_read_command(file, pp, buf, count); |
1210 | if (pp->mode == smu_file_events) | 1190 | if (pp->mode == smu_file_events) |
1211 | return smu_read_events(file, pp, buf, count); | 1191 | return smu_read_events(file, pp, buf, count); |
1212 | 1192 | ||
1213 | return -EBADFD; | 1193 | return -EBADFD; |
1214 | } | 1194 | } |
1215 | 1195 | ||
1216 | static unsigned int smu_fpoll(struct file *file, poll_table *wait) | 1196 | static unsigned int smu_fpoll(struct file *file, poll_table *wait) |
1217 | { | 1197 | { |
1218 | struct smu_private *pp = file->private_data; | 1198 | struct smu_private *pp = file->private_data; |
1219 | unsigned int mask = 0; | 1199 | unsigned int mask = 0; |
1220 | unsigned long flags; | 1200 | unsigned long flags; |
1221 | 1201 | ||
1222 | if (pp == 0) | 1202 | if (pp == 0) |
1223 | return 0; | 1203 | return 0; |
1224 | 1204 | ||
1225 | if (pp->mode == smu_file_commands) { | 1205 | if (pp->mode == smu_file_commands) { |
1226 | poll_wait(file, &pp->wait, wait); | 1206 | poll_wait(file, &pp->wait, wait); |
1227 | 1207 | ||
1228 | spin_lock_irqsave(&pp->lock, flags); | 1208 | spin_lock_irqsave(&pp->lock, flags); |
1229 | if (pp->busy && pp->cmd.status != 1) | 1209 | if (pp->busy && pp->cmd.status != 1) |
1230 | mask |= POLLIN; | 1210 | mask |= POLLIN; |
1231 | spin_unlock_irqrestore(&pp->lock, flags); | 1211 | spin_unlock_irqrestore(&pp->lock, flags); |
1232 | } if (pp->mode == smu_file_events) { | 1212 | } if (pp->mode == smu_file_events) { |
1233 | /* Not yet implemented */ | 1213 | /* Not yet implemented */ |
1234 | } | 1214 | } |
1235 | return mask; | 1215 | return mask; |
1236 | } | 1216 | } |
1237 | 1217 | ||
1238 | static int smu_release(struct inode *inode, struct file *file) | 1218 | static int smu_release(struct inode *inode, struct file *file) |
1239 | { | 1219 | { |
1240 | struct smu_private *pp = file->private_data; | 1220 | struct smu_private *pp = file->private_data; |
1241 | unsigned long flags; | 1221 | unsigned long flags; |
1242 | unsigned int busy; | 1222 | unsigned int busy; |
1243 | 1223 | ||
1244 | if (pp == 0) | 1224 | if (pp == 0) |
1245 | return 0; | 1225 | return 0; |
1246 | 1226 | ||
1247 | file->private_data = NULL; | 1227 | file->private_data = NULL; |
1248 | 1228 | ||
1249 | /* Mark file as closing to avoid races with new request */ | 1229 | /* Mark file as closing to avoid races with new request */ |
1250 | spin_lock_irqsave(&pp->lock, flags); | 1230 | spin_lock_irqsave(&pp->lock, flags); |
1251 | pp->mode = smu_file_closing; | 1231 | pp->mode = smu_file_closing; |
1252 | busy = pp->busy; | 1232 | busy = pp->busy; |
1253 | 1233 | ||
1254 | /* Wait for any pending request to complete */ | 1234 | /* Wait for any pending request to complete */ |
1255 | if (busy && pp->cmd.status == 1) { | 1235 | if (busy && pp->cmd.status == 1) { |
1256 | DECLARE_WAITQUEUE(wait, current); | 1236 | DECLARE_WAITQUEUE(wait, current); |
1257 | 1237 | ||
1258 | add_wait_queue(&pp->wait, &wait); | 1238 | add_wait_queue(&pp->wait, &wait); |
1259 | for (;;) { | 1239 | for (;;) { |
1260 | set_current_state(TASK_UNINTERRUPTIBLE); | 1240 | set_current_state(TASK_UNINTERRUPTIBLE); |
1261 | if (pp->cmd.status != 1) | 1241 | if (pp->cmd.status != 1) |
1262 | break; | 1242 | break; |
1263 | spin_lock_irqsave(&pp->lock, flags); | 1243 | spin_lock_irqsave(&pp->lock, flags); |
1264 | schedule(); | 1244 | schedule(); |
1265 | spin_unlock_irqrestore(&pp->lock, flags); | 1245 | spin_unlock_irqrestore(&pp->lock, flags); |
1266 | } | 1246 | } |
1267 | set_current_state(TASK_RUNNING); | 1247 | set_current_state(TASK_RUNNING); |
1268 | remove_wait_queue(&pp->wait, &wait); | 1248 | remove_wait_queue(&pp->wait, &wait); |
1269 | } | 1249 | } |
1270 | spin_unlock_irqrestore(&pp->lock, flags); | 1250 | spin_unlock_irqrestore(&pp->lock, flags); |
1271 | 1251 | ||
1272 | spin_lock_irqsave(&smu_clist_lock, flags); | 1252 | spin_lock_irqsave(&smu_clist_lock, flags); |
1273 | list_del(&pp->list); | 1253 | list_del(&pp->list); |
1274 | spin_unlock_irqrestore(&smu_clist_lock, flags); | 1254 | spin_unlock_irqrestore(&smu_clist_lock, flags); |
1275 | kfree(pp); | 1255 | kfree(pp); |
1276 | 1256 | ||
1277 | return 0; | 1257 | return 0; |
1278 | } | 1258 | } |
1279 | 1259 | ||
1280 | 1260 | ||
1281 | static struct file_operations smu_device_fops = { | 1261 | static struct file_operations smu_device_fops = { |
1282 | .llseek = no_llseek, | 1262 | .llseek = no_llseek, |
1283 | .read = smu_read, | 1263 | .read = smu_read, |
1284 | .write = smu_write, | 1264 | .write = smu_write, |
1285 | .poll = smu_fpoll, | 1265 | .poll = smu_fpoll, |
1286 | .open = smu_open, | 1266 | .open = smu_open, |
1287 | .release = smu_release, | 1267 | .release = smu_release, |
1288 | }; | 1268 | }; |
1289 | 1269 | ||
1290 | static struct miscdevice pmu_device = { | 1270 | static struct miscdevice pmu_device = { |
1291 | MISC_DYNAMIC_MINOR, "smu", &smu_device_fops | 1271 | MISC_DYNAMIC_MINOR, "smu", &smu_device_fops |
1292 | }; | 1272 | }; |
1293 | 1273 | ||
1294 | static int smu_device_init(void) | 1274 | static int smu_device_init(void) |
1295 | { | 1275 | { |
1296 | if (!smu) | 1276 | if (!smu) |
1297 | return -ENODEV; | 1277 | return -ENODEV; |
1298 | if (misc_register(&pmu_device) < 0) | 1278 | if (misc_register(&pmu_device) < 0) |
1299 | printk(KERN_ERR "via-pmu: cannot register misc device.\n"); | 1279 | printk(KERN_ERR "via-pmu: cannot register misc device.\n"); |
1300 | return 0; | 1280 | return 0; |
1301 | } | 1281 | } |
1302 | device_initcall(smu_device_init); | 1282 | device_initcall(smu_device_init); |
1303 | 1283 |
drivers/macintosh/windfarm_lm75_sensor.c
1 | /* | 1 | /* |
2 | * Windfarm PowerMac thermal control. LM75 sensor | 2 | * Windfarm PowerMac thermal control. LM75 sensor |
3 | * | 3 | * |
4 | * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp. | 4 | * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp. |
5 | * <benh@kernel.crashing.org> | 5 | * <benh@kernel.crashing.org> |
6 | * | 6 | * |
7 | * Released under the term of the GNU GPL v2. | 7 | * Released under the term of the GNU GPL v2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/wait.h> | 16 | #include <linux/wait.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/i2c-dev.h> | 18 | #include <linux/i2c-dev.h> |
19 | #include <asm/prom.h> | 19 | #include <asm/prom.h> |
20 | #include <asm/machdep.h> | 20 | #include <asm/machdep.h> |
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #include <asm/system.h> | 22 | #include <asm/system.h> |
23 | #include <asm/sections.h> | 23 | #include <asm/sections.h> |
24 | #include <asm/pmac_low_i2c.h> | ||
24 | 25 | ||
25 | #include "windfarm.h" | 26 | #include "windfarm.h" |
26 | 27 | ||
27 | #define VERSION "0.1" | 28 | #define VERSION "0.1" |
28 | 29 | ||
29 | #undef DEBUG | 30 | #undef DEBUG |
30 | 31 | ||
31 | #ifdef DEBUG | 32 | #ifdef DEBUG |
32 | #define DBG(args...) printk(args) | 33 | #define DBG(args...) printk(args) |
33 | #else | 34 | #else |
34 | #define DBG(args...) do { } while(0) | 35 | #define DBG(args...) do { } while(0) |
35 | #endif | 36 | #endif |
36 | 37 | ||
37 | struct wf_lm75_sensor { | 38 | struct wf_lm75_sensor { |
38 | int ds1775 : 1; | 39 | int ds1775 : 1; |
39 | int inited : 1; | 40 | int inited : 1; |
40 | struct i2c_client i2c; | 41 | struct i2c_client i2c; |
41 | struct wf_sensor sens; | 42 | struct wf_sensor sens; |
42 | }; | 43 | }; |
43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) | 44 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) |
44 | #define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c) | 45 | #define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c) |
45 | 46 | ||
46 | static int wf_lm75_attach(struct i2c_adapter *adapter); | 47 | static int wf_lm75_attach(struct i2c_adapter *adapter); |
47 | static int wf_lm75_detach(struct i2c_client *client); | 48 | static int wf_lm75_detach(struct i2c_client *client); |
48 | 49 | ||
49 | static struct i2c_driver wf_lm75_driver = { | 50 | static struct i2c_driver wf_lm75_driver = { |
50 | .driver = { | 51 | .driver = { |
51 | .name = "wf_lm75", | 52 | .name = "wf_lm75", |
52 | }, | 53 | }, |
53 | .attach_adapter = wf_lm75_attach, | 54 | .attach_adapter = wf_lm75_attach, |
54 | .detach_client = wf_lm75_detach, | 55 | .detach_client = wf_lm75_detach, |
55 | }; | 56 | }; |
56 | 57 | ||
57 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | 58 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) |
58 | { | 59 | { |
59 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 60 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
60 | s32 data; | 61 | s32 data; |
61 | 62 | ||
62 | if (lm->i2c.adapter == NULL) | 63 | if (lm->i2c.adapter == NULL) |
63 | return -ENODEV; | 64 | return -ENODEV; |
64 | 65 | ||
65 | /* Init chip if necessary */ | 66 | /* Init chip if necessary */ |
66 | if (!lm->inited) { | 67 | if (!lm->inited) { |
67 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1); | 68 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1); |
68 | 69 | ||
69 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", | 70 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", |
70 | sr->name, cfg); | 71 | sr->name, cfg); |
71 | 72 | ||
72 | /* clear shutdown bit, keep other settings as left by | 73 | /* clear shutdown bit, keep other settings as left by |
73 | * the firmware for now | 74 | * the firmware for now |
74 | */ | 75 | */ |
75 | cfg_new = cfg & ~0x01; | 76 | cfg_new = cfg & ~0x01; |
76 | i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new); | 77 | i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new); |
77 | lm->inited = 1; | 78 | lm->inited = 1; |
78 | 79 | ||
79 | /* If we just powered it up, let's wait 200 ms */ | 80 | /* If we just powered it up, let's wait 200 ms */ |
80 | msleep(200); | 81 | msleep(200); |
81 | } | 82 | } |
82 | 83 | ||
83 | /* Read temperature register */ | 84 | /* Read temperature register */ |
84 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0)); | 85 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0)); |
85 | data <<= 8; | 86 | data <<= 8; |
86 | *value = data; | 87 | *value = data; |
87 | 88 | ||
88 | return 0; | 89 | return 0; |
89 | } | 90 | } |
90 | 91 | ||
91 | static void wf_lm75_release(struct wf_sensor *sr) | 92 | static void wf_lm75_release(struct wf_sensor *sr) |
92 | { | 93 | { |
93 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 94 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
94 | 95 | ||
95 | /* check if client is registered and detach from i2c */ | 96 | /* check if client is registered and detach from i2c */ |
96 | if (lm->i2c.adapter) { | 97 | if (lm->i2c.adapter) { |
97 | i2c_detach_client(&lm->i2c); | 98 | i2c_detach_client(&lm->i2c); |
98 | lm->i2c.adapter = NULL; | 99 | lm->i2c.adapter = NULL; |
99 | } | 100 | } |
100 | 101 | ||
101 | kfree(lm); | 102 | kfree(lm); |
102 | } | 103 | } |
103 | 104 | ||
104 | static struct wf_sensor_ops wf_lm75_ops = { | 105 | static struct wf_sensor_ops wf_lm75_ops = { |
105 | .get_value = wf_lm75_get, | 106 | .get_value = wf_lm75_get, |
106 | .release = wf_lm75_release, | 107 | .release = wf_lm75_release, |
107 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
108 | }; | 109 | }; |
109 | 110 | ||
110 | static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, | 111 | static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, |
111 | u8 addr, int ds1775, | 112 | u8 addr, int ds1775, |
112 | const char *loc) | 113 | const char *loc) |
113 | { | 114 | { |
114 | struct wf_lm75_sensor *lm; | 115 | struct wf_lm75_sensor *lm; |
115 | 116 | ||
116 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | 117 | DBG("wf_lm75: creating %s device at address 0x%02x\n", |
117 | ds1775 ? "ds1775" : "lm75", addr); | 118 | ds1775 ? "ds1775" : "lm75", addr); |
118 | 119 | ||
119 | lm = kmalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); | 120 | lm = kmalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); |
120 | if (lm == NULL) | 121 | if (lm == NULL) |
121 | return NULL; | 122 | return NULL; |
122 | memset(lm, 0, sizeof(struct wf_lm75_sensor)); | 123 | memset(lm, 0, sizeof(struct wf_lm75_sensor)); |
123 | 124 | ||
124 | /* Usual rant about sensor names not beeing very consistent in | 125 | /* Usual rant about sensor names not beeing very consistent in |
125 | * the device-tree, oh well ... | 126 | * the device-tree, oh well ... |
126 | * Add more entries below as you deal with more setups | 127 | * Add more entries below as you deal with more setups |
127 | */ | 128 | */ |
128 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) | 129 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) |
129 | lm->sens.name = "hd-temp"; | 130 | lm->sens.name = "hd-temp"; |
130 | else | 131 | else |
131 | goto fail; | 132 | goto fail; |
132 | 133 | ||
133 | lm->inited = 0; | 134 | lm->inited = 0; |
134 | lm->sens.ops = &wf_lm75_ops; | 135 | lm->sens.ops = &wf_lm75_ops; |
135 | lm->ds1775 = ds1775; | 136 | lm->ds1775 = ds1775; |
136 | lm->i2c.addr = (addr >> 1) & 0x7f; | 137 | lm->i2c.addr = (addr >> 1) & 0x7f; |
137 | lm->i2c.adapter = adapter; | 138 | lm->i2c.adapter = adapter; |
138 | lm->i2c.driver = &wf_lm75_driver; | 139 | lm->i2c.driver = &wf_lm75_driver; |
139 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); | 140 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); |
140 | 141 | ||
141 | if (i2c_attach_client(&lm->i2c)) { | 142 | if (i2c_attach_client(&lm->i2c)) { |
142 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", | 143 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", |
143 | ds1775 ? "ds1775" : "lm75", lm->i2c.name); | 144 | ds1775 ? "ds1775" : "lm75", lm->i2c.name); |
144 | goto fail; | 145 | goto fail; |
145 | } | 146 | } |
146 | 147 | ||
147 | if (wf_register_sensor(&lm->sens)) { | 148 | if (wf_register_sensor(&lm->sens)) { |
148 | i2c_detach_client(&lm->i2c); | 149 | i2c_detach_client(&lm->i2c); |
149 | goto fail; | 150 | goto fail; |
150 | } | 151 | } |
151 | 152 | ||
152 | return lm; | 153 | return lm; |
153 | fail: | 154 | fail: |
154 | kfree(lm); | 155 | kfree(lm); |
155 | return NULL; | 156 | return NULL; |
156 | } | 157 | } |
157 | 158 | ||
158 | static int wf_lm75_attach(struct i2c_adapter *adapter) | 159 | static int wf_lm75_attach(struct i2c_adapter *adapter) |
159 | { | 160 | { |
160 | u8 bus_id; | 161 | struct device_node *busnode, *dev; |
161 | struct device_node *smu, *bus, *dev; | 162 | struct pmac_i2c_bus *bus; |
162 | 163 | ||
163 | /* We currently only deal with LM75's hanging off the SMU | ||
164 | * i2c busses. If we extend that driver to other/older | ||
165 | * machines, we should split this function into SMU-i2c, | ||
166 | * keywest-i2c, PMU-i2c, ... | ||
167 | */ | ||
168 | |||
169 | DBG("wf_lm75: adapter %s detected\n", adapter->name); | 164 | DBG("wf_lm75: adapter %s detected\n", adapter->name); |
170 | 165 | ||
171 | if (strncmp(adapter->name, "smu-i2c-", 8) != 0) | 166 | bus = pmac_i2c_adapter_to_bus(adapter); |
172 | return 0; | 167 | if (bus == NULL) |
173 | smu = of_find_node_by_type(NULL, "smu"); | 168 | return -ENODEV; |
174 | if (smu == NULL) | 169 | busnode = pmac_i2c_get_bus_node(bus); |
175 | return 0; | ||
176 | 170 | ||
177 | /* Look for the bus in the device-tree */ | ||
178 | bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16); | ||
179 | |||
180 | DBG("wf_lm75: bus ID is %x\n", bus_id); | ||
181 | |||
182 | /* Look for sensors subdir */ | ||
183 | for (bus = NULL; | ||
184 | (bus = of_get_next_child(smu, bus)) != NULL;) { | ||
185 | u32 *reg; | ||
186 | |||
187 | if (strcmp(bus->name, "i2c")) | ||
188 | continue; | ||
189 | reg = (u32 *)get_property(bus, "reg", NULL); | ||
190 | if (reg == NULL) | ||
191 | continue; | ||
192 | if (bus_id == *reg) | ||
193 | break; | ||
194 | } | ||
195 | of_node_put(smu); | ||
196 | if (bus == NULL) { | ||
197 | printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found" | ||
198 | " in device-tree !\n", bus_id); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | DBG("wf_lm75: bus found, looking for device...\n"); | 171 | DBG("wf_lm75: bus found, looking for device...\n"); |
203 | 172 | ||
204 | /* Now look for lm75(s) in there */ | 173 | /* Now look for lm75(s) in there */ |
205 | for (dev = NULL; | 174 | for (dev = NULL; |
206 | (dev = of_get_next_child(bus, dev)) != NULL;) { | 175 | (dev = of_get_next_child(busnode, dev)) != NULL;) { |
207 | const char *loc = | 176 | const char *loc = |
208 | get_property(dev, "hwsensor-location", NULL); | 177 | get_property(dev, "hwsensor-location", NULL); |
209 | u32 *reg = (u32 *)get_property(dev, "reg", NULL); | 178 | u32 *reg = (u32 *)get_property(dev, "reg", NULL); |
210 | DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg); | 179 | DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg); |
211 | if (loc == NULL || reg == NULL) | 180 | if (loc == NULL || reg == NULL) |
212 | continue; | 181 | continue; |
213 | /* real lm75 */ | 182 | /* real lm75 */ |
214 | if (device_is_compatible(dev, "lm75")) | 183 | if (device_is_compatible(dev, "lm75")) |
215 | wf_lm75_create(adapter, *reg, 0, loc); | 184 | wf_lm75_create(adapter, *reg, 0, loc); |
216 | /* ds1775 (compatible, better resolution */ | 185 | /* ds1775 (compatible, better resolution */ |
217 | else if (device_is_compatible(dev, "ds1775")) | 186 | else if (device_is_compatible(dev, "ds1775")) |
218 | wf_lm75_create(adapter, *reg, 1, loc); | 187 | wf_lm75_create(adapter, *reg, 1, loc); |
219 | } | 188 | } |
220 | |||
221 | of_node_put(bus); | ||
222 | |||
223 | return 0; | 189 | return 0; |
224 | } | 190 | } |
225 | 191 | ||
226 | static int wf_lm75_detach(struct i2c_client *client) | 192 | static int wf_lm75_detach(struct i2c_client *client) |
227 | { | 193 | { |
228 | struct wf_lm75_sensor *lm = i2c_to_lm75(client); | 194 | struct wf_lm75_sensor *lm = i2c_to_lm75(client); |
229 | 195 | ||
230 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); | 196 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); |
231 | 197 | ||
232 | /* Mark client detached */ | 198 | /* Mark client detached */ |
233 | lm->i2c.adapter = NULL; | 199 | lm->i2c.adapter = NULL; |
234 | 200 | ||
235 | /* release sensor */ | 201 | /* release sensor */ |
236 | wf_unregister_sensor(&lm->sens); | 202 | wf_unregister_sensor(&lm->sens); |
237 | 203 | ||
238 | return 0; | 204 | return 0; |
239 | } | 205 | } |
240 | 206 | ||
241 | static int __init wf_lm75_sensor_init(void) | 207 | static int __init wf_lm75_sensor_init(void) |
242 | { | 208 | { |
243 | return i2c_add_driver(&wf_lm75_driver); | 209 | return i2c_add_driver(&wf_lm75_driver); |
244 | } | 210 | } |
245 | 211 | ||
246 | static void __exit wf_lm75_sensor_exit(void) | 212 | static void __exit wf_lm75_sensor_exit(void) |
247 | { | 213 | { |
248 | i2c_del_driver(&wf_lm75_driver); | 214 | i2c_del_driver(&wf_lm75_driver); |
249 | } | 215 | } |
250 | 216 | ||
251 | 217 | ||
252 | module_init(wf_lm75_sensor_init); | 218 | module_init(wf_lm75_sensor_init); |
253 | module_exit(wf_lm75_sensor_exit); | 219 | module_exit(wf_lm75_sensor_exit); |
254 | 220 | ||
255 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | 221 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); |
256 | MODULE_DESCRIPTION("LM75 sensor objects for PowerMacs thermal control"); | 222 | MODULE_DESCRIPTION("LM75 sensor objects for PowerMacs thermal control"); |
257 | MODULE_LICENSE("GPL"); | 223 | MODULE_LICENSE("GPL"); |
258 | 224 |
include/asm-powerpc/pmac_low_i2c.h
1 | /* | 1 | /* |
2 | * include/asm-ppc/pmac_low_i2c.h | 2 | * include/asm-ppc/pmac_low_i2c.h |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) | 4 | * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | #ifndef __PMAC_LOW_I2C_H__ | 12 | #ifndef __PMAC_LOW_I2C_H__ |
13 | #define __PMAC_LOW_I2C_H__ | 13 | #define __PMAC_LOW_I2C_H__ |
14 | #ifdef __KERNEL__ | 14 | #ifdef __KERNEL__ |
15 | 15 | ||
16 | /* i2c mode (based on the platform functions format) */ | 16 | /* i2c mode (based on the platform functions format) */ |
17 | enum { | 17 | enum { |
18 | pmac_i2c_mode_dumb = 1, | 18 | pmac_i2c_mode_dumb = 1, |
19 | pmac_i2c_mode_std = 2, | 19 | pmac_i2c_mode_std = 2, |
20 | pmac_i2c_mode_stdsub = 3, | 20 | pmac_i2c_mode_stdsub = 3, |
21 | pmac_i2c_mode_combined = 4, | 21 | pmac_i2c_mode_combined = 4, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | /* RW bit in address */ | 24 | /* RW bit in address */ |
25 | enum { | 25 | enum { |
26 | pmac_i2c_read = 0x01, | 26 | pmac_i2c_read = 0x01, |
27 | pmac_i2c_write = 0x00 | 27 | pmac_i2c_write = 0x00 |
28 | }; | 28 | }; |
29 | 29 | ||
30 | /* i2c bus type */ | 30 | /* i2c bus type */ |
31 | enum { | 31 | enum { |
32 | pmac_i2c_bus_keywest = 0, | 32 | pmac_i2c_bus_keywest = 0, |
33 | pmac_i2c_bus_pmu = 1, | 33 | pmac_i2c_bus_pmu = 1, |
34 | pmac_i2c_bus_smu = 2, | 34 | pmac_i2c_bus_smu = 2, |
35 | }; | 35 | }; |
36 | 36 | ||
37 | /* i2c bus features */ | 37 | /* i2c bus features */ |
38 | enum { | 38 | enum { |
39 | /* can_largesub : supports >1 byte subaddresses (SMU only) */ | 39 | /* can_largesub : supports >1 byte subaddresses (SMU only) */ |
40 | pmac_i2c_can_largesub = 0x00000001u, | 40 | pmac_i2c_can_largesub = 0x00000001u, |
41 | 41 | ||
42 | /* multibus : device node holds multiple busses, bus number is | 42 | /* multibus : device node holds multiple busses, bus number is |
43 | * encoded in bits 0xff00 of "reg" of a given device | 43 | * encoded in bits 0xff00 of "reg" of a given device |
44 | */ | 44 | */ |
45 | pmac_i2c_multibus = 0x00000002u, | 45 | pmac_i2c_multibus = 0x00000002u, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | /* i2c busses in the system */ | 48 | /* i2c busses in the system */ |
49 | struct pmac_i2c_bus; | 49 | struct pmac_i2c_bus; |
50 | struct i2c_adapter; | 50 | struct i2c_adapter; |
51 | 51 | ||
52 | /* Init, called early during boot */ | 52 | /* Init, called early during boot */ |
53 | extern int pmac_i2c_init(void); | 53 | extern int pmac_i2c_init(void); |
54 | 54 | ||
55 | /* Lookup an i2c bus for a device-node. The node can be either the bus | 55 | /* Lookup an i2c bus for a device-node. The node can be either the bus |
56 | * node itself or a device below it. In the case of a multibus, the bus | 56 | * node itself or a device below it. In the case of a multibus, the bus |
57 | * node itself is the controller node, else, it's a child of the controller | 57 | * node itself is the controller node, else, it's a child of the controller |
58 | * node | 58 | * node |
59 | */ | 59 | */ |
60 | extern struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node); | 60 | extern struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node); |
61 | 61 | ||
62 | /* Get the address for an i2c device. This strips the bus number if | 62 | /* Get the address for an i2c device. This strips the bus number if |
63 | * necessary. The 7 bits address is returned 1 bit right shifted so that the | 63 | * necessary. The 7 bits address is returned 1 bit right shifted so that the |
64 | * direction can be directly ored in | 64 | * direction can be directly ored in |
65 | */ | 65 | */ |
66 | extern u8 pmac_i2c_get_dev_addr(struct device_node *device); | 66 | extern u8 pmac_i2c_get_dev_addr(struct device_node *device); |
67 | 67 | ||
68 | /* Get infos about a bus */ | 68 | /* Get infos about a bus */ |
69 | extern struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus); | 69 | extern struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus); |
70 | extern struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus); | 70 | extern struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus); |
71 | extern int pmac_i2c_get_type(struct pmac_i2c_bus *bus); | 71 | extern int pmac_i2c_get_type(struct pmac_i2c_bus *bus); |
72 | extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus); | 72 | extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus); |
73 | extern int pmac_i2c_get_channel(struct pmac_i2c_bus *bus); | ||
73 | 74 | ||
74 | /* i2c layer adapter attach/detach */ | 75 | /* i2c layer adapter attach/detach */ |
75 | extern void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, | 76 | extern void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, |
76 | struct i2c_adapter *adapter); | 77 | struct i2c_adapter *adapter); |
77 | extern void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, | 78 | extern void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, |
78 | struct i2c_adapter *adapter); | 79 | struct i2c_adapter *adapter); |
79 | extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus); | 80 | extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus); |
81 | extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter); | ||
80 | 82 | ||
81 | /* March a device or bus with an i2c adapter structure, to be used by drivers | 83 | /* March a device or bus with an i2c adapter structure, to be used by drivers |
82 | * to match device-tree nodes with i2c adapters during adapter discovery | 84 | * to match device-tree nodes with i2c adapters during adapter discovery |
83 | * callbacks | 85 | * callbacks |
84 | */ | 86 | */ |
85 | extern int pmac_i2c_match_adapter(struct device_node *dev, | 87 | extern int pmac_i2c_match_adapter(struct device_node *dev, |
86 | struct i2c_adapter *adapter); | 88 | struct i2c_adapter *adapter); |
87 | 89 | ||
88 | 90 | ||
89 | /* (legacy) Locking functions exposed to i2c-keywest */ | 91 | /* (legacy) Locking functions exposed to i2c-keywest */ |
90 | extern int pmac_low_i2c_lock(struct device_node *np); | 92 | extern int pmac_low_i2c_lock(struct device_node *np); |
91 | extern int pmac_low_i2c_unlock(struct device_node *np); | 93 | extern int pmac_low_i2c_unlock(struct device_node *np); |
92 | 94 | ||
93 | /* Access functions for platform code */ | 95 | /* Access functions for platform code */ |
94 | extern int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled); | 96 | extern int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled); |
95 | extern void pmac_i2c_close(struct pmac_i2c_bus *bus); | 97 | extern void pmac_i2c_close(struct pmac_i2c_bus *bus); |
96 | extern int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode); | 98 | extern int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode); |
97 | extern int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, | 99 | extern int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, |
98 | u32 subaddr, u8 *data, int len); | 100 | u32 subaddr, u8 *data, int len); |
99 | 101 | ||
100 | 102 | ||
101 | #endif /* __KERNEL__ */ | 103 | #endif /* __KERNEL__ */ |
102 | #endif /* __PMAC_LOW_I2C_H__ */ | 104 | #endif /* __PMAC_LOW_I2C_H__ */ |
103 | 105 |