aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-04 16:15:48 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-04 16:15:48 -0500
commit42270035c6550101f7dc742a630c2590dd2d3ae0 (patch)
tree7b3d198f01b5c4c6b64f4cedf747f729438b7247 /drivers
parent2c89a8d09f03bc569d3237d97e2293d67c36d75d (diff)
parent8d91cbad8e6fd5b37bf584740f134508709ba035 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm: (30 commits) [ARM] Acorn: move the i2c bus driver into drivers/i2c [ARM] ARM SCSI: Don't try to dma_map_sg too many scatterlist entries [ARM] ARM FAS216: don't modify scsi_cmnd request_bufflen [ARM] rtc-pcf8583: Final fixes for this RTC on RiscPC [ARM] rtc-pcf8583: correct month and year offsets [ARM] rtc-pcf8583: don't use BCD_TO_BIN/BIN_TO_BCD [ARM] EBSA110: Work around build errors [ARM] 4241/1: Define mb() as compiler barrier on a uniprocessor system [ARM] 4239/1: S3C24XX: Update kconfig entries for PM [ARM] 4238/1: S3C24XX: docs: update suspend and resume [ARM] 4237/2: oprofile: Always allow backtraces on ARM [ARM] Yet more asm/apm-emulation.h stuff ARM: OMAP: Add missing get_irqnr_preamble and arch_ret_to_user for omap2 ARM: OMAP: Use linux/delay.h not asm/delay.h ARM: OMAP: Remove obsolete alsa typedefs ARM: OMAP: omap1510->15xx conversions needed for sx1 ARM: OMAP: Add missing includes to board-nokia770 ARM: OMAP: Workqueue changes for board-h4.c ARM: OMAP: dmtimer.c omap1 register fix ARM: OMAP: board-nokia770: correct lcd name ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acorn/char/Makefile1
-rw-r--r--drivers/acorn/char/i2c.c368
-rw-r--r--drivers/acorn/char/pcf8583.c284
-rw-r--r--drivers/acorn/char/pcf8583.h41
-rw-r--r--drivers/i2c/busses/Kconfig10
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-acorn.c97
-rw-r--r--drivers/rtc/Kconfig8
-rw-r--r--drivers/rtc/rtc-pcf8583.c29
-rw-r--r--drivers/scsi/arm/cumana_2.c4
-rw-r--r--drivers/scsi/arm/eesox.c4
-rw-r--r--drivers/scsi/arm/fas216.c9
-rw-r--r--drivers/scsi/arm/powertec.c5
-rw-r--r--drivers/scsi/arm/scsi.h2
14 files changed, 142 insertions, 721 deletions
diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile
index 2fa9a8bf48a0..d006c9f168d2 100644
--- a/drivers/acorn/char/Makefile
+++ b/drivers/acorn/char/Makefile
@@ -2,5 +2,4 @@
2# Makefile for the acorn character device drivers. 2# Makefile for the acorn character device drivers.
3# 3#
4 4
5obj-$(CONFIG_ARCH_ACORN) += i2c.o pcf8583.o
6obj-$(CONFIG_L7200_KEYB) += defkeymap-l7200.o keyb_l7200.o 5obj-$(CONFIG_L7200_KEYB) += defkeymap-l7200.o keyb_l7200.o
diff --git a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c
deleted file mode 100644
index d276fd14d63a..000000000000
--- a/drivers/acorn/char/i2c.c
+++ /dev/null
@@ -1,368 +0,0 @@
1/*
2 * linux/drivers/acorn/char/i2c.c
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ARM IOC/IOMD i2c driver.
11 *
12 * On Acorn machines, the following i2c devices are on the bus:
13 * - PCF8583 real time clock & static RAM
14 */
15#include <linux/capability.h>
16#include <linux/init.h>
17#include <linux/time.h>
18#include <linux/miscdevice.h>
19#include <linux/rtc.h>
20#include <linux/i2c.h>
21#include <linux/i2c-algo-bit.h>
22#include <linux/fs.h>
23
24#include <asm/hardware.h>
25#include <asm/io.h>
26#include <asm/hardware/ioc.h>
27#include <asm/system.h>
28#include <asm/uaccess.h>
29
30#include "pcf8583.h"
31
32extern int (*set_rtc)(void);
33
34static struct i2c_client *rtc_client;
35static const unsigned char days_in_mon[] =
36 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
37
38#define CMOS_CHECKSUM (63)
39
40/*
41 * Acorn machines store the year in the static RAM at
42 * location 128.
43 */
44#define CMOS_YEAR (64 + 128)
45
46static inline int rtc_command(int cmd, void *data)
47{
48 int ret = -EIO;
49
50 if (rtc_client)
51 ret = rtc_client->driver->command(rtc_client, cmd, data);
52
53 return ret;
54}
55
56/*
57 * Update the century + year bytes in the CMOS RAM, ensuring
58 * that the check byte is correctly adjusted for the change.
59 */
60static int rtc_update_year(unsigned int new_year)
61{
62 unsigned char yr[2], chk;
63 struct mem cmos_year = { CMOS_YEAR, sizeof(yr), yr };
64 struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
65 int ret;
66
67 ret = rtc_command(MEM_READ, &cmos_check);
68 if (ret)
69 goto out;
70 ret = rtc_command(MEM_READ, &cmos_year);
71 if (ret)
72 goto out;
73
74 chk -= yr[1] + yr[0];
75
76 yr[1] = new_year / 100;
77 yr[0] = new_year % 100;
78
79 chk += yr[1] + yr[0];
80
81 ret = rtc_command(MEM_WRITE, &cmos_year);
82 if (ret == 0)
83 ret = rtc_command(MEM_WRITE, &cmos_check);
84 out:
85 return ret;
86}
87
88/*
89 * Read the current RTC time and date, and update xtime.
90 */
91static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year)
92{
93 unsigned char ctrl, yr[2];
94 struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr };
95 int real_year, year_offset;
96
97 /*
98 * Ensure that the RTC is running.
99 */
100 rtc_command(RTC_GETCTRL, &ctrl);
101 if (ctrl & 0xc0) {
102 unsigned char new_ctrl = ctrl & ~0xc0;
103
104 printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n",
105 ctrl, new_ctrl);
106
107 rtc_command(RTC_SETCTRL, &new_ctrl);
108 }
109
110 if (rtc_command(RTC_GETDATETIME, rtctm) ||
111 rtc_command(MEM_READ, &rtcmem))
112 return;
113
114 real_year = yr[0];
115
116 /*
117 * The RTC year holds the LSB two bits of the current
118 * year, which should reflect the LSB two bits of the
119 * CMOS copy of the year. Any difference indicates
120 * that we have to correct the CMOS version.
121 */
122 year_offset = rtctm->year_off - (real_year & 3);
123 if (year_offset < 0)
124 /*
125 * RTC year wrapped. Adjust it appropriately.
126 */
127 year_offset += 4;
128
129 *year = real_year + year_offset + yr[1] * 100;
130}
131
132static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year)
133{
134 unsigned char leap;
135 int ret;
136
137 leap = (!(year % 4) && (year % 100)) || !(year % 400);
138
139 if (rtctm->mon > 12 || rtctm->mon == 0 || rtctm->mday == 0)
140 return -EINVAL;
141
142 if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap)))
143 return -EINVAL;
144
145 if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60)
146 return -EINVAL;
147
148 /*
149 * The RTC's own 2-bit year must reflect the least
150 * significant two bits of the CMOS year.
151 */
152 rtctm->year_off = (year % 100) & 3;
153
154 ret = rtc_command(RTC_SETDATETIME, rtctm);
155 if (ret == 0)
156 ret = rtc_update_year(year);
157
158 return ret;
159}
160
161/*
162 * Set the RTC time only. Note that
163 * we do not touch the date.
164 */
165static int k_set_rtc_time(void)
166{
167 struct rtc_tm new_rtctm, old_rtctm;
168 unsigned long nowtime = xtime.tv_sec;
169
170 if (rtc_command(RTC_GETDATETIME, &old_rtctm))
171 return 0;
172
173 new_rtctm.cs = xtime.tv_nsec / 10000000;
174 new_rtctm.secs = nowtime % 60; nowtime /= 60;
175 new_rtctm.mins = nowtime % 60; nowtime /= 60;
176 new_rtctm.hours = nowtime % 24;
177
178 /*
179 * avoid writing when we're going to change the day
180 * of the month. We will retry in the next minute.
181 * This basically means that if the RTC must not drift
182 * by more than 1 minute in 11 minutes.
183 *
184 * [ rtc: 1/1/2000 23:58:00, real 2/1/2000 00:01:00,
185 * rtc gets set to 1/1/2000 00:01:00 ]
186 */
187 if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) ||
188 (new_rtctm.hours == 23 && new_rtctm.mins == 59))
189 return 1;
190
191 return rtc_command(RTC_SETTIME, &new_rtctm);
192}
193
194static int rtc_ioctl(struct inode *inode, struct file *file,
195 unsigned int cmd, unsigned long arg)
196{
197 unsigned int year;
198 struct rtc_time rtctm;
199 struct rtc_tm rtc_raw;
200
201 switch (cmd) {
202 case RTC_ALM_READ:
203 case RTC_ALM_SET:
204 break;
205
206 case RTC_RD_TIME:
207 memset(&rtctm, 0, sizeof(struct rtc_time));
208 get_rtc_time(&rtc_raw, &year);
209 rtctm.tm_sec = rtc_raw.secs;
210 rtctm.tm_min = rtc_raw.mins;
211 rtctm.tm_hour = rtc_raw.hours;
212 rtctm.tm_mday = rtc_raw.mday;
213 rtctm.tm_mon = rtc_raw.mon - 1; /* month starts at 0 */
214 rtctm.tm_year = year - 1900; /* starts at 1900 */
215 return copy_to_user((void *)arg, &rtctm, sizeof(rtctm))
216 ? -EFAULT : 0;
217
218 case RTC_SET_TIME:
219 if (!capable(CAP_SYS_TIME))
220 return -EACCES;
221
222 if (copy_from_user(&rtctm, (void *)arg, sizeof(rtctm)))
223 return -EFAULT;
224 rtc_raw.secs = rtctm.tm_sec;
225 rtc_raw.mins = rtctm.tm_min;
226 rtc_raw.hours = rtctm.tm_hour;
227 rtc_raw.mday = rtctm.tm_mday;
228 rtc_raw.mon = rtctm.tm_mon + 1;
229 year = rtctm.tm_year + 1900;
230 return set_rtc_time(&rtc_raw, year);
231 break;
232
233 case RTC_EPOCH_READ:
234 return put_user(1900, (unsigned long *)arg);
235
236 }
237 return -EINVAL;
238}
239
240static const struct file_operations rtc_fops = {
241 .ioctl = rtc_ioctl,
242};
243
244static struct miscdevice rtc_dev = {
245 .minor = RTC_MINOR,
246 .name = "rtc",
247 .fops = &rtc_fops,
248};
249
250/* IOC / IOMD i2c driver */
251
252#define FORCE_ONES 0xdc
253#define SCL 0x02
254#define SDA 0x01
255
256/*
257 * We must preserve all non-i2c output bits in IOC_CONTROL.
258 * Note also that we need to preserve the value of SCL and
259 * SDA outputs as well (which may be different from the
260 * values read back from IOC_CONTROL).
261 */
262static u_int force_ones;
263
264static void ioc_setscl(void *data, int state)
265{
266 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
267 u_int ones = force_ones;
268
269 if (state)
270 ones |= SCL;
271 else
272 ones &= ~SCL;
273
274 force_ones = ones;
275
276 ioc_writeb(ioc_control | ones, IOC_CONTROL);
277}
278
279static void ioc_setsda(void *data, int state)
280{
281 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
282 u_int ones = force_ones;
283
284 if (state)
285 ones |= SDA;
286 else
287 ones &= ~SDA;
288
289 force_ones = ones;
290
291 ioc_writeb(ioc_control | ones, IOC_CONTROL);
292}
293
294static int ioc_getscl(void *data)
295{
296 return (ioc_readb(IOC_CONTROL) & SCL) != 0;
297}
298
299static int ioc_getsda(void *data)
300{
301 return (ioc_readb(IOC_CONTROL) & SDA) != 0;
302}
303
304static struct i2c_algo_bit_data ioc_data = {
305 .setsda = ioc_setsda,
306 .setscl = ioc_setscl,
307 .getsda = ioc_getsda,
308 .getscl = ioc_getscl,
309 .udelay = 80,
310 .timeout = 100
311};
312
313static int ioc_client_reg(struct i2c_client *client)
314{
315 if (client->driver->id == I2C_DRIVERID_PCF8583 &&
316 client->addr == 0x50) {
317 struct rtc_tm rtctm;
318 unsigned int year;
319 struct timespec tv;
320
321 rtc_client = client;
322 get_rtc_time(&rtctm, &year);
323
324 tv.tv_nsec = rtctm.cs * 10000000;
325 tv.tv_sec = mktime(year, rtctm.mon, rtctm.mday,
326 rtctm.hours, rtctm.mins, rtctm.secs);
327 do_settimeofday(&tv);
328 set_rtc = k_set_rtc_time;
329 }
330
331 return 0;
332}
333
334static int ioc_client_unreg(struct i2c_client *client)
335{
336 if (client == rtc_client) {
337 set_rtc = NULL;
338 rtc_client = NULL;
339 }
340
341 return 0;
342}
343
344static struct i2c_adapter ioc_ops = {
345 .id = I2C_HW_B_IOC,
346 .algo_data = &ioc_data,
347 .client_register = ioc_client_reg,
348 .client_unregister = ioc_client_unreg,
349};
350
351static int __init i2c_ioc_init(void)
352{
353 int ret;
354
355 force_ones = FORCE_ONES | SCL | SDA;
356
357 ret = i2c_bit_add_bus(&ioc_ops);
358
359 if (ret >= 0){
360 ret = misc_register(&rtc_dev);
361 if(ret < 0)
362 i2c_del_adapter(&ioc_ops);
363 }
364
365 return ret;
366}
367
368__initcall(i2c_ioc_init);
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
deleted file mode 100644
index 9b49f316ae92..000000000000
--- a/drivers/acorn/char/pcf8583.c
+++ /dev/null
@@ -1,284 +0,0 @@
1/*
2 * linux/drivers/acorn/char/pcf8583.c
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Driver for PCF8583 RTC & RAM chip
11 */
12#include <linux/module.h>
13#include <linux/i2c.h>
14#include <linux/slab.h>
15#include <linux/string.h>
16#include <linux/mc146818rtc.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/bcd.h>
20
21#include "pcf8583.h"
22
23static struct i2c_driver pcf8583_driver;
24
25static unsigned short ignore[] = { I2C_CLIENT_END };
26static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
27static unsigned short *forces[] = { NULL };
28
29static struct i2c_client_address_data addr_data = {
30 .normal_i2c = normal_addr,
31 .probe = ignore,
32 .ignore = ignore,
33 .forces = forces,
34};
35
36#define set_ctrl(x, v) i2c_set_clientdata(x, (void *)(unsigned int)(v))
37#define get_ctrl(x) ((unsigned int)i2c_get_clientdata(x))
38
39static int
40pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
41{
42 struct i2c_client *c;
43 unsigned char buf[1], ad[1] = { 0 };
44 struct i2c_msg msgs[2] = {
45 {
46 .addr = addr,
47 .flags = 0,
48 .len = 1,
49 .buf = ad,
50 }, {
51 .addr = addr,
52 .flags = I2C_M_RD,
53 .len = 1,
54 .buf = buf,
55 }
56 };
57
58 c = kmalloc(sizeof(*c), GFP_KERNEL);
59 if (!c)
60 return -ENOMEM;
61
62 memset(c, 0, sizeof(*c));
63 c->addr = addr;
64 c->adapter = adap;
65 c->driver = &pcf8583_driver;
66
67 if (i2c_transfer(c->adapter, msgs, 2) == 2)
68 set_ctrl(c, buf[0]);
69
70 return i2c_attach_client(c);
71}
72
73static int
74pcf8583_probe(struct i2c_adapter *adap)
75{
76 return i2c_probe(adap, &addr_data, pcf8583_attach);
77}
78
79static int
80pcf8583_detach(struct i2c_client *client)
81{
82 i2c_detach_client(client);
83 kfree(client);
84 return 0;
85}
86
87static int
88pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
89{
90 unsigned char buf[8], addr[1] = { 1 };
91 struct i2c_msg msgs[2] = {
92 {
93 .addr = client->addr,
94 .flags = 0,
95 .len = 1,
96 .buf = addr,
97 }, {
98 .addr = client->addr,
99 .flags = I2C_M_RD,
100 .len = 6,
101 .buf = buf,
102 }
103 };
104 int ret = -EIO;
105
106 memset(buf, 0, sizeof(buf));
107
108 ret = i2c_transfer(client->adapter, msgs, 2);
109 if (ret == 2) {
110 dt->year_off = buf[4] >> 6;
111 dt->wday = buf[5] >> 5;
112
113 buf[4] &= 0x3f;
114 buf[5] &= 0x1f;
115
116 dt->cs = BCD_TO_BIN(buf[0]);
117 dt->secs = BCD_TO_BIN(buf[1]);
118 dt->mins = BCD_TO_BIN(buf[2]);
119 dt->hours = BCD_TO_BIN(buf[3]);
120 dt->mday = BCD_TO_BIN(buf[4]);
121 dt->mon = BCD_TO_BIN(buf[5]);
122
123 ret = 0;
124 }
125
126 return ret;
127}
128
129static int
130pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
131{
132 unsigned char buf[8];
133 int ret, len = 6;
134
135 buf[0] = 0;
136 buf[1] = get_ctrl(client) | 0x80;
137 buf[2] = BIN_TO_BCD(dt->cs);
138 buf[3] = BIN_TO_BCD(dt->secs);
139 buf[4] = BIN_TO_BCD(dt->mins);
140 buf[5] = BIN_TO_BCD(dt->hours);
141
142 if (datetoo) {
143 len = 8;
144 buf[6] = BIN_TO_BCD(dt->mday) | (dt->year_off << 6);
145 buf[7] = BIN_TO_BCD(dt->mon) | (dt->wday << 5);
146 }
147
148 ret = i2c_master_send(client, (char *)buf, len);
149 if (ret == len)
150 ret = 0;
151
152 buf[1] = get_ctrl(client);
153 i2c_master_send(client, (char *)buf, 2);
154
155 return ret;
156}
157
158static int
159pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
160{
161 *ctrl = get_ctrl(client);
162 return 0;
163}
164
165static int
166pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
167{
168 unsigned char buf[2];
169
170 buf[0] = 0;
171 buf[1] = *ctrl;
172 set_ctrl(client, *ctrl);
173
174 return i2c_master_send(client, (char *)buf, 2);
175}
176
177static int
178pcf8583_read_mem(struct i2c_client *client, struct mem *mem)
179{
180 unsigned char addr[1];
181 struct i2c_msg msgs[2] = {
182 {
183 .addr = client->addr,
184 .flags = 0,
185 .len = 1,
186 .buf = addr,
187 }, {
188 .addr = client->addr,
189 .flags = I2C_M_RD,
190 .len = mem->nr,
191 .buf = mem->data,
192 }
193 };
194
195 if (mem->loc < 8)
196 return -EINVAL;
197
198 addr[0] = mem->loc;
199
200 return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
201}
202
203static int
204pcf8583_write_mem(struct i2c_client *client, struct mem *mem)
205{
206 unsigned char addr[1];
207 struct i2c_msg msgs[2] = {
208 {
209 .addr = client->addr,
210 .flags = 0,
211 .len = 1,
212 .buf = addr,
213 }, {
214 .addr = client->addr,
215 .flags = I2C_M_NOSTART,
216 .len = mem->nr,
217 .buf = mem->data,
218 }
219 };
220
221 if (mem->loc < 8)
222 return -EINVAL;
223
224 addr[0] = mem->loc;
225
226 return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
227}
228
229static int
230pcf8583_command(struct i2c_client *client, unsigned int cmd, void *arg)
231{
232 switch (cmd) {
233 case RTC_GETDATETIME:
234 return pcf8583_get_datetime(client, arg);
235
236 case RTC_SETTIME:
237 return pcf8583_set_datetime(client, arg, 0);
238
239 case RTC_SETDATETIME:
240 return pcf8583_set_datetime(client, arg, 1);
241
242 case RTC_GETCTRL:
243 return pcf8583_get_ctrl(client, arg);
244
245 case RTC_SETCTRL:
246 return pcf8583_set_ctrl(client, arg);
247
248 case MEM_READ:
249 return pcf8583_read_mem(client, arg);
250
251 case MEM_WRITE:
252 return pcf8583_write_mem(client, arg);
253
254 default:
255 return -EINVAL;
256 }
257}
258
259static struct i2c_driver pcf8583_driver = {
260 .driver = {
261 .name = "PCF8583",
262 },
263 .id = I2C_DRIVERID_PCF8583,
264 .attach_adapter = pcf8583_probe,
265 .detach_client = pcf8583_detach,
266 .command = pcf8583_command
267};
268
269static __init int pcf8583_init(void)
270{
271 return i2c_add_driver(&pcf8583_driver);
272}
273
274static __exit void pcf8583_exit(void)
275{
276 i2c_del_driver(&pcf8583_driver);
277}
278
279module_init(pcf8583_init);
280module_exit(pcf8583_exit);
281
282MODULE_AUTHOR("Russell King");
283MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
284MODULE_LICENSE("GPL");
diff --git a/drivers/acorn/char/pcf8583.h b/drivers/acorn/char/pcf8583.h
deleted file mode 100644
index 847f7fdb8763..000000000000
--- a/drivers/acorn/char/pcf8583.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * linux/drivers/acorn/char/pcf8583.h
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10struct rtc_tm {
11 unsigned char cs;
12 unsigned char secs;
13 unsigned char mins;
14 unsigned char hours;
15 unsigned char mday;
16 unsigned char mon;
17 unsigned char year_off;
18 unsigned char wday;
19};
20
21struct mem {
22 unsigned int loc;
23 unsigned int nr;
24 unsigned char *data;
25};
26
27#define RTC_GETDATETIME 0
28#define RTC_SETTIME 1
29#define RTC_SETDATETIME 2
30#define RTC_GETCTRL 3
31#define RTC_SETCTRL 4
32#define MEM_READ 5
33#define MEM_WRITE 6
34
35#define CTRL_STOP 0x80
36#define CTRL_HOLD 0x40
37#define CTRL_32KHZ 0x00
38#define CTRL_MASK 0x08
39#define CTRL_ALARMEN 0x04
40#define CTRL_ALARM 0x02
41#define CTRL_TIMER 0x01
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 4d44a2db29dd..fb19dbb31e42 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -495,6 +495,16 @@ config I2C_VERSATILE
495 This driver can also be built as a module. If so, the module 495 This driver can also be built as a module. If so, the module
496 will be called i2c-versatile. 496 will be called i2c-versatile.
497 497
498config I2C_ACORN
499 bool "Acorn IOC/IOMD I2C bus support"
500 depends on I2C && ARCH_ACORN
501 default y
502 select I2C_ALGOBIT
503 help
504 Say yes if you want to support the I2C bus on Acorn platforms.
505
506 If you don't know, say Y.
507
498config I2C_VIA 508config I2C_VIA
499 tristate "VIA 82C586B" 509 tristate "VIA 82C586B"
500 depends on I2C && PCI && EXPERIMENTAL 510 depends on I2C && PCI && EXPERIMENTAL
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 03505aa44bbf..290b54018354 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
42obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o 42obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
43obj-$(CONFIG_I2C_STUB) += i2c-stub.o 43obj-$(CONFIG_I2C_STUB) += i2c-stub.o
44obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o 44obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
45obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o
45obj-$(CONFIG_I2C_VIA) += i2c-via.o 46obj-$(CONFIG_I2C_VIA) += i2c-via.o
46obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o 47obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
47obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o 48obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c
new file mode 100644
index 000000000000..09bd7f40b90c
--- /dev/null
+++ b/drivers/i2c/busses/i2c-acorn.c
@@ -0,0 +1,97 @@
1/*
2 * linux/drivers/acorn/char/i2c.c
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ARM IOC/IOMD i2c driver.
11 *
12 * On Acorn machines, the following i2c devices are on the bus:
13 * - PCF8583 real time clock & static RAM
14 */
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/i2c-algo-bit.h>
18
19#include <asm/hardware.h>
20#include <asm/io.h>
21#include <asm/hardware/ioc.h>
22#include <asm/system.h>
23
24#define FORCE_ONES 0xdc
25#define SCL 0x02
26#define SDA 0x01
27
28/*
29 * We must preserve all non-i2c output bits in IOC_CONTROL.
30 * Note also that we need to preserve the value of SCL and
31 * SDA outputs as well (which may be different from the
32 * values read back from IOC_CONTROL).
33 */
34static u_int force_ones;
35
36static void ioc_setscl(void *data, int state)
37{
38 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
39 u_int ones = force_ones;
40
41 if (state)
42 ones |= SCL;
43 else
44 ones &= ~SCL;
45
46 force_ones = ones;
47
48 ioc_writeb(ioc_control | ones, IOC_CONTROL);
49}
50
51static void ioc_setsda(void *data, int state)
52{
53 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
54 u_int ones = force_ones;
55
56 if (state)
57 ones |= SDA;
58 else
59 ones &= ~SDA;
60
61 force_ones = ones;
62
63 ioc_writeb(ioc_control | ones, IOC_CONTROL);
64}
65
66static int ioc_getscl(void *data)
67{
68 return (ioc_readb(IOC_CONTROL) & SCL) != 0;
69}
70
71static int ioc_getsda(void *data)
72{
73 return (ioc_readb(IOC_CONTROL) & SDA) != 0;
74}
75
76static struct i2c_algo_bit_data ioc_data = {
77 .setsda = ioc_setsda,
78 .setscl = ioc_setscl,
79 .getsda = ioc_getsda,
80 .getscl = ioc_getscl,
81 .udelay = 80,
82 .timeout = 100
83};
84
85static struct i2c_adapter ioc_ops = {
86 .id = I2C_HW_B_IOC,
87 .algo_data = &ioc_data,
88};
89
90static int __init i2c_ioc_init(void)
91{
92 force_ones = FORCE_ONES | SCL | SDA;
93
94 return i2c_bit_add_bus(&ioc_ops);
95}
96
97__initcall(i2c_ioc_init);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index deef29646e0e..95826b92ca4b 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -207,10 +207,12 @@ config RTC_DRV_PCF8563
207 207
208config RTC_DRV_PCF8583 208config RTC_DRV_PCF8583
209 tristate "Philips PCF8583" 209 tristate "Philips PCF8583"
210 depends on RTC_CLASS && I2C 210 depends on RTC_CLASS && I2C && ARCH_RPC
211 help 211 help
212 If you say yes here you get support for the 212 If you say yes here you get support for the Philips PCF8583
213 Philips PCF8583 RTC chip. 213 RTC chip found on Acorn RiscPCs. This driver supports the
214 platform specific method of retrieving the current year from
215 the RTC's SRAM.
214 216
215 This driver can also be built as a module. If so, the module 217 This driver can also be built as a module. If so, the module
216 will be called rtc-pcf8583. 218 will be called rtc-pcf8583.
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index 5875ebb8c79d..d48b03374586 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -40,7 +40,7 @@ struct pcf8583 {
40#define CTRL_ALARM 0x02 40#define CTRL_ALARM 0x02
41#define CTRL_TIMER 0x01 41#define CTRL_TIMER 0x01
42 42
43static unsigned short normal_i2c[] = { I2C_CLIENT_END }; 43static unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
44 44
45/* Module parameters */ 45/* Module parameters */
46I2C_CLIENT_INSMOD; 46I2C_CLIENT_INSMOD;
@@ -81,11 +81,11 @@ static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt)
81 buf[4] &= 0x3f; 81 buf[4] &= 0x3f;
82 buf[5] &= 0x1f; 82 buf[5] &= 0x1f;
83 83
84 dt->tm_sec = BCD_TO_BIN(buf[1]); 84 dt->tm_sec = BCD2BIN(buf[1]);
85 dt->tm_min = BCD_TO_BIN(buf[2]); 85 dt->tm_min = BCD2BIN(buf[2]);
86 dt->tm_hour = BCD_TO_BIN(buf[3]); 86 dt->tm_hour = BCD2BIN(buf[3]);
87 dt->tm_mday = BCD_TO_BIN(buf[4]); 87 dt->tm_mday = BCD2BIN(buf[4]);
88 dt->tm_mon = BCD_TO_BIN(buf[5]); 88 dt->tm_mon = BCD2BIN(buf[5]) - 1;
89 } 89 }
90 90
91 return ret == 2 ? 0 : -EIO; 91 return ret == 2 ? 0 : -EIO;
@@ -99,14 +99,14 @@ static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt,
99 buf[0] = 0; 99 buf[0] = 0;
100 buf[1] = get_ctrl(client) | 0x80; 100 buf[1] = get_ctrl(client) | 0x80;
101 buf[2] = 0; 101 buf[2] = 0;
102 buf[3] = BIN_TO_BCD(dt->tm_sec); 102 buf[3] = BIN2BCD(dt->tm_sec);
103 buf[4] = BIN_TO_BCD(dt->tm_min); 103 buf[4] = BIN2BCD(dt->tm_min);
104 buf[5] = BIN_TO_BCD(dt->tm_hour); 104 buf[5] = BIN2BCD(dt->tm_hour);
105 105
106 if (datetoo) { 106 if (datetoo) {
107 len = 8; 107 len = 8;
108 buf[6] = BIN_TO_BCD(dt->tm_mday) | (dt->tm_year << 6); 108 buf[6] = BIN2BCD(dt->tm_mday) | (dt->tm_year << 6);
109 buf[7] = BIN_TO_BCD(dt->tm_mon) | (dt->tm_wday << 5); 109 buf[7] = BIN2BCD(dt->tm_mon + 1) | (dt->tm_wday << 5);
110 } 110 }
111 111
112 ret = i2c_master_send(client, (char *)buf, len); 112 ret = i2c_master_send(client, (char *)buf, len);
@@ -226,7 +226,7 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm)
226 */ 226 */
227 year_offset += 4; 227 year_offset += 4;
228 228
229 tm->tm_year = real_year + year_offset + year[1] * 100; 229 tm->tm_year = (real_year + year_offset + year[1] * 100) - 1900;
230 230
231 return 0; 231 return 0;
232} 232}
@@ -237,6 +237,7 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm)
237 unsigned char year[2], chk; 237 unsigned char year[2], chk;
238 struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year }; 238 struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year };
239 struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; 239 struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
240 unsigned int proper_year = tm->tm_year + 1900;
240 int ret; 241 int ret;
241 242
242 /* 243 /*
@@ -258,8 +259,8 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm)
258 259
259 chk -= year[1] + year[0]; 260 chk -= year[1] + year[0];
260 261
261 year[1] = tm->tm_year / 100; 262 year[1] = proper_year / 100;
262 year[0] = tm->tm_year % 100; 263 year[0] = proper_year % 100;
263 264
264 chk += year[1] + year[0]; 265 chk += year[1] + year[0];
265 266
diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
index d2d51dc51ab8..82add77ad131 100644
--- a/drivers/scsi/arm/cumana_2.c
+++ b/drivers/scsi/arm/cumana_2.c
@@ -178,10 +178,10 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
178 dma_dir = DMA_MODE_READ, 178 dma_dir = DMA_MODE_READ,
179 alatch_dir = ALATCH_DMA_IN; 179 alatch_dir = ALATCH_DMA_IN;
180 180
181 dma_map_sg(dev, info->sg, bufs + 1, map_dir); 181 dma_map_sg(dev, info->sg, bufs, map_dir);
182 182
183 disable_dma(dmach); 183 disable_dma(dmach);
184 set_dma_sg(dmach, info->sg, bufs + 1); 184 set_dma_sg(dmach, info->sg, bufs);
185 writeb(alatch_dir, info->base + CUMANASCSI2_ALATCH); 185 writeb(alatch_dir, info->base + CUMANASCSI2_ALATCH);
186 set_dma_mode(dmach, dma_dir); 186 set_dma_mode(dmach, dma_dir);
187 enable_dma(dmach); 187 enable_dma(dmach);
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index d4136524fc46..ed06a8c19ad6 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -175,10 +175,10 @@ eesoxscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
175 map_dir = DMA_FROM_DEVICE, 175 map_dir = DMA_FROM_DEVICE,
176 dma_dir = DMA_MODE_READ; 176 dma_dir = DMA_MODE_READ;
177 177
178 dma_map_sg(dev, info->sg, bufs + 1, map_dir); 178 dma_map_sg(dev, info->sg, bufs, map_dir);
179 179
180 disable_dma(dmach); 180 disable_dma(dmach);
181 set_dma_sg(dmach, info->sg, bufs + 1); 181 set_dma_sg(dmach, info->sg, bufs);
182 set_dma_mode(dmach, dma_dir); 182 set_dma_mode(dmach, dma_dir);
183 enable_dma(dmach); 183 enable_dma(dmach);
184 return fasdma_real_all; 184 return fasdma_real_all;
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 2969cc0ff259..fb5f20284389 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -633,7 +633,7 @@ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
633 633
634 BUG_ON(bytes_transferred < 0); 634 BUG_ON(bytes_transferred < 0);
635 635
636 info->SCpnt->request_bufflen -= bytes_transferred; 636 SCp->phase -= bytes_transferred;
637 637
638 while (bytes_transferred != 0) { 638 while (bytes_transferred != 0) {
639 if (SCp->this_residual > bytes_transferred) 639 if (SCp->this_residual > bytes_transferred)
@@ -715,7 +715,7 @@ static void fas216_cleanuptransfer(FAS216_Info *info)
715 return; 715 return;
716 716
717 if (dmatype == fasdma_real_all) 717 if (dmatype == fasdma_real_all)
718 total = info->SCpnt->request_bufflen; 718 total = info->scsi.SCp.phase;
719 else 719 else
720 total = info->scsi.SCp.this_residual; 720 total = info->scsi.SCp.this_residual;
721 721
@@ -753,7 +753,7 @@ static void fas216_transfer(FAS216_Info *info)
753 fas216_log(info, LOG_BUFFER, 753 fas216_log(info, LOG_BUFFER,
754 "starttransfer: buffer %p length 0x%06x reqlen 0x%06x", 754 "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
755 info->scsi.SCp.ptr, info->scsi.SCp.this_residual, 755 info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
756 info->SCpnt->request_bufflen); 756 info->scsi.SCp.phase);
757 757
758 if (!info->scsi.SCp.ptr) { 758 if (!info->scsi.SCp.ptr) {
759 fas216_log(info, LOG_ERROR, "null buffer passed to " 759 fas216_log(info, LOG_ERROR, "null buffer passed to "
@@ -784,7 +784,7 @@ static void fas216_transfer(FAS216_Info *info)
784 info->dma.transfer_type = dmatype; 784 info->dma.transfer_type = dmatype;
785 785
786 if (dmatype == fasdma_real_all) 786 if (dmatype == fasdma_real_all)
787 fas216_set_stc(info, info->SCpnt->request_bufflen); 787 fas216_set_stc(info, info->scsi.SCp.phase);
788 else 788 else
789 fas216_set_stc(info, info->scsi.SCp.this_residual); 789 fas216_set_stc(info, info->scsi.SCp.this_residual);
790 790
@@ -2114,6 +2114,7 @@ request_sense:
2114 SCpnt->SCp.buffers_residual = 0; 2114 SCpnt->SCp.buffers_residual = 0;
2115 SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer; 2115 SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer;
2116 SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); 2116 SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
2117 SCpnt->SCp.phase = sizeof(SCpnt->sense_buffer);
2117 SCpnt->SCp.Message = 0; 2118 SCpnt->SCp.Message = 0;
2118 SCpnt->SCp.Status = 0; 2119 SCpnt->SCp.Status = 0;
2119 SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer); 2120 SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index f9cd20bfb958..159047a34997 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -148,10 +148,10 @@ powertecscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
148 map_dir = DMA_FROM_DEVICE, 148 map_dir = DMA_FROM_DEVICE,
149 dma_dir = DMA_MODE_READ; 149 dma_dir = DMA_MODE_READ;
150 150
151 dma_map_sg(dev, info->sg, bufs + 1, map_dir); 151 dma_map_sg(dev, info->sg, bufs, map_dir);
152 152
153 disable_dma(dmach); 153 disable_dma(dmach);
154 set_dma_sg(dmach, info->sg, bufs + 1); 154 set_dma_sg(dmach, info->sg, bufs);
155 set_dma_mode(dmach, dma_dir); 155 set_dma_mode(dmach, dma_dir);
156 enable_dma(dmach); 156 enable_dma(dmach);
157 return fasdma_real_all; 157 return fasdma_real_all;
@@ -342,6 +342,7 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
342 info->base = base; 342 info->base = base;
343 powertecscsi_terminator_ctl(host, term[ec->slot_no]); 343 powertecscsi_terminator_ctl(host, term[ec->slot_no]);
344 344
345 info->ec = ec;
345 info->info.scsi.io_base = base + POWERTEC_FAS216_OFFSET; 346 info->info.scsi.io_base = base + POWERTEC_FAS216_OFFSET;
346 info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT; 347 info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT;
347 info->info.scsi.irq = ec->irq; 348 info->info.scsi.irq = ec->irq;
diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h
index 3a39579bd08e..21ba57155bea 100644
--- a/drivers/scsi/arm/scsi.h
+++ b/drivers/scsi/arm/scsi.h
@@ -80,6 +80,7 @@ static inline void init_SCp(struct scsi_cmnd *SCpnt)
80 (page_address(SCpnt->SCp.buffer->page) + 80 (page_address(SCpnt->SCp.buffer->page) +
81 SCpnt->SCp.buffer->offset); 81 SCpnt->SCp.buffer->offset);
82 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; 82 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
83 SCpnt->SCp.phase = SCpnt->request_bufflen;
83 84
84#ifdef BELT_AND_BRACES 85#ifdef BELT_AND_BRACES
85 /* 86 /*
@@ -98,6 +99,7 @@ static inline void init_SCp(struct scsi_cmnd *SCpnt)
98 } else { 99 } else {
99 SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer; 100 SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
100 SCpnt->SCp.this_residual = SCpnt->request_bufflen; 101 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
102 SCpnt->SCp.phase = SCpnt->request_bufflen;
101 } 103 }
102 104
103 /* 105 /*