diff options
-rw-r--r-- | arch/mips/include/asm/mach-au1x00/au1xxx_psc.h | 13 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-au1550.c | 252 |
2 files changed, 99 insertions, 166 deletions
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h b/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h index 892b7f168eb4..5a5cb7386427 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h | |||
@@ -394,19 +394,6 @@ typedef struct psc_spi { | |||
394 | #define PSC_SPITXRX_LC (1 << 29) | 394 | #define PSC_SPITXRX_LC (1 << 29) |
395 | #define PSC_SPITXRX_SR (1 << 28) | 395 | #define PSC_SPITXRX_SR (1 << 28) |
396 | 396 | ||
397 | /* PSC in SMBus (I2C) Mode. */ | ||
398 | typedef struct psc_smb { | ||
399 | u32 psc_sel; | ||
400 | u32 psc_ctrl; | ||
401 | u32 psc_smbcfg; | ||
402 | u32 psc_smbmsk; | ||
403 | u32 psc_smbpcr; | ||
404 | u32 psc_smbstat; | ||
405 | u32 psc_smbevnt; | ||
406 | u32 psc_smbtxrx; | ||
407 | u32 psc_smbtmr; | ||
408 | } psc_smb_t; | ||
409 | |||
410 | /* SMBus Config Register. */ | 397 | /* SMBus Config Register. */ |
411 | #define PSC_SMBCFG_RT_MASK (3 << 30) | 398 | #define PSC_SMBCFG_RT_MASK (3 << 30) |
412 | #define PSC_SMBCFG_RT_FIFO1 (0 << 30) | 399 | #define PSC_SMBCFG_RT_FIFO1 (0 << 30) |
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 532828bc50e6..70b027c9037d 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c | |||
@@ -39,29 +39,42 @@ | |||
39 | #include <asm/mach-au1x00/au1xxx.h> | 39 | #include <asm/mach-au1x00/au1xxx.h> |
40 | #include <asm/mach-au1x00/au1xxx_psc.h> | 40 | #include <asm/mach-au1x00/au1xxx_psc.h> |
41 | 41 | ||
42 | #define PSC_SEL 0x00 | ||
43 | #define PSC_CTRL 0x04 | ||
44 | #define PSC_SMBCFG 0x08 | ||
45 | #define PSC_SMBMSK 0x0C | ||
46 | #define PSC_SMBPCR 0x10 | ||
47 | #define PSC_SMBSTAT 0x14 | ||
48 | #define PSC_SMBEVNT 0x18 | ||
49 | #define PSC_SMBTXRX 0x1C | ||
50 | #define PSC_SMBTMR 0x20 | ||
51 | |||
42 | struct i2c_au1550_data { | 52 | struct i2c_au1550_data { |
43 | u32 psc_base; | 53 | void __iomem *psc_base; |
44 | int xfer_timeout; | 54 | int xfer_timeout; |
45 | int ack_timeout; | 55 | int ack_timeout; |
46 | struct i2c_adapter adap; | 56 | struct i2c_adapter adap; |
47 | struct resource *ioarea; | 57 | struct resource *ioarea; |
48 | }; | 58 | }; |
49 | 59 | ||
50 | static int | 60 | static inline void WR(struct i2c_au1550_data *a, int r, unsigned long v) |
51 | wait_xfer_done(struct i2c_au1550_data *adap) | ||
52 | { | 61 | { |
53 | u32 stat; | 62 | __raw_writel(v, a->psc_base + r); |
54 | int i; | 63 | wmb(); |
55 | volatile psc_smb_t *sp; | 64 | } |
56 | 65 | ||
57 | sp = (volatile psc_smb_t *)(adap->psc_base); | 66 | static inline unsigned long RD(struct i2c_au1550_data *a, int r) |
67 | { | ||
68 | return __raw_readl(a->psc_base + r); | ||
69 | } | ||
58 | 70 | ||
59 | /* Wait for Tx Buffer Empty | 71 | static int wait_xfer_done(struct i2c_au1550_data *adap) |
60 | */ | 72 | { |
73 | int i; | ||
74 | |||
75 | /* Wait for Tx Buffer Empty */ | ||
61 | for (i = 0; i < adap->xfer_timeout; i++) { | 76 | for (i = 0; i < adap->xfer_timeout; i++) { |
62 | stat = sp->psc_smbstat; | 77 | if (RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_TE) |
63 | au_sync(); | ||
64 | if ((stat & PSC_SMBSTAT_TE) != 0) | ||
65 | return 0; | 78 | return 0; |
66 | 79 | ||
67 | udelay(1); | 80 | udelay(1); |
@@ -70,41 +83,27 @@ wait_xfer_done(struct i2c_au1550_data *adap) | |||
70 | return -ETIMEDOUT; | 83 | return -ETIMEDOUT; |
71 | } | 84 | } |
72 | 85 | ||
73 | static int | 86 | static int wait_ack(struct i2c_au1550_data *adap) |
74 | wait_ack(struct i2c_au1550_data *adap) | ||
75 | { | 87 | { |
76 | u32 stat; | 88 | unsigned long stat; |
77 | volatile psc_smb_t *sp; | ||
78 | 89 | ||
79 | if (wait_xfer_done(adap)) | 90 | if (wait_xfer_done(adap)) |
80 | return -ETIMEDOUT; | 91 | return -ETIMEDOUT; |
81 | 92 | ||
82 | sp = (volatile psc_smb_t *)(adap->psc_base); | 93 | stat = RD(adap, PSC_SMBEVNT); |
83 | |||
84 | stat = sp->psc_smbevnt; | ||
85 | au_sync(); | ||
86 | |||
87 | if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) | 94 | if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) |
88 | return -ETIMEDOUT; | 95 | return -ETIMEDOUT; |
89 | 96 | ||
90 | return 0; | 97 | return 0; |
91 | } | 98 | } |
92 | 99 | ||
93 | static int | 100 | static int wait_master_done(struct i2c_au1550_data *adap) |
94 | wait_master_done(struct i2c_au1550_data *adap) | ||
95 | { | 101 | { |
96 | u32 stat; | 102 | int i; |
97 | int i; | ||
98 | volatile psc_smb_t *sp; | ||
99 | 103 | ||
100 | sp = (volatile psc_smb_t *)(adap->psc_base); | 104 | /* Wait for Master Done. */ |
101 | |||
102 | /* Wait for Master Done. | ||
103 | */ | ||
104 | for (i = 0; i < adap->xfer_timeout; i++) { | 105 | for (i = 0; i < adap->xfer_timeout; i++) { |
105 | stat = sp->psc_smbevnt; | 106 | if ((RD(adap, PSC_SMBEVNT) & PSC_SMBEVNT_MD) != 0) |
106 | au_sync(); | ||
107 | if ((stat & PSC_SMBEVNT_MD) != 0) | ||
108 | return 0; | 107 | return 0; |
109 | udelay(1); | 108 | udelay(1); |
110 | } | 109 | } |
@@ -115,29 +114,20 @@ wait_master_done(struct i2c_au1550_data *adap) | |||
115 | static int | 114 | static int |
116 | do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) | 115 | do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) |
117 | { | 116 | { |
118 | volatile psc_smb_t *sp; | 117 | unsigned long stat; |
119 | u32 stat; | ||
120 | 118 | ||
121 | sp = (volatile psc_smb_t *)(adap->psc_base); | 119 | /* Reset the FIFOs, clear events. */ |
122 | 120 | stat = RD(adap, PSC_SMBSTAT); | |
123 | /* Reset the FIFOs, clear events. | 121 | WR(adap, PSC_SMBEVNT, PSC_SMBEVNT_ALLCLR); |
124 | */ | ||
125 | stat = sp->psc_smbstat; | ||
126 | sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR; | ||
127 | au_sync(); | ||
128 | 122 | ||
129 | if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) { | 123 | if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) { |
130 | sp->psc_smbpcr = PSC_SMBPCR_DC; | 124 | WR(adap, PSC_SMBPCR, PSC_SMBPCR_DC); |
131 | au_sync(); | 125 | while ((RD(adap, PSC_SMBPCR) & PSC_SMBPCR_DC) != 0) |
132 | do { | 126 | cpu_relax(); |
133 | stat = sp->psc_smbpcr; | ||
134 | au_sync(); | ||
135 | } while ((stat & PSC_SMBPCR_DC) != 0); | ||
136 | udelay(50); | 127 | udelay(50); |
137 | } | 128 | } |
138 | 129 | ||
139 | /* Write out the i2c chip address and specify operation | 130 | /* Write out the i2c chip address and specify operation */ |
140 | */ | ||
141 | addr <<= 1; | 131 | addr <<= 1; |
142 | if (rd) | 132 | if (rd) |
143 | addr |= 1; | 133 | addr |= 1; |
@@ -146,56 +136,42 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) | |||
146 | if (q) | 136 | if (q) |
147 | addr |= PSC_SMBTXRX_STP; | 137 | addr |= PSC_SMBTXRX_STP; |
148 | 138 | ||
149 | /* Put byte into fifo, start up master. | 139 | /* Put byte into fifo, start up master. */ |
150 | */ | 140 | WR(adap, PSC_SMBTXRX, addr); |
151 | sp->psc_smbtxrx = addr; | 141 | WR(adap, PSC_SMBPCR, PSC_SMBPCR_MS); |
152 | au_sync(); | ||
153 | sp->psc_smbpcr = PSC_SMBPCR_MS; | ||
154 | au_sync(); | ||
155 | if (wait_ack(adap)) | 142 | if (wait_ack(adap)) |
156 | return -EIO; | 143 | return -EIO; |
157 | return (q) ? wait_master_done(adap) : 0; | 144 | return (q) ? wait_master_done(adap) : 0; |
158 | } | 145 | } |
159 | 146 | ||
160 | static u32 | 147 | static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out) |
161 | wait_for_rx_byte(struct i2c_au1550_data *adap, u32 *ret_data) | ||
162 | { | 148 | { |
163 | int j; | 149 | int j; |
164 | u32 data, stat; | ||
165 | volatile psc_smb_t *sp; | ||
166 | 150 | ||
167 | if (wait_xfer_done(adap)) | 151 | if (wait_xfer_done(adap)) |
168 | return -EIO; | 152 | return -EIO; |
169 | 153 | ||
170 | sp = (volatile psc_smb_t *)(adap->psc_base); | ||
171 | |||
172 | j = adap->xfer_timeout * 100; | 154 | j = adap->xfer_timeout * 100; |
173 | do { | 155 | do { |
174 | j--; | 156 | j--; |
175 | if (j <= 0) | 157 | if (j <= 0) |
176 | return -EIO; | 158 | return -EIO; |
177 | 159 | ||
178 | stat = sp->psc_smbstat; | 160 | if ((RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_RE) == 0) |
179 | au_sync(); | ||
180 | if ((stat & PSC_SMBSTAT_RE) == 0) | ||
181 | j = 0; | 161 | j = 0; |
182 | else | 162 | else |
183 | udelay(1); | 163 | udelay(1); |
184 | } while (j > 0); | 164 | } while (j > 0); |
185 | data = sp->psc_smbtxrx; | 165 | |
186 | au_sync(); | 166 | *out = RD(adap, PSC_SMBTXRX); |
187 | *ret_data = data; | ||
188 | 167 | ||
189 | return 0; | 168 | return 0; |
190 | } | 169 | } |
191 | 170 | ||
192 | static int | 171 | static int i2c_read(struct i2c_au1550_data *adap, unsigned char *buf, |
193 | i2c_read(struct i2c_au1550_data *adap, unsigned char *buf, | ||
194 | unsigned int len) | 172 | unsigned int len) |
195 | { | 173 | { |
196 | int i; | 174 | int i; |
197 | u32 data; | ||
198 | volatile psc_smb_t *sp; | ||
199 | 175 | ||
200 | if (len == 0) | 176 | if (len == 0) |
201 | return 0; | 177 | return 0; |
@@ -204,62 +180,46 @@ i2c_read(struct i2c_au1550_data *adap, unsigned char *buf, | |||
204 | * zero bytes for timing, waiting for bytes to appear in the | 180 | * zero bytes for timing, waiting for bytes to appear in the |
205 | * receive fifo, then reading the bytes. | 181 | * receive fifo, then reading the bytes. |
206 | */ | 182 | */ |
207 | |||
208 | sp = (volatile psc_smb_t *)(adap->psc_base); | ||
209 | |||
210 | i = 0; | 183 | i = 0; |
211 | while (i < (len-1)) { | 184 | while (i < (len - 1)) { |
212 | sp->psc_smbtxrx = 0; | 185 | WR(adap, PSC_SMBTXRX, 0); |
213 | au_sync(); | 186 | if (wait_for_rx_byte(adap, &buf[i])) |
214 | if (wait_for_rx_byte(adap, &data)) | ||
215 | return -EIO; | 187 | return -EIO; |
216 | 188 | ||
217 | buf[i] = data; | ||
218 | i++; | 189 | i++; |
219 | } | 190 | } |
220 | 191 | ||
221 | /* The last byte has to indicate transfer done. | 192 | /* The last byte has to indicate transfer done. */ |
222 | */ | 193 | WR(adap, PSC_SMBTXRX, PSC_SMBTXRX_STP); |
223 | sp->psc_smbtxrx = PSC_SMBTXRX_STP; | ||
224 | au_sync(); | ||
225 | if (wait_master_done(adap)) | 194 | if (wait_master_done(adap)) |
226 | return -EIO; | 195 | return -EIO; |
227 | 196 | ||
228 | data = sp->psc_smbtxrx; | 197 | buf[i] = (unsigned char)(RD(adap, PSC_SMBTXRX) & 0xff); |
229 | au_sync(); | ||
230 | buf[i] = data; | ||
231 | return 0; | 198 | return 0; |
232 | } | 199 | } |
233 | 200 | ||
234 | static int | 201 | static int i2c_write(struct i2c_au1550_data *adap, unsigned char *buf, |
235 | i2c_write(struct i2c_au1550_data *adap, unsigned char *buf, | ||
236 | unsigned int len) | 202 | unsigned int len) |
237 | { | 203 | { |
238 | int i; | 204 | int i; |
239 | u32 data; | 205 | unsigned long data; |
240 | volatile psc_smb_t *sp; | ||
241 | 206 | ||
242 | if (len == 0) | 207 | if (len == 0) |
243 | return 0; | 208 | return 0; |
244 | 209 | ||
245 | sp = (volatile psc_smb_t *)(adap->psc_base); | ||
246 | |||
247 | i = 0; | 210 | i = 0; |
248 | while (i < (len-1)) { | 211 | while (i < (len-1)) { |
249 | data = buf[i]; | 212 | data = buf[i]; |
250 | sp->psc_smbtxrx = data; | 213 | WR(adap, PSC_SMBTXRX, data); |
251 | au_sync(); | ||
252 | if (wait_ack(adap)) | 214 | if (wait_ack(adap)) |
253 | return -EIO; | 215 | return -EIO; |
254 | i++; | 216 | i++; |
255 | } | 217 | } |
256 | 218 | ||
257 | /* The last byte has to indicate transfer done. | 219 | /* The last byte has to indicate transfer done. */ |
258 | */ | ||
259 | data = buf[i]; | 220 | data = buf[i]; |
260 | data |= PSC_SMBTXRX_STP; | 221 | data |= PSC_SMBTXRX_STP; |
261 | sp->psc_smbtxrx = data; | 222 | WR(adap, PSC_SMBTXRX, data); |
262 | au_sync(); | ||
263 | if (wait_master_done(adap)) | 223 | if (wait_master_done(adap)) |
264 | return -EIO; | 224 | return -EIO; |
265 | return 0; | 225 | return 0; |
@@ -269,12 +229,10 @@ static int | |||
269 | au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | 229 | au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) |
270 | { | 230 | { |
271 | struct i2c_au1550_data *adap = i2c_adap->algo_data; | 231 | struct i2c_au1550_data *adap = i2c_adap->algo_data; |
272 | volatile psc_smb_t *sp = (volatile psc_smb_t *)adap->psc_base; | ||
273 | struct i2c_msg *p; | 232 | struct i2c_msg *p; |
274 | int i, err = 0; | 233 | int i, err = 0; |
275 | 234 | ||
276 | sp->psc_ctrl = PSC_CTRL_ENABLE; | 235 | WR(adap, PSC_CTRL, PSC_CTRL_ENABLE); |
277 | au_sync(); | ||
278 | 236 | ||
279 | for (i = 0; !err && i < num; i++) { | 237 | for (i = 0; !err && i < num; i++) { |
280 | p = &msgs[i]; | 238 | p = &msgs[i]; |
@@ -293,14 +251,12 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | |||
293 | if (err == 0) | 251 | if (err == 0) |
294 | err = num; | 252 | err = num; |
295 | 253 | ||
296 | sp->psc_ctrl = PSC_CTRL_SUSPEND; | 254 | WR(adap, PSC_CTRL, PSC_CTRL_SUSPEND); |
297 | au_sync(); | ||
298 | 255 | ||
299 | return err; | 256 | return err; |
300 | } | 257 | } |
301 | 258 | ||
302 | static u32 | 259 | static u32 au1550_func(struct i2c_adapter *adap) |
303 | au1550_func(struct i2c_adapter *adap) | ||
304 | { | 260 | { |
305 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 261 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
306 | } | 262 | } |
@@ -312,57 +268,45 @@ static const struct i2c_algorithm au1550_algo = { | |||
312 | 268 | ||
313 | static void i2c_au1550_setup(struct i2c_au1550_data *priv) | 269 | static void i2c_au1550_setup(struct i2c_au1550_data *priv) |
314 | { | 270 | { |
315 | volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; | 271 | unsigned long cfg; |
316 | u32 stat; | ||
317 | |||
318 | sp->psc_ctrl = PSC_CTRL_DISABLE; | ||
319 | au_sync(); | ||
320 | sp->psc_sel = PSC_SEL_PS_SMBUSMODE; | ||
321 | sp->psc_smbcfg = 0; | ||
322 | au_sync(); | ||
323 | sp->psc_ctrl = PSC_CTRL_ENABLE; | ||
324 | au_sync(); | ||
325 | do { | ||
326 | stat = sp->psc_smbstat; | ||
327 | au_sync(); | ||
328 | } while ((stat & PSC_SMBSTAT_SR) == 0); | ||
329 | 272 | ||
330 | sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | | 273 | WR(priv, PSC_CTRL, PSC_CTRL_DISABLE); |
331 | PSC_SMBCFG_DD_DISABLE); | 274 | WR(priv, PSC_SEL, PSC_SEL_PS_SMBUSMODE); |
275 | WR(priv, PSC_SMBCFG, 0); | ||
276 | WR(priv, PSC_CTRL, PSC_CTRL_ENABLE); | ||
277 | while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) | ||
278 | cpu_relax(); | ||
279 | |||
280 | cfg = PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE; | ||
281 | WR(priv, PSC_SMBCFG, cfg); | ||
332 | 282 | ||
333 | /* Divide by 8 to get a 6.25 MHz clock. The later protocol | 283 | /* Divide by 8 to get a 6.25 MHz clock. The later protocol |
334 | * timings are based on this clock. | 284 | * timings are based on this clock. |
335 | */ | 285 | */ |
336 | sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); | 286 | cfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); |
337 | sp->psc_smbmsk = PSC_SMBMSK_ALLMASK; | 287 | WR(priv, PSC_SMBCFG, cfg); |
338 | au_sync(); | 288 | WR(priv, PSC_SMBMSK, PSC_SMBMSK_ALLMASK); |
339 | 289 | ||
340 | /* Set the protocol timer values. See Table 71 in the | 290 | /* Set the protocol timer values. See Table 71 in the |
341 | * Au1550 Data Book for standard timing values. | 291 | * Au1550 Data Book for standard timing values. |
342 | */ | 292 | */ |
343 | sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ | 293 | WR(priv, PSC_SMBTMR, PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ |
344 | PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ | 294 | PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ |
345 | PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ | 295 | PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ |
346 | PSC_SMBTMR_SET_CH(15); | 296 | PSC_SMBTMR_SET_CH(15)); |
347 | au_sync(); | ||
348 | 297 | ||
349 | sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE; | 298 | cfg |= PSC_SMBCFG_DE_ENABLE; |
350 | do { | 299 | WR(priv, PSC_SMBCFG, cfg); |
351 | stat = sp->psc_smbstat; | 300 | while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) |
352 | au_sync(); | 301 | cpu_relax(); |
353 | } while ((stat & PSC_SMBSTAT_SR) == 0); | ||
354 | 302 | ||
355 | sp->psc_ctrl = PSC_CTRL_SUSPEND; | 303 | WR(priv, PSC_CTRL, PSC_CTRL_SUSPEND); |
356 | au_sync(); | ||
357 | } | 304 | } |
358 | 305 | ||
359 | static void i2c_au1550_disable(struct i2c_au1550_data *priv) | 306 | static void i2c_au1550_disable(struct i2c_au1550_data *priv) |
360 | { | 307 | { |
361 | volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; | 308 | WR(priv, PSC_SMBCFG, 0); |
362 | 309 | WR(priv, PSC_CTRL, PSC_CTRL_DISABLE); | |
363 | sp->psc_smbcfg = 0; | ||
364 | sp->psc_ctrl = PSC_CTRL_DISABLE; | ||
365 | au_sync(); | ||
366 | } | 310 | } |
367 | 311 | ||
368 | /* | 312 | /* |
@@ -396,7 +340,11 @@ i2c_au1550_probe(struct platform_device *pdev) | |||
396 | goto out_mem; | 340 | goto out_mem; |
397 | } | 341 | } |
398 | 342 | ||
399 | priv->psc_base = CKSEG1ADDR(r->start); | 343 | priv->psc_base = ioremap(r->start, resource_size(r)); |
344 | if (!priv->psc_base) { | ||
345 | ret = -EIO; | ||
346 | goto out_map; | ||
347 | } | ||
400 | priv->xfer_timeout = 200; | 348 | priv->xfer_timeout = 200; |
401 | priv->ack_timeout = 200; | 349 | priv->ack_timeout = 200; |
402 | 350 | ||
@@ -406,8 +354,7 @@ i2c_au1550_probe(struct platform_device *pdev) | |||
406 | priv->adap.dev.parent = &pdev->dev; | 354 | priv->adap.dev.parent = &pdev->dev; |
407 | strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name)); | 355 | strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name)); |
408 | 356 | ||
409 | /* Now, set up the PSC for SMBus PIO mode. | 357 | /* Now, set up the PSC for SMBus PIO mode. */ |
410 | */ | ||
411 | i2c_au1550_setup(priv); | 358 | i2c_au1550_setup(priv); |
412 | 359 | ||
413 | ret = i2c_add_numbered_adapter(&priv->adap); | 360 | ret = i2c_add_numbered_adapter(&priv->adap); |
@@ -417,7 +364,8 @@ i2c_au1550_probe(struct platform_device *pdev) | |||
417 | } | 364 | } |
418 | 365 | ||
419 | i2c_au1550_disable(priv); | 366 | i2c_au1550_disable(priv); |
420 | 367 | iounmap(priv->psc_base); | |
368 | out_map: | ||
421 | release_resource(priv->ioarea); | 369 | release_resource(priv->ioarea); |
422 | kfree(priv->ioarea); | 370 | kfree(priv->ioarea); |
423 | out_mem: | 371 | out_mem: |
@@ -426,14 +374,14 @@ out: | |||
426 | return ret; | 374 | return ret; |
427 | } | 375 | } |
428 | 376 | ||
429 | static int __devexit | 377 | static int __devexit i2c_au1550_remove(struct platform_device *pdev) |
430 | i2c_au1550_remove(struct platform_device *pdev) | ||
431 | { | 378 | { |
432 | struct i2c_au1550_data *priv = platform_get_drvdata(pdev); | 379 | struct i2c_au1550_data *priv = platform_get_drvdata(pdev); |
433 | 380 | ||
434 | platform_set_drvdata(pdev, NULL); | 381 | platform_set_drvdata(pdev, NULL); |
435 | i2c_del_adapter(&priv->adap); | 382 | i2c_del_adapter(&priv->adap); |
436 | i2c_au1550_disable(priv); | 383 | i2c_au1550_disable(priv); |
384 | iounmap(priv->psc_base); | ||
437 | release_resource(priv->ioarea); | 385 | release_resource(priv->ioarea); |
438 | kfree(priv->ioarea); | 386 | kfree(priv->ioarea); |
439 | kfree(priv); | 387 | kfree(priv); |
@@ -476,14 +424,12 @@ static struct platform_driver au1xpsc_smbus_driver = { | |||
476 | .resume = i2c_au1550_resume, | 424 | .resume = i2c_au1550_resume, |
477 | }; | 425 | }; |
478 | 426 | ||
479 | static int __init | 427 | static int __init i2c_au1550_init(void) |
480 | i2c_au1550_init(void) | ||
481 | { | 428 | { |
482 | return platform_driver_register(&au1xpsc_smbus_driver); | 429 | return platform_driver_register(&au1xpsc_smbus_driver); |
483 | } | 430 | } |
484 | 431 | ||
485 | static void __exit | 432 | static void __exit i2c_au1550_exit(void) |
486 | i2c_au1550_exit(void) | ||
487 | { | 433 | { |
488 | platform_driver_unregister(&au1xpsc_smbus_driver); | 434 | platform_driver_unregister(&au1xpsc_smbus_driver); |
489 | } | 435 | } |