aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DMA-mapping.txt8
-rw-r--r--Documentation/accounting/delay-accounting.txt110
-rw-r--r--Documentation/accounting/getdelays.c396
-rw-r--r--Documentation/accounting/taskstats.txt181
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--Documentation/memory-barriers.txt5
-rw-r--r--Documentation/ramdisk.txt12
-rw-r--r--MAINTAINERS16
-rw-r--r--arch/i386/kernel/crash.c2
-rw-r--r--arch/i386/kernel/setup.c5
-rw-r--r--arch/i386/kernel/traps.c40
-rw-r--r--arch/i386/lib/usercopy.c2
-rw-r--r--arch/sparc64/kernel/head.S13
-rw-r--r--arch/sparc64/kernel/pci_psycho.c6
-rw-r--r--arch/sparc64/kernel/time.c2
-rw-r--r--arch/um/Makefile-x86_641
-rw-r--r--arch/um/include/longjmp.h4
-rw-r--r--arch/um/include/os.h68
-rw-r--r--arch/um/kernel/vmlinux.lds.S2
-rw-r--r--arch/um/os-Linux/process.c8
-rw-r--r--arch/um/os-Linux/skas/process.c16
-rw-r--r--arch/um/os-Linux/uaccess.c3
-rw-r--r--block/ioctl.c4
-rw-r--r--drivers/block/Kconfig10
-rw-r--r--drivers/block/cpqarray.c2
-rw-r--r--drivers/block/rd.c2
-rw-r--r--drivers/char/nsc_gpio.c6
-rw-r--r--drivers/char/pc8736x_gpio.c15
-rw-r--r--drivers/char/scx200_gpio.c72
-rw-r--r--drivers/char/tpm/tpm.c1
-rw-r--r--drivers/char/tpm/tpm_tis.c77
-rw-r--r--drivers/infiniband/core/cm.c21
-rw-r--r--drivers/infiniband/core/cma.c22
-rw-r--r--drivers/infiniband/core/fmr_pool.c8
-rw-r--r--drivers/infiniband/core/sa_query.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c13
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c2
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c3
-rw-r--r--drivers/leds/leds-net48xx.c7
-rw-r--r--drivers/rtc/Kconfig10
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-isl1208.c591
-rw-r--r--drivers/serial/sunsab.c2
-rw-r--r--drivers/serial/sunsu.c5
-rw-r--r--drivers/video/Kconfig20
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/mbx/Makefile4
-rw-r--r--drivers/video/mbx/mbxdebugfs.c188
-rw-r--r--drivers/video/mbx/mbxfb.c683
-rw-r--r--drivers/video/mbx/reg_bits.h418
-rw-r--r--drivers/video/mbx/regs.h195
-rw-r--r--fs/char_dev.c22
-rw-r--r--fs/namei.c8
-rw-r--r--fs/proc/array.c6
-rw-r--r--fs/proc/base.c2
-rw-r--r--fs/reiserfs/procfs.c25
-rw-r--r--include/asm-alpha/barrier.h3
-rw-r--r--include/asm-arm/system.h1
-rw-r--r--include/asm-arm26/system.h1
-rw-r--r--include/asm-cris/system.h1
-rw-r--r--include/asm-frv/system.h1
-rw-r--r--include/asm-generic/Kbuild.asm5
-rw-r--r--include/asm-h8300/system.h1
-rw-r--r--include/asm-i386/system.h2
-rw-r--r--include/asm-ia64/system.h3
-rw-r--r--include/asm-m32r/system.h1
-rw-r--r--include/asm-m68k/system.h1
-rw-r--r--include/asm-m68knommu/system.h1
-rw-r--r--include/asm-mips/system.h3
-rw-r--r--include/asm-parisc/system.h2
-rw-r--r--include/asm-powerpc/system.h1
-rw-r--r--include/asm-ppc/system.h1
-rw-r--r--include/asm-s390/system.h1
-rw-r--r--include/asm-sh/system.h1
-rw-r--r--include/asm-sh64/system.h1
-rw-r--r--include/asm-sparc/system.h1
-rw-r--r--include/asm-sparc64/system.h2
-rw-r--r--include/asm-v850/system.h1
-rw-r--r--include/asm-x86_64/system.h1
-rw-r--r--include/asm-xtensa/system.h1
-rw-r--r--include/linux/delayacct.h119
-rw-r--r--include/linux/i2c-id.h1
-rw-r--r--include/linux/if_vlan.h5
-rw-r--r--include/linux/kthread.h1
-rw-r--r--include/linux/list.h11
-rw-r--r--include/linux/module.h10
-rw-r--r--include/linux/namei.h2
-rw-r--r--include/linux/nsc_gpio.h2
-rw-r--r--include/linux/sched.h56
-rw-r--r--include/linux/taskstats.h137
-rw-r--r--include/linux/taskstats_kern.h89
-rw-r--r--include/linux/time.h12
-rw-r--r--include/linux/vmalloc.h1
-rw-r--r--include/net/genetlink.h20
-rw-r--r--include/rdma/ib_addr.h10
-rw-r--r--include/rdma/ib_fmr_pool.h2
-rw-r--r--include/video/mbxfb.h28
-rw-r--r--init/Kconfig24
-rw-r--r--init/main.c4
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/acct.c4
-rw-r--r--kernel/delayacct.c178
-rw-r--r--kernel/exit.c10
-rw-r--r--kernel/fork.c6
-rw-r--r--kernel/kallsyms.c4
-rw-r--r--kernel/kthread.c24
-rw-r--r--kernel/module.c11
-rw-r--r--kernel/rtmutex-tester.c1
-rw-r--r--kernel/sched.c84
-rw-r--r--kernel/softirq.c2
-rw-r--r--kernel/taskstats.c568
-rw-r--r--kernel/timer.c20
-rw-r--r--lib/Kconfig.debug10
-rw-r--r--lib/idr.c16
-rw-r--r--mm/memory.c6
-rw-r--r--mm/nommu.c2
-rw-r--r--mm/vmalloc.c7
-rw-r--r--net/core/skbuff.c91
-rw-r--r--net/ipv4/ip_input.c3
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--security/selinux/hooks.c14
122 files changed, 4614 insertions, 387 deletions
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index 7c717699032c..63392c9132b4 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -698,12 +698,12 @@ these interfaces. Remember that, as defined, consistent mappings are
698always going to be SAC addressable. 698always going to be SAC addressable.
699 699
700The first thing your driver needs to do is query the PCI platform 700The first thing your driver needs to do is query the PCI platform
701layer with your devices DAC addressing capabilities: 701layer if it is capable of handling your devices DAC addressing
702capabilities:
702 703
703 int pci_dac_set_dma_mask(struct pci_dev *pdev, u64 mask); 704 int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
704 705
705This routine behaves identically to pci_set_dma_mask. You may not 706You may not use the following interfaces if this routine fails.
706use the following interfaces if this routine fails.
707 707
708Next, DMA addresses using this API are kept track of using the 708Next, DMA addresses using this API are kept track of using the
709dma64_addr_t type. It is guaranteed to be big enough to hold any 709dma64_addr_t type. It is guaranteed to be big enough to hold any
diff --git a/Documentation/accounting/delay-accounting.txt b/Documentation/accounting/delay-accounting.txt
new file mode 100644
index 000000000000..be215e58423b
--- /dev/null
+++ b/Documentation/accounting/delay-accounting.txt
@@ -0,0 +1,110 @@
1Delay accounting
2----------------
3
4Tasks encounter delays in execution when they wait
5for some kernel resource to become available e.g. a
6runnable task may wait for a free CPU to run on.
7
8The per-task delay accounting functionality measures
9the delays experienced by a task while
10
11a) waiting for a CPU (while being runnable)
12b) completion of synchronous block I/O initiated by the task
13c) swapping in pages
14
15and makes these statistics available to userspace through
16the taskstats interface.
17
18Such delays provide feedback for setting a task's cpu priority,
19io priority and rss limit values appropriately. Long delays for
20important tasks could be a trigger for raising its corresponding priority.
21
22The functionality, through its use of the taskstats interface, also provides
23delay statistics aggregated for all tasks (or threads) belonging to a
24thread group (corresponding to a traditional Unix process). This is a commonly
25needed aggregation that is more efficiently done by the kernel.
26
27Userspace utilities, particularly resource management applications, can also
28aggregate delay statistics into arbitrary groups. To enable this, delay
29statistics of a task are available both during its lifetime as well as on its
30exit, ensuring continuous and complete monitoring can be done.
31
32
33Interface
34---------
35
36Delay accounting uses the taskstats interface which is described
37in detail in a separate document in this directory. Taskstats returns a
38generic data structure to userspace corresponding to per-pid and per-tgid
39statistics. The delay accounting functionality populates specific fields of
40this structure. See
41 include/linux/taskstats.h
42for a description of the fields pertaining to delay accounting.
43It will generally be in the form of counters returning the cumulative
44delay seen for cpu, sync block I/O, swapin etc.
45
46Taking the difference of two successive readings of a given
47counter (say cpu_delay_total) for a task will give the delay
48experienced by the task waiting for the corresponding resource
49in that interval.
50
51When a task exits, records containing the per-task statistics
52are sent to userspace without requiring a command. If it is the last exiting
53task of a thread group, the per-tgid statistics are also sent. More details
54are given in the taskstats interface description.
55
56The getdelays.c userspace utility in this directory allows simple commands to
57be run and the corresponding delay statistics to be displayed. It also serves
58as an example of using the taskstats interface.
59
60Usage
61-----
62
63Compile the kernel with
64 CONFIG_TASK_DELAY_ACCT=y
65 CONFIG_TASKSTATS=y
66
67Enable the accounting at boot time by adding
68the following to the kernel boot options
69 delayacct
70
71and after the system has booted up, use a utility
72similar to getdelays.c to access the delays
73seen by a given task or a task group (tgid).
74The utility also allows a given command to be
75executed and the corresponding delays to be
76seen.
77
78General format of the getdelays command
79
80getdelays [-t tgid] [-p pid] [-c cmd...]
81
82
83Get delays, since system boot, for pid 10
84# ./getdelays -p 10
85(output similar to next case)
86
87Get sum of delays, since system boot, for all pids with tgid 5
88# ./getdelays -t 5
89
90
91CPU count real total virtual total delay total
92 7876 92005750 100000000 24001500
93IO count delay total
94 0 0
95MEM count delay total
96 0 0
97
98Get delays seen in executing a given simple command
99# ./getdelays -c ls /
100
101bin data1 data3 data5 dev home media opt root srv sys usr
102boot data2 data4 data6 etc lib mnt proc sbin subdomain tmp var
103
104
105CPU count real total virtual total delay total
106 6 4000250 4000000 0
107IO count delay total
108 0 0
109MEM count delay total
110 0 0
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
new file mode 100644
index 000000000000..795ca3911cc5
--- /dev/null
+++ b/Documentation/accounting/getdelays.c
@@ -0,0 +1,396 @@
1/* getdelays.c
2 *
3 * Utility to get per-pid and per-tgid delay accounting statistics
4 * Also illustrates usage of the taskstats interface
5 *
6 * Copyright (C) Shailabh Nagar, IBM Corp. 2005
7 * Copyright (C) Balbir Singh, IBM Corp. 2006
8 * Copyright (c) Jay Lan, SGI. 2006
9 *
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <errno.h>
15#include <unistd.h>
16#include <poll.h>
17#include <string.h>
18#include <fcntl.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <sys/socket.h>
22#include <sys/types.h>
23#include <signal.h>
24
25#include <linux/genetlink.h>
26#include <linux/taskstats.h>
27
28/*
29 * Generic macros for dealing with netlink sockets. Might be duplicated
30 * elsewhere. It is recommended that commercial grade applications use
31 * libnl or libnetlink and use the interfaces provided by the library
32 */
33#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
34#define GENLMSG_PAYLOAD(glh) (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
35#define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN))
36#define NLA_PAYLOAD(len) (len - NLA_HDRLEN)
37
38#define err(code, fmt, arg...) do { printf(fmt, ##arg); exit(code); } while (0)
39int done = 0;
40int rcvbufsz=0;
41
42 char name[100];
43int dbg=0, print_delays=0;
44__u64 stime, utime;
45#define PRINTF(fmt, arg...) { \
46 if (dbg) { \
47 printf(fmt, ##arg); \
48 } \
49 }
50
51/* Maximum size of response requested or message sent */
52#define MAX_MSG_SIZE 256
53/* Maximum number of cpus expected to be specified in a cpumask */
54#define MAX_CPUS 32
55/* Maximum length of pathname to log file */
56#define MAX_FILENAME 256
57
58struct msgtemplate {
59 struct nlmsghdr n;
60 struct genlmsghdr g;
61 char buf[MAX_MSG_SIZE];
62};
63
64char cpumask[100+6*MAX_CPUS];
65
66/*
67 * Create a raw netlink socket and bind
68 */
69static int create_nl_socket(int protocol)
70{
71 int fd;
72 struct sockaddr_nl local;
73
74 fd = socket(AF_NETLINK, SOCK_RAW, protocol);
75 if (fd < 0)
76 return -1;
77
78 if (rcvbufsz)
79 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
80 &rcvbufsz, sizeof(rcvbufsz)) < 0) {
81 printf("Unable to set socket rcv buf size to %d\n",
82 rcvbufsz);
83 return -1;
84 }
85
86 memset(&local, 0, sizeof(local));
87 local.nl_family = AF_NETLINK;
88
89 if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
90 goto error;
91
92 return fd;
93error:
94 close(fd);
95 return -1;
96}
97
98
99int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
100 __u8 genl_cmd, __u16 nla_type,
101 void *nla_data, int nla_len)
102{
103 struct nlattr *na;
104 struct sockaddr_nl nladdr;
105 int r, buflen;
106 char *buf;
107
108 struct msgtemplate msg;
109
110 msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
111 msg.n.nlmsg_type = nlmsg_type;
112 msg.n.nlmsg_flags = NLM_F_REQUEST;
113 msg.n.nlmsg_seq = 0;
114 msg.n.nlmsg_pid = nlmsg_pid;
115 msg.g.cmd = genl_cmd;
116 msg.g.version = 0x1;
117 na = (struct nlattr *) GENLMSG_DATA(&msg);
118 na->nla_type = nla_type;
119 na->nla_len = nla_len + 1 + NLA_HDRLEN;
120 memcpy(NLA_DATA(na), nla_data, nla_len);
121 msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
122
123 buf = (char *) &msg;
124 buflen = msg.n.nlmsg_len ;
125 memset(&nladdr, 0, sizeof(nladdr));
126 nladdr.nl_family = AF_NETLINK;
127 while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
128 sizeof(nladdr))) < buflen) {
129 if (r > 0) {
130 buf += r;
131 buflen -= r;
132 } else if (errno != EAGAIN)
133 return -1;
134 }
135 return 0;
136}
137
138
139/*
140 * Probe the controller in genetlink to find the family id
141 * for the TASKSTATS family
142 */
143int get_family_id(int sd)
144{
145 struct {
146 struct nlmsghdr n;
147 struct genlmsghdr g;
148 char buf[256];
149 } ans;
150
151 int id, rc;
152 struct nlattr *na;
153 int rep_len;
154
155 strcpy(name, TASKSTATS_GENL_NAME);
156 rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
157 CTRL_ATTR_FAMILY_NAME, (void *)name,
158 strlen(TASKSTATS_GENL_NAME)+1);
159
160 rep_len = recv(sd, &ans, sizeof(ans), 0);
161 if (ans.n.nlmsg_type == NLMSG_ERROR ||
162 (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
163 return 0;
164
165 na = (struct nlattr *) GENLMSG_DATA(&ans);
166 na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
167 if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
168 id = *(__u16 *) NLA_DATA(na);
169 }
170 return id;
171}
172
173void print_delayacct(struct taskstats *t)
174{
175 printf("\n\nCPU %15s%15s%15s%15s\n"
176 " %15llu%15llu%15llu%15llu\n"
177 "IO %15s%15s\n"
178 " %15llu%15llu\n"
179 "MEM %15s%15s\n"
180 " %15llu%15llu\n\n",
181 "count", "real total", "virtual total", "delay total",
182 t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
183 t->cpu_delay_total,
184 "count", "delay total",
185 t->blkio_count, t->blkio_delay_total,
186 "count", "delay total", t->swapin_count, t->swapin_delay_total);
187}
188
189int main(int argc, char *argv[])
190{
191 int c, rc, rep_len, aggr_len, len2, cmd_type;
192 __u16 id;
193 __u32 mypid;
194
195 struct nlattr *na;
196 int nl_sd = -1;
197 int len = 0;
198 pid_t tid = 0;
199 pid_t rtid = 0;
200
201 int fd = 0;
202 int count = 0;
203 int write_file = 0;
204 int maskset = 0;
205 char logfile[128];
206 int loop = 0;
207
208 struct msgtemplate msg;
209
210 while (1) {
211 c = getopt(argc, argv, "dw:r:m:t:p:v:l");
212 if (c < 0)
213 break;
214
215 switch (c) {
216 case 'd':
217 printf("print delayacct stats ON\n");
218 print_delays = 1;
219 break;
220 case 'w':
221 strncpy(logfile, optarg, MAX_FILENAME);
222 printf("write to file %s\n", logfile);
223 write_file = 1;
224 break;
225 case 'r':
226 rcvbufsz = atoi(optarg);
227 printf("receive buf size %d\n", rcvbufsz);
228 if (rcvbufsz < 0)
229 err(1, "Invalid rcv buf size\n");
230 break;
231 case 'm':
232 strncpy(cpumask, optarg, sizeof(cpumask));
233 maskset = 1;
234 printf("cpumask %s maskset %d\n", cpumask, maskset);
235 break;
236 case 't':
237 tid = atoi(optarg);
238 if (!tid)
239 err(1, "Invalid tgid\n");
240 cmd_type = TASKSTATS_CMD_ATTR_TGID;
241 print_delays = 1;
242 break;
243 case 'p':
244 tid = atoi(optarg);
245 if (!tid)
246 err(1, "Invalid pid\n");
247 cmd_type = TASKSTATS_CMD_ATTR_PID;
248 print_delays = 1;
249 break;
250 case 'v':
251 printf("debug on\n");
252 dbg = 1;
253 break;
254 case 'l':
255 printf("listen forever\n");
256 loop = 1;
257 break;
258 default:
259 printf("Unknown option %d\n", c);
260 exit(-1);
261 }
262 }
263
264 if (write_file) {
265 fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC,
266 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
267 if (fd == -1) {
268 perror("Cannot open output file\n");
269 exit(1);
270 }
271 }
272
273 if ((nl_sd = create_nl_socket(NETLINK_GENERIC)) < 0)
274 err(1, "error creating Netlink socket\n");
275
276
277 mypid = getpid();
278 id = get_family_id(nl_sd);
279 if (!id) {
280 printf("Error getting family id, errno %d", errno);
281 goto err;
282 }
283 PRINTF("family id %d\n", id);
284
285 if (maskset) {
286 rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
287 TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
288 &cpumask, sizeof(cpumask));
289 PRINTF("Sent register cpumask, retval %d\n", rc);
290 if (rc < 0) {
291 printf("error sending register cpumask\n");
292 goto err;
293 }
294 }
295
296 if (tid) {
297 rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
298 cmd_type, &tid, sizeof(__u32));
299 PRINTF("Sent pid/tgid, retval %d\n", rc);
300 if (rc < 0) {
301 printf("error sending tid/tgid cmd\n");
302 goto done;
303 }
304 }
305
306 do {
307 int i;
308
309 rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
310 PRINTF("received %d bytes\n", rep_len);
311
312 if (rep_len < 0) {
313 printf("nonfatal reply error: errno %d\n", errno);
314 continue;
315 }
316 if (msg.n.nlmsg_type == NLMSG_ERROR ||
317 !NLMSG_OK((&msg.n), rep_len)) {
318 printf("fatal reply error, errno %d\n", errno);
319 goto done;
320 }
321
322 PRINTF("nlmsghdr size=%d, nlmsg_len=%d, rep_len=%d\n",
323 sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);
324
325
326 rep_len = GENLMSG_PAYLOAD(&msg.n);
327
328 na = (struct nlattr *) GENLMSG_DATA(&msg);
329 len = 0;
330 i = 0;
331 while (len < rep_len) {
332 len += NLA_ALIGN(na->nla_len);
333 switch (na->nla_type) {
334 case TASKSTATS_TYPE_AGGR_TGID:
335 /* Fall through */
336 case TASKSTATS_TYPE_AGGR_PID:
337 aggr_len = NLA_PAYLOAD(na->nla_len);
338 len2 = 0;
339 /* For nested attributes, na follows */
340 na = (struct nlattr *) NLA_DATA(na);
341 done = 0;
342 while (len2 < aggr_len) {
343 switch (na->nla_type) {
344 case TASKSTATS_TYPE_PID:
345 rtid = *(int *) NLA_DATA(na);
346 if (print_delays)
347 printf("PID\t%d\n", rtid);
348 break;
349 case TASKSTATS_TYPE_TGID:
350 rtid = *(int *) NLA_DATA(na);
351 if (print_delays)
352 printf("TGID\t%d\n", rtid);
353 break;
354 case TASKSTATS_TYPE_STATS:
355 count++;
356 if (print_delays)
357 print_delayacct((struct taskstats *) NLA_DATA(na));
358 if (fd) {
359 if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
360 err(1,"write error\n");
361 }
362 }
363 if (!loop)
364 goto done;
365 break;
366 default:
367 printf("Unknown nested nla_type %d\n", na->nla_type);
368 break;
369 }
370 len2 += NLA_ALIGN(na->nla_len);
371 na = (struct nlattr *) ((char *) na + len2);
372 }
373 break;
374
375 default:
376 printf("Unknown nla_type %d\n", na->nla_type);
377 break;
378 }
379 na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
380 }
381 } while (loop);
382done:
383 if (maskset) {
384 rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
385 TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
386 &cpumask, sizeof(cpumask));
387 printf("Sent deregister mask, retval %d\n", rc);
388 if (rc < 0)
389 err(rc, "error sending deregister cpumask\n");
390 }
391err:
392 close(nl_sd);
393 if (fd)
394 close(fd);
395 return 0;
396}
diff --git a/Documentation/accounting/taskstats.txt b/Documentation/accounting/taskstats.txt
new file mode 100644
index 000000000000..92ebf29e9041
--- /dev/null
+++ b/Documentation/accounting/taskstats.txt
@@ -0,0 +1,181 @@
1Per-task statistics interface
2-----------------------------
3
4
5Taskstats is a netlink-based interface for sending per-task and
6per-process statistics from the kernel to userspace.
7
8Taskstats was designed for the following benefits:
9
10- efficiently provide statistics during lifetime of a task and on its exit
11- unified interface for multiple accounting subsystems
12- extensibility for use by future accounting patches
13
14Terminology
15-----------
16
17"pid", "tid" and "task" are used interchangeably and refer to the standard
18Linux task defined by struct task_struct. per-pid stats are the same as
19per-task stats.
20
21"tgid", "process" and "thread group" are used interchangeably and refer to the
22tasks that share an mm_struct i.e. the traditional Unix process. Despite the
23use of tgid, there is no special treatment for the task that is thread group
24leader - a process is deemed alive as long as it has any task belonging to it.
25
26Usage
27-----
28
29To get statistics during a task's lifetime, userspace opens a unicast netlink
30socket (NETLINK_GENERIC family) and sends commands specifying a pid or a tgid.
31The response contains statistics for a task (if pid is specified) or the sum of
32statistics for all tasks of the process (if tgid is specified).
33
34To obtain statistics for tasks which are exiting, the userspace listener
35sends a register command and specifies a cpumask. Whenever a task exits on
36one of the cpus in the cpumask, its per-pid statistics are sent to the
37registered listener. Using cpumasks allows the data received by one listener
38to be limited and assists in flow control over the netlink interface and is
39explained in more detail below.
40
41If the exiting task is the last thread exiting its thread group,
42an additional record containing the per-tgid stats is also sent to userspace.
43The latter contains the sum of per-pid stats for all threads in the thread
44group, both past and present.
45
46getdelays.c is a simple utility demonstrating usage of the taskstats interface
47for reporting delay accounting statistics. Users can register cpumasks,
48send commands and process responses, listen for per-tid/tgid exit data,
49write the data received to a file and do basic flow control by increasing
50receive buffer sizes.
51
52Interface
53---------
54
55The user-kernel interface is encapsulated in include/linux/taskstats.h
56
57To avoid this documentation becoming obsolete as the interface evolves, only
58an outline of the current version is given. taskstats.h always overrides the
59description here.
60
61struct taskstats is the common accounting structure for both per-pid and
62per-tgid data. It is versioned and can be extended by each accounting subsystem
63that is added to the kernel. The fields and their semantics are defined in the
64taskstats.h file.
65
66The data exchanged between user and kernel space is a netlink message belonging
67to the NETLINK_GENERIC family and using the netlink attributes interface.
68The messages are in the format
69
70 +----------+- - -+-------------+-------------------+
71 | nlmsghdr | Pad | genlmsghdr | taskstats payload |
72 +----------+- - -+-------------+-------------------+
73
74
75The taskstats payload is one of the following three kinds:
76
771. Commands: Sent from user to kernel. Commands to get data on
78a pid/tgid consist of one attribute, of type TASKSTATS_CMD_ATTR_PID/TGID,
79containing a u32 pid or tgid in the attribute payload. The pid/tgid denotes
80the task/process for which userspace wants statistics.
81
82Commands to register/deregister interest in exit data from a set of cpus
83consist of one attribute, of type
84TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK and contain a cpumask in the
85attribute payload. The cpumask is specified as an ascii string of
86comma-separated cpu ranges e.g. to listen to exit data from cpus 1,2,3,5,7,8
87the cpumask would be "1-3,5,7-8". If userspace forgets to deregister interest
88in cpus before closing the listening socket, the kernel cleans up its interest
89set over time. However, for the sake of efficiency, an explicit deregistration
90is advisable.
91
922. Response for a command: sent from the kernel in response to a userspace
93command. The payload is a series of three attributes of type:
94
95a) TASKSTATS_TYPE_AGGR_PID/TGID : attribute containing no payload but indicates
96a pid/tgid will be followed by some stats.
97
98b) TASKSTATS_TYPE_PID/TGID: attribute whose payload is the pid/tgid whose stats
99is being returned.
100
101c) TASKSTATS_TYPE_STATS: attribute with a struct taskstsats as payload. The
102same structure is used for both per-pid and per-tgid stats.
103
1043. New message sent by kernel whenever a task exits. The payload consists of a
105 series of attributes of the following type:
106
107a) TASKSTATS_TYPE_AGGR_PID: indicates next two attributes will be pid+stats
108b) TASKSTATS_TYPE_PID: contains exiting task's pid
109c) TASKSTATS_TYPE_STATS: contains the exiting task's per-pid stats
110d) TASKSTATS_TYPE_AGGR_TGID: indicates next two attributes will be tgid+stats
111e) TASKSTATS_TYPE_TGID: contains tgid of process to which task belongs
112f) TASKSTATS_TYPE_STATS: contains the per-tgid stats for exiting task's process
113
114
115per-tgid stats
116--------------
117
118Taskstats provides per-process stats, in addition to per-task stats, since
119resource management is often done at a process granularity and aggregating task
120stats in userspace alone is inefficient and potentially inaccurate (due to lack
121of atomicity).
122
123However, maintaining per-process, in addition to per-task stats, within the
124kernel has space and time overheads. To address this, the taskstats code
125accumalates each exiting task's statistics into a process-wide data structure.
126When the last task of a process exits, the process level data accumalated also
127gets sent to userspace (along with the per-task data).
128
129When a user queries to get per-tgid data, the sum of all other live threads in
130the group is added up and added to the accumalated total for previously exited
131threads of the same thread group.
132
133Extending taskstats
134-------------------
135
136There are two ways to extend the taskstats interface to export more
137per-task/process stats as patches to collect them get added to the kernel
138in future:
139
1401. Adding more fields to the end of the existing struct taskstats. Backward
141 compatibility is ensured by the version number within the
142 structure. Userspace will use only the fields of the struct that correspond
143 to the version its using.
144
1452. Defining separate statistic structs and using the netlink attributes
146 interface to return them. Since userspace processes each netlink attribute
147 independently, it can always ignore attributes whose type it does not
148 understand (because it is using an older version of the interface).
149
150
151Choosing between 1. and 2. is a matter of trading off flexibility and
152overhead. If only a few fields need to be added, then 1. is the preferable
153path since the kernel and userspace don't need to incur the overhead of
154processing new netlink attributes. But if the new fields expand the existing
155struct too much, requiring disparate userspace accounting utilities to
156unnecessarily receive large structures whose fields are of no interest, then
157extending the attributes structure would be worthwhile.
158
159Flow control for taskstats
160--------------------------
161
162When the rate of task exits becomes large, a listener may not be able to keep
163up with the kernel's rate of sending per-tid/tgid exit data leading to data
164loss. This possibility gets compounded when the taskstats structure gets
165extended and the number of cpus grows large.
166
167To avoid losing statistics, userspace should do one or more of the following:
168
169- increase the receive buffer sizes for the netlink sockets opened by
170listeners to receive exit data.
171
172- create more listeners and reduce the number of cpus being listened to by
173each listener. In the extreme case, there could be one listener for each cpu.
174Users may also consider setting the cpu affinity of the listener to the subset
175of cpus to which it listens, especially if they are listening to just one cpu.
176
177Despite these measures, if the userspace receives ENOBUFS error messages
178indicated overflow of receive buffers, it should take measures to handle the
179loss of data.
180
181----
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 149f62ba14a5..e11f7728ec6f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -448,6 +448,8 @@ running once the system is up.
448 Format: <area>[,<node>] 448 Format: <area>[,<node>]
449 See also Documentation/networking/decnet.txt. 449 See also Documentation/networking/decnet.txt.
450 450
451 delayacct [KNL] Enable per-task delay accounting
452
451 dhash_entries= [KNL] 453 dhash_entries= [KNL]
452 Set number of hash buckets for dentry cache. 454 Set number of hash buckets for dentry cache.
453 455
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 28d1bc3edb1c..46b9b389df35 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -1015,10 +1015,9 @@ CPU from reordering them.
1015There are some more advanced barrier functions: 1015There are some more advanced barrier functions:
1016 1016
1017 (*) set_mb(var, value) 1017 (*) set_mb(var, value)
1018 (*) set_wmb(var, value)
1019 1018
1020 These assign the value to the variable and then insert at least a write 1019 This assigns the value to the variable and then inserts at least a write
1021 barrier after it, depending on the function. They aren't guaranteed to 1020 barrier after it, depending on the function. It isn't guaranteed to
1022 insert anything more than a compiler barrier in a UP compilation. 1021 insert anything more than a compiler barrier in a UP compilation.
1023 1022
1024 1023
diff --git a/Documentation/ramdisk.txt b/Documentation/ramdisk.txt
index 7c25584e082c..52f75b7d51c2 100644
--- a/Documentation/ramdisk.txt
+++ b/Documentation/ramdisk.txt
@@ -6,7 +6,7 @@ Contents:
6 1) Overview 6 1) Overview
7 2) Kernel Command Line Parameters 7 2) Kernel Command Line Parameters
8 3) Using "rdev -r" 8 3) Using "rdev -r"
9 4) An Example of Creating a Compressed RAM Disk 9 4) An Example of Creating a Compressed RAM Disk
10 10
11 11
121) Overview 121) Overview
@@ -34,7 +34,7 @@ make it clearer. The original "ramdisk=<ram_size>" has been kept around for
34compatibility reasons, but it may be removed in the future. 34compatibility reasons, but it may be removed in the future.
35 35
36The new RAM disk also has the ability to load compressed RAM disk images, 36The new RAM disk also has the ability to load compressed RAM disk images,
37allowing one to squeeze more programs onto an average installation or 37allowing one to squeeze more programs onto an average installation or
38rescue floppy disk. 38rescue floppy disk.
39 39
40 40
@@ -51,7 +51,7 @@ default is 4096 (4 MB) (8192 (8 MB) on S390).
51 =================== 51 ===================
52 52
53This parameter tells the RAM disk driver how many bytes to use per block. The 53This parameter tells the RAM disk driver how many bytes to use per block. The
54default is 512. 54default is 1024 (BLOCK_SIZE).
55 55
56 56
573) Using "rdev -r" 573) Using "rdev -r"
@@ -70,7 +70,7 @@ These numbers are no magical secrets, as seen below:
70./arch/i386/kernel/setup.c:#define RAMDISK_PROMPT_FLAG 0x8000 70./arch/i386/kernel/setup.c:#define RAMDISK_PROMPT_FLAG 0x8000
71./arch/i386/kernel/setup.c:#define RAMDISK_LOAD_FLAG 0x4000 71./arch/i386/kernel/setup.c:#define RAMDISK_LOAD_FLAG 0x4000
72 72
73Consider a typical two floppy disk setup, where you will have the 73Consider a typical two floppy disk setup, where you will have the
74kernel on disk one, and have already put a RAM disk image onto disk #2. 74kernel on disk one, and have already put a RAM disk image onto disk #2.
75 75
76Hence you want to set bits 0 to 13 as 0, meaning that your RAM disk 76Hence you want to set bits 0 to 13 as 0, meaning that your RAM disk
@@ -97,12 +97,12 @@ Since the default start = 0 and the default prompt = 1, you could use:
97 append = "load_ramdisk=1" 97 append = "load_ramdisk=1"
98 98
99 99
1004) An Example of Creating a Compressed RAM Disk 1004) An Example of Creating a Compressed RAM Disk
101---------------------------------------------- 101----------------------------------------------
102 102
103To create a RAM disk image, you will need a spare block device to 103To create a RAM disk image, you will need a spare block device to
104construct it on. This can be the RAM disk device itself, or an 104construct it on. This can be the RAM disk device itself, or an
105unused disk partition (such as an unmounted swap partition). For this 105unused disk partition (such as an unmounted swap partition). For this
106example, we will use the RAM disk device, "/dev/ram0". 106example, we will use the RAM disk device, "/dev/ram0".
107 107
108Note: This technique should not be done on a machine with less than 8 MB 108Note: This technique should not be done on a machine with less than 8 MB
diff --git a/MAINTAINERS b/MAINTAINERS
index a3462c3414cd..e99028ca2f7c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -771,6 +771,7 @@ M: aliakc@web.de
771P: Jamie Lenehan 771P: Jamie Lenehan
772M: lenehan@twibble.org 772M: lenehan@twibble.org
773W: http://twibble.org/dist/dc395x/ 773W: http://twibble.org/dist/dc395x/
774L: dc395x@twibble.org
774L: http://lists.twibble.org/mailman/listinfo/dc395x/ 775L: http://lists.twibble.org/mailman/listinfo/dc395x/
775S: Maintained 776S: Maintained
776 777
@@ -1501,6 +1502,7 @@ P: Yi Zhu
1501M: yi.zhu@intel.com 1502M: yi.zhu@intel.com
1502P: James Ketrenos 1503P: James Ketrenos
1503M: jketreno@linux.intel.com 1504M: jketreno@linux.intel.com
1505L: ipw2100-devel@lists.sourceforge.net
1504L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel 1506L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
1505W: http://ipw2100.sourceforge.net 1507W: http://ipw2100.sourceforge.net
1506S: Supported 1508S: Supported
@@ -1510,6 +1512,7 @@ P: Yi Zhu
1510M: yi.zhu@intel.com 1512M: yi.zhu@intel.com
1511P: James Ketrenos 1513P: James Ketrenos
1512M: jketreno@linux.intel.com 1514M: jketreno@linux.intel.com
1515L: ipw2100-devel@lists.sourceforge.net
1513L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel 1516L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
1514W: http://ipw2200.sourceforge.net 1517W: http://ipw2200.sourceforge.net
1515S: Supported 1518S: Supported
@@ -2226,6 +2229,7 @@ S: Maintained
2226 2229
2227PCMCIA SUBSYSTEM 2230PCMCIA SUBSYSTEM
2228P: Linux PCMCIA Team 2231P: Linux PCMCIA Team
2232L: linux-pcmcia@lists.infradead.org
2229L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia 2233L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia
2230T: git kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git 2234T: git kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
2231S: Maintained 2235S: Maintained
@@ -2236,6 +2240,12 @@ M: tsbogend@alpha.franken.de
2236L: netdev@vger.kernel.org 2240L: netdev@vger.kernel.org
2237S: Maintained 2241S: Maintained
2238 2242
2243PER-TASK DELAY ACCOUNTING
2244P: Shailabh Nagar
2245M: nagar@watson.ibm.com
2246L: linux-kernel@vger.kernel.org
2247S: Maintained
2248
2239PERSONALITY HANDLING 2249PERSONALITY HANDLING
2240P: Christoph Hellwig 2250P: Christoph Hellwig
2241M: hch@infradead.org 2251M: hch@infradead.org
@@ -2763,6 +2773,12 @@ P: Deepak Saxena
2763M: dsaxena@plexity.net 2773M: dsaxena@plexity.net
2764S: Maintained 2774S: Maintained
2765 2775
2776TASKSTATS STATISTICS INTERFACE
2777P: Shailabh Nagar
2778M: nagar@watson.ibm.com
2779L: linux-kernel@vger.kernel.org
2780S: Maintained
2781
2766TI PARALLEL LINK CABLE DRIVER 2782TI PARALLEL LINK CABLE DRIVER
2767P: Romain Lievin 2783P: Romain Lievin
2768M: roms@lpg.ticalc.org 2784M: roms@lpg.ticalc.org
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 48f0f62f781c..5b96f038367f 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -90,7 +90,7 @@ static void crash_save_self(struct pt_regs *regs)
90 crash_save_this_cpu(regs, cpu); 90 crash_save_this_cpu(regs, cpu);
91} 91}
92 92
93#ifdef CONFIG_SMP 93#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
94static atomic_t waiting_for_crash_ipi; 94static atomic_t waiting_for_crash_ipi;
95 95
96static int crash_nmi_callback(struct pt_regs *regs, int cpu) 96static int crash_nmi_callback(struct pt_regs *regs, int cpu)
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 7864395c1441..f1682206d304 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -1327,7 +1327,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
1327 res->start = e820.map[i].addr; 1327 res->start = e820.map[i].addr;
1328 res->end = res->start + e820.map[i].size - 1; 1328 res->end = res->start + e820.map[i].size - 1;
1329 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; 1329 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
1330 request_resource(&iomem_resource, res); 1330 if (request_resource(&iomem_resource, res)) {
1331 kfree(res);
1332 continue;
1333 }
1331 if (e820.map[i].type == E820_RAM) { 1334 if (e820.map[i].type == E820_RAM) {
1332 /* 1335 /*
1333 * We don't know which RAM region contains kernel data, 1336 * We don't know which RAM region contains kernel data,
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 5cfd4f42eeba..313ac1f7dc5a 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -324,35 +324,35 @@ void show_registers(struct pt_regs *regs)
324 324
325static void handle_BUG(struct pt_regs *regs) 325static void handle_BUG(struct pt_regs *regs)
326{ 326{
327 unsigned long eip = regs->eip;
327 unsigned short ud2; 328 unsigned short ud2;
328 unsigned short line;
329 char *file;
330 char c;
331 unsigned long eip;
332
333 eip = regs->eip;
334 329
335 if (eip < PAGE_OFFSET) 330 if (eip < PAGE_OFFSET)
336 goto no_bug; 331 return;
337 if (__get_user(ud2, (unsigned short __user *)eip)) 332 if (__get_user(ud2, (unsigned short __user *)eip))
338 goto no_bug; 333 return;
339 if (ud2 != 0x0b0f) 334 if (ud2 != 0x0b0f)
340 goto no_bug; 335 return;
341 if (__get_user(line, (unsigned short __user *)(eip + 2)))
342 goto bug;
343 if (__get_user(file, (char * __user *)(eip + 4)) ||
344 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
345 file = "<bad filename>";
346 336
347 printk(KERN_EMERG "------------[ cut here ]------------\n"); 337 printk(KERN_EMERG "------------[ cut here ]------------\n");
348 printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
349 338
350no_bug: 339#ifdef CONFIG_DEBUG_BUGVERBOSE
351 return; 340 do {
341 unsigned short line;
342 char *file;
343 char c;
352 344
353 /* Here we know it was a BUG but file-n-line is unavailable */ 345 if (__get_user(line, (unsigned short __user *)(eip + 2)))
354bug: 346 break;
355 printk(KERN_EMERG "Kernel BUG\n"); 347 if (__get_user(file, (char * __user *)(eip + 4)) ||
348 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
349 file = "<bad filename>";
350
351 printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
352 return;
353 } while (0);
354#endif
355 printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
356} 356}
357 357
358/* This is gone through when something in the kernel 358/* This is gone through when something in the kernel
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index 4b75212ab6dd..efc7e7d5f4d0 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -843,7 +843,6 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr
843unsigned long 843unsigned long
844copy_to_user(void __user *to, const void *from, unsigned long n) 844copy_to_user(void __user *to, const void *from, unsigned long n)
845{ 845{
846 might_sleep();
847 BUG_ON((long) n < 0); 846 BUG_ON((long) n < 0);
848 if (access_ok(VERIFY_WRITE, to, n)) 847 if (access_ok(VERIFY_WRITE, to, n))
849 n = __copy_to_user(to, from, n); 848 n = __copy_to_user(to, from, n);
@@ -870,7 +869,6 @@ EXPORT_SYMBOL(copy_to_user);
870unsigned long 869unsigned long
871copy_from_user(void *to, const void __user *from, unsigned long n) 870copy_from_user(void *to, const void __user *from, unsigned long n)
872{ 871{
873 might_sleep();
874 BUG_ON((long) n < 0); 872 BUG_ON((long) n < 0);
875 if (access_ok(VERIFY_READ, from, n)) 873 if (access_ok(VERIFY_READ, from, n))
876 n = __copy_from_user(to, from, n); 874 n = __copy_from_user(to, from, n);
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 75684b56767e..c8e9dc9d68a9 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -551,9 +551,10 @@ setup_trap_table:
551 save %sp, -192, %sp 551 save %sp, -192, %sp
552 552
553 /* Force interrupts to be disabled. */ 553 /* Force interrupts to be disabled. */
554 rdpr %pstate, %o1 554 rdpr %pstate, %l0
555 andn %o1, PSTATE_IE, %o1 555 andn %l0, PSTATE_IE, %o1
556 wrpr %o1, 0x0, %pstate 556 wrpr %o1, 0x0, %pstate
557 rdpr %pil, %l1
557 wrpr %g0, 15, %pil 558 wrpr %g0, 15, %pil
558 559
559 /* Make the firmware call to jump over to the Linux trap table. */ 560 /* Make the firmware call to jump over to the Linux trap table. */
@@ -622,11 +623,9 @@ setup_trap_table:
622 call init_irqwork_curcpu 623 call init_irqwork_curcpu
623 nop 624 nop
624 625
625 /* Now we can turn interrupts back on. */ 626 /* Now we can restore interrupt state. */
626 rdpr %pstate, %o1 627 wrpr %l0, 0, %pstate
627 or %o1, PSTATE_IE, %o1 628 wrpr %l1, 0x0, %pil
628 wrpr %o1, 0, %pstate
629 wrpr %g0, 0x0, %pil
630 629
631 ret 630 ret
632 restore 631 restore
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 197a7ffd57ee..1ec0aab68c08 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1099,9 +1099,6 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1099{ 1099{
1100 char *name = pbm->name; 1100 char *name = pbm->name;
1101 1101
1102 sprintf(name, "PSYCHO%d PBM%c",
1103 p->index,
1104 (pbm == &p->pbm_A ? 'A' : 'B'));
1105 pbm->io_space.name = pbm->mem_space.name = name; 1102 pbm->io_space.name = pbm->mem_space.name = name;
1106 1103
1107 request_resource(&ioport_resource, &pbm->io_space); 1104 request_resource(&ioport_resource, &pbm->io_space);
@@ -1203,12 +1200,13 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1203 pbm->io_space.flags = IORESOURCE_IO; 1200 pbm->io_space.flags = IORESOURCE_IO;
1204 pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE; 1201 pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE;
1205 pbm->mem_space.flags = IORESOURCE_MEM; 1202 pbm->mem_space.flags = IORESOURCE_MEM;
1206 pbm_register_toplevel_resources(p, pbm);
1207 1203
1208 pbm->parent = p; 1204 pbm->parent = p;
1209 pbm->prom_node = dp; 1205 pbm->prom_node = dp;
1210 pbm->name = dp->full_name; 1206 pbm->name = dp->full_name;
1211 1207
1208 pbm_register_toplevel_resources(p, pbm);
1209
1212 printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", 1210 printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
1213 pbm->name, 1211 pbm->name,
1214 pbm->chip_version, pbm->chip_revision); 1212 pbm->chip_version, pbm->chip_revision);
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index b43de647ba73..094d3e35be18 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -928,8 +928,6 @@ static void sparc64_start_timers(void)
928 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" 928 __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
929 : /* no outputs */ 929 : /* no outputs */
930 : "r" (pstate)); 930 : "r" (pstate));
931
932 local_irq_enable();
933} 931}
934 932
935struct freq_table { 933struct freq_table {
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index dffd1184c956..9558a7cf34d5 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -11,6 +11,7 @@ USER_CFLAGS += -fno-builtin -m64
11CHECKFLAGS += -m64 11CHECKFLAGS += -m64
12AFLAGS += -m64 12AFLAGS += -m64
13LDFLAGS += -m elf_x86_64 13LDFLAGS += -m elf_x86_64
14CPPFLAGS += -m64
14 15
15ELF_ARCH := i386:x86-64 16ELF_ARCH := i386:x86-64
16ELF_FORMAT := elf64-x86-64 17ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
index 8e7053013f7b..1b5c0131a12e 100644
--- a/arch/um/include/longjmp.h
+++ b/arch/um/include/longjmp.h
@@ -8,8 +8,8 @@
8 longjmp(*buf, val); \ 8 longjmp(*buf, val); \
9} while(0) 9} while(0)
10 10
11#define UML_SETJMP(buf, enable) ({ \ 11#define UML_SETJMP(buf) ({ \
12 int n; \ 12 int n, enable; \
13 enable = get_signals(); \ 13 enable = get_signals(); \
14 n = setjmp(*buf); \ 14 n = setjmp(*buf); \
15 if(n != 0) \ 15 if(n != 0) \
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index b6c52496e15a..5316e8a4a4fd 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -15,9 +15,9 @@
15#include "irq_user.h" 15#include "irq_user.h"
16#include "sysdep/tls.h" 16#include "sysdep/tls.h"
17 17
18#define OS_TYPE_FILE 1 18#define OS_TYPE_FILE 1
19#define OS_TYPE_DIR 2 19#define OS_TYPE_DIR 2
20#define OS_TYPE_SYMLINK 3 20#define OS_TYPE_SYMLINK 3
21#define OS_TYPE_CHARDEV 4 21#define OS_TYPE_CHARDEV 4
22#define OS_TYPE_BLOCKDEV 5 22#define OS_TYPE_BLOCKDEV 5
23#define OS_TYPE_FIFO 6 23#define OS_TYPE_FIFO 6
@@ -61,68 +61,68 @@ struct openflags {
61}; 61};
62 62
63#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \ 63#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
64 .t = 0, .a = 0, .e = 0, .cl = 0 }) 64 .t = 0, .a = 0, .e = 0, .cl = 0 })
65 65
66static inline struct openflags of_read(struct openflags flags) 66static inline struct openflags of_read(struct openflags flags)
67{ 67{
68 flags.r = 1; 68 flags.r = 1;
69 return(flags); 69 return flags;
70} 70}
71 71
72static inline struct openflags of_write(struct openflags flags) 72static inline struct openflags of_write(struct openflags flags)
73{ 73{
74 flags.w = 1; 74 flags.w = 1;
75 return(flags); 75 return flags;
76} 76}
77 77
78static inline struct openflags of_rdwr(struct openflags flags) 78static inline struct openflags of_rdwr(struct openflags flags)
79{ 79{
80 return(of_read(of_write(flags))); 80 return of_read(of_write(flags));
81} 81}
82 82
83static inline struct openflags of_set_rw(struct openflags flags, int r, int w) 83static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
84{ 84{
85 flags.r = r; 85 flags.r = r;
86 flags.w = w; 86 flags.w = w;
87 return(flags); 87 return flags;
88} 88}
89 89
90static inline struct openflags of_sync(struct openflags flags) 90static inline struct openflags of_sync(struct openflags flags)
91{ 91{
92 flags.s = 1; 92 flags.s = 1;
93 return(flags); 93 return flags;
94} 94}
95 95
96static inline struct openflags of_create(struct openflags flags) 96static inline struct openflags of_create(struct openflags flags)
97{ 97{
98 flags.c = 1; 98 flags.c = 1;
99 return(flags); 99 return flags;
100} 100}
101 101
102static inline struct openflags of_trunc(struct openflags flags) 102static inline struct openflags of_trunc(struct openflags flags)
103{ 103{
104 flags.t = 1; 104 flags.t = 1;
105 return(flags); 105 return flags;
106} 106}
107 107
108static inline struct openflags of_append(struct openflags flags) 108static inline struct openflags of_append(struct openflags flags)
109{ 109{
110 flags.a = 1; 110 flags.a = 1;
111 return(flags); 111 return flags;
112} 112}
113 113
114static inline struct openflags of_excl(struct openflags flags) 114static inline struct openflags of_excl(struct openflags flags)
115{ 115{
116 flags.e = 1; 116 flags.e = 1;
117 return(flags); 117 return flags;
118} 118}
119 119
120static inline struct openflags of_cloexec(struct openflags flags) 120static inline struct openflags of_cloexec(struct openflags flags)
121{ 121{
122 flags.cl = 1; 122 flags.cl = 1;
123 return(flags); 123 return flags;
124} 124}
125 125
126/* file.c */ 126/* file.c */
127extern int os_stat_file(const char *file_name, struct uml_stat *buf); 127extern int os_stat_file(const char *file_name, struct uml_stat *buf);
128extern int os_stat_fd(const int fd, struct uml_stat *buf); 128extern int os_stat_fd(const int fd, struct uml_stat *buf);
@@ -204,7 +204,7 @@ extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
204 204
205extern int os_map_memory(void *virt, int fd, unsigned long long off, 205extern int os_map_memory(void *virt, int fd, unsigned long long off,
206 unsigned long len, int r, int w, int x); 206 unsigned long len, int r, int w, int x);
207extern int os_protect_memory(void *addr, unsigned long len, 207extern int os_protect_memory(void *addr, unsigned long len,
208 int r, int w, int x); 208 int r, int w, int x);
209extern int os_unmap_memory(void *addr, int len); 209extern int os_unmap_memory(void *addr, int len);
210extern int os_drop_memory(void *addr, int length); 210extern int os_drop_memory(void *addr, int length);
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
index 72acdce205e0..f8aeb448aab6 100644
--- a/arch/um/kernel/vmlinux.lds.S
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -1,5 +1,3 @@
1/* in case the preprocessor is a 32bit one */
2#undef i386
3#ifdef CONFIG_LD_SCRIPT_STATIC 1#ifdef CONFIG_LD_SCRIPT_STATIC
4#include "uml.lds.S" 2#include "uml.lds.S"
5#else 3#else
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index b1cda818f5b5..b98d3ca2cd1b 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -273,12 +273,12 @@ void init_new_thread_signals(void)
273int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) 273int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
274{ 274{
275 jmp_buf buf; 275 jmp_buf buf;
276 int n, enable; 276 int n;
277 277
278 *jmp_ptr = &buf; 278 *jmp_ptr = &buf;
279 n = UML_SETJMP(&buf, enable); 279 n = UML_SETJMP(&buf);
280 if(n != 0) 280 if(n != 0)
281 return(n); 281 return n;
282 (*fn)(arg); 282 (*fn)(arg);
283 return(0); 283 return 0;
284} 284}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index bf35572d9cfa..7baf90fda58b 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -435,7 +435,6 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
435{ 435{
436 unsigned long flags; 436 unsigned long flags;
437 jmp_buf switch_buf, fork_buf; 437 jmp_buf switch_buf, fork_buf;
438 int enable;
439 438
440 *switch_buf_ptr = &switch_buf; 439 *switch_buf_ptr = &switch_buf;
441 *fork_buf_ptr = &fork_buf; 440 *fork_buf_ptr = &fork_buf;
@@ -450,7 +449,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
450 */ 449 */
451 flags = get_signals(); 450 flags = get_signals();
452 block_signals(); 451 block_signals();
453 if(UML_SETJMP(&fork_buf, enable) == 0) 452 if(UML_SETJMP(&fork_buf) == 0)
454 new_thread_proc(stack, handler); 453 new_thread_proc(stack, handler);
455 454
456 remove_sigstack(); 455 remove_sigstack();
@@ -467,21 +466,19 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
467void thread_wait(void *sw, void *fb) 466void thread_wait(void *sw, void *fb)
468{ 467{
469 jmp_buf buf, **switch_buf = sw, *fork_buf; 468 jmp_buf buf, **switch_buf = sw, *fork_buf;
470 int enable;
471 469
472 *switch_buf = &buf; 470 *switch_buf = &buf;
473 fork_buf = fb; 471 fork_buf = fb;
474 if(UML_SETJMP(&buf, enable) == 0) 472 if(UML_SETJMP(&buf) == 0)
475 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); 473 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
476} 474}
477 475
478void switch_threads(void *me, void *next) 476void switch_threads(void *me, void *next)
479{ 477{
480 jmp_buf my_buf, **me_ptr = me, *next_buf = next; 478 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
481 int enable;
482 479
483 *me_ptr = &my_buf; 480 *me_ptr = &my_buf;
484 if(UML_SETJMP(&my_buf, enable) == 0) 481 if(UML_SETJMP(&my_buf) == 0)
485 UML_LONGJMP(next_buf, 1); 482 UML_LONGJMP(next_buf, 1);
486} 483}
487 484
@@ -495,14 +492,14 @@ static jmp_buf *cb_back;
495int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) 492int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
496{ 493{
497 jmp_buf **switch_buf = switch_buf_ptr; 494 jmp_buf **switch_buf = switch_buf_ptr;
498 int n, enable; 495 int n;
499 496
500 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 497 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
501 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, 498 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
502 SIGVTALRM, -1); 499 SIGVTALRM, -1);
503 500
504 *fork_buf_ptr = &initial_jmpbuf; 501 *fork_buf_ptr = &initial_jmpbuf;
505 n = UML_SETJMP(&initial_jmpbuf, enable); 502 n = UML_SETJMP(&initial_jmpbuf);
506 switch(n){ 503 switch(n){
507 case INIT_JMP_NEW_THREAD: 504 case INIT_JMP_NEW_THREAD:
508 new_thread_proc((void *) stack, new_thread_handler); 505 new_thread_proc((void *) stack, new_thread_handler);
@@ -529,14 +526,13 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
529void initial_thread_cb_skas(void (*proc)(void *), void *arg) 526void initial_thread_cb_skas(void (*proc)(void *), void *arg)
530{ 527{
531 jmp_buf here; 528 jmp_buf here;
532 int enable;
533 529
534 cb_proc = proc; 530 cb_proc = proc;
535 cb_arg = arg; 531 cb_arg = arg;
536 cb_back = &here; 532 cb_back = &here;
537 533
538 block_signals(); 534 block_signals();
539 if(UML_SETJMP(&here, enable) == 0) 535 if(UML_SETJMP(&here) == 0)
540 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); 536 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
541 unblock_signals(); 537 unblock_signals();
542 538
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index e523719330b2..865f6a6a2590 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -14,11 +14,10 @@ unsigned long __do_user_copy(void *to, const void *from, int n,
14 int n), int *faulted_out) 14 int n), int *faulted_out)
15{ 15{
16 unsigned long *faddrp = (unsigned long *) fault_addr, ret; 16 unsigned long *faddrp = (unsigned long *) fault_addr, ret;
17 int enable;
18 17
19 jmp_buf jbuf; 18 jmp_buf jbuf;
20 *fault_catcher = &jbuf; 19 *fault_catcher = &jbuf;
21 if(UML_SETJMP(&jbuf, enable) == 0){ 20 if(UML_SETJMP(&jbuf) == 0){
22 (*op)(to, from, n); 21 (*op)(to, from, n);
23 ret = 0; 22 ret = 0;
24 *faulted_out = 0; 23 *faulted_out = 0;
diff --git a/block/ioctl.c b/block/ioctl.c
index 9cfa2e1ecb24..309760b7e37f 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -72,7 +72,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
72 bdevp = bdget_disk(disk, part); 72 bdevp = bdget_disk(disk, part);
73 if (!bdevp) 73 if (!bdevp)
74 return -ENOMEM; 74 return -ENOMEM;
75 mutex_lock(&bdevp->bd_mutex); 75 mutex_lock_nested(&bdevp->bd_mutex, BD_MUTEX_PARTITION);
76 if (bdevp->bd_openers) { 76 if (bdevp->bd_openers) {
77 mutex_unlock(&bdevp->bd_mutex); 77 mutex_unlock(&bdevp->bd_mutex);
78 bdput(bdevp); 78 bdput(bdevp);
@@ -82,7 +82,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
82 fsync_bdev(bdevp); 82 fsync_bdev(bdevp);
83 invalidate_bdev(bdevp, 0); 83 invalidate_bdev(bdevp, 0);
84 84
85 mutex_lock(&bdev->bd_mutex); 85 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_WHOLE);
86 delete_partition(disk, part); 86 delete_partition(disk, part);
87 mutex_unlock(&bdev->bd_mutex); 87 mutex_unlock(&bdev->bd_mutex);
88 mutex_unlock(&bdevp->bd_mutex); 88 mutex_unlock(&bdevp->bd_mutex);
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 93d94749310b..b5382cedf0c0 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -400,6 +400,16 @@ config BLK_DEV_RAM_SIZE
400 what are you doing. If you are using IBM S/390, then set this to 400 what are you doing. If you are using IBM S/390, then set this to
401 8192. 401 8192.
402 402
403config BLK_DEV_RAM_BLOCKSIZE
404 int "Default RAM disk block size (bytes)"
405 depends on BLK_DEV_RAM
406 default "1024"
407 help
408 The default value is 1024 kilobytes. PAGE_SIZE is a much more
409 efficient choice however. The default is kept to ensure initrd
410 setups function - apparently needed by the rd_load_image routine
411 that supposes the filesystem in the image uses a 1024 blocksize.
412
403config BLK_DEV_INITRD 413config BLK_DEV_INITRD
404 bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" 414 bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
405 depends on BROKEN || !FRV 415 depends on BROKEN || !FRV
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 757f42dd8e86..78082edc14b4 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -1739,8 +1739,6 @@ static void getgeometry(int ctlr)
1739 (log_index < id_ctlr_buf->nr_drvs) 1739 (log_index < id_ctlr_buf->nr_drvs)
1740 && (log_unit < NWD); 1740 && (log_unit < NWD);
1741 log_unit++) { 1741 log_unit++) {
1742 struct gendisk *disk = ida_gendisk[ctlr][log_unit];
1743
1744 size = sizeof(sense_log_drv_stat_t); 1742 size = sizeof(sense_log_drv_stat_t);
1745 1743
1746 /* 1744 /*
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 3cf246abb5ec..a3f64bfe6b58 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -84,7 +84,7 @@ int rd_size = CONFIG_BLK_DEV_RAM_SIZE; /* Size of the RAM disks */
84 * behaviour. The default is still BLOCK_SIZE (needed by rd_load_image that 84 * behaviour. The default is still BLOCK_SIZE (needed by rd_load_image that
85 * supposes the filesystem in the image uses a BLOCK_SIZE blocksize). 85 * supposes the filesystem in the image uses a BLOCK_SIZE blocksize).
86 */ 86 */
87static int rd_blocksize = BLOCK_SIZE; /* blocksize of the RAM disks */ 87static int rd_blocksize = CONFIG_BLK_DEV_RAM_BLOCKSIZE;
88 88
89/* 89/*
90 * Copyright (C) 2000 Linus Torvalds. 90 * Copyright (C) 2000 Linus Torvalds.
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c
index 5b91e4e25641..7719bd75810b 100644
--- a/drivers/char/nsc_gpio.c
+++ b/drivers/char/nsc_gpio.c
@@ -68,13 +68,11 @@ ssize_t nsc_gpio_write(struct file *file, const char __user *data,
68 amp->gpio_config(m, ~1, 0); 68 amp->gpio_config(m, ~1, 0);
69 break; 69 break;
70 case 'T': 70 case 'T':
71 dev_dbg(dev, "GPIO%d output is push pull\n", 71 dev_dbg(dev, "GPIO%d output is push pull\n", m);
72 m);
73 amp->gpio_config(m, ~2, 2); 72 amp->gpio_config(m, ~2, 2);
74 break; 73 break;
75 case 't': 74 case 't':
76 dev_dbg(dev, "GPIO%d output is open drain\n", 75 dev_dbg(dev, "GPIO%d output is open drain\n", m);
77 m);
78 amp->gpio_config(m, ~2, 0); 76 amp->gpio_config(m, ~2, 0);
79 break; 77 break;
80 case 'P': 78 case 'P':
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index 11bd78c80628..645eb81cb5a9 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -212,22 +212,21 @@ static void pc8736x_gpio_change(unsigned index)
212 pc8736x_gpio_set(index, !pc8736x_gpio_current(index)); 212 pc8736x_gpio_set(index, !pc8736x_gpio_current(index));
213} 213}
214 214
215static struct nsc_gpio_ops pc8736x_access = { 215static struct nsc_gpio_ops pc8736x_gpio_ops = {
216 .owner = THIS_MODULE, 216 .owner = THIS_MODULE,
217 .gpio_config = pc8736x_gpio_configure, 217 .gpio_config = pc8736x_gpio_configure,
218 .gpio_dump = nsc_gpio_dump, 218 .gpio_dump = nsc_gpio_dump,
219 .gpio_get = pc8736x_gpio_get, 219 .gpio_get = pc8736x_gpio_get,
220 .gpio_set = pc8736x_gpio_set, 220 .gpio_set = pc8736x_gpio_set,
221 .gpio_set_high = pc8736x_gpio_set_high,
222 .gpio_set_low = pc8736x_gpio_set_low,
223 .gpio_change = pc8736x_gpio_change, 221 .gpio_change = pc8736x_gpio_change,
224 .gpio_current = pc8736x_gpio_current 222 .gpio_current = pc8736x_gpio_current
225}; 223};
224EXPORT_SYMBOL(pc8736x_gpio_ops);
226 225
227static int pc8736x_gpio_open(struct inode *inode, struct file *file) 226static int pc8736x_gpio_open(struct inode *inode, struct file *file)
228{ 227{
229 unsigned m = iminor(inode); 228 unsigned m = iminor(inode);
230 file->private_data = &pc8736x_access; 229 file->private_data = &pc8736x_gpio_ops;
231 230
232 dev_dbg(&pdev->dev, "open %d\n", m); 231 dev_dbg(&pdev->dev, "open %d\n", m);
233 232
@@ -236,7 +235,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file)
236 return nonseekable_open(inode, file); 235 return nonseekable_open(inode, file);
237} 236}
238 237
239static const struct file_operations pc8736x_gpio_fops = { 238static const struct file_operations pc8736x_gpio_fileops = {
240 .owner = THIS_MODULE, 239 .owner = THIS_MODULE,
241 .open = pc8736x_gpio_open, 240 .open = pc8736x_gpio_open,
242 .write = nsc_gpio_write, 241 .write = nsc_gpio_write,
@@ -278,7 +277,7 @@ static int __init pc8736x_gpio_init(void)
278 dev_err(&pdev->dev, "no device found\n"); 277 dev_err(&pdev->dev, "no device found\n");
279 goto undo_platform_dev_add; 278 goto undo_platform_dev_add;
280 } 279 }
281 pc8736x_access.dev = &pdev->dev; 280 pc8736x_gpio_ops.dev = &pdev->dev;
282 281
283 /* Verify that chip and it's GPIO unit are both enabled. 282 /* Verify that chip and it's GPIO unit are both enabled.
284 My BIOS does this, so I take minimum action here 283 My BIOS does this, so I take minimum action here
@@ -328,7 +327,7 @@ static int __init pc8736x_gpio_init(void)
328 pc8736x_init_shadow(); 327 pc8736x_init_shadow();
329 328
330 /* ignore minor errs, and succeed */ 329 /* ignore minor errs, and succeed */
331 cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fops); 330 cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops);
332 cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT); 331 cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);
333 332
334 return 0; 333 return 0;
@@ -355,7 +354,5 @@ static void __exit pc8736x_gpio_cleanup(void)
355 platform_device_put(pdev); 354 platform_device_put(pdev);
356} 355}
357 356
358EXPORT_SYMBOL(pc8736x_access);
359
360module_init(pc8736x_gpio_init); 357module_init(pc8736x_gpio_init);
361module_exit(pc8736x_gpio_cleanup); 358module_exit(pc8736x_gpio_cleanup);
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 425c58719db6..b956c7babd18 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -5,7 +5,6 @@
5 5
6 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */ 6 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */
7 7
8#include <linux/config.h>
9#include <linux/device.h> 8#include <linux/device.h>
10#include <linux/fs.h> 9#include <linux/fs.h>
11#include <linux/module.h> 10#include <linux/module.h>
@@ -22,37 +21,37 @@
22#include <linux/scx200_gpio.h> 21#include <linux/scx200_gpio.h>
23#include <linux/nsc_gpio.h> 22#include <linux/nsc_gpio.h>
24 23
25#define NAME "scx200_gpio" 24#define DRVNAME "scx200_gpio"
26#define DEVNAME NAME
27 25
28static struct platform_device *pdev; 26static struct platform_device *pdev;
29 27
30MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); 28MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
31MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); 29MODULE_DESCRIPTION("NatSemi/AMD SCx200 GPIO Pin Driver");
32MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
33 31
34static int major = 0; /* default to dynamic major */ 32static int major = 0; /* default to dynamic major */
35module_param(major, int, 0); 33module_param(major, int, 0);
36MODULE_PARM_DESC(major, "Major device number"); 34MODULE_PARM_DESC(major, "Major device number");
37 35
38struct nsc_gpio_ops scx200_access = { 36#define MAX_PINS 32 /* 64 later, when known ok */
37
38struct nsc_gpio_ops scx200_gpio_ops = {
39 .owner = THIS_MODULE, 39 .owner = THIS_MODULE,
40 .gpio_config = scx200_gpio_configure, 40 .gpio_config = scx200_gpio_configure,
41 .gpio_dump = nsc_gpio_dump, 41 .gpio_dump = nsc_gpio_dump,
42 .gpio_get = scx200_gpio_get, 42 .gpio_get = scx200_gpio_get,
43 .gpio_set = scx200_gpio_set, 43 .gpio_set = scx200_gpio_set,
44 .gpio_set_high = scx200_gpio_set_high,
45 .gpio_set_low = scx200_gpio_set_low,
46 .gpio_change = scx200_gpio_change, 44 .gpio_change = scx200_gpio_change,
47 .gpio_current = scx200_gpio_current 45 .gpio_current = scx200_gpio_current
48}; 46};
47EXPORT_SYMBOL(scx200_gpio_ops);
49 48
50static int scx200_gpio_open(struct inode *inode, struct file *file) 49static int scx200_gpio_open(struct inode *inode, struct file *file)
51{ 50{
52 unsigned m = iminor(inode); 51 unsigned m = iminor(inode);
53 file->private_data = &scx200_access; 52 file->private_data = &scx200_gpio_ops;
54 53
55 if (m > 63) 54 if (m >= MAX_PINS)
56 return -EINVAL; 55 return -EINVAL;
57 return nonseekable_open(inode, file); 56 return nonseekable_open(inode, file);
58} 57}
@@ -62,8 +61,7 @@ static int scx200_gpio_release(struct inode *inode, struct file *file)
62 return 0; 61 return 0;
63} 62}
64 63
65 64static const struct file_operations scx200_gpio_fileops = {
66static const struct file_operations scx200_gpio_fops = {
67 .owner = THIS_MODULE, 65 .owner = THIS_MODULE,
68 .write = nsc_gpio_write, 66 .write = nsc_gpio_write,
69 .read = nsc_gpio_read, 67 .read = nsc_gpio_read,
@@ -71,21 +69,20 @@ static const struct file_operations scx200_gpio_fops = {
71 .release = scx200_gpio_release, 69 .release = scx200_gpio_release,
72}; 70};
73 71
74struct cdev *scx200_devices; 72struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */
75static int num_pins = 32;
76 73
77static int __init scx200_gpio_init(void) 74static int __init scx200_gpio_init(void)
78{ 75{
79 int rc, i; 76 int rc;
80 dev_t dev = MKDEV(major, 0); 77 dev_t devid;
81 78
82 if (!scx200_gpio_present()) { 79 if (!scx200_gpio_present()) {
83 printk(KERN_ERR NAME ": no SCx200 gpio present\n"); 80 printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n");
84 return -ENODEV; 81 return -ENODEV;
85 } 82 }
86 83
87 /* support dev_dbg() with pdev->dev */ 84 /* support dev_dbg() with pdev->dev */
88 pdev = platform_device_alloc(DEVNAME, 0); 85 pdev = platform_device_alloc(DRVNAME, 0);
89 if (!pdev) 86 if (!pdev)
90 return -ENOMEM; 87 return -ENOMEM;
91 88
@@ -94,37 +91,25 @@ static int __init scx200_gpio_init(void)
94 goto undo_malloc; 91 goto undo_malloc;
95 92
96 /* nsc_gpio uses dev_dbg(), so needs this */ 93 /* nsc_gpio uses dev_dbg(), so needs this */
97 scx200_access.dev = &pdev->dev; 94 scx200_gpio_ops.dev = &pdev->dev;
98 95
99 if (major) 96 if (major) {
100 rc = register_chrdev_region(dev, num_pins, "scx200_gpio"); 97 devid = MKDEV(major, 0);
101 else { 98 rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio");
102 rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio"); 99 } else {
103 major = MAJOR(dev); 100 rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio");
101 major = MAJOR(devid);
104 } 102 }
105 if (rc < 0) { 103 if (rc < 0) {
106 dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); 104 dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc);
107 goto undo_platform_device_add; 105 goto undo_platform_device_add;
108 } 106 }
109 scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL); 107
110 if (!scx200_devices) { 108 cdev_init(&scx200_gpio_cdev, &scx200_gpio_fileops);
111 rc = -ENOMEM; 109 cdev_add(&scx200_gpio_cdev, devid, MAX_PINS);
112 goto undo_chrdev_region;
113 }
114 for (i = 0; i < num_pins; i++) {
115 struct cdev *cdev = &scx200_devices[i];
116 cdev_init(cdev, &scx200_gpio_fops);
117 cdev->owner = THIS_MODULE;
118 rc = cdev_add(cdev, MKDEV(major, i), 1);
119 /* tolerate 'minor' errors */
120 if (rc)
121 dev_err(&pdev->dev, "Error %d on minor %d", rc, i);
122 }
123 110
124 return 0; /* succeed */ 111 return 0; /* succeed */
125 112
126undo_chrdev_region:
127 unregister_chrdev_region(dev, num_pins);
128undo_platform_device_add: 113undo_platform_device_add:
129 platform_device_del(pdev); 114 platform_device_del(pdev);
130undo_malloc: 115undo_malloc:
@@ -135,10 +120,11 @@ undo_malloc:
135 120
136static void __exit scx200_gpio_cleanup(void) 121static void __exit scx200_gpio_cleanup(void)
137{ 122{
138 kfree(scx200_devices); 123 cdev_del(&scx200_gpio_cdev);
139 unregister_chrdev_region(MKDEV(major, 0), num_pins); 124 /* cdev_put(&scx200_gpio_cdev); */
125
126 unregister_chrdev_region(MKDEV(major, 0), MAX_PINS);
140 platform_device_unregister(pdev); 127 platform_device_unregister(pdev);
141 /* kfree(pdev); */
142} 128}
143 129
144module_init(scx200_gpio_init); 130module_init(scx200_gpio_init);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 6889e7db3aff..a082a2e34252 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1141,6 +1141,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1141 put_device(dev); 1141 put_device(dev);
1142 clear_bit(chip->dev_num, dev_mask); 1142 clear_bit(chip->dev_num, dev_mask);
1143 kfree(chip); 1143 kfree(chip);
1144 kfree(devname);
1144 return NULL; 1145 return NULL;
1145 } 1146 }
1146 1147
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 3232b1932597..ee7ac6f43c65 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -424,6 +424,7 @@ static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
424 iowrite32(interrupt, 424 iowrite32(interrupt,
425 chip->vendor.iobase + 425 chip->vendor.iobase +
426 TPM_INT_STATUS(chip->vendor.locality)); 426 TPM_INT_STATUS(chip->vendor.locality));
427 ioread32(chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality));
427 return IRQ_HANDLED; 428 return IRQ_HANDLED;
428} 429}
429 430
@@ -431,23 +432,19 @@ static int interrupts = 1;
431module_param(interrupts, bool, 0444); 432module_param(interrupts, bool, 0444);
432MODULE_PARM_DESC(interrupts, "Enable interrupts"); 433MODULE_PARM_DESC(interrupts, "Enable interrupts");
433 434
434static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, 435static int tpm_tis_init(struct device *dev, resource_size_t start,
435 const struct pnp_device_id *pnp_id) 436 resource_size_t len)
436{ 437{
437 u32 vendor, intfcaps, intmask; 438 u32 vendor, intfcaps, intmask;
438 int rc, i; 439 int rc, i;
439 unsigned long start, len;
440 struct tpm_chip *chip; 440 struct tpm_chip *chip;
441 441
442 start = pnp_mem_start(pnp_dev, 0);
443 len = pnp_mem_len(pnp_dev, 0);
444
445 if (!start) 442 if (!start)
446 start = TIS_MEM_BASE; 443 start = TIS_MEM_BASE;
447 if (!len) 444 if (!len)
448 len = TIS_MEM_LEN; 445 len = TIS_MEM_LEN;
449 446
450 if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis))) 447 if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
451 return -ENODEV; 448 return -ENODEV;
452 449
453 chip->vendor.iobase = ioremap(start, len); 450 chip->vendor.iobase = ioremap(start, len);
@@ -464,7 +461,7 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
464 chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 461 chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
465 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 462 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
466 463
467 dev_info(&pnp_dev->dev, 464 dev_info(dev,
468 "1.2 TPM (device-id 0x%X, rev-id %d)\n", 465 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
469 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); 466 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
470 467
@@ -472,26 +469,26 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
472 intfcaps = 469 intfcaps =
473 ioread32(chip->vendor.iobase + 470 ioread32(chip->vendor.iobase +
474 TPM_INTF_CAPS(chip->vendor.locality)); 471 TPM_INTF_CAPS(chip->vendor.locality));
475 dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n", 472 dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
476 intfcaps); 473 intfcaps);
477 if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) 474 if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
478 dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n"); 475 dev_dbg(dev, "\tBurst Count Static\n");
479 if (intfcaps & TPM_INTF_CMD_READY_INT) 476 if (intfcaps & TPM_INTF_CMD_READY_INT)
480 dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n"); 477 dev_dbg(dev, "\tCommand Ready Int Support\n");
481 if (intfcaps & TPM_INTF_INT_EDGE_FALLING) 478 if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
482 dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n"); 479 dev_dbg(dev, "\tInterrupt Edge Falling\n");
483 if (intfcaps & TPM_INTF_INT_EDGE_RISING) 480 if (intfcaps & TPM_INTF_INT_EDGE_RISING)
484 dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n"); 481 dev_dbg(dev, "\tInterrupt Edge Rising\n");
485 if (intfcaps & TPM_INTF_INT_LEVEL_LOW) 482 if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
486 dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n"); 483 dev_dbg(dev, "\tInterrupt Level Low\n");
487 if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) 484 if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
488 dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n"); 485 dev_dbg(dev, "\tInterrupt Level High\n");
489 if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) 486 if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
490 dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n"); 487 dev_dbg(dev, "\tLocality Change Int Support\n");
491 if (intfcaps & TPM_INTF_STS_VALID_INT) 488 if (intfcaps & TPM_INTF_STS_VALID_INT)
492 dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n"); 489 dev_dbg(dev, "\tSts Valid Int Support\n");
493 if (intfcaps & TPM_INTF_DATA_AVAIL_INT) 490 if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
494 dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n"); 491 dev_dbg(dev, "\tData Avail Int Support\n");
495 492
496 if (request_locality(chip, 0) != 0) { 493 if (request_locality(chip, 0) != 0) {
497 rc = -ENODEV; 494 rc = -ENODEV;
@@ -594,6 +591,16 @@ out_err:
594 return rc; 591 return rc;
595} 592}
596 593
594static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
595 const struct pnp_device_id *pnp_id)
596{
597 resource_size_t start, len;
598 start = pnp_mem_start(pnp_dev, 0);
599 len = pnp_mem_len(pnp_dev, 0);
600
601 return tpm_tis_init(&pnp_dev->dev, start, len);
602}
603
597static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) 604static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
598{ 605{
599 return tpm_pm_suspend(&dev->dev, msg); 606 return tpm_pm_suspend(&dev->dev, msg);
@@ -628,8 +635,36 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
628 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); 635 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
629MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 636MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
630 637
638static struct device_driver tis_drv = {
639 .name = "tpm_tis",
640 .bus = &platform_bus_type,
641 .owner = THIS_MODULE,
642 .suspend = tpm_pm_suspend,
643 .resume = tpm_pm_resume,
644};
645
646static struct platform_device *pdev;
647
648static int force;
649module_param(force, bool, 0444);
650MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
631static int __init init_tis(void) 651static int __init init_tis(void)
632{ 652{
653 int rc;
654
655 if (force) {
656 rc = driver_register(&tis_drv);
657 if (rc < 0)
658 return rc;
659 if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
660 return PTR_ERR(pdev);
661 if((rc=tpm_tis_init(&pdev->dev, 0, 0)) != 0) {
662 platform_device_unregister(pdev);
663 driver_unregister(&tis_drv);
664 }
665 return rc;
666 }
667
633 return pnp_register_driver(&tis_pnp_driver); 668 return pnp_register_driver(&tis_pnp_driver);
634} 669}
635 670
@@ -654,7 +689,11 @@ static void __exit cleanup_tis(void)
654 tpm_remove_hardware(chip->dev); 689 tpm_remove_hardware(chip->dev);
655 } 690 }
656 spin_unlock(&tis_lock); 691 spin_unlock(&tis_lock);
657 pnp_unregister_driver(&tis_pnp_driver); 692 if (force) {
693 platform_device_unregister(pdev);
694 driver_unregister(&tis_drv);
695 } else
696 pnp_unregister_driver(&tis_pnp_driver);
658} 697}
659 698
660module_init(init_tis); 699module_init(init_tis);
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 3f6705f3083a..f85c97f7500a 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -701,7 +701,7 @@ static void cm_reset_to_idle(struct cm_id_private *cm_id_priv)
701 } 701 }
702} 702}
703 703
704void ib_destroy_cm_id(struct ib_cm_id *cm_id) 704static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
705{ 705{
706 struct cm_id_private *cm_id_priv; 706 struct cm_id_private *cm_id_priv;
707 struct cm_work *work; 707 struct cm_work *work;
@@ -735,12 +735,22 @@ retest:
735 sizeof cm_id_priv->av.port->cm_dev->ca_guid, 735 sizeof cm_id_priv->av.port->cm_dev->ca_guid,
736 NULL, 0); 736 NULL, 0);
737 break; 737 break;
738 case IB_CM_REQ_RCVD:
739 if (err == -ENOMEM) {
740 /* Do not reject to allow future retries. */
741 cm_reset_to_idle(cm_id_priv);
742 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
743 } else {
744 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
745 ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED,
746 NULL, 0, NULL, 0);
747 }
748 break;
738 case IB_CM_MRA_REQ_RCVD: 749 case IB_CM_MRA_REQ_RCVD:
739 case IB_CM_REP_SENT: 750 case IB_CM_REP_SENT:
740 case IB_CM_MRA_REP_RCVD: 751 case IB_CM_MRA_REP_RCVD:
741 ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); 752 ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
742 /* Fall through */ 753 /* Fall through */
743 case IB_CM_REQ_RCVD:
744 case IB_CM_MRA_REQ_SENT: 754 case IB_CM_MRA_REQ_SENT:
745 case IB_CM_REP_RCVD: 755 case IB_CM_REP_RCVD:
746 case IB_CM_MRA_REP_SENT: 756 case IB_CM_MRA_REP_SENT:
@@ -775,6 +785,11 @@ retest:
775 kfree(cm_id_priv->private_data); 785 kfree(cm_id_priv->private_data);
776 kfree(cm_id_priv); 786 kfree(cm_id_priv);
777} 787}
788
789void ib_destroy_cm_id(struct ib_cm_id *cm_id)
790{
791 cm_destroy_id(cm_id, 0);
792}
778EXPORT_SYMBOL(ib_destroy_cm_id); 793EXPORT_SYMBOL(ib_destroy_cm_id);
779 794
780int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask, 795int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
@@ -1163,7 +1178,7 @@ static void cm_process_work(struct cm_id_private *cm_id_priv,
1163 } 1178 }
1164 cm_deref_id(cm_id_priv); 1179 cm_deref_id(cm_id_priv);
1165 if (ret) 1180 if (ret)
1166 ib_destroy_cm_id(&cm_id_priv->id); 1181 cm_destroy_id(&cm_id_priv->id, ret);
1167} 1182}
1168 1183
1169static void cm_format_mra(struct cm_mra_msg *mra_msg, 1184static void cm_format_mra(struct cm_mra_msg *mra_msg,
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 863f64befc7c..d6f99d5720fc 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -262,14 +262,14 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv)
262static int cma_acquire_ib_dev(struct rdma_id_private *id_priv) 262static int cma_acquire_ib_dev(struct rdma_id_private *id_priv)
263{ 263{
264 struct cma_device *cma_dev; 264 struct cma_device *cma_dev;
265 union ib_gid *gid; 265 union ib_gid gid;
266 int ret = -ENODEV; 266 int ret = -ENODEV;
267 267
268 gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr); 268 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid),
269 269
270 mutex_lock(&lock); 270 mutex_lock(&lock);
271 list_for_each_entry(cma_dev, &dev_list, list) { 271 list_for_each_entry(cma_dev, &dev_list, list) {
272 ret = ib_find_cached_gid(cma_dev->device, gid, 272 ret = ib_find_cached_gid(cma_dev->device, &gid,
273 &id_priv->id.port_num, NULL); 273 &id_priv->id.port_num, NULL);
274 if (!ret) { 274 if (!ret) {
275 cma_attach_to_dev(id_priv, cma_dev); 275 cma_attach_to_dev(id_priv, cma_dev);
@@ -812,6 +812,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
812 cma_modify_qp_err(&id_priv->id); 812 cma_modify_qp_err(&id_priv->id);
813 status = ib_event->param.rej_rcvd.reason; 813 status = ib_event->param.rej_rcvd.reason;
814 event = RDMA_CM_EVENT_REJECTED; 814 event = RDMA_CM_EVENT_REJECTED;
815 private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE;
815 break; 816 break;
816 default: 817 default:
817 printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", 818 printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d",
@@ -1134,8 +1135,8 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
1134 struct ib_sa_path_rec path_rec; 1135 struct ib_sa_path_rec path_rec;
1135 1136
1136 memset(&path_rec, 0, sizeof path_rec); 1137 memset(&path_rec, 0, sizeof path_rec);
1137 path_rec.sgid = *ib_addr_get_sgid(addr); 1138 ib_addr_get_sgid(addr, &path_rec.sgid);
1138 path_rec.dgid = *ib_addr_get_dgid(addr); 1139 ib_addr_get_dgid(addr, &path_rec.dgid);
1139 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr)); 1140 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr));
1140 path_rec.numb_path = 1; 1141 path_rec.numb_path = 1;
1141 1142
@@ -1263,7 +1264,7 @@ static int cma_bind_loopback(struct rdma_id_private *id_priv)
1263{ 1264{
1264 struct cma_device *cma_dev; 1265 struct cma_device *cma_dev;
1265 struct ib_port_attr port_attr; 1266 struct ib_port_attr port_attr;
1266 union ib_gid *gid; 1267 union ib_gid gid;
1267 u16 pkey; 1268 u16 pkey;
1268 int ret; 1269 int ret;
1269 u8 p; 1270 u8 p;
@@ -1284,8 +1285,7 @@ static int cma_bind_loopback(struct rdma_id_private *id_priv)
1284 } 1285 }
1285 1286
1286port_found: 1287port_found:
1287 gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr); 1288 ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
1288 ret = ib_get_cached_gid(cma_dev->device, p, 0, gid);
1289 if (ret) 1289 if (ret)
1290 goto out; 1290 goto out;
1291 1291
@@ -1293,6 +1293,7 @@ port_found:
1293 if (ret) 1293 if (ret)
1294 goto out; 1294 goto out;
1295 1295
1296 ib_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
1296 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); 1297 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
1297 id_priv->id.port_num = p; 1298 id_priv->id.port_num = p;
1298 cma_attach_to_dev(id_priv, cma_dev); 1299 cma_attach_to_dev(id_priv, cma_dev);
@@ -1339,6 +1340,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
1339{ 1340{
1340 struct cma_work *work; 1341 struct cma_work *work;
1341 struct sockaddr_in *src_in, *dst_in; 1342 struct sockaddr_in *src_in, *dst_in;
1343 union ib_gid gid;
1342 int ret; 1344 int ret;
1343 1345
1344 work = kzalloc(sizeof *work, GFP_KERNEL); 1346 work = kzalloc(sizeof *work, GFP_KERNEL);
@@ -1351,8 +1353,8 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
1351 goto err; 1353 goto err;
1352 } 1354 }
1353 1355
1354 ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, 1356 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
1355 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr)); 1357 ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
1356 1358
1357 if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) { 1359 if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) {
1358 src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; 1360 src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr;
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 615fe9cc6c56..86a3b2d401db 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -426,7 +426,7 @@ EXPORT_SYMBOL(ib_flush_fmr_pool);
426struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle, 426struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
427 u64 *page_list, 427 u64 *page_list,
428 int list_len, 428 int list_len,
429 u64 *io_virtual_address) 429 u64 io_virtual_address)
430{ 430{
431 struct ib_fmr_pool *pool = pool_handle; 431 struct ib_fmr_pool *pool = pool_handle;
432 struct ib_pool_fmr *fmr; 432 struct ib_pool_fmr *fmr;
@@ -440,7 +440,7 @@ struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
440 fmr = ib_fmr_cache_lookup(pool, 440 fmr = ib_fmr_cache_lookup(pool,
441 page_list, 441 page_list,
442 list_len, 442 list_len,
443 *io_virtual_address); 443 io_virtual_address);
444 if (fmr) { 444 if (fmr) {
445 /* found in cache */ 445 /* found in cache */
446 ++fmr->ref_count; 446 ++fmr->ref_count;
@@ -464,7 +464,7 @@ struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
464 spin_unlock_irqrestore(&pool->pool_lock, flags); 464 spin_unlock_irqrestore(&pool->pool_lock, flags);
465 465
466 result = ib_map_phys_fmr(fmr->fmr, page_list, list_len, 466 result = ib_map_phys_fmr(fmr->fmr, page_list, list_len,
467 *io_virtual_address); 467 io_virtual_address);
468 468
469 if (result) { 469 if (result) {
470 spin_lock_irqsave(&pool->pool_lock, flags); 470 spin_lock_irqsave(&pool->pool_lock, flags);
@@ -481,7 +481,7 @@ struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
481 fmr->ref_count = 1; 481 fmr->ref_count = 1;
482 482
483 if (pool->cache_bucket) { 483 if (pool->cache_bucket) {
484 fmr->io_virtual_address = *io_virtual_address; 484 fmr->io_virtual_address = io_virtual_address;
485 fmr->page_list_len = list_len; 485 fmr->page_list_len = list_len;
486 memcpy(fmr->page_list, page_list, list_len * sizeof(*page_list)); 486 memcpy(fmr->page_list, page_list, list_len * sizeof(*page_list));
487 487
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index e911c99ff843..aeda484ffd82 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -488,13 +488,13 @@ static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
488 spin_unlock_irqrestore(&tid_lock, flags); 488 spin_unlock_irqrestore(&tid_lock, flags);
489} 489}
490 490
491static int send_mad(struct ib_sa_query *query, int timeout_ms) 491static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
492{ 492{
493 unsigned long flags; 493 unsigned long flags;
494 int ret, id; 494 int ret, id;
495 495
496retry: 496retry:
497 if (!idr_pre_get(&query_idr, GFP_ATOMIC)) 497 if (!idr_pre_get(&query_idr, gfp_mask))
498 return -ENOMEM; 498 return -ENOMEM;
499 spin_lock_irqsave(&idr_lock, flags); 499 spin_lock_irqsave(&idr_lock, flags);
500 ret = idr_get_new(&query_idr, query, &id); 500 ret = idr_get_new(&query_idr, query, &id);
@@ -630,7 +630,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
630 630
631 *sa_query = &query->sa_query; 631 *sa_query = &query->sa_query;
632 632
633 ret = send_mad(&query->sa_query, timeout_ms); 633 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
634 if (ret < 0) 634 if (ret < 0)
635 goto err2; 635 goto err2;
636 636
@@ -752,7 +752,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
752 752
753 *sa_query = &query->sa_query; 753 *sa_query = &query->sa_query;
754 754
755 ret = send_mad(&query->sa_query, timeout_ms); 755 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
756 if (ret < 0) 756 if (ret < 0)
757 goto err2; 757 goto err2;
758 758
@@ -844,7 +844,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
844 844
845 *sa_query = &query->sa_query; 845 *sa_query = &query->sa_query;
846 846
847 ret = send_mad(&query->sa_query, timeout_ms); 847 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
848 if (ret < 0) 848 if (ret < 0)
849 goto err2; 849 goto err2;
850 850
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index b12aa03be251..e215041b2db9 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -303,9 +303,10 @@ int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr)
303 memset(attr, 0, sizeof *attr); 303 memset(attr, 0, sizeof *attr);
304 attr->dlid = be16_to_cpu(ah->av->dlid); 304 attr->dlid = be16_to_cpu(ah->av->dlid);
305 attr->sl = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; 305 attr->sl = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28;
306 attr->static_rate = ah->av->msg_sr & 0x7;
307 attr->src_path_bits = ah->av->g_slid & 0x7F;
308 attr->port_num = be32_to_cpu(ah->av->port_pd) >> 24; 306 attr->port_num = be32_to_cpu(ah->av->port_pd) >> 24;
307 attr->static_rate = mthca_rate_to_ib(dev, ah->av->msg_sr & 0x7,
308 attr->port_num);
309 attr->src_path_bits = ah->av->g_slid & 0x7F;
309 attr->ah_flags = mthca_ah_grh_present(ah) ? IB_AH_GRH : 0; 310 attr->ah_flags = mthca_ah_grh_present(ah) ? IB_AH_GRH : 0;
310 311
311 if (attr->ah_flags) { 312 if (attr->ah_flags) {
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 490fc783bb0c..cd8b6721ac9c 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -222,9 +222,8 @@ static void *get_send_wqe(struct mthca_qp *qp, int n)
222 (PAGE_SIZE - 1)); 222 (PAGE_SIZE - 1));
223} 223}
224 224
225static void mthca_wq_init(struct mthca_wq *wq) 225static void mthca_wq_reset(struct mthca_wq *wq)
226{ 226{
227 /* mthca_alloc_qp_common() initializes the locks */
228 wq->next_ind = 0; 227 wq->next_ind = 0;
229 wq->last_comp = wq->max - 1; 228 wq->last_comp = wq->max - 1;
230 wq->head = 0; 229 wq->head = 0;
@@ -845,10 +844,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
845 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, 844 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn,
846 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); 845 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
847 846
848 mthca_wq_init(&qp->sq); 847 mthca_wq_reset(&qp->sq);
849 qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); 848 qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
850 849
851 mthca_wq_init(&qp->rq); 850 mthca_wq_reset(&qp->rq);
852 qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1); 851 qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1);
853 852
854 if (mthca_is_memfree(dev)) { 853 if (mthca_is_memfree(dev)) {
@@ -1112,9 +1111,9 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1112 qp->atomic_rd_en = 0; 1111 qp->atomic_rd_en = 0;
1113 qp->resp_depth = 0; 1112 qp->resp_depth = 0;
1114 qp->sq_policy = send_policy; 1113 qp->sq_policy = send_policy;
1115 mthca_wq_init(&qp->sq); 1114 mthca_wq_reset(&qp->sq);
1116 mthca_wq_init(&qp->rq); 1115 mthca_wq_reset(&qp->rq);
1117 /* these are initialized separately so lockdep can tell them apart */ 1116
1118 spin_lock_init(&qp->sq.lock); 1117 spin_lock_init(&qp->sq.lock);
1119 spin_lock_init(&qp->rq.lock); 1118 spin_lock_init(&qp->rq.lock);
1120 1119
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index ff117bbf81b4..72febf1f8ff8 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -594,7 +594,7 @@ int iser_reg_page_vec(struct iser_conn *ib_conn,
594 mem = ib_fmr_pool_map_phys(ib_conn->fmr_pool, 594 mem = ib_fmr_pool_map_phys(ib_conn->fmr_pool,
595 page_list, 595 page_list,
596 page_vec->length, 596 page_vec->length,
597 &io_addr); 597 io_addr);
598 598
599 if (IS_ERR(mem)) { 599 if (IS_ERR(mem)) {
600 status = (int)PTR_ERR(mem); 600 status = (int)PTR_ERR(mem);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 4e22afef7206..8f472e7113b4 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -615,9 +615,10 @@ static int srp_map_fmr(struct srp_device *dev, struct scatterlist *scat,
615 (sg_dma_address(&scat[i]) & dev->fmr_page_mask) + j; 615 (sg_dma_address(&scat[i]) & dev->fmr_page_mask) + j;
616 616
617 req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool, 617 req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool,
618 dma_pages, page_cnt, &io_addr); 618 dma_pages, page_cnt, io_addr);
619 if (IS_ERR(req->fmr)) { 619 if (IS_ERR(req->fmr)) {
620 ret = PTR_ERR(req->fmr); 620 ret = PTR_ERR(req->fmr);
621 req->fmr = NULL;
621 goto out; 622 goto out;
622 } 623 }
623 624
diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c
index 35ee52f9b79e..713c4a8aa77d 100644
--- a/drivers/leds/leds-net48xx.c
+++ b/drivers/leds/leds-net48xx.c
@@ -18,6 +18,7 @@
18#include <asm/io.h> 18#include <asm/io.h>
19#include <linux/scx200_gpio.h> 19#include <linux/scx200_gpio.h>
20 20
21#define DRVNAME "net48xx-led"
21#define NET48XX_ERROR_LED_GPIO 20 22#define NET48XX_ERROR_LED_GPIO 20
22 23
23static struct platform_device *pdev; 24static struct platform_device *pdev;
@@ -66,13 +67,13 @@ static int net48xx_led_remove(struct platform_device *pdev)
66} 67}
67 68
68static struct platform_driver net48xx_led_driver = { 69static struct platform_driver net48xx_led_driver = {
69 .driver.owner = THIS_MODULE,
70 .probe = net48xx_led_probe, 70 .probe = net48xx_led_probe,
71 .remove = net48xx_led_remove, 71 .remove = net48xx_led_remove,
72 .suspend = net48xx_led_suspend, 72 .suspend = net48xx_led_suspend,
73 .resume = net48xx_led_resume, 73 .resume = net48xx_led_resume,
74 .driver = { 74 .driver = {
75 .name = "net48xx-led", 75 .name = DRVNAME,
76 .owner = THIS_MODULE,
76 }, 77 },
77}; 78};
78 79
@@ -89,7 +90,7 @@ static int __init net48xx_led_init(void)
89 if (ret < 0) 90 if (ret < 0)
90 goto out; 91 goto out;
91 92
92 pdev = platform_device_register_simple("net48xx-led", -1, NULL, 0); 93 pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
93 if (IS_ERR(pdev)) { 94 if (IS_ERR(pdev)) {
94 ret = PTR_ERR(pdev); 95 ret = PTR_ERR(pdev);
95 platform_driver_unregister(&net48xx_led_driver); 96 platform_driver_unregister(&net48xx_led_driver);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f5b9f187a930..7ff1d88094b6 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -121,6 +121,16 @@ config RTC_DRV_DS1553
121 This driver can also be built as a module. If so, the module 121 This driver can also be built as a module. If so, the module
122 will be called rtc-ds1553. 122 will be called rtc-ds1553.
123 123
124config RTC_DRV_ISL1208
125 tristate "Intersil 1208"
126 depends on RTC_CLASS && I2C
127 help
128 If you say yes here you get support for the
129 Intersil 1208 RTC chip.
130
131 This driver can also be built as a module. If so, the module
132 will be called rtc-isl1208.
133
124config RTC_DRV_DS1672 134config RTC_DRV_DS1672
125 tristate "Dallas/Maxim DS1672" 135 tristate "Dallas/Maxim DS1672"
126 depends on RTC_CLASS && I2C 136 depends on RTC_CLASS && I2C
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 54220714ff49..bbcfb09d81d9 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
12obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o 12obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
13 13
14obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o 14obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
15obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
15obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o 16obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
16obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o 17obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
17obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o 18obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
new file mode 100644
index 000000000000..f324d0a635d4
--- /dev/null
+++ b/drivers/rtc/rtc-isl1208.c
@@ -0,0 +1,591 @@
1/*
2 * Intersil ISL1208 rtc class driver
3 *
4 * Copyright 2005,2006 Hebert Valerio Riedel <hvr@gnu.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/i2c.h>
15#include <linux/bcd.h>
16#include <linux/rtc.h>
17
18#define DRV_NAME "isl1208"
19#define DRV_VERSION "0.2"
20
21/* Register map */
22/* rtc section */
23#define ISL1208_REG_SC 0x00
24#define ISL1208_REG_MN 0x01
25#define ISL1208_REG_HR 0x02
26#define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */
27#define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */
28#define ISL1208_REG_DT 0x03
29#define ISL1208_REG_MO 0x04
30#define ISL1208_REG_YR 0x05
31#define ISL1208_REG_DW 0x06
32#define ISL1208_RTC_SECTION_LEN 7
33
34/* control/status section */
35#define ISL1208_REG_SR 0x07
36#define ISL1208_REG_SR_ARST (1<<7) /* auto reset */
37#define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */
38#define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */
39#define ISL1208_REG_SR_ALM (1<<2) /* alarm */
40#define ISL1208_REG_SR_BAT (1<<1) /* battery */
41#define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */
42#define ISL1208_REG_INT 0x08
43#define ISL1208_REG_09 0x09 /* reserved */
44#define ISL1208_REG_ATR 0x0a
45#define ISL1208_REG_DTR 0x0b
46
47/* alarm section */
48#define ISL1208_REG_SCA 0x0c
49#define ISL1208_REG_MNA 0x0d
50#define ISL1208_REG_HRA 0x0e
51#define ISL1208_REG_DTA 0x0f
52#define ISL1208_REG_MOA 0x10
53#define ISL1208_REG_DWA 0x11
54#define ISL1208_ALARM_SECTION_LEN 6
55
56/* user section */
57#define ISL1208_REG_USR1 0x12
58#define ISL1208_REG_USR2 0x13
59#define ISL1208_USR_SECTION_LEN 2
60
61/* i2c configuration */
62#define ISL1208_I2C_ADDR 0xde
63
64static unsigned short normal_i2c[] = {
65 ISL1208_I2C_ADDR>>1, I2C_CLIENT_END
66};
67I2C_CLIENT_INSMOD; /* defines addr_data */
68
69static int isl1208_attach_adapter(struct i2c_adapter *adapter);
70static int isl1208_detach_client(struct i2c_client *client);
71
72static struct i2c_driver isl1208_driver = {
73 .driver = {
74 .name = DRV_NAME,
75 },
76 .id = I2C_DRIVERID_ISL1208,
77 .attach_adapter = &isl1208_attach_adapter,
78 .detach_client = &isl1208_detach_client,
79};
80
81/* block read */
82static int
83isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
84 unsigned len)
85{
86 u8 reg_addr[1] = { reg };
87 struct i2c_msg msgs[2] = {
88 { client->addr, client->flags, sizeof(reg_addr), reg_addr },
89 { client->addr, client->flags | I2C_M_RD, len, buf }
90 };
91 int ret;
92
93 BUG_ON(len == 0);
94 BUG_ON(reg > ISL1208_REG_USR2);
95 BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
96
97 ret = i2c_transfer(client->adapter, msgs, 2);
98 if (ret > 0)
99 ret = 0;
100 return ret;
101}
102
103/* block write */
104static int
105isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
106 unsigned len)
107{
108 u8 i2c_buf[ISL1208_REG_USR2 + 2];
109 struct i2c_msg msgs[1] = {
110 { client->addr, client->flags, len + 1, i2c_buf }
111 };
112 int ret;
113
114 BUG_ON(len == 0);
115 BUG_ON(reg > ISL1208_REG_USR2);
116 BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
117
118 i2c_buf[0] = reg;
119 memcpy(&i2c_buf[1], &buf[0], len);
120
121 ret = i2c_transfer(client->adapter, msgs, 1);
122 if (ret > 0)
123 ret = 0;
124 return ret;
125}
126
127/* simple check to see wether we have a isl1208 */
128static int isl1208_i2c_validate_client(struct i2c_client *client)
129{
130 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
131 u8 zero_mask[ISL1208_RTC_SECTION_LEN] = {
132 0x80, 0x80, 0x40, 0xc0, 0xe0, 0x00, 0xf8
133 };
134 int i;
135 int ret;
136
137 ret = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
138 if (ret < 0)
139 return ret;
140
141 for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) {
142 if (regs[i] & zero_mask[i]) /* check if bits are cleared */
143 return -ENODEV;
144 }
145
146 return 0;
147}
148
149static int isl1208_i2c_get_sr(struct i2c_client *client)
150{
151 return i2c_smbus_read_byte_data(client, ISL1208_REG_SR) == -1 ? -EIO:0;
152}
153
154static int isl1208_i2c_get_atr(struct i2c_client *client)
155{
156 int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR);
157
158 if (atr < 0)
159 return -EIO;
160
161 /* The 6bit value in the ATR register controls the load
162 * capacitance C_load * in steps of 0.25pF
163 *
164 * bit (1<<5) of the ATR register is inverted
165 *
166 * C_load(ATR=0x20) = 4.50pF
167 * C_load(ATR=0x00) = 12.50pF
168 * C_load(ATR=0x1f) = 20.25pF
169 *
170 */
171
172 atr &= 0x3f; /* mask out lsb */
173 atr ^= 1<<5; /* invert 6th bit */
174 atr += 2*9; /* add offset of 4.5pF; unit[atr] = 0.25pF */
175
176 return atr;
177}
178
179static int isl1208_i2c_get_dtr(struct i2c_client *client)
180{
181 int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR);
182
183 if (dtr < 0)
184 return -EIO;
185
186 /* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */
187 dtr = ((dtr & 0x3) * 20) * (dtr & (1<<2) ? -1 : 1);
188
189 return dtr;
190}
191
192static int isl1208_i2c_get_usr(struct i2c_client *client)
193{
194 u8 buf[ISL1208_USR_SECTION_LEN] = { 0, };
195 int ret;
196
197 ret = isl1208_i2c_read_regs (client, ISL1208_REG_USR1, buf,
198 ISL1208_USR_SECTION_LEN);
199 if (ret < 0)
200 return ret;
201
202 return (buf[1] << 8) | buf[0];
203}
204
205static int isl1208_i2c_set_usr(struct i2c_client *client, u16 usr)
206{
207 u8 buf[ISL1208_USR_SECTION_LEN];
208
209 buf[0] = usr & 0xff;
210 buf[1] = (usr >> 8) & 0xff;
211
212 return isl1208_i2c_set_regs (client, ISL1208_REG_USR1, buf,
213 ISL1208_USR_SECTION_LEN);
214}
215
216static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
217{
218 struct i2c_client *const client = to_i2c_client(dev);
219 int sr, dtr, atr, usr;
220
221 sr = isl1208_i2c_get_sr(client);
222 if (sr < 0) {
223 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
224 return sr;
225 }
226
227 seq_printf(seq, "status_reg\t:%s%s%s%s%s%s (0x%.2x)\n",
228 (sr & ISL1208_REG_SR_RTCF) ? " RTCF" : "",
229 (sr & ISL1208_REG_SR_BAT) ? " BAT" : "",
230 (sr & ISL1208_REG_SR_ALM) ? " ALM" : "",
231 (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "",
232 (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "",
233 (sr & ISL1208_REG_SR_ARST) ? " ARST" : "",
234 sr);
235
236 seq_printf(seq, "batt_status\t: %s\n",
237 (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay");
238
239 dtr = isl1208_i2c_get_dtr(client);
240 if (dtr >= 0 -1)
241 seq_printf(seq, "digital_trim\t: %d ppm\n", dtr);
242
243 atr = isl1208_i2c_get_atr(client);
244 if (atr >= 0)
245 seq_printf(seq, "analog_trim\t: %d.%.2d pF\n",
246 atr>>2, (atr&0x3)*25);
247
248 usr = isl1208_i2c_get_usr(client);
249 if (usr >= 0)
250 seq_printf(seq, "user_data\t: 0x%.4x\n", usr);
251
252 return 0;
253}
254
255
256static int isl1208_i2c_read_time(struct i2c_client *client,
257 struct rtc_time *tm)
258{
259 int sr;
260 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
261
262 sr = isl1208_i2c_get_sr(client);
263 if (sr < 0) {
264 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
265 return -EIO;
266 }
267
268 sr = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
269 if (sr < 0) {
270 dev_err(&client->dev, "%s: reading RTC section failed\n",
271 __func__);
272 return sr;
273 }
274
275 tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]);
276 tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]);
277 { /* HR field has a more complex interpretation */
278 const u8 _hr = regs[ISL1208_REG_HR];
279 if (_hr & ISL1208_REG_HR_MIL) /* 24h format */
280 tm->tm_hour = BCD2BIN(_hr & 0x3f);
281 else { // 12h format
282 tm->tm_hour = BCD2BIN(_hr & 0x1f);
283 if (_hr & ISL1208_REG_HR_PM) /* PM flag set */
284 tm->tm_hour += 12;
285 }
286 }
287
288 tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]);
289 tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
290 tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100;
291 tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]);
292
293 return 0;
294}
295
296static int isl1208_i2c_read_alarm(struct i2c_client *client,
297 struct rtc_wkalrm *alarm)
298{
299 struct rtc_time *const tm = &alarm->time;
300 u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, };
301 int sr;
302
303 sr = isl1208_i2c_get_sr(client);
304 if (sr < 0) {
305 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
306 return sr;
307 }
308
309 sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs,
310 ISL1208_ALARM_SECTION_LEN);
311 if (sr < 0) {
312 dev_err(&client->dev, "%s: reading alarm section failed\n",
313 __func__);
314 return sr;
315 }
316
317 /* MSB of each alarm register is an enable bit */
318 tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA-ISL1208_REG_SCA] & 0x7f);
319 tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA-ISL1208_REG_SCA] & 0x7f);
320 tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA-ISL1208_REG_SCA] & 0x3f);
321 tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA-ISL1208_REG_SCA] & 0x3f);
322 tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MOA-ISL1208_REG_SCA] & 0x1f)-1;
323 tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA-ISL1208_REG_SCA] & 0x03);
324
325 return 0;
326}
327
328static int isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm)
329{
330 return isl1208_i2c_read_time(to_i2c_client(dev), tm);
331}
332
333static int isl1208_i2c_set_time(struct i2c_client *client,
334 struct rtc_time const *tm)
335{
336 int sr;
337 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
338
339 regs[ISL1208_REG_SC] = BIN2BCD(tm->tm_sec);
340 regs[ISL1208_REG_MN] = BIN2BCD(tm->tm_min);
341 regs[ISL1208_REG_HR] = BIN2BCD(tm->tm_hour) | ISL1208_REG_HR_MIL;
342
343 regs[ISL1208_REG_DT] = BIN2BCD(tm->tm_mday);
344 regs[ISL1208_REG_MO] = BIN2BCD(tm->tm_mon + 1);
345 regs[ISL1208_REG_YR] = BIN2BCD(tm->tm_year - 100);
346
347 regs[ISL1208_REG_DW] = BIN2BCD(tm->tm_wday & 7);
348
349 sr = isl1208_i2c_get_sr(client);
350 if (sr < 0) {
351 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
352 return sr;
353 }
354
355 /* set WRTC */
356 sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR,
357 sr | ISL1208_REG_SR_WRTC);
358 if (sr < 0) {
359 dev_err(&client->dev, "%s: writing SR failed\n", __func__);
360 return sr;
361 }
362
363 /* write RTC registers */
364 sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
365 if (sr < 0) {
366 dev_err(&client->dev, "%s: writing RTC section failed\n",
367 __func__);
368 return sr;
369 }
370
371 /* clear WRTC again */
372 sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR,
373 sr & ~ISL1208_REG_SR_WRTC);
374 if (sr < 0) {
375 dev_err(&client->dev, "%s: writing SR failed\n", __func__);
376 return sr;
377 }
378
379 return 0;
380}
381
382
383static int isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
384{
385 return isl1208_i2c_set_time(to_i2c_client(dev), tm);
386}
387
388static int isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
389{
390 return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm);
391}
392
393static struct rtc_class_ops isl1208_rtc_ops = {
394 .proc = isl1208_rtc_proc,
395 .read_time = isl1208_rtc_read_time,
396 .set_time = isl1208_rtc_set_time,
397 .read_alarm = isl1208_rtc_read_alarm,
398 //.set_alarm = isl1208_rtc_set_alarm,
399};
400
401/* sysfs interface */
402
403static ssize_t isl1208_sysfs_show_atrim(struct device *dev,
404 struct device_attribute *attr,
405 char *buf)
406{
407 int atr;
408
409 atr = isl1208_i2c_get_atr(to_i2c_client(dev));
410 if (atr < 0)
411 return atr;
412
413 return sprintf(buf, "%d.%.2d pF\n", atr>>2, (atr&0x3)*25);
414}
415static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL);
416
417static ssize_t isl1208_sysfs_show_dtrim(struct device *dev,
418 struct device_attribute *attr,
419 char *buf)
420{
421 int dtr;
422
423 dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
424 if (dtr < 0)
425 return dtr;
426
427 return sprintf(buf, "%d ppm\n", dtr);
428}
429static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL);
430
431static ssize_t isl1208_sysfs_show_usr(struct device *dev,
432 struct device_attribute *attr,
433 char *buf)
434{
435 int usr;
436
437 usr = isl1208_i2c_get_usr(to_i2c_client(dev));
438 if (usr < 0)
439 return usr;
440
441 return sprintf(buf, "0x%.4x\n", usr);
442}
443
444static ssize_t isl1208_sysfs_store_usr(struct device *dev,
445 struct device_attribute *attr,
446 const char *buf, size_t count)
447{
448 int usr = -1;
449
450 if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
451 if (sscanf(buf, "%x", &usr) != 1)
452 return -EINVAL;
453 } else {
454 if (sscanf(buf, "%d", &usr) != 1)
455 return -EINVAL;
456 }
457
458 if (usr < 0 || usr > 0xffff)
459 return -EINVAL;
460
461 return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
462}
463static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
464 isl1208_sysfs_store_usr);
465
466static int
467isl1208_probe(struct i2c_adapter *adapter, int addr, int kind)
468{
469 int rc = 0;
470 struct i2c_client *new_client = NULL;
471 struct rtc_device *rtc = NULL;
472
473 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
474 rc = -ENODEV;
475 goto failout;
476 }
477
478 new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
479 if (new_client == NULL) {
480 rc = -ENOMEM;
481 goto failout;
482 }
483
484 new_client->addr = addr;
485 new_client->adapter = adapter;
486 new_client->driver = &isl1208_driver;
487 new_client->flags = 0;
488 strcpy(new_client->name, DRV_NAME);
489
490 if (kind < 0) {
491 rc = isl1208_i2c_validate_client(new_client);
492 if (rc < 0)
493 goto failout;
494 }
495
496 rc = i2c_attach_client(new_client);
497 if (rc < 0)
498 goto failout;
499
500 dev_info(&new_client->dev,
501 "chip found, driver version " DRV_VERSION "\n");
502
503 rtc = rtc_device_register(isl1208_driver.driver.name,
504 &new_client->dev,
505 &isl1208_rtc_ops, THIS_MODULE);
506
507 if (IS_ERR(rtc)) {
508 rc = PTR_ERR(rtc);
509 goto failout_detach;
510 }
511
512 i2c_set_clientdata(new_client, rtc);
513
514 rc = isl1208_i2c_get_sr(new_client);
515 if (rc < 0) {
516 dev_err(&new_client->dev, "reading status failed\n");
517 goto failout_unregister;
518 }
519
520 if (rc & ISL1208_REG_SR_RTCF)
521 dev_warn(&new_client->dev, "rtc power failure detected, "
522 "please set clock.\n");
523
524 rc = device_create_file(&new_client->dev, &dev_attr_atrim);
525 if (rc < 0)
526 goto failout_unregister;
527 rc = device_create_file(&new_client->dev, &dev_attr_dtrim);
528 if (rc < 0)
529 goto failout_atrim;
530 rc = device_create_file(&new_client->dev, &dev_attr_usr);
531 if (rc < 0)
532 goto failout_dtrim;
533
534 return 0;
535
536 failout_dtrim:
537 device_remove_file(&new_client->dev, &dev_attr_dtrim);
538 failout_atrim:
539 device_remove_file(&new_client->dev, &dev_attr_atrim);
540 failout_unregister:
541 rtc_device_unregister(rtc);
542 failout_detach:
543 i2c_detach_client(new_client);
544 failout:
545 kfree(new_client);
546 return rc;
547}
548
549static int
550isl1208_attach_adapter (struct i2c_adapter *adapter)
551{
552 return i2c_probe(adapter, &addr_data, isl1208_probe);
553}
554
555static int
556isl1208_detach_client(struct i2c_client *client)
557{
558 int rc;
559 struct rtc_device *const rtc = i2c_get_clientdata(client);
560
561 if (rtc)
562 rtc_device_unregister(rtc); /* do we need to kfree? */
563
564 rc = i2c_detach_client(client);
565 if (rc)
566 return rc;
567
568 kfree(client);
569
570 return 0;
571}
572
573/* module management */
574
575static int __init isl1208_init(void)
576{
577 return i2c_add_driver(&isl1208_driver);
578}
579
580static void __exit isl1208_exit(void)
581{
582 i2c_del_driver(&isl1208_driver);
583}
584
585MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
586MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
587MODULE_LICENSE("GPL");
588MODULE_VERSION(DRV_VERSION);
589
590module_init(isl1208_init);
591module_exit(isl1208_exit);
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 0dbd4df44c05..979497f108c8 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -1052,7 +1052,7 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
1052 if (err) 1052 if (err)
1053 return err; 1053 return err;
1054 1054
1055 err = sunsab_init_one(&up[0], op, 0, 1055 err = sunsab_init_one(&up[1], op, 0,
1056 (inst * 2) + 1); 1056 (inst * 2) + 1);
1057 if (err) { 1057 if (err) {
1058 of_iounmap(up[0].port.membase, 1058 of_iounmap(up[0].port.membase,
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 93bdaa3169fc..d3a5aeee73a3 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1200,6 +1200,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
1200 if (up->port.type == PORT_UNKNOWN) 1200 if (up->port.type == PORT_UNKNOWN)
1201 return -ENODEV; 1201 return -ENODEV;
1202 1202
1203 printk("%s: %s port at %lx, irq %u\n",
1204 to_of_device(up->port.dev)->node->full_name,
1205 (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
1206 up->port.mapbase, up->port.irq);
1207
1203#ifdef CONFIG_SERIO 1208#ifdef CONFIG_SERIO
1204 serio = &up->serio; 1209 serio = &up->serio;
1205 serio->port_data = up; 1210 serio->port_data = up;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3badb48d662b..6533b0f39231 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1518,6 +1518,26 @@ config FB_PXA_PARAMETERS
1518 1518
1519 <file:Documentation/fb/pxafb.txt> describes the available parameters. 1519 <file:Documentation/fb/pxafb.txt> describes the available parameters.
1520 1520
1521config FB_MBX
1522 tristate "2700G LCD framebuffer support"
1523 depends on FB && ARCH_PXA
1524 select FB_CFB_FILLRECT
1525 select FB_CFB_COPYAREA
1526 select FB_CFB_IMAGEBLIT
1527 ---help---
1528 Framebuffer driver for the Intel 2700G (Marathon) Graphics
1529 Accelerator
1530
1531config FB_MBX_DEBUG
1532 bool "Enable debugging info via debugfs"
1533 depends on FB_MBX && DEBUG_FS
1534 default n
1535 ---help---
1536 Enable this if you want debugging information using the debug
1537 filesystem (debugfs)
1538
1539 If unsure, say N.
1540
1521config FB_W100 1541config FB_W100
1522 tristate "W100 frame buffer support" 1542 tristate "W100 frame buffer support"
1523 depends on FB && PXA_SHARPSL 1543 depends on FB && PXA_SHARPSL
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 6283d015f8f5..95563c9c6b9c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_FB_SIS) += sis/
38obj-$(CONFIG_FB_KYRO) += kyro/ 38obj-$(CONFIG_FB_KYRO) += kyro/
39obj-$(CONFIG_FB_SAVAGE) += savage/ 39obj-$(CONFIG_FB_SAVAGE) += savage/
40obj-$(CONFIG_FB_GEODE) += geode/ 40obj-$(CONFIG_FB_GEODE) += geode/
41obj-$(CONFIG_FB_MBX) += mbx/
41obj-$(CONFIG_FB_I810) += vgastate.o 42obj-$(CONFIG_FB_I810) += vgastate.o
42obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o 43obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
43obj-$(CONFIG_FB_VIRGE) += virgefb.o 44obj-$(CONFIG_FB_VIRGE) += virgefb.o
diff --git a/drivers/video/mbx/Makefile b/drivers/video/mbx/Makefile
new file mode 100644
index 000000000000..16c1165cf9c7
--- /dev/null
+++ b/drivers/video/mbx/Makefile
@@ -0,0 +1,4 @@
1# Makefile for the 2700G controller driver.
2
3obj-$(CONFIG_FB_MBX) += mbxfb.o
4obj-$(CONFIG_FB_MBX_DEBUG) += mbxfbdebugfs.o
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
new file mode 100644
index 000000000000..84aab3ad024e
--- /dev/null
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -0,0 +1,188 @@
1#include <linux/debugfs.h>
2
3#define BIG_BUFFER_SIZE (1024)
4
5static char big_buffer[BIG_BUFFER_SIZE];
6
7struct mbxfb_debugfs_data {
8 struct dentry *dir;
9 struct dentry *sysconf;
10 struct dentry *clock;
11 struct dentry *display;
12 struct dentry *gsctl;
13};
14
15static int open_file_generic(struct inode *inode, struct file *file)
16{
17 file->private_data = inode->u.generic_ip;
18 return 0;
19}
20
21static ssize_t write_file_dummy(struct file *file, const char __user *buf,
22 size_t count, loff_t *ppos)
23{
24 return count;
25}
26
27static ssize_t sysconf_read_file(struct file *file, char __user *userbuf,
28 size_t count, loff_t *ppos)
29{
30 char * s = big_buffer;
31
32 s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG);
33 s += sprintf(s, "PFBASE = %08lx\n", PFBASE);
34 s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL);
35 s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG);
36 s += sprintf(s, "SYSRST = %08lx\n", SYSRST);
37
38 return simple_read_from_buffer(userbuf, count, ppos,
39 big_buffer, s-big_buffer);
40}
41
42
43static ssize_t gsctl_read_file(struct file *file, char __user *userbuf,
44 size_t count, loff_t *ppos)
45{
46 char * s = big_buffer;
47
48 s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL);
49 s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL);
50 s += sprintf(s, "GBBASE = %08lx\n", GBBASE);
51 s += sprintf(s, "VBBASE = %08lx\n", VBBASE);
52 s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL);
53 s += sprintf(s, "VCMSK = %08lx\n", VCMSK);
54 s += sprintf(s, "GSCADR = %08lx\n", GSCADR);
55 s += sprintf(s, "VSCADR = %08lx\n", VSCADR);
56 s += sprintf(s, "VUBASE = %08lx\n", VUBASE);
57 s += sprintf(s, "VVBASE = %08lx\n", VVBASE);
58 s += sprintf(s, "GSADR = %08lx\n", GSADR);
59 s += sprintf(s, "VSADR = %08lx\n", VSADR);
60 s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL);
61 s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE);
62 s += sprintf(s, "HCPOS = %08lx\n", HCPOS);
63 s += sprintf(s, "HCBADR = %08lx\n", HCBADR);
64 s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK);
65 s += sprintf(s, "GPLUT = %08lx\n", GPLUT);
66
67 return simple_read_from_buffer(userbuf, count, ppos,
68 big_buffer, s-big_buffer);
69}
70
71static ssize_t display_read_file(struct file *file, char __user *userbuf,
72 size_t count, loff_t *ppos)
73{
74 char * s = big_buffer;
75
76 s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL);
77 s += sprintf(s, "DHT01 = %08lx\n", DHT01);
78 s += sprintf(s, "DHT02 = %08lx\n", DHT02);
79 s += sprintf(s, "DHT03 = %08lx\n", DHT03);
80 s += sprintf(s, "DVT01 = %08lx\n", DVT01);
81 s += sprintf(s, "DVT02 = %08lx\n", DVT02);
82 s += sprintf(s, "DVT03 = %08lx\n", DVT03);
83 s += sprintf(s, "DBCOL = %08lx\n", DBCOL);
84 s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR);
85 s += sprintf(s, "DINTRS = %08lx\n", DINTRS);
86 s += sprintf(s, "DINTRE = %08lx\n", DINTRE);
87 s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT);
88 s += sprintf(s, "DSIG = %08lx\n", DSIG);
89 s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL);
90 s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL);
91 s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL);
92 s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL);
93 s += sprintf(s, "DLSTS = %08lx\n", DLSTS);
94 s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL);
95 s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM);
96 s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL);
97 s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL);
98 s += sprintf(s, "DHDET = %08lx\n", DHDET);
99 s += sprintf(s, "DVDET = %08lx\n", DVDET);
100 s += sprintf(s, "DODMSK = %08lx\n", DODMSK);
101 s += sprintf(s, "CSC01 = %08lx\n", CSC01);
102 s += sprintf(s, "CSC02 = %08lx\n", CSC02);
103 s += sprintf(s, "CSC03 = %08lx\n", CSC03);
104 s += sprintf(s, "CSC04 = %08lx\n", CSC04);
105 s += sprintf(s, "CSC05 = %08lx\n", CSC05);
106
107 return simple_read_from_buffer(userbuf, count, ppos,
108 big_buffer, s-big_buffer);
109}
110
111static ssize_t clock_read_file(struct file *file, char __user *userbuf,
112 size_t count, loff_t *ppos)
113{
114 char * s = big_buffer;
115
116 s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC);
117 s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC);
118 s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP);
119 s += sprintf(s, "COREPLL = %08lx\n", COREPLL);
120 s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL);
121 s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT);
122 s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK);
123 s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK);
124 s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK);
125 s += sprintf(s, "M24CLK = %08lx\n", M24CLK);
126 s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK);
127 s += sprintf(s, "SDCLK = %08lx\n", SDCLK);
128 s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV);
129
130 return simple_read_from_buffer(userbuf, count, ppos,
131 big_buffer, s-big_buffer);
132}
133
134static struct file_operations sysconf_fops = {
135 .read = sysconf_read_file,
136 .write = write_file_dummy,
137 .open = open_file_generic,
138};
139
140static struct file_operations clock_fops = {
141 .read = clock_read_file,
142 .write = write_file_dummy,
143 .open = open_file_generic,
144};
145
146static struct file_operations display_fops = {
147 .read = display_read_file,
148 .write = write_file_dummy,
149 .open = open_file_generic,
150};
151
152static struct file_operations gsctl_fops = {
153 .read = gsctl_read_file,
154 .write = write_file_dummy,
155 .open = open_file_generic,
156};
157
158
159static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
160{
161 struct mbxfb_info *mfbi = fbi->par;
162 struct mbxfb_debugfs_data *dbg;
163
164 dbg = kzalloc(sizeof(struct mbxfb_debugfs_data), GFP_KERNEL);
165 mfbi->debugfs_data = dbg;
166
167 dbg->dir = debugfs_create_dir("mbxfb", NULL);
168 dbg->sysconf = debugfs_create_file("sysconf", 0444, dbg->dir,
169 fbi, &sysconf_fops);
170 dbg->clock = debugfs_create_file("clock", 0444, dbg->dir,
171 fbi, &clock_fops);
172 dbg->display = debugfs_create_file("display", 0444, dbg->dir,
173 fbi, &display_fops);
174 dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir,
175 fbi, &gsctl_fops);
176}
177
178static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
179{
180 struct mbxfb_info *mfbi = fbi->par;
181 struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
182
183 debugfs_remove(dbg->gsctl);
184 debugfs_remove(dbg->display);
185 debugfs_remove(dbg->clock);
186 debugfs_remove(dbg->sysconf);
187 debugfs_remove(dbg->dir);
188}
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
new file mode 100644
index 000000000000..6849ab75d403
--- /dev/null
+++ b/drivers/video/mbx/mbxfb.c
@@ -0,0 +1,683 @@
1/*
2 * linux/drivers/video/mbx/mbxfb.c
3 *
4 * Copyright (C) 2006 Compulab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on pxafb.c
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for
11 * more details.
12 *
13 * Intel 2700G (Marathon) Graphics Accelerator Frame Buffer Driver
14 *
15 */
16
17#include <linux/delay.h>
18#include <linux/fb.h>
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include <asm/io.h>
24
25#include <video/mbxfb.h>
26
27#include "regs.h"
28#include "reg_bits.h"
29
30static unsigned long virt_base_2700;
31
32#define MIN_XRES 16
33#define MIN_YRES 16
34#define MAX_XRES 2048
35#define MAX_YRES 2048
36
37#define MAX_PALETTES 16
38
39/* FIXME: take care of different chip revisions with different sizes
40 of ODFB */
41#define MEMORY_OFFSET 0x60000
42
43struct mbxfb_info {
44 struct device *dev;
45
46 struct resource *fb_res;
47 struct resource *fb_req;
48
49 struct resource *reg_res;
50 struct resource *reg_req;
51
52 void __iomem *fb_virt_addr;
53 unsigned long fb_phys_addr;
54
55 void __iomem *reg_virt_addr;
56 unsigned long reg_phys_addr;
57
58 int (*platform_probe) (struct fb_info * fb);
59 int (*platform_remove) (struct fb_info * fb);
60
61 u32 pseudo_palette[MAX_PALETTES];
62#ifdef CONFIG_FB_MBX_DEBUG
63 void *debugfs_data;
64#endif
65
66};
67
68static struct fb_var_screeninfo mbxfb_default __devinitdata = {
69 .xres = 640,
70 .yres = 480,
71 .xres_virtual = 640,
72 .yres_virtual = 480,
73 .bits_per_pixel = 16,
74 .red = {11, 5, 0},
75 .green = {5, 6, 0},
76 .blue = {0, 5, 0},
77 .activate = FB_ACTIVATE_TEST,
78 .height = -1,
79 .width = -1,
80 .pixclock = 40000,
81 .left_margin = 48,
82 .right_margin = 16,
83 .upper_margin = 33,
84 .lower_margin = 10,
85 .hsync_len = 96,
86 .vsync_len = 2,
87 .vmode = FB_VMODE_NONINTERLACED,
88 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
89};
90
91static struct fb_fix_screeninfo mbxfb_fix __devinitdata = {
92 .id = "MBX",
93 .type = FB_TYPE_PACKED_PIXELS,
94 .visual = FB_VISUAL_TRUECOLOR,
95 .xpanstep = 0,
96 .ypanstep = 0,
97 .ywrapstep = 0,
98 .accel = FB_ACCEL_NONE,
99};
100
101struct pixclock_div {
102 u8 m;
103 u8 n;
104 u8 p;
105};
106
107static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
108 struct pixclock_div *div)
109{
110 u8 m, n, p;
111 unsigned int err = 0;
112 unsigned int min_err = ~0x0;
113 unsigned int clk;
114 unsigned int best_clk = 0;
115 unsigned int ref_clk = 13000; /* FIXME: take from platform data */
116 unsigned int pixclock;
117
118 /* convert pixclock to KHz */
119 pixclock = PICOS2KHZ(pixclock_ps);
120
121 for (m = 1; m < 64; m++) {
122 for (n = 1; n < 8; n++) {
123 for (p = 0; p < 8; p++) {
124 clk = (ref_clk * m) / (n * (1 << p));
125 err = (clk > pixclock) ? (clk - pixclock) :
126 (pixclock - clk);
127 if (err < min_err) {
128 min_err = err;
129 best_clk = clk;
130 div->m = m;
131 div->n = n;
132 div->p = p;
133 }
134 }
135 }
136 }
137 return KHZ2PICOS(best_clk);
138}
139
140static int mbxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
141 u_int trans, struct fb_info *info)
142{
143 u32 val, ret = 1;
144
145 if (regno < MAX_PALETTES) {
146 u32 *pal = info->pseudo_palette;
147
148 val = (red & 0xf800) | ((green & 0xfc00) >> 5) |
149 ((blue & 0xf800) >> 11);
150 pal[regno] = val;
151 ret = 0;
152 }
153
154 return ret;
155}
156
157static int mbxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
158{
159 struct pixclock_div div;
160
161 var->pixclock = mbxfb_get_pixclock(var->pixclock, &div);
162
163 if (var->xres < MIN_XRES)
164 var->xres = MIN_XRES;
165 if (var->yres < MIN_YRES)
166 var->yres = MIN_YRES;
167 if (var->xres > MAX_XRES)
168 return -EINVAL;
169 if (var->yres > MAX_YRES)
170 return -EINVAL;
171 var->xres_virtual = max(var->xres_virtual, var->xres);
172 var->yres_virtual = max(var->yres_virtual, var->yres);
173
174 switch (var->bits_per_pixel) {
175 /* 8 bits-per-pixel is not supported yet */
176 case 8:
177 return -EINVAL;
178 case 16:
179 var->green.length = (var->green.length == 5) ? 5 : 6;
180 var->red.length = 5;
181 var->blue.length = 5;
182 var->transp.length = 6 - var->green.length;
183 var->blue.offset = 0;
184 var->green.offset = 5;
185 var->red.offset = 5 + var->green.length;
186 var->transp.offset = (5 + var->red.offset) & 15;
187 break;
188 case 24: /* RGB 888 */
189 case 32: /* RGBA 8888 */
190 var->red.offset = 16;
191 var->red.length = 8;
192 var->green.offset = 8;
193 var->green.length = 8;
194 var->blue.offset = 0;
195 var->blue.length = 8;
196 var->transp.length = var->bits_per_pixel - 24;
197 var->transp.offset = (var->transp.length) ? 24 : 0;
198 break;
199 }
200 var->red.msb_right = 0;
201 var->green.msb_right = 0;
202 var->blue.msb_right = 0;
203 var->transp.msb_right = 0;
204
205 return 0;
206}
207
208static int mbxfb_set_par(struct fb_info *info)
209{
210 struct fb_var_screeninfo *var = &info->var;
211 struct pixclock_div div;
212 ushort hbps, ht, hfps, has;
213 ushort vbps, vt, vfps, vas;
214 u32 gsctrl = readl(GSCTRL);
215 u32 gsadr = readl(GSADR);
216
217 info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
218
219 /* setup color mode */
220 gsctrl &= ~(FMsk(GSCTRL_GPIXFMT));
221 /* FIXME: add *WORKING* support for 8-bits per color */
222 if (info->var.bits_per_pixel == 8) {
223 return -EINVAL;
224 } else {
225 fb_dealloc_cmap(&info->cmap);
226 gsctrl &= ~GSCTRL_LUT_EN;
227
228 info->fix.visual = FB_VISUAL_TRUECOLOR;
229 switch (info->var.bits_per_pixel) {
230 case 16:
231 if (info->var.green.length == 5)
232 gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
233 else
234 gsctrl |= GSCTRL_GPIXFMT_RGB565;
235 break;
236 case 24:
237 gsctrl |= GSCTRL_GPIXFMT_RGB888;
238 break;
239 case 32:
240 gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
241 break;
242 }
243 }
244
245 /* setup resolution */
246 gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
247 gsctrl |= Gsctrl_Width(info->var.xres - 1) |
248 Gsctrl_Height(info->var.yres - 1);
249 writel(gsctrl, GSCTRL);
250 udelay(1000);
251
252 gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
253 gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
254 (8 * 16) - 1);
255 writel(gsadr, GSADR);
256 udelay(1000);
257
258 /* setup timings */
259 var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
260
261 writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
262 Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);
263
264 hbps = var->hsync_len;
265 has = hbps + var->left_margin;
266 hfps = has + var->xres;
267 ht = hfps + var->right_margin;
268
269 vbps = var->vsync_len;
270 vas = vbps + var->upper_margin;
271 vfps = vas + var->yres;
272 vt = vfps + var->lower_margin;
273
274 writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
275 writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
276 writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
277 writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
278
279 writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
280 writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
281 writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
282 writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
283 writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
284
285 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
286
287 return 0;
288}
289
290static int mbxfb_blank(int blank, struct fb_info *info)
291{
292 switch (blank) {
293 case FB_BLANK_POWERDOWN:
294 case FB_BLANK_VSYNC_SUSPEND:
295 case FB_BLANK_HSYNC_SUSPEND:
296 case FB_BLANK_NORMAL:
297 writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
298 udelay(1000);
299 writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
300 udelay(1000);
301 writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
302 udelay(1000);
303 break;
304 case FB_BLANK_UNBLANK:
305 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
306 udelay(1000);
307 writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
308 udelay(1000);
309 break;
310 }
311 return 0;
312}
313
314static struct fb_ops mbxfb_ops = {
315 .owner = THIS_MODULE,
316 .fb_check_var = mbxfb_check_var,
317 .fb_set_par = mbxfb_set_par,
318 .fb_setcolreg = mbxfb_setcolreg,
319 .fb_fillrect = cfb_fillrect,
320 .fb_copyarea = cfb_copyarea,
321 .fb_imageblit = cfb_imageblit,
322 .fb_blank = mbxfb_blank,
323};
324
325/*
326 Enable external SDRAM controller. Assume that all clocks are active
327 by now.
328*/
329static void __devinit setup_memc(struct fb_info *fbi)
330{
331 struct mbxfb_info *mfbi = fbi->par;
332 unsigned long tmp;
333 int i;
334
335 /* FIXME: use platfrom specific parameters */
336 /* setup SDRAM controller */
337 writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
338 LMCFG_LMA_TS),
339 LMCFG);
340 udelay(1000);
341
342 writel(LMPWR_MC_PWR_ACT, LMPWR);
343 udelay(1000);
344
345 /* setup SDRAM timings */
346 writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
347 Lmtim_Trc(9) | Lmtim_Tdpl(2)),
348 LMTIM);
349 udelay(1000);
350 /* setup SDRAM refresh rate */
351 writel(0xc2b, LMREFRESH);
352 udelay(1000);
353 /* setup SDRAM type parameters */
354 writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
355 LMTYPE_COLSZ_8),
356 LMTYPE);
357 udelay(1000);
358 /* enable memory controller */
359 writel(LMPWR_MC_PWR_ACT, LMPWR);
360 udelay(1000);
361
362 /* perform dummy reads */
363 for ( i = 0; i < 16; i++ ) {
364 tmp = readl(fbi->screen_base);
365 }
366}
367
368static void enable_clocks(struct fb_info *fbi)
369{
370 /* enable clocks */
371 writel(SYSCLKSRC_PLL_2, SYSCLKSRC);
372 udelay(1000);
373 writel(PIXCLKSRC_PLL_1, PIXCLKSRC);
374 udelay(1000);
375 writel(0x00000000, CLKSLEEP);
376 udelay(1000);
377 writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) |
378 CORE_PLL_EN),
379 COREPLL);
380 udelay(1000);
381 writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
382 DISP_PLL_EN),
383 DISPPLL);
384
385 writel(0x00000000, VOVRCLK);
386 udelay(1000);
387 writel(PIXCLK_EN, PIXCLK);
388 udelay(1000);
389 writel(MEMCLK_EN, MEMCLK);
390 udelay(1000);
391 writel(0x00000006, M24CLK);
392 udelay(1000);
393 writel(0x00000006, MBXCLK);
394 udelay(1000);
395 writel(SDCLK_EN, SDCLK);
396 udelay(1000);
397 writel(0x00000001, PIXCLKDIV);
398 udelay(1000);
399}
400
401static void __devinit setup_graphics(struct fb_info *fbi)
402{
403 unsigned long gsctrl;
404
405 gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
406 Gsctrl_Height(fbi->var.yres - 1);
407 switch (fbi->var.bits_per_pixel) {
408 case 16:
409 if (fbi->var.green.length == 5)
410 gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
411 else
412 gsctrl |= GSCTRL_GPIXFMT_RGB565;
413 break;
414 case 24:
415 gsctrl |= GSCTRL_GPIXFMT_RGB888;
416 break;
417 case 32:
418 gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
419 break;
420 }
421
422 writel(gsctrl, GSCTRL);
423 udelay(1000);
424 writel(0x00000000, GBBASE);
425 udelay(1000);
426 writel(0x00ffffff, GDRCTRL);
427 udelay(1000);
428 writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
429 udelay(1000);
430 writel(0x00000000, GPLUT);
431 udelay(1000);
432}
433
434static void __devinit setup_display(struct fb_info *fbi)
435{
436 unsigned long dsctrl = 0;
437
438 dsctrl = DSCTRL_BLNK_POL;
439 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
440 dsctrl |= DSCTRL_HS_POL;
441 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
442 dsctrl |= DSCTRL_VS_POL;
443 writel(dsctrl, DSCTRL);
444 udelay(1000);
445 writel(0xd0303010, DMCTRL);
446 udelay(1000);
447 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
448}
449
450static void __devinit enable_controller(struct fb_info *fbi)
451{
452 writel(SYSRST_RST, SYSRST);
453 udelay(1000);
454
455
456 enable_clocks(fbi);
457 setup_memc(fbi);
458 setup_graphics(fbi);
459 setup_display(fbi);
460}
461
462#ifdef CONFIG_PM
463/*
464 * Power management hooks. Note that we won't be called from IRQ context,
465 * unlike the blank functions above, so we may sleep.
466 */
467static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
468{
469 /* make frame buffer memory enter self-refresh mode */
470 writel(LMPWR_MC_PWR_SRM, LMPWR);
471 while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
472 ; /* empty statement */
473
474 /* reset the device, since it's initial state is 'mostly sleeping' */
475 writel(SYSRST_RST, SYSRST);
476 return 0;
477}
478
479static int mbxfb_resume(struct platform_device *dev)
480{
481 struct fb_info *fbi = platform_get_drvdata(dev);
482
483 enable_clocks(fbi);
484/* setup_graphics(fbi); */
485/* setup_display(fbi); */
486
487 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
488 return 0;
489}
490#else
491#define mbxfb_suspend NULL
492#define mbxfb_resume NULL
493#endif
494
495/* debugfs entries */
496#ifndef CONFIG_FB_MBX_DEBUG
497#define mbxfb_debugfs_init(x) do {} while(0)
498#define mbxfb_debugfs_remove(x) do {} while(0)
499#endif
500
501#define res_size(_r) (((_r)->end - (_r)->start) + 1)
502
503static int __devinit mbxfb_probe(struct platform_device *dev)
504{
505 int ret;
506 struct fb_info *fbi;
507 struct mbxfb_info *mfbi;
508 struct mbxfb_platform_data *pdata;
509
510 dev_dbg(dev, "mbxfb_probe\n");
511
512 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
513 if (fbi == NULL) {
514 dev_err(&dev->dev, "framebuffer_alloc failed\n");
515 return -ENOMEM;
516 }
517
518 mfbi = fbi->par;
519 fbi->pseudo_palette = mfbi->pseudo_palette;
520 pdata = dev->dev.platform_data;
521 if (pdata->probe)
522 mfbi->platform_probe = pdata->probe;
523 if (pdata->remove)
524 mfbi->platform_remove = pdata->remove;
525
526 mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
527 mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
528
529 if (!mfbi->fb_res || !mfbi->reg_res) {
530 dev_err(&dev->dev, "no resources found\n");
531 ret = -ENODEV;
532 goto err1;
533 }
534
535 mfbi->fb_req = request_mem_region(mfbi->fb_res->start,
536 res_size(mfbi->fb_res), dev->name);
537 if (mfbi->fb_req == NULL) {
538 dev_err(&dev->dev, "failed to claim framebuffer memory\n");
539 ret = -EINVAL;
540 goto err1;
541 }
542 mfbi->fb_phys_addr = mfbi->fb_res->start;
543
544 mfbi->reg_req = request_mem_region(mfbi->reg_res->start,
545 res_size(mfbi->reg_res), dev->name);
546 if (mfbi->reg_req == NULL) {
547 dev_err(&dev->dev, "failed to claim Marathon registers\n");
548 ret = -EINVAL;
549 goto err2;
550 }
551 mfbi->reg_phys_addr = mfbi->reg_res->start;
552
553 mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
554 res_size(mfbi->reg_req));
555 if (!mfbi->reg_virt_addr) {
556 dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
557 ret = -EINVAL;
558 goto err3;
559 }
560 virt_base_2700 = (unsigned long)mfbi->reg_virt_addr;
561
562 mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
563 res_size(mfbi->fb_req));
564 if (!mfbi->reg_virt_addr) {
565 dev_err(&dev->dev, "failed to ioremap frame buffer\n");
566 ret = -EINVAL;
567 goto err4;
568 }
569
570 /* FIXME: get from platform */
571 fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
572 fbi->screen_size = 8 * 1024 * 1024; /* 8 Megs */
573 fbi->fbops = &mbxfb_ops;
574
575 fbi->var = mbxfb_default;
576 fbi->fix = mbxfb_fix;
577 fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
578 fbi->fix.smem_len = 8 * 1024 * 1024;
579 fbi->fix.line_length = 640 * 2;
580
581 ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
582 if (ret < 0) {
583 dev_err(&dev->dev, "fb_alloc_cmap failed\n");
584 ret = -EINVAL;
585 goto err5;
586 }
587
588 platform_set_drvdata(dev, fbi);
589
590 printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);
591
592 if (mfbi->platform_probe)
593 mfbi->platform_probe(fbi);
594
595 enable_controller(fbi);
596
597 mbxfb_debugfs_init(fbi);
598
599 ret = register_framebuffer(fbi);
600 if (ret < 0) {
601 dev_err(&dev->dev, "register_framebuffer failed\n");
602 ret = -EINVAL;
603 goto err6;
604 }
605
606 return 0;
607
608err6:
609 fb_dealloc_cmap(&fbi->cmap);
610err5:
611 iounmap(mfbi->fb_virt_addr);
612err4:
613 iounmap(mfbi->reg_virt_addr);
614err3:
615 release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
616err2:
617 release_mem_region(mfbi->fb_res->start, res_size(mfbi->fb_res));
618err1:
619 framebuffer_release(fbi);
620
621 return ret;
622}
623
624static int __devexit mbxfb_remove(struct platform_device *dev)
625{
626 struct fb_info *fbi = platform_get_drvdata(dev);
627
628 writel(SYSRST_RST, SYSRST);
629 udelay(1000);
630
631 mbxfb_debugfs_remove(fbi);
632
633 if (fbi) {
634 struct mbxfb_info *mfbi = fbi->par;
635
636 unregister_framebuffer(fbi);
637 if (mfbi) {
638 if (mfbi->platform_remove)
639 mfbi->platform_remove(fbi);
640
641 if (mfbi->fb_virt_addr)
642 iounmap(mfbi->fb_virt_addr);
643 if (mfbi->reg_virt_addr)
644 iounmap(mfbi->reg_virt_addr);
645 if (mfbi->reg_req)
646 release_mem_region(mfbi->reg_req->start,
647 res_size(mfbi->reg_req));
648 if (mfbi->fb_req)
649 release_mem_region(mfbi->fb_req->start,
650 res_size(mfbi->fb_req));
651 }
652 framebuffer_release(fbi);
653 }
654
655 return 0;
656}
657
658static struct platform_driver mbxfb_driver = {
659 .probe = mbxfb_probe,
660 .remove = mbxfb_remove,
661 .suspend = mbxfb_suspend,
662 .resume = mbxfb_resume,
663 .driver = {
664 .name = "mbx-fb",
665 },
666};
667
668int __devinit mbxfb_init(void)
669{
670 return platform_driver_register(&mbxfb_driver);
671}
672
673static void __devexit mbxfb_exit(void)
674{
675 platform_driver_unregister(&mbxfb_driver);
676}
677
678module_init(mbxfb_init);
679module_exit(mbxfb_exit);
680
681MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
682MODULE_AUTHOR("Mike Rapoport, Compulab");
683MODULE_LICENSE("GPL");
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
new file mode 100644
index 000000000000..c226a8e45312
--- /dev/null
+++ b/drivers/video/mbx/reg_bits.h
@@ -0,0 +1,418 @@
1#ifndef __REG_BITS_2700G_
2#define __REG_BITS_2700G_
3
4/* use defines from asm-arm/arch-pxa/bitfields.h for bit fields access */
5#define UData(Data) ((unsigned long) (Data))
6#define Fld(Size, Shft) (((Size) << 16) + (Shft))
7#define FSize(Field) ((Field) >> 16)
8#define FShft(Field) ((Field) & 0x0000FFFF)
9#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field))
10#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1)
11#define F1stBit(Field) (UData (1) << FShft (Field))
12
13#define SYSRST_RST (1 << 0)
14
15/* SYSCLKSRC - SYSCLK Source Control Register */
16#define SYSCLKSRC_SEL Fld(2,0)
17#define SYSCLKSRC_REF ((0x0) << FShft(SYSCLKSRC_SEL))
18#define SYSCLKSRC_PLL_1 ((0x1) << FShft(SYSCLKSRC_SEL))
19#define SYSCLKSRC_PLL_2 ((0x2) << FShft(SYSCLKSRC_SEL))
20
21/* PIXCLKSRC - PIXCLK Source Control Register */
22#define PIXCLKSRC_SEL Fld(2,0)
23#define PIXCLKSRC_REF ((0x0) << FShft(PIXCLKSRC_SEL))
24#define PIXCLKSRC_PLL_1 ((0x1) << FShft(PIXCLKSRC_SEL))
25#define PIXCLKSRC_PLL_2 ((0x2) << FShft(PIXCLKSRC_SEL))
26
27/* Clock Disable Register */
28#define CLKSLEEP_SLP (1 << 0)
29
30/* Core PLL Control Register */
31#define CORE_PLL_M Fld(6,7)
32#define Core_Pll_M(x) ((x) << FShft(CORE_PLL_M))
33#define CORE_PLL_N Fld(3,4)
34#define Core_Pll_N(x) ((x) << FShft(CORE_PLL_N))
35#define CORE_PLL_P Fld(3,1)
36#define Core_Pll_P(x) ((x) << FShft(CORE_PLL_P))
37#define CORE_PLL_EN (1 << 0)
38
39/* Display PLL Control Register */
40#define DISP_PLL_M Fld(6,7)
41#define Disp_Pll_M(x) ((x) << FShft(DISP_PLL_M))
42#define DISP_PLL_N Fld(3,4)
43#define Disp_Pll_N(x) ((x) << FShft(DISP_PLL_N))
44#define DISP_PLL_P Fld(3,1)
45#define Disp_Pll_P(x) ((x) << FShft(DISP_PLL_P))
46#define DISP_PLL_EN (1 << 0)
47
48/* PLL status register */
49#define PLLSTAT_CORE_PLL_LOST_L (1 << 3)
50#define PLLSTAT_CORE_PLL_LSTS (1 << 2)
51#define PLLSTAT_DISP_PLL_LOST_L (1 << 1)
52#define PLLSTAT_DISP_PLL_LSTS (1 << 0)
53
54/* Video and scale clock control register */
55#define VOVRCLK_EN (1 << 0)
56
57/* Pixel clock control register */
58#define PIXCLK_EN (1 << 0)
59
60/* Memory clock control register */
61#define MEMCLK_EN (1 << 0)
62
63/* MBX clock control register */
64#define MBXCLK_DIV Fld(2,2)
65#define MBXCLK_DIV_1 ((0x0) << FShft(MBXCLK_DIV))
66#define MBXCLK_DIV_2 ((0x1) << FShft(MBXCLK_DIV))
67#define MBXCLK_DIV_3 ((0x2) << FShft(MBXCLK_DIV))
68#define MBXCLK_DIV_4 ((0x3) << FShft(MBXCLK_DIV))
69#define MBXCLK_EN Fld(2,0)
70#define MBXCLK_EN_NONE ((0x0) << FShft(MBXCLK_EN))
71#define MBXCLK_EN_2D ((0x1) << FShft(MBXCLK_EN))
72#define MBXCLK_EN_BOTH ((0x2) << FShft(MBXCLK_EN))
73
74/* M24 clock control register */
75#define M24CLK_DIV Fld(2,1)
76#define M24CLK_DIV_1 ((0x0) << FShft(M24CLK_DIV))
77#define M24CLK_DIV_2 ((0x1) << FShft(M24CLK_DIV))
78#define M24CLK_DIV_3 ((0x2) << FShft(M24CLK_DIV))
79#define M24CLK_DIV_4 ((0x3) << FShft(M24CLK_DIV))
80#define M24CLK_EN (1 << 0)
81
82/* SDRAM clock control register */
83#define SDCLK_EN (1 << 0)
84
85/* PixClk Divisor Register */
86#define PIXCLKDIV_PD Fld(9,0)
87#define Pixclkdiv_Pd(x) ((x) << FShft(PIXCLKDIV_PD))
88
89/* LCD Config control register */
90#define LCDCFG_IN_FMT Fld(3,28)
91#define Lcdcfg_In_Fmt(x) ((x) << FShft(LCDCFG_IN_FMT))
92#define LCDCFG_LCD1DEN_POL (1 << 27)
93#define LCDCFG_LCD1FCLK_POL (1 << 26)
94#define LCDCFG_LCD1LCLK_POL (1 << 25)
95#define LCDCFG_LCD1D_POL (1 << 24)
96#define LCDCFG_LCD2DEN_POL (1 << 23)
97#define LCDCFG_LCD2FCLK_POL (1 << 22)
98#define LCDCFG_LCD2LCLK_POL (1 << 21)
99#define LCDCFG_LCD2D_POL (1 << 20)
100#define LCDCFG_LCD1_TS (1 << 19)
101#define LCDCFG_LCD1D_DS (1 << 18)
102#define LCDCFG_LCD1C_DS (1 << 17)
103#define LCDCFG_LCD1_IS_IN (1 << 16)
104#define LCDCFG_LCD2_TS (1 << 3)
105#define LCDCFG_LCD2D_DS (1 << 2)
106#define LCDCFG_LCD2C_DS (1 << 1)
107#define LCDCFG_LCD2_IS_IN (1 << 0)
108
109/* On-Die Frame Buffer Power Control Register */
110#define ODFBPWR_SLOW (1 << 2)
111#define ODFBPWR_MODE Fld(2,0)
112#define ODFBPWR_MODE_ACT ((0x0) << FShft(ODFBPWR_MODE))
113#define ODFBPWR_MODE_ACT_LP ((0x1) << FShft(ODFBPWR_MODE))
114#define ODFBPWR_MODE_SLEEP ((0x2) << FShft(ODFBPWR_MODE))
115#define ODFBPWR_MODE_SHUTD ((0x3) << FShft(ODFBPWR_MODE))
116
117/* On-Die Frame Buffer Power State Status Register */
118#define ODFBSTAT_ACT (1 << 2)
119#define ODFBSTAT_SLP (1 << 1)
120#define ODFBSTAT_SDN (1 << 0)
121
122/* LMRST - Local Memory (SDRAM) Reset */
123#define LMRST_MC_RST (1 << 0)
124
125/* LMCFG - Local Memory (SDRAM) Configuration Register */
126#define LMCFG_LMC_DS (1 << 5)
127#define LMCFG_LMD_DS (1 << 4)
128#define LMCFG_LMA_DS (1 << 3)
129#define LMCFG_LMC_TS (1 << 2)
130#define LMCFG_LMD_TS (1 << 1)
131#define LMCFG_LMA_TS (1 << 0)
132
133/* LMPWR - Local Memory (SDRAM) Power Control Register */
134#define LMPWR_MC_PWR_CNT Fld(2,0)
135#define LMPWR_MC_PWR_ACT ((0x0) << FShft(LMPWR_MC_PWR_CNT)) /* Active */
136#define LMPWR_MC_PWR_SRM ((0x1) << FShft(LMPWR_MC_PWR_CNT)) /* Self-refresh */
137#define LMPWR_MC_PWR_DPD ((0x3) << FShft(LMPWR_MC_PWR_CNT)) /* deep power down */
138
139/* LMPWRSTAT - Local Memory (SDRAM) Power Status Register */
140#define LMPWRSTAT_MC_PWR_CNT Fld(2,0)
141#define LMPWRSTAT_MC_PWR_ACT ((0x0) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Active */
142#define LMPWRSTAT_MC_PWR_SRM ((0x1) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Self-refresh */
143#define LMPWRSTAT_MC_PWR_DPD ((0x3) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* deep power down */
144
145/* LMTYPE - Local Memory (SDRAM) Type Register */
146#define LMTYPE_CASLAT Fld(3,10)
147#define LMTYPE_CASLAT_1 ((0x1) << FShft(LMTYPE_CASLAT))
148#define LMTYPE_CASLAT_2 ((0x2) << FShft(LMTYPE_CASLAT))
149#define LMTYPE_CASLAT_3 ((0x3) << FShft(LMTYPE_CASLAT))
150#define LMTYPE_BKSZ Fld(2,8)
151#define LMTYPE_BKSZ_1 ((0x1) << FShft(LMTYPE_BKSZ))
152#define LMTYPE_BKSZ_2 ((0x2) << FShft(LMTYPE_BKSZ))
153#define LMTYPE_ROWSZ Fld(4,4)
154#define LMTYPE_ROWSZ_11 ((0xb) << FShft(LMTYPE_ROWSZ))
155#define LMTYPE_ROWSZ_12 ((0xc) << FShft(LMTYPE_ROWSZ))
156#define LMTYPE_ROWSZ_13 ((0xd) << FShft(LMTYPE_ROWSZ))
157#define LMTYPE_COLSZ Fld(4,0)
158#define LMTYPE_COLSZ_7 ((0x7) << FShft(LMTYPE_COLSZ))
159#define LMTYPE_COLSZ_8 ((0x8) << FShft(LMTYPE_COLSZ))
160#define LMTYPE_COLSZ_9 ((0x9) << FShft(LMTYPE_COLSZ))
161#define LMTYPE_COLSZ_10 ((0xa) << FShft(LMTYPE_COLSZ))
162#define LMTYPE_COLSZ_11 ((0xb) << FShft(LMTYPE_COLSZ))
163#define LMTYPE_COLSZ_12 ((0xc) << FShft(LMTYPE_COLSZ))
164
165/* LMTIM - Local Memory (SDRAM) Timing Register */
166#define LMTIM_TRAS Fld(4,16)
167#define Lmtim_Tras(x) ((x) << FShft(LMTIM_TRAS))
168#define LMTIM_TRP Fld(4,12)
169#define Lmtim_Trp(x) ((x) << FShft(LMTIM_TRP))
170#define LMTIM_TRCD Fld(4,8)
171#define Lmtim_Trcd(x) ((x) << FShft(LMTIM_TRCD))
172#define LMTIM_TRC Fld(4,4)
173#define Lmtim_Trc(x) ((x) << FShft(LMTIM_TRC))
174#define LMTIM_TDPL Fld(4,0)
175#define Lmtim_Tdpl(x) ((x) << FShft(LMTIM_TDPL))
176
177/* LMREFRESH - Local Memory (SDRAM) tREF Control Register */
178#define LMREFRESH_TREF Fld(2,0)
179#define Lmrefresh_Tref(x) ((x) << FShft(LMREFRESH_TREF))
180
181/* GSCTRL - Graphics surface control register */
182#define GSCTRL_LUT_EN (1 << 31)
183#define GSCTRL_GPIXFMT Fld(4,27)
184#define GSCTRL_GPIXFMT_INDEXED ((0x0) << FShft(GSCTRL_GPIXFMT))
185#define GSCTRL_GPIXFMT_ARGB4444 ((0x4) << FShft(GSCTRL_GPIXFMT))
186#define GSCTRL_GPIXFMT_ARGB1555 ((0x5) << FShft(GSCTRL_GPIXFMT))
187#define GSCTRL_GPIXFMT_RGB888 ((0x6) << FShft(GSCTRL_GPIXFMT))
188#define GSCTRL_GPIXFMT_RGB565 ((0x7) << FShft(GSCTRL_GPIXFMT))
189#define GSCTRL_GPIXFMT_ARGB8888 ((0x8) << FShft(GSCTRL_GPIXFMT))
190#define GSCTRL_GAMMA_EN (1 << 26)
191
192#define GSCTRL_GSWIDTH Fld(11,11)
193#define Gsctrl_Width(Pixel) /* Display Width [1..2048 pix.] */ \
194 (((Pixel) - 1) << FShft(GSCTRL_GSWIDTH))
195
196#define GSCTRL_GSHEIGHT Fld(11,0)
197#define Gsctrl_Height(Pixel) /* Display Height [1..2048 pix.] */ \
198 (((Pixel) - 1) << FShft(GSCTRL_GSHEIGHT))
199
200/* GBBASE fileds */
201#define GBBASE_GLALPHA Fld(8,24)
202#define Gbbase_Glalpha(x) ((x) << FShft(GBBASE_GLALPHA))
203
204#define GBBASE_COLKEY Fld(24,0)
205#define Gbbase_Colkey(x) ((x) << FShft(GBBASE_COLKEY))
206
207/* GDRCTRL fields */
208#define GDRCTRL_PIXDBL (1 << 31)
209#define GDRCTRL_PIXHLV (1 << 30)
210#define GDRCTRL_LNDBL (1 << 29)
211#define GDRCTRL_LNHLV (1 << 28)
212#define GDRCTRL_COLKEYM Fld(24,0)
213#define Gdrctrl_Colkeym(x) ((x) << FShft(GDRCTRL_COLKEYM))
214
215/* GSCADR graphics stream control address register fields */
216#define GSCADR_STR_EN (1 << 31)
217#define GSCADR_COLKEY_EN (1 << 30)
218#define GSCADR_COLKEYSCR (1 << 29)
219#define GSCADR_BLEND_M Fld(2,27)
220#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M))
221#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M))
222#define GSCADR_BLEND_GLOB ((0x2) << FShft(GSCADR_BLEND_M))
223#define GSCADR_BLEND_PIX ((0x3) << FShft(GSCADR_BLEND_M))
224#define GSCADR_BLEND_POS Fld(2,24)
225#define GSCADR_BLEND_GFX ((0x0) << FShft(GSCADR_BLEND_POS))
226#define GSCADR_BLEND_VID ((0x1) << FShft(GSCADR_BLEND_POS))
227#define GSCADR_BLEND_CUR ((0x2) << FShft(GSCADR_BLEND_POS))
228#define GSCADR_GBASE_ADR Fld(23,0)
229#define Gscadr_Gbase_Adr(x) ((x) << FShft(GSCADR_GBASE_ADR))
230
231/* GSADR graphics stride address register fields */
232#define GSADR_SRCSTRIDE Fld(10,22)
233#define Gsadr_Srcstride(x) ((x) << FShft(GSADR_SRCSTRIDE))
234#define GSADR_XSTART Fld(11,11)
235#define Gsadr_Xstart(x) ((x) << FShft(GSADR_XSTART))
236#define GSADR_YSTART Fld(11,0)
237#define Gsadr_Ystart(y) ((y) << FShft(GSADR_YSTART))
238
239/* GPLUT graphics palette register fields */
240#define GPLUT_LUTADR Fld(8,24)
241#define Gplut_Lutadr(x) ((x) << FShft(GPLUT_LUTADR))
242#define GPLUT_LUTDATA Fld(24,0)
243#define Gplut_Lutdata(x) ((x) << FShft(GPLUT_LUTDATA))
244
245/* HCCTRL - Hardware Cursor Register fields */
246#define HCCTRL_CUR_EN (1 << 31)
247#define HCCTRL_COLKEY_EN (1 << 29)
248#define HCCTRL_COLKEYSRC (1 << 28)
249#define HCCTRL_BLEND_M Fld(2,26)
250#define HCCTRL_BLEND_NONE ((0x0) << FShft(HCCTRL_BLEND_M))
251#define HCCTRL_BLEND_INV ((0x1) << FShft(HCCTRL_BLEND_M))
252#define HCCTRL_BLEND_GLOB ((0x2) << FShft(HCCTRL_BLEND_M))
253#define HCCTRL_BLEND_PIX ((0x3) << FShft(HCCTRL_BLEND_M))
254#define HCCTRL_CPIXFMT Fld(3,23)
255#define HCCTRL_CPIXFMT_RGB332 ((0x3) << FShft(HCCTRL_CPIXFMT))
256#define HCCTRL_CPIXFMT_ARGB4444 ((0x4) << FShft(HCCTRL_CPIXFMT))
257#define HCCTRL_CPIXFMT_ARGB1555 ((0x5) << FShft(HCCTRL_CPIXFMT))
258#define HCCTRL_CBASE_ADR Fld(23,0)
259#define Hcctrl_Cbase_Adr(x) ((x) << FShft(HCCTRL_CBASE_ADR))
260
261/* HCSIZE Hardware Cursor Size Register fields */
262#define HCSIZE_BLEND_POS Fld(2,29)
263#define HCSIZE_BLEND_GFX ((0x0) << FShft(HCSIZE_BLEND_POS))
264#define HCSIZE_BLEND_VID ((0x1) << FShft(HCSIZE_BLEND_POS))
265#define HCSIZE_BLEND_CUR ((0x2) << FShft(HCSIZE_BLEND_POS))
266#define HCSIZE_CWIDTH Fld(3,16)
267#define Hcsize_Cwidth(x) ((x) << FShft(HCSIZE_CWIDTH))
268#define HCSIZE_CHEIGHT Fld(3,0)
269#define Hcsize_Cheight(x) ((x) << FShft(HCSIZE_CHEIGHT))
270
271/* HCPOS Hardware Cursor Position Register fields */
272#define HCPOS_SWITCHSRC (1 << 30)
273#define HCPOS_CURBLINK Fld(6,24)
274#define Hcpos_Curblink(x) ((x) << FShft(HCPOS_CURBLINK))
275#define HCPOS_XSTART Fld(12,12)
276#define Hcpos_Xstart(x) ((x) << FShft(HCPOS_XSTART))
277#define HCPOS_YSTART Fld(12,0)
278#define Hcpos_Ystart(y) ((y) << FShft(HCPOS_YSTART))
279
280/* HCBADR Hardware Cursor Blend Address Register */
281#define HCBADR_GLALPHA Fld(8,24)
282#define Hcbadr_Glalpha(x) ((x) << FShft(HCBADR_GLALPHA))
283#define HCBADR_COLKEY Fld(24,0)
284#define Hcbadr_Colkey(x) ((x) << FShft(HCBADR_COLKEY))
285
286/* HCCKMSK - Hardware Cursor Color Key Mask Register */
287#define HCCKMSK_COLKEY_M Fld(24,0)
288#define Hcckmsk_Colkey_M(x) ((x) << FShft(HCCKMSK_COLKEY_M))
289
290/* DSCTRL - Display sync control register */
291#define DSCTRL_SYNCGEN_EN (1 << 31)
292#define DSCTRL_DPL_RST (1 << 29)
293#define DSCTRL_PWRDN_M (1 << 28)
294#define DSCTRL_UPDSYNCCNT (1 << 26)
295#define DSCTRL_UPDINTCNT (1 << 25)
296#define DSCTRL_UPDCNT (1 << 24)
297#define DSCTRL_UPDWAIT Fld(4,16)
298#define Dsctrl_Updwait(x) ((x) << FShft(DSCTRL_UPDWAIT))
299#define DSCTRL_CLKPOL (1 << 11)
300#define DSCTRL_CSYNC_EN (1 << 10)
301#define DSCTRL_VS_SLAVE (1 << 7)
302#define DSCTRL_HS_SLAVE (1 << 6)
303#define DSCTRL_BLNK_POL (1 << 5)
304#define DSCTRL_BLNK_DIS (1 << 4)
305#define DSCTRL_VS_POL (1 << 3)
306#define DSCTRL_VS_DIS (1 << 2)
307#define DSCTRL_HS_POL (1 << 1)
308#define DSCTRL_HS_DIS (1 << 0)
309
310/* DHT01 - Display horizontal timing register 01 */
311#define DHT01_HBPS Fld(12,16)
312#define Dht01_Hbps(x) ((x) << FShft(DHT01_HBPS))
313#define DHT01_HT Fld(12,0)
314#define Dht01_Ht(x) ((x) << FShft(DHT01_HT))
315
316/* DHT02 - Display horizontal timing register 02 */
317#define DHT02_HAS Fld(12,16)
318#define Dht02_Has(x) ((x) << FShft(DHT02_HAS))
319#define DHT02_HLBS Fld(12,0)
320#define Dht02_Hlbs(x) ((x) << FShft(DHT02_HLBS))
321
322/* DHT03 - Display horizontal timing register 03 */
323#define DHT03_HFPS Fld(12,16)
324#define Dht03_Hfps(x) ((x) << FShft(DHT03_HFPS))
325#define DHT03_HRBS Fld(12,0)
326#define Dht03_Hrbs(x) ((x) << FShft(DHT03_HRBS))
327
328/* DVT01 - Display vertical timing register 01 */
329#define DVT01_VBPS Fld(12,16)
330#define Dvt01_Vbps(x) ((x) << FShft(DVT01_VBPS))
331#define DVT01_VT Fld(12,0)
332#define Dvt01_Vt(x) ((x) << FShft(DVT01_VT))
333
334/* DVT02 - Display vertical timing register 02 */
335#define DVT02_VAS Fld(12,16)
336#define Dvt02_Vas(x) ((x) << FShft(DVT02_VAS))
337#define DVT02_VTBS Fld(12,0)
338#define Dvt02_Vtbs(x) ((x) << FShft(DVT02_VTBS))
339
340/* DVT03 - Display vertical timing register 03 */
341#define DVT03_VFPS Fld(12,16)
342#define Dvt03_Vfps(x) ((x) << FShft(DVT03_VFPS))
343#define DVT03_VBBS Fld(12,0)
344#define Dvt03_Vbbs(x) ((x) << FShft(DVT03_VBBS))
345
346/* DVECTRL - display vertical event control register */
347#define DVECTRL_VEVENT Fld(12,16)
348#define Dvectrl_Vevent(x) ((x) << FShft(DVECTRL_VEVENT))
349#define DVECTRL_VFETCH Fld(12,0)
350#define Dvectrl_Vfetch(x) ((x) << FShft(DVECTRL_VFETCH))
351
352/* DHDET - display horizontal DE timing register */
353#define DHDET_HDES Fld(12,16)
354#define Dhdet_Hdes(x) ((x) << FShft(DHDET_HDES))
355#define DHDET_HDEF Fld(12,0)
356#define Dhdet_Hdef(x) ((x) << FShft(DHDET_HDEF))
357
358/* DVDET - display vertical DE timing register */
359#define DVDET_VDES Fld(12,16)
360#define Dvdet_Vdes(x) ((x) << FShft(DVDET_VDES))
361#define DVDET_VDEF Fld(12,0)
362#define Dvdet_Vdef(x) ((x) << FShft(DVDET_VDEF))
363
364/* DODMSK - display output data mask register */
365#define DODMSK_MASK_LVL (1 << 31)
366#define DODMSK_BLNK_LVL (1 << 30)
367#define DODMSK_MASK_B Fld(8,16)
368#define Dodmsk_Mask_B(x) ((x) << FShft(DODMSK_MASK_B))
369#define DODMSK_MASK_G Fld(8,8)
370#define Dodmsk_Mask_G(x) ((x) << FShft(DODMSK_MASK_G))
371#define DODMSK_MASK_R Fld(8,0)
372#define Dodmsk_Mask_R(x) ((x) << FShft(DODMSK_MASK_R))
373
374/* DBCOL - display border color control register */
375#define DBCOL_BORDCOL Fld(24,0)
376#define Dbcol_Bordcol(x) ((x) << FShft(DBCOL_BORDCOL))
377
378/* DVLNUM - display vertical line number register */
379#define DVLNUM_VLINE Fld(12,0)
380#define Dvlnum_Vline(x) ((x) << FShft(DVLNUM_VLINE))
381
382/* DMCTRL - Display Memory Control Register */
383#define DMCTRL_MEM_REF Fld(2,30)
384#define DMCTRL_MEM_REF_ACT ((0x0) << FShft(DMCTRL_MEM_REF))
385#define DMCTRL_MEM_REF_HB ((0x1) << FShft(DMCTRL_MEM_REF))
386#define DMCTRL_MEM_REF_VB ((0x2) << FShft(DMCTRL_MEM_REF))
387#define DMCTRL_MEM_REF_BOTH ((0x3) << FShft(DMCTRL_MEM_REF))
388#define DMCTRL_UV_THRHLD Fld(6,24)
389#define Dmctrl_Uv_Thrhld(x) ((x) << FShft(DMCTRL_UV_THRHLD))
390#define DMCTRL_V_THRHLD Fld(7,16)
391#define Dmctrl_V_Thrhld(x) ((x) << FShft(DMCTRL_V_THRHLD))
392#define DMCTRL_D_THRHLD Fld(7,8)
393#define Dmctrl_D_Thrhld(x) ((x) << FShft(DMCTRL_D_THRHLD))
394#define DMCTRL_BURSTLEN Fld(6,0)
395#define Dmctrl_Burstlen(x) ((x) << FShft(DMCTRL_BURSTLEN))
396
397
398/* DLSTS - display load status register */
399#define DLSTS_RLD_ADONE (1 << 23)
400/* #define DLSTS_RLD_ADOUT Fld(23,0) */
401
402/* DLLCTRL - display list load control register */
403#define DLLCTRL_RLD_ADRLN Fld(8,24)
404#define Dllctrl_Rld_Adrln(x) ((x) << FShft(DLLCTRL_RLD_ADRLN))
405
406/* SPOCTRL - Scale Pitch/Order Control Register */
407#define SPOCTRL_H_SC_BP (1 << 31)
408#define SPOCTRL_V_SC_BP (1 << 30)
409#define SPOCTRL_HV_SC_OR (1 << 29)
410#define SPOCTRL_VS_UR_C (1 << 27)
411#define SPOCTRL_VORDER Fld(2,16)
412#define SPOCTRL_VORDER_1TAP ((0x0) << FShft(SPOCTRL_VORDER))
413#define SPOCTRL_VORDER_2TAP ((0x1) << FShft(SPOCTRL_VORDER))
414#define SPOCTRL_VORDER_4TAP ((0x3) << FShft(SPOCTRL_VORDER))
415#define SPOCTRL_VPITCH Fld(16,0)
416#define Spoctrl_Vpitch(x) ((x) << FShft(SPOCTRL_VPITCH))
417
418#endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
new file mode 100644
index 000000000000..ad20be07666b
--- /dev/null
+++ b/drivers/video/mbx/regs.h
@@ -0,0 +1,195 @@
1#ifndef __REGS_2700G_
2#define __REGS_2700G_
3
4/* extern unsigned long virt_base_2700; */
5/* #define __REG_2700G(x) (*(volatile unsigned long*)((x)+virt_base_2700)) */
6#define __REG_2700G(x) ((x)+virt_base_2700)
7
8/* System Configuration Registers (0x0000_0000 0x0000_0010) */
9#define SYSCFG __REG_2700G(0x00000000)
10#define PFBASE __REG_2700G(0x00000004)
11#define PFCEIL __REG_2700G(0x00000008)
12#define POLLFLAG __REG_2700G(0x0000000c)
13#define SYSRST __REG_2700G(0x00000010)
14
15/* Interrupt Control Registers (0x0000_0014 0x0000_002F) */
16#define NINTPW __REG_2700G(0x00000014)
17#define MINTENABLE __REG_2700G(0x00000018)
18#define MINTSTAT __REG_2700G(0x0000001c)
19#define SINTENABLE __REG_2700G(0x00000020)
20#define SINTSTAT __REG_2700G(0x00000024)
21#define SINTCLR __REG_2700G(0x00000028)
22
23/* Clock Control Registers (0x0000_002C 0x0000_005F) */
24#define SYSCLKSRC __REG_2700G(0x0000002c)
25#define PIXCLKSRC __REG_2700G(0x00000030)
26#define CLKSLEEP __REG_2700G(0x00000034)
27#define COREPLL __REG_2700G(0x00000038)
28#define DISPPLL __REG_2700G(0x0000003c)
29#define PLLSTAT __REG_2700G(0x00000040)
30#define VOVRCLK __REG_2700G(0x00000044)
31#define PIXCLK __REG_2700G(0x00000048)
32#define MEMCLK __REG_2700G(0x0000004c)
33#define M24CLK __REG_2700G(0x00000054)
34#define MBXCLK __REG_2700G(0x00000054)
35#define SDCLK __REG_2700G(0x00000058)
36#define PIXCLKDIV __REG_2700G(0x0000005c)
37
38/* LCD Port Control Register (0x0000_0060 0x0000_006F) */
39#define LCD_CONFIG __REG_2700G(0x00000060)
40
41/* On-Die Frame Buffer Registers (0x0000_0064 0x0000_006B) */
42#define ODFBPWR __REG_2700G(0x00000064)
43#define ODFBSTAT __REG_2700G(0x00000068)
44
45/* GPIO Registers (0x0000_006C 0x0000_007F) */
46#define GPIOCGF __REG_2700G(0x0000006c)
47#define GPIOHI __REG_2700G(0x00000070)
48#define GPIOLO __REG_2700G(0x00000074)
49#define GPIOSTAT __REG_2700G(0x00000078)
50
51/* Pulse Width Modulator (PWM) Registers (0x0000_0200 0x0000_02FF) */
52#define PWMRST __REG_2700G(0x00000200)
53#define PWMCFG __REG_2700G(0x00000204)
54#define PWM0DIV __REG_2700G(0x00000210)
55#define PWM0DUTY __REG_2700G(0x00000214)
56#define PWM0PER __REG_2700G(0x00000218)
57#define PWM1DIV __REG_2700G(0x00000220)
58#define PWM1DUTY __REG_2700G(0x00000224)
59#define PWM1PER __REG_2700G(0x00000228)
60
61/* Identification (ID) Registers (0x0000_0300 0x0000_0FFF) */
62#define ID __REG_2700G(0x00000FF0)
63
64/* Local Memory (SDRAM) Interface Registers (0x0000_1000 0x0000_1FFF) */
65#define LMRST __REG_2700G(0x00001000)
66#define LMCFG __REG_2700G(0x00001004)
67#define LMPWR __REG_2700G(0x00001008)
68#define LMPWRSTAT __REG_2700G(0x0000100c)
69#define LMCEMR __REG_2700G(0x00001010)
70#define LMTYPE __REG_2700G(0x00001014)
71#define LMTIM __REG_2700G(0x00001018)
72#define LMREFRESH __REG_2700G(0x0000101c)
73#define LMPROTMIN __REG_2700G(0x00001020)
74#define LMPROTMAX __REG_2700G(0x00001024)
75#define LMPROTCFG __REG_2700G(0x00001028)
76#define LMPROTERR __REG_2700G(0x0000102c)
77
78/* Plane Controller Registers (0x0000_2000 0x0000_2FFF) */
79#define GSCTRL __REG_2700G(0x00002000)
80#define VSCTRL __REG_2700G(0x00002004)
81#define GBBASE __REG_2700G(0x00002020)
82#define VBBASE __REG_2700G(0x00002024)
83#define GDRCTRL __REG_2700G(0x00002040)
84#define VCMSK __REG_2700G(0x00002044)
85#define GSCADR __REG_2700G(0x00002060)
86#define VSCADR __REG_2700G(0x00002064)
87#define VUBASE __REG_2700G(0x00002084)
88#define VVBASE __REG_2700G(0x000020a4)
89#define GSADR __REG_2700G(0x000020c0)
90#define VSADR __REG_2700G(0x000020c4)
91#define HCCTRL __REG_2700G(0x00002100)
92#define HCSIZE __REG_2700G(0x00002110)
93#define HCPOS __REG_2700G(0x00002120)
94#define HCBADR __REG_2700G(0x00002130)
95#define HCCKMSK __REG_2700G(0x00002140)
96#define GPLUT __REG_2700G(0x00002150)
97#define DSCTRL __REG_2700G(0x00002154)
98#define DHT01 __REG_2700G(0x00002158)
99#define DHT02 __REG_2700G(0x0000215c)
100#define DHT03 __REG_2700G(0x00002160)
101#define DVT01 __REG_2700G(0x00002164)
102#define DVT02 __REG_2700G(0x00002168)
103#define DVT03 __REG_2700G(0x0000216c)
104#define DBCOL __REG_2700G(0x00002170)
105#define BGCOLOR __REG_2700G(0x00002174)
106#define DINTRS __REG_2700G(0x00002178)
107#define DINTRE __REG_2700G(0x0000217c)
108#define DINTRCNT __REG_2700G(0x00002180)
109#define DSIG __REG_2700G(0x00002184)
110#define DMCTRL __REG_2700G(0x00002188)
111#define CLIPCTRL __REG_2700G(0x0000218c)
112#define SPOCTRL __REG_2700G(0x00002190)
113#define SVCTRL __REG_2700G(0x00002194)
114
115/* 0x0000_2198 */
116/* 0x0000_21A8 VSCOEFF[0:4] Video Scalar Vertical Coefficient [0:4] 4.14.5 */
117#define VSCOEFF0 __REG_2700G(0x00002198)
118#define VSCOEFF1 __REG_2700G(0x0000219c)
119#define VSCOEFF2 __REG_2700G(0x000021a0)
120#define VSCOEFF3 __REG_2700G(0x000021a4)
121#define VSCOEFF4 __REG_2700G(0x000021a8)
122
123#define SHCTRL __REG_2700G(0x000021b0)
124
125/* 0x0000_21B4 */
126/* 0x0000_21D4 HSCOEFF[0:8] Video Scalar Horizontal Coefficient [0:8] 4.14.7 */
127#define HSCOEFF0 __REG_2700G(0x000021b4)
128#define HSCOEFF1 __REG_2700G(0x000021b8)
129#define HSCOEFF2 __REG_2700G(0x000021bc)
130#define HSCOEFF3 __REG_2700G(0x000021b0)
131#define HSCOEFF4 __REG_2700G(0x000021c4)
132#define HSCOEFF5 __REG_2700G(0x000021c8)
133#define HSCOEFF6 __REG_2700G(0x000021cc)
134#define HSCOEFF7 __REG_2700G(0x000021d0)
135#define HSCOEFF8 __REG_2700G(0x000021d4)
136
137#define SSSIZE __REG_2700G(0x000021D8)
138
139/* 0x0000_2200 */
140/* 0x0000_2240 VIDGAM[0:16] Video Gamma LUT Index [0:16] 4.15.2 */
141#define VIDGAM0 __REG_2700G(0x00002200)
142#define VIDGAM1 __REG_2700G(0x00002204)
143#define VIDGAM2 __REG_2700G(0x00002208)
144#define VIDGAM3 __REG_2700G(0x0000220c)
145#define VIDGAM4 __REG_2700G(0x00002210)
146#define VIDGAM5 __REG_2700G(0x00002214)
147#define VIDGAM6 __REG_2700G(0x00002218)
148#define VIDGAM7 __REG_2700G(0x0000221c)
149#define VIDGAM8 __REG_2700G(0x00002220)
150#define VIDGAM9 __REG_2700G(0x00002224)
151#define VIDGAM10 __REG_2700G(0x00002228)
152#define VIDGAM11 __REG_2700G(0x0000222c)
153#define VIDGAM12 __REG_2700G(0x00002230)
154#define VIDGAM13 __REG_2700G(0x00002234)
155#define VIDGAM14 __REG_2700G(0x00002238)
156#define VIDGAM15 __REG_2700G(0x0000223c)
157#define VIDGAM16 __REG_2700G(0x00002240)
158
159/* 0x0000_2250 */
160/* 0x0000_2290 GFXGAM[0:16] Graphics Gamma LUT Index [0:16] 4.15.3 */
161#define GFXGAM0 __REG_2700G(0x00002250)
162#define GFXGAM1 __REG_2700G(0x00002254)
163#define GFXGAM2 __REG_2700G(0x00002258)
164#define GFXGAM3 __REG_2700G(0x0000225c)
165#define GFXGAM4 __REG_2700G(0x00002260)
166#define GFXGAM5 __REG_2700G(0x00002264)
167#define GFXGAM6 __REG_2700G(0x00002268)
168#define GFXGAM7 __REG_2700G(0x0000226c)
169#define GFXGAM8 __REG_2700G(0x00002270)
170#define GFXGAM9 __REG_2700G(0x00002274)
171#define GFXGAM10 __REG_2700G(0x00002278)
172#define GFXGAM11 __REG_2700G(0x0000227c)
173#define GFXGAM12 __REG_2700G(0x00002280)
174#define GFXGAM13 __REG_2700G(0x00002284)
175#define GFXGAM14 __REG_2700G(0x00002288)
176#define GFXGAM15 __REG_2700G(0x0000228c)
177#define GFXGAM16 __REG_2700G(0x00002290)
178
179#define DLSTS __REG_2700G(0x00002300)
180#define DLLCTRL __REG_2700G(0x00002304)
181#define DVLNUM __REG_2700G(0x00002308)
182#define DUCTRL __REG_2700G(0x0000230c)
183#define DVECTRL __REG_2700G(0x00002310)
184#define DHDET __REG_2700G(0x00002314)
185#define DVDET __REG_2700G(0x00002318)
186#define DODMSK __REG_2700G(0x0000231c)
187#define CSC01 __REG_2700G(0x00002330)
188#define CSC02 __REG_2700G(0x00002334)
189#define CSC03 __REG_2700G(0x00002338)
190#define CSC04 __REG_2700G(0x0000233c)
191#define CSC05 __REG_2700G(0x00002340)
192
193#define FB_MEMORY_START __REG_2700G(0x00060000)
194
195#endif /* __REGS_2700G_ */
diff --git a/fs/char_dev.c b/fs/char_dev.c
index a4cbc6706ef0..3483d3cf8087 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -182,6 +182,28 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
182 return 0; 182 return 0;
183} 183}
184 184
185/**
186 * register_chrdev() - Register a major number for character devices.
187 * @major: major device number or 0 for dynamic allocation
188 * @name: name of this range of devices
189 * @fops: file operations associated with this devices
190 *
191 * If @major == 0 this functions will dynamically allocate a major and return
192 * its number.
193 *
194 * If @major > 0 this function will attempt to reserve a device with the given
195 * major number and will return zero on success.
196 *
197 * Returns a -ve errno on failure.
198 *
199 * The name of this device has nothing to do with the name of the device in
200 * /dev. It only helps to keep track of the different owners of devices. If
201 * your module name has only one type of devices it's ok to use e.g. the name
202 * of the module here.
203 *
204 * This function registers a range of 256 minor numbers. The first minor number
205 * is 0.
206 */
185int register_chrdev(unsigned int major, const char *name, 207int register_chrdev(unsigned int major, const char *name,
186 const struct file_operations *fops) 208 const struct file_operations *fops)
187{ 209{
diff --git a/fs/namei.c b/fs/namei.c
index c9750d755aff..e01070d7bf58 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1712,8 +1712,14 @@ do_link:
1712 if (error) 1712 if (error)
1713 goto exit_dput; 1713 goto exit_dput;
1714 error = __do_follow_link(&path, nd); 1714 error = __do_follow_link(&path, nd);
1715 if (error) 1715 if (error) {
1716 /* Does someone understand code flow here? Or it is only
1717 * me so stupid? Anathema to whoever designed this non-sense
1718 * with "intent.open".
1719 */
1720 release_open_intent(nd);
1716 return error; 1721 return error;
1722 }
1717 nd->flags &= ~LOOKUP_PARENT; 1723 nd->flags &= ~LOOKUP_PARENT;
1718 if (nd->last_type == LAST_BIND) 1724 if (nd->last_type == LAST_BIND)
1719 goto ok; 1725 goto ok;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 7495d3e20775..0b615d62a159 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -74,6 +74,7 @@
74#include <linux/times.h> 74#include <linux/times.h>
75#include <linux/cpuset.h> 75#include <linux/cpuset.h>
76#include <linux/rcupdate.h> 76#include <linux/rcupdate.h>
77#include <linux/delayacct.h>
77 78
78#include <asm/uaccess.h> 79#include <asm/uaccess.h>
79#include <asm/pgtable.h> 80#include <asm/pgtable.h>
@@ -411,7 +412,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
411 412
412 res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ 413 res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
413%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ 414%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
414%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n", 415%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
415 task->pid, 416 task->pid,
416 tcomm, 417 tcomm,
417 state, 418 state,
@@ -455,7 +456,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
455 task->exit_signal, 456 task->exit_signal,
456 task_cpu(task), 457 task_cpu(task),
457 task->rt_priority, 458 task->rt_priority,
458 task->policy); 459 task->policy,
460 (unsigned long long)delayacct_blkio_ticks(task));
459 if(mm) 461 if(mm)
460 mmput(mm); 462 mmput(mm);
461 return res; 463 return res;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 243a94af0427..474eae345068 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1339,6 +1339,7 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
1339 inode->i_uid = 0; 1339 inode->i_uid = 0;
1340 inode->i_gid = 0; 1340 inode->i_gid = 0;
1341 } 1341 }
1342 inode->i_mode &= ~(S_ISUID | S_ISGID);
1342 security_task_to_inode(task, inode); 1343 security_task_to_inode(task, inode);
1343 put_task_struct(task); 1344 put_task_struct(task);
1344 return 1; 1345 return 1;
@@ -1389,6 +1390,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1389 inode->i_uid = 0; 1390 inode->i_uid = 0;
1390 inode->i_gid = 0; 1391 inode->i_gid = 0;
1391 } 1392 }
1393 inode->i_mode &= ~(S_ISUID | S_ISGID);
1392 security_task_to_inode(task, inode); 1394 security_task_to_inode(task, inode);
1393 put_task_struct(task); 1395 put_task_struct(task);
1394 return 1; 1396 return 1;
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index 5d8a8cfebc70..c533ec1bcaec 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -492,9 +492,17 @@ static void add_file(struct super_block *sb, char *name,
492 492
493int reiserfs_proc_info_init(struct super_block *sb) 493int reiserfs_proc_info_init(struct super_block *sb)
494{ 494{
495 char b[BDEVNAME_SIZE];
496 char *s;
497
498 /* Some block devices use /'s */
499 strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE);
500 s = strchr(b, '/');
501 if (s)
502 *s = '!';
503
495 spin_lock_init(&__PINFO(sb).lock); 504 spin_lock_init(&__PINFO(sb).lock);
496 REISERFS_SB(sb)->procdir = 505 REISERFS_SB(sb)->procdir = proc_mkdir(b, proc_info_root);
497 proc_mkdir(reiserfs_bdevname(sb), proc_info_root);
498 if (REISERFS_SB(sb)->procdir) { 506 if (REISERFS_SB(sb)->procdir) {
499 REISERFS_SB(sb)->procdir->owner = THIS_MODULE; 507 REISERFS_SB(sb)->procdir->owner = THIS_MODULE;
500 REISERFS_SB(sb)->procdir->data = sb; 508 REISERFS_SB(sb)->procdir->data = sb;
@@ -508,13 +516,22 @@ int reiserfs_proc_info_init(struct super_block *sb)
508 return 0; 516 return 0;
509 } 517 }
510 reiserfs_warning(sb, "reiserfs: cannot create /proc/%s/%s", 518 reiserfs_warning(sb, "reiserfs: cannot create /proc/%s/%s",
511 proc_info_root_name, reiserfs_bdevname(sb)); 519 proc_info_root_name, b);
512 return 1; 520 return 1;
513} 521}
514 522
515int reiserfs_proc_info_done(struct super_block *sb) 523int reiserfs_proc_info_done(struct super_block *sb)
516{ 524{
517 struct proc_dir_entry *de = REISERFS_SB(sb)->procdir; 525 struct proc_dir_entry *de = REISERFS_SB(sb)->procdir;
526 char b[BDEVNAME_SIZE];
527 char *s;
528
529 /* Some block devices use /'s */
530 strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE);
531 s = strchr(b, '/');
532 if (s)
533 *s = '!';
534
518 if (de) { 535 if (de) {
519 remove_proc_entry("journal", de); 536 remove_proc_entry("journal", de);
520 remove_proc_entry("oidmap", de); 537 remove_proc_entry("oidmap", de);
@@ -528,7 +545,7 @@ int reiserfs_proc_info_done(struct super_block *sb)
528 __PINFO(sb).exiting = 1; 545 __PINFO(sb).exiting = 1;
529 spin_unlock(&__PINFO(sb).lock); 546 spin_unlock(&__PINFO(sb).lock);
530 if (proc_info_root) { 547 if (proc_info_root) {
531 remove_proc_entry(reiserfs_bdevname(sb), proc_info_root); 548 remove_proc_entry(b, proc_info_root);
532 REISERFS_SB(sb)->procdir = NULL; 549 REISERFS_SB(sb)->procdir = NULL;
533 } 550 }
534 return 0; 551 return 0;
diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
index 681ff581afa5..384dc08d6f53 100644
--- a/include/asm-alpha/barrier.h
+++ b/include/asm-alpha/barrier.h
@@ -30,7 +30,4 @@ __asm__ __volatile__("mb": : :"memory")
30#define set_mb(var, value) \ 30#define set_mb(var, value) \
31do { var = value; mb(); } while (0) 31do { var = value; mb(); } while (0)
32 32
33#define set_wmb(var, value) \
34do { var = value; wmb(); } while (0)
35
36#endif /* __BARRIER_H */ 33#endif /* __BARRIER_H */
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 6001febfe63b..0947cbf9b69a 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -176,7 +176,6 @@ extern unsigned int user_debug;
176#define wmb() mb() 176#define wmb() mb()
177#define read_barrier_depends() do { } while(0) 177#define read_barrier_depends() do { } while(0)
178#define set_mb(var, value) do { var = value; mb(); } while (0) 178#define set_mb(var, value) do { var = value; mb(); } while (0)
179#define set_wmb(var, value) do { var = value; wmb(); } while (0)
180#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); 179#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
181 180
182/* 181/*
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index d1f69d706198..00ae32aa1dba 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -90,7 +90,6 @@ extern unsigned int user_debug;
90 90
91#define read_barrier_depends() do { } while(0) 91#define read_barrier_depends() do { } while(0)
92#define set_mb(var, value) do { var = value; mb(); } while (0) 92#define set_mb(var, value) do { var = value; mb(); } while (0)
93#define set_wmb(var, value) do { var = value; wmb(); } while (0)
94 93
95/* 94/*
96 * We assume knowledge of how 95 * We assume knowledge of how
diff --git a/include/asm-cris/system.h b/include/asm-cris/system.h
index b1c593b6dbff..b869f6161aaa 100644
--- a/include/asm-cris/system.h
+++ b/include/asm-cris/system.h
@@ -17,7 +17,6 @@ extern struct task_struct *resume(struct task_struct *prev, struct task_struct *
17#define wmb() mb() 17#define wmb() mb()
18#define read_barrier_depends() do { } while(0) 18#define read_barrier_depends() do { } while(0)
19#define set_mb(var, value) do { var = value; mb(); } while (0) 19#define set_mb(var, value) do { var = value; mb(); } while (0)
20#define set_wmb(var, value) do { var = value; wmb(); } while (0)
21 20
22#ifdef CONFIG_SMP 21#ifdef CONFIG_SMP
23#define smp_mb() mb() 22#define smp_mb() mb()
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index 351863dfd06e..1166899317d7 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -179,7 +179,6 @@ do { \
179#define rmb() asm volatile ("membar" : : :"memory") 179#define rmb() asm volatile ("membar" : : :"memory")
180#define wmb() asm volatile ("membar" : : :"memory") 180#define wmb() asm volatile ("membar" : : :"memory")
181#define set_mb(var, value) do { var = value; mb(); } while (0) 181#define set_mb(var, value) do { var = value; mb(); } while (0)
182#define set_wmb(var, value) do { var = value; wmb(); } while (0)
183 182
184#define smp_mb() mb() 183#define smp_mb() mb()
185#define smp_rmb() rmb() 184#define smp_rmb() rmb()
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index d8d0bcecd23f..6b16dda18115 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -1,11 +1,8 @@
1unifdef-y += a.out.h auxvec.h byteorder.h errno.h fcntl.h ioctl.h \ 1unifdef-y += a.out.h auxvec.h byteorder.h errno.h fcntl.h ioctl.h \
2 ioctls.h ipcbuf.h irq.h mman.h msgbuf.h param.h poll.h \ 2 ioctls.h ipcbuf.h mman.h msgbuf.h param.h poll.h \
3 posix_types.h ptrace.h resource.h sembuf.h shmbuf.h shmparam.h \ 3 posix_types.h ptrace.h resource.h sembuf.h shmbuf.h shmparam.h \
4 sigcontext.h siginfo.h signal.h socket.h sockios.h stat.h \ 4 sigcontext.h siginfo.h signal.h socket.h sockios.h stat.h \
5 statfs.h termbits.h termios.h timex.h types.h unistd.h user.h 5 statfs.h termbits.h termios.h timex.h types.h unistd.h user.h
6 6
7# These really shouldn't be exported
8unifdef-y += atomic.h io.h
9
10# These probably shouldn't be exported 7# These probably shouldn't be exported
11unifdef-y += elf.h page.h 8unifdef-y += elf.h page.h
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 134e0929fce5..5084a9d42922 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -84,7 +84,6 @@ asmlinkage void resume(void);
84#define wmb() asm volatile ("" : : :"memory") 84#define wmb() asm volatile ("" : : :"memory")
85#define set_rmb(var, value) do { xchg(&var, value); } while (0) 85#define set_rmb(var, value) do { xchg(&var, value); } while (0)
86#define set_mb(var, value) set_rmb(var, value) 86#define set_mb(var, value) set_rmb(var, value)
87#define set_wmb(var, value) do { var = value; wmb(); } while (0)
88 87
89#ifdef CONFIG_SMP 88#ifdef CONFIG_SMP
90#define smp_mb() mb() 89#define smp_mb() mb()
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 2db168ef949f..49928eb33f8b 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -453,8 +453,6 @@ static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long l
453#define set_mb(var, value) do { var = value; barrier(); } while (0) 453#define set_mb(var, value) do { var = value; barrier(); } while (0)
454#endif 454#endif
455 455
456#define set_wmb(var, value) do { var = value; wmb(); } while (0)
457
458#include <linux/irqflags.h> 456#include <linux/irqflags.h>
459 457
460/* 458/*
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 65db43ce4de6..fc9677bc87ee 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -98,12 +98,11 @@ extern struct ia64_boot_param {
98#endif 98#endif
99 99
100/* 100/*
101 * XXX check on these---I suspect what Linus really wants here is 101 * XXX check on this ---I suspect what Linus really wants here is
102 * acquire vs release semantics but we can't discuss this stuff with 102 * acquire vs release semantics but we can't discuss this stuff with
103 * Linus just yet. Grrr... 103 * Linus just yet. Grrr...
104 */ 104 */
105#define set_mb(var, value) do { (var) = (value); mb(); } while (0) 105#define set_mb(var, value) do { (var) = (value); mb(); } while (0)
106#define set_wmb(var, value) do { (var) = (value); mb(); } while (0)
107 106
108#define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */ 107#define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */
109 108
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index 311cebf44eff..9e618afec6ed 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -336,7 +336,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
336#endif 336#endif
337 337
338#define set_mb(var, value) do { xchg(&var, value); } while (0) 338#define set_mb(var, value) do { xchg(&var, value); } while (0)
339#define set_wmb(var, value) do { var = value; wmb(); } while (0)
340 339
341#define arch_align_stack(x) (x) 340#define arch_align_stack(x) (x)
342 341
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index d6dd8052cd6f..131a0cb0f491 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -80,7 +80,6 @@ static inline int irqs_disabled(void)
80#define wmb() barrier() 80#define wmb() barrier()
81#define read_barrier_depends() do { } while(0) 81#define read_barrier_depends() do { } while(0)
82#define set_mb(var, value) do { xchg(&var, value); } while (0) 82#define set_mb(var, value) do { xchg(&var, value); } while (0)
83#define set_wmb(var, value) do { var = value; wmb(); } while (0)
84 83
85#define smp_mb() barrier() 84#define smp_mb() barrier()
86#define smp_rmb() barrier() 85#define smp_rmb() barrier()
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 2bbe2db00a22..2a814498672d 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -106,7 +106,6 @@ asmlinkage void resume(void);
106#define wmb() asm volatile ("" : : :"memory") 106#define wmb() asm volatile ("" : : :"memory")
107#define set_rmb(var, value) do { xchg(&var, value); } while (0) 107#define set_rmb(var, value) do { xchg(&var, value); } while (0)
108#define set_mb(var, value) set_rmb(var, value) 108#define set_mb(var, value) set_rmb(var, value)
109#define set_wmb(var, value) do { var = value; wmb(); } while (0)
110 109
111#ifdef CONFIG_SMP 110#ifdef CONFIG_SMP
112#define smp_mb() mb() 111#define smp_mb() mb()
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 13c98dde82dc..dcb4701d5728 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -143,9 +143,6 @@
143#define set_mb(var, value) \ 143#define set_mb(var, value) \
144do { var = value; mb(); } while (0) 144do { var = value; mb(); } while (0)
145 145
146#define set_wmb(var, value) \
147do { var = value; wmb(); } while (0)
148
149/* 146/*
150 * switch_to(n) should switch tasks to task nr n, first 147 * switch_to(n) should switch tasks to task nr n, first
151 * checking that n isn't the current task, in which case it does nothing. 148 * checking that n isn't the current task, in which case it does nothing.
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index 5fe2d2329ab5..74f037a39e6f 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -143,8 +143,6 @@ static inline void set_eiem(unsigned long val)
143#define read_barrier_depends() do { } while(0) 143#define read_barrier_depends() do { } while(0)
144 144
145#define set_mb(var, value) do { var = value; mb(); } while (0) 145#define set_mb(var, value) do { var = value; mb(); } while (0)
146#define set_wmb(var, value) do { var = value; wmb(); } while (0)
147
148 146
149#ifndef CONFIG_PA20 147#ifndef CONFIG_PA20
150/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, 148/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index c6569516ba35..7307aa775671 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -39,7 +39,6 @@
39#define read_barrier_depends() do { } while(0) 39#define read_barrier_depends() do { } while(0)
40 40
41#define set_mb(var, value) do { var = value; mb(); } while (0) 41#define set_mb(var, value) do { var = value; mb(); } while (0)
42#define set_wmb(var, value) do { var = value; wmb(); } while (0)
43 42
44#ifdef __KERNEL__ 43#ifdef __KERNEL__
45#ifdef CONFIG_SMP 44#ifdef CONFIG_SMP
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index fb49c0c49ea1..738943584c01 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -33,7 +33,6 @@
33#define read_barrier_depends() do { } while(0) 33#define read_barrier_depends() do { } while(0)
34 34
35#define set_mb(var, value) do { var = value; mb(); } while (0) 35#define set_mb(var, value) do { var = value; mb(); } while (0)
36#define set_wmb(var, value) do { var = value; wmb(); } while (0)
37 36
38#ifdef CONFIG_SMP 37#ifdef CONFIG_SMP
39#define smp_mb() mb() 38#define smp_mb() mb()
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index 9ab186ffde23..36a3a85d611a 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -299,7 +299,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
299 299
300 300
301#define set_mb(var, value) do { var = value; mb(); } while (0) 301#define set_mb(var, value) do { var = value; mb(); } while (0)
302#define set_wmb(var, value) do { var = value; wmb(); } while (0)
303 302
304#ifdef __s390x__ 303#ifdef __s390x__
305 304
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index ce2e60664a86..ad35ad4958f4 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -101,7 +101,6 @@ extern void __xchg_called_with_bad_pointer(void);
101#endif 101#endif
102 102
103#define set_mb(var, value) do { xchg(&var, value); } while (0) 103#define set_mb(var, value) do { xchg(&var, value); } while (0)
104#define set_wmb(var, value) do { var = value; wmb(); } while (0)
105 104
106/* Interrupt Control */ 105/* Interrupt Control */
107static __inline__ void local_irq_enable(void) 106static __inline__ void local_irq_enable(void)
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index 7606f6e1f01e..87ef6f1ad5a4 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -66,7 +66,6 @@ extern void __xchg_called_with_bad_pointer(void);
66 66
67#define set_rmb(var, value) do { xchg(&var, value); } while (0) 67#define set_rmb(var, value) do { xchg(&var, value); } while (0)
68#define set_mb(var, value) set_rmb(var, value) 68#define set_mb(var, value) set_rmb(var, value)
69#define set_wmb(var, value) do { var = value; wmb(); } while (0)
70 69
71/* Interrupt Control */ 70/* Interrupt Control */
72#ifndef HARD_CLI 71#ifndef HARD_CLI
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index cb7dda1e5e91..100c3eaf3c1f 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -199,7 +199,6 @@ static inline unsigned long getipl(void)
199#define wmb() mb() 199#define wmb() mb()
200#define read_barrier_depends() do { } while(0) 200#define read_barrier_depends() do { } while(0)
201#define set_mb(__var, __value) do { __var = __value; mb(); } while(0) 201#define set_mb(__var, __value) do { __var = __value; mb(); } while(0)
202#define set_wmb(__var, __value) set_mb(__var, __value)
203#define smp_mb() __asm__ __volatile__("":::"memory") 202#define smp_mb() __asm__ __volatile__("":::"memory")
204#define smp_rmb() __asm__ __volatile__("":::"memory") 203#define smp_rmb() __asm__ __volatile__("":::"memory")
205#define smp_wmb() __asm__ __volatile__("":::"memory") 204#define smp_wmb() __asm__ __volatile__("":::"memory")
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 4ca68600c670..a8b7432c9a70 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -123,8 +123,6 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
123#define read_barrier_depends() do { } while(0) 123#define read_barrier_depends() do { } while(0)
124#define set_mb(__var, __value) \ 124#define set_mb(__var, __value) \
125 do { __var = __value; membar_storeload_storestore(); } while(0) 125 do { __var = __value; membar_storeload_storestore(); } while(0)
126#define set_wmb(__var, __value) \
127 do { __var = __value; wmb(); } while(0)
128 126
129#ifdef CONFIG_SMP 127#ifdef CONFIG_SMP
130#define smp_mb() mb() 128#define smp_mb() mb()
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index 7091af4b7866..da39916f10b0 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -68,7 +68,6 @@ static inline int irqs_disabled (void)
68#define read_barrier_depends() ((void)0) 68#define read_barrier_depends() ((void)0)
69#define set_rmb(var, value) do { xchg (&var, value); } while (0) 69#define set_rmb(var, value) do { xchg (&var, value); } while (0)
70#define set_mb(var, value) set_rmb (var, value) 70#define set_mb(var, value) set_rmb (var, value)
71#define set_wmb(var, value) do { var = value; wmb (); } while (0)
72 71
73#define smp_mb() mb () 72#define smp_mb() mb ()
74#define smp_rmb() rmb () 73#define smp_rmb() rmb ()
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index f67f2873a922..6bf170bceae1 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -240,7 +240,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
240#endif 240#endif
241#define read_barrier_depends() do {} while(0) 241#define read_barrier_depends() do {} while(0)
242#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) 242#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
243#define set_wmb(var, value) do { var = value; wmb(); } while (0)
244 243
245#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0) 244#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
246 245
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index f986170bd2a1..932bda92a21c 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -99,7 +99,6 @@ static inline void disable_coprocessor(int i)
99#endif 99#endif
100 100
101#define set_mb(var, value) do { var = value; mb(); } while (0) 101#define set_mb(var, value) do { var = value; mb(); } while (0)
102#define set_wmb(var, value) do { var = value; wmb(); } while (0)
103 102
104#if !defined (__ASSEMBLY__) 103#if !defined (__ASSEMBLY__)
105 104
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
new file mode 100644
index 000000000000..7e8b6011b8f3
--- /dev/null
+++ b/include/linux/delayacct.h
@@ -0,0 +1,119 @@
1/* delayacct.h - per-task delay accounting
2 *
3 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 */
16
17#ifndef _LINUX_DELAYACCT_H
18#define _LINUX_DELAYACCT_H
19
20#include <linux/sched.h>
21#include <linux/taskstats_kern.h>
22
23/*
24 * Per-task flags relevant to delay accounting
25 * maintained privately to avoid exhausting similar flags in sched.h:PF_*
26 * Used to set current->delays->flags
27 */
28#define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */
29
30#ifdef CONFIG_TASK_DELAY_ACCT
31
32extern int delayacct_on; /* Delay accounting turned on/off */
33extern kmem_cache_t *delayacct_cache;
34extern void delayacct_init(void);
35extern void __delayacct_tsk_init(struct task_struct *);
36extern void __delayacct_tsk_exit(struct task_struct *);
37extern void __delayacct_blkio_start(void);
38extern void __delayacct_blkio_end(void);
39extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
40extern __u64 __delayacct_blkio_ticks(struct task_struct *);
41
42static inline void delayacct_set_flag(int flag)
43{
44 if (current->delays)
45 current->delays->flags |= flag;
46}
47
48static inline void delayacct_clear_flag(int flag)
49{
50 if (current->delays)
51 current->delays->flags &= ~flag;
52}
53
54static inline void delayacct_tsk_init(struct task_struct *tsk)
55{
56 /* reinitialize in case parent's non-null pointer was dup'ed*/
57 tsk->delays = NULL;
58 if (unlikely(delayacct_on))
59 __delayacct_tsk_init(tsk);
60}
61
62static inline void delayacct_tsk_exit(struct task_struct *tsk)
63{
64 if (tsk->delays)
65 __delayacct_tsk_exit(tsk);
66}
67
68static inline void delayacct_blkio_start(void)
69{
70 if (current->delays)
71 __delayacct_blkio_start();
72}
73
74static inline void delayacct_blkio_end(void)
75{
76 if (current->delays)
77 __delayacct_blkio_end();
78}
79
80static inline int delayacct_add_tsk(struct taskstats *d,
81 struct task_struct *tsk)
82{
83 if (likely(!delayacct_on))
84 return -EINVAL;
85 if (!tsk->delays)
86 return 0;
87 return __delayacct_add_tsk(d, tsk);
88}
89
90static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
91{
92 if (tsk->delays)
93 return __delayacct_blkio_ticks(tsk);
94 return 0;
95}
96
97#else
98static inline void delayacct_set_flag(int flag)
99{}
100static inline void delayacct_clear_flag(int flag)
101{}
102static inline void delayacct_init(void)
103{}
104static inline void delayacct_tsk_init(struct task_struct *tsk)
105{}
106static inline void delayacct_tsk_exit(struct task_struct *tsk)
107{}
108static inline void delayacct_blkio_start(void)
109{}
110static inline void delayacct_blkio_end(void)
111{}
112static inline int delayacct_add_tsk(struct taskstats *d,
113 struct task_struct *tsk)
114{ return 0; }
115static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
116{ return 0; }
117#endif /* CONFIG_TASK_DELAY_ACCT */
118
119#endif
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 21338bb3441d..9418519a55d1 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -115,6 +115,7 @@
115#define I2C_DRIVERID_BT866 85 /* Conexant bt866 video encoder */ 115#define I2C_DRIVERID_BT866 85 /* Conexant bt866 video encoder */
116#define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ 116#define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */
117#define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ 117#define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */
118#define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */
118 119
119#define I2C_DRIVERID_I2CDEV 900 120#define I2C_DRIVERID_I2CDEV 900
120#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ 121#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index eef0876d8307..383627ad328f 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -23,8 +23,8 @@ struct vlan_collection;
23struct vlan_dev_info; 23struct vlan_dev_info;
24struct hlist_node; 24struct hlist_node;
25 25
26#include <linux/proc_fs.h> /* for proc_dir_entry */
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28 28
29#define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header) 29#define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header)
30 * that VLAN requires. 30 * that VLAN requires.
@@ -185,7 +185,8 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
185 * This allows the VLAN to have a different MAC than the underlying 185 * This allows the VLAN to have a different MAC than the underlying
186 * device, and still route correctly. 186 * device, and still route correctly.
187 */ 187 */
188 if (!memcmp(eth_hdr(skb)->h_dest, skb->dev->dev_addr, ETH_ALEN)) 188 if (!compare_ether_addr(eth_hdr(skb)->h_dest,
189 skb->dev->dev_addr))
189 skb->pkt_type = PACKET_HOST; 190 skb->pkt_type = PACKET_HOST;
190 break; 191 break;
191 }; 192 };
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 7cce5dfa092f..1c65e7a9f186 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -28,7 +28,6 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
28 28
29void kthread_bind(struct task_struct *k, unsigned int cpu); 29void kthread_bind(struct task_struct *k, unsigned int cpu);
30int kthread_stop(struct task_struct *k); 30int kthread_stop(struct task_struct *k);
31int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
32int kthread_should_stop(void); 31int kthread_should_stop(void);
33 32
34#endif /* _LINUX_KTHREAD_H */ 33#endif /* _LINUX_KTHREAD_H */
diff --git a/include/linux/list.h b/include/linux/list.h
index 6b74adf5297f..65a5b5ceda49 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -265,6 +265,17 @@ static inline void list_move_tail(struct list_head *list,
265} 265}
266 266
267/** 267/**
268 * list_is_last - tests whether @list is the last entry in list @head
269 * @list: the entry to test
270 * @head: the head of the list
271 */
272static inline int list_is_last(const struct list_head *list,
273 const struct list_head *head)
274{
275 return list->next == head;
276}
277
278/**
268 * list_empty - tests whether a list is empty 279 * list_empty - tests whether a list is empty
269 * @head: the list to test. 280 * @head: the list to test.
270 */ 281 */
diff --git a/include/linux/module.h b/include/linux/module.h
index d06c74fb8c26..0dfb794c52d3 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -362,10 +362,8 @@ int is_module_address(unsigned long addr);
362 362
363/* Returns module and fills in value, defined and namebuf, or NULL if 363/* Returns module and fills in value, defined and namebuf, or NULL if
364 symnum out of range. */ 364 symnum out of range. */
365struct module *module_get_kallsym(unsigned int symnum, 365struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
366 unsigned long *value, 366 char *type, char *name, size_t namelen);
367 char *type,
368 char namebuf[128]);
369 367
370/* Look for this name: can be of form module:name. */ 368/* Look for this name: can be of form module:name. */
371unsigned long module_kallsyms_lookup_name(const char *name); 369unsigned long module_kallsyms_lookup_name(const char *name);
@@ -535,8 +533,8 @@ static inline const char *module_address_lookup(unsigned long addr,
535 533
536static inline struct module *module_get_kallsym(unsigned int symnum, 534static inline struct module *module_get_kallsym(unsigned int symnum,
537 unsigned long *value, 535 unsigned long *value,
538 char *type, 536 char *type, char *name,
539 char namebuf[128]) 537 size_t namelen)
540{ 538{
541 return NULL; 539 return NULL;
542} 540}
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 58cb3d3d44b4..45511a5918d3 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -11,7 +11,7 @@ struct open_intent {
11 struct file *file; 11 struct file *file;
12}; 12};
13 13
14enum { MAX_NESTED_LINKS = 5 }; 14enum { MAX_NESTED_LINKS = 8 };
15 15
16struct nameidata { 16struct nameidata {
17 struct dentry *dentry; 17 struct dentry *dentry;
diff --git a/include/linux/nsc_gpio.h b/include/linux/nsc_gpio.h
index 135742cfada5..7da0cf3702ee 100644
--- a/include/linux/nsc_gpio.h
+++ b/include/linux/nsc_gpio.h
@@ -25,8 +25,6 @@ struct nsc_gpio_ops {
25 void (*gpio_dump) (struct nsc_gpio_ops *amp, unsigned iminor); 25 void (*gpio_dump) (struct nsc_gpio_ops *amp, unsigned iminor);
26 int (*gpio_get) (unsigned iminor); 26 int (*gpio_get) (unsigned iminor);
27 void (*gpio_set) (unsigned iminor, int state); 27 void (*gpio_set) (unsigned iminor, int state);
28 void (*gpio_set_high)(unsigned iminor);
29 void (*gpio_set_low) (unsigned iminor);
30 void (*gpio_change) (unsigned iminor); 28 void (*gpio_change) (unsigned iminor);
31 int (*gpio_current) (unsigned iminor); 29 int (*gpio_current) (unsigned iminor);
32 struct device* dev; /* for dev_dbg() support, set in init */ 30 struct device* dev; /* for dev_dbg() support, set in init */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1c876e27ff93..6afa72e080cb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -463,6 +463,10 @@ struct signal_struct {
463#ifdef CONFIG_BSD_PROCESS_ACCT 463#ifdef CONFIG_BSD_PROCESS_ACCT
464 struct pacct_struct pacct; /* per-process accounting information */ 464 struct pacct_struct pacct; /* per-process accounting information */
465#endif 465#endif
466#ifdef CONFIG_TASKSTATS
467 spinlock_t stats_lock;
468 struct taskstats *stats;
469#endif
466}; 470};
467 471
468/* Context switch must be unlocked if interrupts are to be enabled */ 472/* Context switch must be unlocked if interrupts are to be enabled */
@@ -537,7 +541,7 @@ extern struct user_struct root_user;
537struct backing_dev_info; 541struct backing_dev_info;
538struct reclaim_state; 542struct reclaim_state;
539 543
540#ifdef CONFIG_SCHEDSTATS 544#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
541struct sched_info { 545struct sched_info {
542 /* cumulative counters */ 546 /* cumulative counters */
543 unsigned long cpu_time, /* time spent on the cpu */ 547 unsigned long cpu_time, /* time spent on the cpu */
@@ -548,9 +552,53 @@ struct sched_info {
548 unsigned long last_arrival, /* when we last ran on a cpu */ 552 unsigned long last_arrival, /* when we last ran on a cpu */
549 last_queued; /* when we were last queued to run */ 553 last_queued; /* when we were last queued to run */
550}; 554};
555#endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
551 556
557#ifdef CONFIG_SCHEDSTATS
552extern struct file_operations proc_schedstat_operations; 558extern struct file_operations proc_schedstat_operations;
559#endif /* CONFIG_SCHEDSTATS */
560
561#ifdef CONFIG_TASK_DELAY_ACCT
562struct task_delay_info {
563 spinlock_t lock;
564 unsigned int flags; /* Private per-task flags */
565
566 /* For each stat XXX, add following, aligned appropriately
567 *
568 * struct timespec XXX_start, XXX_end;
569 * u64 XXX_delay;
570 * u32 XXX_count;
571 *
572 * Atomicity of updates to XXX_delay, XXX_count protected by
573 * single lock above (split into XXX_lock if contention is an issue).
574 */
575
576 /*
577 * XXX_count is incremented on every XXX operation, the delay
578 * associated with the operation is added to XXX_delay.
579 * XXX_delay contains the accumulated delay time in nanoseconds.
580 */
581 struct timespec blkio_start, blkio_end; /* Shared by blkio, swapin */
582 u64 blkio_delay; /* wait for sync block io completion */
583 u64 swapin_delay; /* wait for swapin block io completion */
584 u32 blkio_count; /* total count of the number of sync block */
585 /* io operations performed */
586 u32 swapin_count; /* total count of the number of swapin block */
587 /* io operations performed */
588};
589#endif /* CONFIG_TASK_DELAY_ACCT */
590
591static inline int sched_info_on(void)
592{
593#ifdef CONFIG_SCHEDSTATS
594 return 1;
595#elif defined(CONFIG_TASK_DELAY_ACCT)
596 extern int delayacct_on;
597 return delayacct_on;
598#else
599 return 0;
553#endif 600#endif
601}
554 602
555enum idle_type 603enum idle_type
556{ 604{
@@ -747,7 +795,7 @@ struct task_struct {
747 cpumask_t cpus_allowed; 795 cpumask_t cpus_allowed;
748 unsigned int time_slice, first_time_slice; 796 unsigned int time_slice, first_time_slice;
749 797
750#ifdef CONFIG_SCHEDSTATS 798#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
751 struct sched_info sched_info; 799 struct sched_info sched_info;
752#endif 800#endif
753 801
@@ -945,6 +993,10 @@ struct task_struct {
945 * cache last used pipe for splice 993 * cache last used pipe for splice
946 */ 994 */
947 struct pipe_inode_info *splice_pipe; 995 struct pipe_inode_info *splice_pipe;
996#ifdef CONFIG_TASK_DELAY_ACCT
997 spinlock_t delays_lock;
998 struct task_delay_info *delays;
999#endif
948}; 1000};
949 1001
950static inline pid_t process_group(struct task_struct *tsk) 1002static inline pid_t process_group(struct task_struct *tsk)
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
new file mode 100644
index 000000000000..f1cb6cddd19d
--- /dev/null
+++ b/include/linux/taskstats.h
@@ -0,0 +1,137 @@
1/* taskstats.h - exporting per-task statistics
2 *
3 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4 * (C) Balbir Singh, IBM Corp. 2006
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2.1 of the GNU Lesser General Public License
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 */
14
15#ifndef _LINUX_TASKSTATS_H
16#define _LINUX_TASKSTATS_H
17
18/* Format for per-task data returned to userland when
19 * - a task exits
20 * - listener requests stats for a task
21 *
22 * The struct is versioned. Newer versions should only add fields to
23 * the bottom of the struct to maintain backward compatibility.
24 *
25 *
26 * To add new fields
27 * a) bump up TASKSTATS_VERSION
28 * b) add comment indicating new version number at end of struct
29 * c) add new fields after version comment; maintain 64-bit alignment
30 */
31
32#define TASKSTATS_VERSION 1
33
34struct taskstats {
35
36 /* Version 1 */
37 __u16 version;
38 __u16 padding[3]; /* Userspace should not interpret the padding
39 * field which can be replaced by useful
40 * fields if struct taskstats is extended.
41 */
42
43 /* Delay accounting fields start
44 *
45 * All values, until comment "Delay accounting fields end" are
46 * available only if delay accounting is enabled, even though the last
47 * few fields are not delays
48 *
49 * xxx_count is the number of delay values recorded
50 * xxx_delay_total is the corresponding cumulative delay in nanoseconds
51 *
52 * xxx_delay_total wraps around to zero on overflow
53 * xxx_count incremented regardless of overflow
54 */
55
56 /* Delay waiting for cpu, while runnable
57 * count, delay_total NOT updated atomically
58 */
59 __u64 cpu_count;
60 __u64 cpu_delay_total;
61
62 /* Following four fields atomically updated using task->delays->lock */
63
64 /* Delay waiting for synchronous block I/O to complete
65 * does not account for delays in I/O submission
66 */
67 __u64 blkio_count;
68 __u64 blkio_delay_total;
69
70 /* Delay waiting for page fault I/O (swap in only) */
71 __u64 swapin_count;
72 __u64 swapin_delay_total;
73
74 /* cpu "wall-clock" running time
75 * On some architectures, value will adjust for cpu time stolen
76 * from the kernel in involuntary waits due to virtualization.
77 * Value is cumulative, in nanoseconds, without a corresponding count
78 * and wraps around to zero silently on overflow
79 */
80 __u64 cpu_run_real_total;
81
82 /* cpu "virtual" running time
83 * Uses time intervals seen by the kernel i.e. no adjustment
84 * for kernel's involuntary waits due to virtualization.
85 * Value is cumulative, in nanoseconds, without a corresponding count
86 * and wraps around to zero silently on overflow
87 */
88 __u64 cpu_run_virtual_total;
89 /* Delay accounting fields end */
90 /* version 1 ends here */
91};
92
93
94/*
95 * Commands sent from userspace
96 * Not versioned. New commands should only be inserted at the enum's end
97 * prior to __TASKSTATS_CMD_MAX
98 */
99
100enum {
101 TASKSTATS_CMD_UNSPEC = 0, /* Reserved */
102 TASKSTATS_CMD_GET, /* user->kernel request/get-response */
103 TASKSTATS_CMD_NEW, /* kernel->user event */
104 __TASKSTATS_CMD_MAX,
105};
106
107#define TASKSTATS_CMD_MAX (__TASKSTATS_CMD_MAX - 1)
108
109enum {
110 TASKSTATS_TYPE_UNSPEC = 0, /* Reserved */
111 TASKSTATS_TYPE_PID, /* Process id */
112 TASKSTATS_TYPE_TGID, /* Thread group id */
113 TASKSTATS_TYPE_STATS, /* taskstats structure */
114 TASKSTATS_TYPE_AGGR_PID, /* contains pid + stats */
115 TASKSTATS_TYPE_AGGR_TGID, /* contains tgid + stats */
116 __TASKSTATS_TYPE_MAX,
117};
118
119#define TASKSTATS_TYPE_MAX (__TASKSTATS_TYPE_MAX - 1)
120
121enum {
122 TASKSTATS_CMD_ATTR_UNSPEC = 0,
123 TASKSTATS_CMD_ATTR_PID,
124 TASKSTATS_CMD_ATTR_TGID,
125 TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
126 TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
127 __TASKSTATS_CMD_ATTR_MAX,
128};
129
130#define TASKSTATS_CMD_ATTR_MAX (__TASKSTATS_CMD_ATTR_MAX - 1)
131
132/* NETLINK_GENERIC related info */
133
134#define TASKSTATS_GENL_NAME "TASKSTATS"
135#define TASKSTATS_GENL_VERSION 0x1
136
137#endif /* _LINUX_TASKSTATS_H */
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
new file mode 100644
index 000000000000..16894b7edcc8
--- /dev/null
+++ b/include/linux/taskstats_kern.h
@@ -0,0 +1,89 @@
1/* taskstats_kern.h - kernel header for per-task statistics interface
2 *
3 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4 * (C) Balbir Singh, IBM Corp. 2006
5 */
6
7#ifndef _LINUX_TASKSTATS_KERN_H
8#define _LINUX_TASKSTATS_KERN_H
9
10#include <linux/taskstats.h>
11#include <linux/sched.h>
12#include <net/genetlink.h>
13
14#ifdef CONFIG_TASKSTATS
15extern kmem_cache_t *taskstats_cache;
16extern struct mutex taskstats_exit_mutex;
17
18static inline void taskstats_exit_free(struct taskstats *tidstats)
19{
20 if (tidstats)
21 kmem_cache_free(taskstats_cache, tidstats);
22}
23
24static inline void taskstats_tgid_init(struct signal_struct *sig)
25{
26 spin_lock_init(&sig->stats_lock);
27 sig->stats = NULL;
28}
29
30static inline void taskstats_tgid_alloc(struct signal_struct *sig)
31{
32 struct taskstats *stats;
33 unsigned long flags;
34
35 stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
36 if (!stats)
37 return;
38
39 spin_lock_irqsave(&sig->stats_lock, flags);
40 if (!sig->stats) {
41 sig->stats = stats;
42 stats = NULL;
43 }
44 spin_unlock_irqrestore(&sig->stats_lock, flags);
45
46 if (stats)
47 kmem_cache_free(taskstats_cache, stats);
48}
49
50static inline void taskstats_tgid_free(struct signal_struct *sig)
51{
52 struct taskstats *stats = NULL;
53 unsigned long flags;
54
55 spin_lock_irqsave(&sig->stats_lock, flags);
56 if (sig->stats) {
57 stats = sig->stats;
58 sig->stats = NULL;
59 }
60 spin_unlock_irqrestore(&sig->stats_lock, flags);
61 if (stats)
62 kmem_cache_free(taskstats_cache, stats);
63}
64
65extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
66extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
67extern void taskstats_init_early(void);
68extern void taskstats_tgid_alloc(struct signal_struct *);
69#else
70static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
71{}
72static inline void taskstats_exit_free(struct taskstats *ptidstats)
73{}
74static inline void taskstats_exit_send(struct task_struct *tsk,
75 struct taskstats *tidstats,
76 int group_dead, unsigned int cpu)
77{}
78static inline void taskstats_tgid_init(struct signal_struct *sig)
79{}
80static inline void taskstats_tgid_alloc(struct signal_struct *sig)
81{}
82static inline void taskstats_tgid_free(struct signal_struct *sig)
83{}
84static inline void taskstats_init_early(void)
85{}
86#endif /* CONFIG_TASKSTATS */
87
88#endif
89
diff --git a/include/linux/time.h b/include/linux/time.h
index c05f8bb9a323..a5b739967b74 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -71,6 +71,18 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
71extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec); 71extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
72 72
73/* 73/*
74 * sub = lhs - rhs, in normalized form
75 */
76static inline struct timespec timespec_sub(struct timespec lhs,
77 struct timespec rhs)
78{
79 struct timespec ts_delta;
80 set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec,
81 lhs.tv_nsec - rhs.tv_nsec);
82 return ts_delta;
83}
84
85/*
74 * Returns true if the timespec is norm, false if denorm: 86 * Returns true if the timespec is norm, false if denorm:
75 */ 87 */
76#define timespec_valid(ts) \ 88#define timespec_valid(ts) \
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index f6024ab4eff0..71b6363caaaf 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -11,6 +11,7 @@ struct vm_area_struct;
11#define VM_ALLOC 0x00000002 /* vmalloc() */ 11#define VM_ALLOC 0x00000002 /* vmalloc() */
12#define VM_MAP 0x00000004 /* vmap()ed pages */ 12#define VM_MAP 0x00000004 /* vmap()ed pages */
13#define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ 13#define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
14#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
14/* bits [20..32] reserved for arch specific ioremap internals */ 15/* bits [20..32] reserved for arch specific ioremap internals */
15 16
16/* 17/*
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 805de50df00d..8c2287264266 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -150,4 +150,24 @@ static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
150 return nlmsg_unicast(genl_sock, skb, pid); 150 return nlmsg_unicast(genl_sock, skb, pid);
151} 151}
152 152
153/**
154 * gennlmsg_data - head of message payload
155 * @gnlh: genetlink messsage header
156 */
157static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
158{
159 return ((unsigned char *) gnlh + GENL_HDRLEN);
160}
161
162/**
163 * genlmsg_len - length of message payload
164 * @gnlh: genetlink message header
165 */
166static inline int genlmsg_len(const struct genlmsghdr *gnlh)
167{
168 struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
169 NLMSG_HDRLEN);
170 return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
171}
172
153#endif /* __NET_GENERIC_NETLINK_H */ 173#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index fcb5ba87dcc5..0ff67398928d 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -89,9 +89,10 @@ static inline void ib_addr_set_pkey(struct rdma_dev_addr *dev_addr, u16 pkey)
89 dev_addr->broadcast[9] = (unsigned char) pkey; 89 dev_addr->broadcast[9] = (unsigned char) pkey;
90} 90}
91 91
92static inline union ib_gid *ib_addr_get_sgid(struct rdma_dev_addr *dev_addr) 92static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr,
93 union ib_gid *gid)
93{ 94{
94 return (union ib_gid *) (dev_addr->src_dev_addr + 4); 95 memcpy(gid, dev_addr->src_dev_addr + 4, sizeof *gid);
95} 96}
96 97
97static inline void ib_addr_set_sgid(struct rdma_dev_addr *dev_addr, 98static inline void ib_addr_set_sgid(struct rdma_dev_addr *dev_addr,
@@ -100,9 +101,10 @@ static inline void ib_addr_set_sgid(struct rdma_dev_addr *dev_addr,
100 memcpy(dev_addr->src_dev_addr + 4, gid, sizeof *gid); 101 memcpy(dev_addr->src_dev_addr + 4, gid, sizeof *gid);
101} 102}
102 103
103static inline union ib_gid *ib_addr_get_dgid(struct rdma_dev_addr *dev_addr) 104static inline void ib_addr_get_dgid(struct rdma_dev_addr *dev_addr,
105 union ib_gid *gid)
104{ 106{
105 return (union ib_gid *) (dev_addr->dst_dev_addr + 4); 107 memcpy(gid, dev_addr->dst_dev_addr + 4, sizeof *gid);
106} 108}
107 109
108static inline void ib_addr_set_dgid(struct rdma_dev_addr *dev_addr, 110static inline void ib_addr_set_dgid(struct rdma_dev_addr *dev_addr,
diff --git a/include/rdma/ib_fmr_pool.h b/include/rdma/ib_fmr_pool.h
index 4ace54cd0cce..00dadbf94e1d 100644
--- a/include/rdma/ib_fmr_pool.h
+++ b/include/rdma/ib_fmr_pool.h
@@ -88,7 +88,7 @@ int ib_flush_fmr_pool(struct ib_fmr_pool *pool);
88struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle, 88struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
89 u64 *page_list, 89 u64 *page_list,
90 int list_len, 90 int list_len,
91 u64 *io_virtual_address); 91 u64 io_virtual_address);
92 92
93int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr); 93int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr);
94 94
diff --git a/include/video/mbxfb.h b/include/video/mbxfb.h
new file mode 100644
index 000000000000..3bde0f5cd55c
--- /dev/null
+++ b/include/video/mbxfb.h
@@ -0,0 +1,28 @@
1#ifndef __MBX_FB_H
2#define __MBX_FB_H
3
4struct mbxfb_val {
5 unsigned int defval;
6 unsigned int min;
7 unsigned int max;
8};
9
10struct fb_info;
11
12struct mbxfb_platform_data {
13 /* Screen info */
14 struct mbxfb_val xres;
15 struct mbxfb_val yres;
16 struct mbxfb_val bpp;
17
18 /* Memory info */
19 unsigned long memsize; /* if 0 use ODFB? */
20 unsigned long timings1;
21 unsigned long timings2;
22 unsigned long timings3;
23
24 int (*probe)(struct fb_info *fb);
25 int (*remove)(struct fb_info *fb);
26};
27
28#endif /* __MBX_FB_H */
diff --git a/init/Kconfig b/init/Kconfig
index a5b073a103e7..a099fc6526d9 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -158,6 +158,30 @@ config BSD_PROCESS_ACCT_V3
158 for processing it. A preliminary version of these tools is available 158 for processing it. A preliminary version of these tools is available
159 at <http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/>. 159 at <http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/>.
160 160
161config TASKSTATS
162 bool "Export task/process statistics through netlink (EXPERIMENTAL)"
163 depends on NET
164 default n
165 help
166 Export selected statistics for tasks/processes through the
167 generic netlink interface. Unlike BSD process accounting, the
168 statistics are available during the lifetime of tasks/processes as
169 responses to commands. Like BSD accounting, they are sent to user
170 space on task exit.
171
172 Say N if unsure.
173
174config TASK_DELAY_ACCT
175 bool "Enable per-task delay accounting (EXPERIMENTAL)"
176 depends on TASKSTATS
177 help
178 Collect information on time spent by a task waiting for system
179 resources like cpu, synchronous block I/O completion and swapping
180 in pages. Such statistics can help in setting a task's priorities
181 relative to other tasks for cpu, io, rss limits etc.
182
183 Say N if unsure.
184
161config SYSCTL 185config SYSCTL
162 bool "Sysctl support" if EMBEDDED 186 bool "Sysctl support" if EMBEDDED
163 default y 187 default y
diff --git a/init/main.c b/init/main.c
index 628b8e9e841a..8651a720a092 100644
--- a/init/main.c
+++ b/init/main.c
@@ -41,6 +41,8 @@
41#include <linux/cpu.h> 41#include <linux/cpu.h>
42#include <linux/cpuset.h> 42#include <linux/cpuset.h>
43#include <linux/efi.h> 43#include <linux/efi.h>
44#include <linux/taskstats_kern.h>
45#include <linux/delayacct.h>
44#include <linux/unistd.h> 46#include <linux/unistd.h>
45#include <linux/rmap.h> 47#include <linux/rmap.h>
46#include <linux/mempolicy.h> 48#include <linux/mempolicy.h>
@@ -574,6 +576,8 @@ asmlinkage void __init start_kernel(void)
574 proc_root_init(); 576 proc_root_init();
575#endif 577#endif
576 cpuset_init(); 578 cpuset_init();
579 taskstats_init_early();
580 delayacct_init();
577 581
578 check_bugs(); 582 check_bugs();
579 583
diff --git a/kernel/Makefile b/kernel/Makefile
index 47dbcd570cd8..d62ec66c1af2 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -48,6 +48,8 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
48obj-$(CONFIG_SECCOMP) += seccomp.o 48obj-$(CONFIG_SECCOMP) += seccomp.o
49obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o 49obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
50obj-$(CONFIG_RELAY) += relay.o 50obj-$(CONFIG_RELAY) += relay.o
51obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
52obj-$(CONFIG_TASKSTATS) += taskstats.o
51 53
52ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) 54ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
53# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is 55# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/acct.c b/kernel/acct.c
index f18e0b8df3e1..2a7c933651c7 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -488,7 +488,7 @@ static void do_acct_process(struct file *file)
488 old_encode_dev(tty_devnum(current->signal->tty)) : 0; 488 old_encode_dev(tty_devnum(current->signal->tty)) : 0;
489 read_unlock(&tasklist_lock); 489 read_unlock(&tasklist_lock);
490 490
491 spin_lock(&current->sighand->siglock); 491 spin_lock_irq(&current->sighand->siglock);
492 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime))); 492 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
493 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime))); 493 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
494 ac.ac_flag = pacct->ac_flag; 494 ac.ac_flag = pacct->ac_flag;
@@ -496,7 +496,7 @@ static void do_acct_process(struct file *file)
496 ac.ac_minflt = encode_comp_t(pacct->ac_minflt); 496 ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
497 ac.ac_majflt = encode_comp_t(pacct->ac_majflt); 497 ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
498 ac.ac_exitcode = pacct->ac_exitcode; 498 ac.ac_exitcode = pacct->ac_exitcode;
499 spin_unlock(&current->sighand->siglock); 499 spin_unlock_irq(&current->sighand->siglock);
500 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ 500 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
501 ac.ac_rw = encode_comp_t(ac.ac_io / 1024); 501 ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
502 ac.ac_swaps = encode_comp_t(0); 502 ac.ac_swaps = encode_comp_t(0);
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
new file mode 100644
index 000000000000..f05392d64267
--- /dev/null
+++ b/kernel/delayacct.c
@@ -0,0 +1,178 @@
1/* delayacct.c - per-task delay accounting
2 *
3 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 */
15
16#include <linux/sched.h>
17#include <linux/slab.h>
18#include <linux/time.h>
19#include <linux/sysctl.h>
20#include <linux/delayacct.h>
21
22int delayacct_on __read_mostly; /* Delay accounting turned on/off */
23kmem_cache_t *delayacct_cache;
24
25static int __init delayacct_setup_enable(char *str)
26{
27 delayacct_on = 1;
28 return 1;
29}
30__setup("delayacct", delayacct_setup_enable);
31
32void delayacct_init(void)
33{
34 delayacct_cache = kmem_cache_create("delayacct_cache",
35 sizeof(struct task_delay_info),
36 0,
37 SLAB_PANIC,
38 NULL, NULL);
39 delayacct_tsk_init(&init_task);
40}
41
42void __delayacct_tsk_init(struct task_struct *tsk)
43{
44 spin_lock_init(&tsk->delays_lock);
45 /* No need to acquire tsk->delays_lock for allocation here unless
46 __delayacct_tsk_init called after tsk is attached to tasklist
47 */
48 tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL);
49 if (tsk->delays)
50 spin_lock_init(&tsk->delays->lock);
51}
52
53void __delayacct_tsk_exit(struct task_struct *tsk)
54{
55 struct task_delay_info *delays = tsk->delays;
56 spin_lock(&tsk->delays_lock);
57 tsk->delays = NULL;
58 spin_unlock(&tsk->delays_lock);
59 kmem_cache_free(delayacct_cache, delays);
60}
61
62/*
63 * Start accounting for a delay statistic using
64 * its starting timestamp (@start)
65 */
66
67static inline void delayacct_start(struct timespec *start)
68{
69 do_posix_clock_monotonic_gettime(start);
70}
71
72/*
73 * Finish delay accounting for a statistic using
74 * its timestamps (@start, @end), accumalator (@total) and @count
75 */
76
77static void delayacct_end(struct timespec *start, struct timespec *end,
78 u64 *total, u32 *count)
79{
80 struct timespec ts;
81 s64 ns;
82
83 do_posix_clock_monotonic_gettime(end);
84 ts = timespec_sub(*end, *start);
85 ns = timespec_to_ns(&ts);
86 if (ns < 0)
87 return;
88
89 spin_lock(&current->delays->lock);
90 *total += ns;
91 (*count)++;
92 spin_unlock(&current->delays->lock);
93}
94
95void __delayacct_blkio_start(void)
96{
97 delayacct_start(&current->delays->blkio_start);
98}
99
100void __delayacct_blkio_end(void)
101{
102 if (current->delays->flags & DELAYACCT_PF_SWAPIN)
103 /* Swapin block I/O */
104 delayacct_end(&current->delays->blkio_start,
105 &current->delays->blkio_end,
106 &current->delays->swapin_delay,
107 &current->delays->swapin_count);
108 else /* Other block I/O */
109 delayacct_end(&current->delays->blkio_start,
110 &current->delays->blkio_end,
111 &current->delays->blkio_delay,
112 &current->delays->blkio_count);
113}
114
115int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
116{
117 s64 tmp;
118 struct timespec ts;
119 unsigned long t1,t2,t3;
120
121 spin_lock(&tsk->delays_lock);
122
123 /* Though tsk->delays accessed later, early exit avoids
124 * unnecessary returning of other data
125 */
126 if (!tsk->delays)
127 goto done;
128
129 tmp = (s64)d->cpu_run_real_total;
130 cputime_to_timespec(tsk->utime + tsk->stime, &ts);
131 tmp += timespec_to_ns(&ts);
132 d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
133
134 /*
135 * No locking available for sched_info (and too expensive to add one)
136 * Mitigate by taking snapshot of values
137 */
138 t1 = tsk->sched_info.pcnt;
139 t2 = tsk->sched_info.run_delay;
140 t3 = tsk->sched_info.cpu_time;
141
142 d->cpu_count += t1;
143
144 jiffies_to_timespec(t2, &ts);
145 tmp = (s64)d->cpu_delay_total + timespec_to_ns(&ts);
146 d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp;
147
148 tmp = (s64)d->cpu_run_virtual_total + (s64)jiffies_to_usecs(t3) * 1000;
149 d->cpu_run_virtual_total =
150 (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp;
151
152 /* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
153
154 spin_lock(&tsk->delays->lock);
155 tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
156 d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
157 tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
158 d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
159 d->blkio_count += tsk->delays->blkio_count;
160 d->swapin_count += tsk->delays->swapin_count;
161 spin_unlock(&tsk->delays->lock);
162
163done:
164 spin_unlock(&tsk->delays_lock);
165 return 0;
166}
167
168__u64 __delayacct_blkio_ticks(struct task_struct *tsk)
169{
170 __u64 ret;
171
172 spin_lock(&tsk->delays->lock);
173 ret = nsec_to_clock_t(tsk->delays->blkio_delay +
174 tsk->delays->swapin_delay);
175 spin_unlock(&tsk->delays->lock);
176 return ret;
177}
178
diff --git a/kernel/exit.c b/kernel/exit.c
index 6664c084783d..dba194a8d416 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -25,6 +25,8 @@
25#include <linux/mount.h> 25#include <linux/mount.h>
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/mempolicy.h> 27#include <linux/mempolicy.h>
28#include <linux/taskstats_kern.h>
29#include <linux/delayacct.h>
28#include <linux/cpuset.h> 30#include <linux/cpuset.h>
29#include <linux/syscalls.h> 31#include <linux/syscalls.h>
30#include <linux/signal.h> 32#include <linux/signal.h>
@@ -843,7 +845,9 @@ static void exit_notify(struct task_struct *tsk)
843fastcall NORET_TYPE void do_exit(long code) 845fastcall NORET_TYPE void do_exit(long code)
844{ 846{
845 struct task_struct *tsk = current; 847 struct task_struct *tsk = current;
848 struct taskstats *tidstats;
846 int group_dead; 849 int group_dead;
850 unsigned int mycpu;
847 851
848 profile_task_exit(tsk); 852 profile_task_exit(tsk);
849 853
@@ -881,6 +885,8 @@ fastcall NORET_TYPE void do_exit(long code)
881 current->comm, current->pid, 885 current->comm, current->pid,
882 preempt_count()); 886 preempt_count());
883 887
888 taskstats_exit_alloc(&tidstats, &mycpu);
889
884 acct_update_integrals(tsk); 890 acct_update_integrals(tsk);
885 if (tsk->mm) { 891 if (tsk->mm) {
886 update_hiwater_rss(tsk->mm); 892 update_hiwater_rss(tsk->mm);
@@ -900,6 +906,10 @@ fastcall NORET_TYPE void do_exit(long code)
900#endif 906#endif
901 if (unlikely(tsk->audit_context)) 907 if (unlikely(tsk->audit_context))
902 audit_free(tsk); 908 audit_free(tsk);
909 taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
910 taskstats_exit_free(tidstats);
911 delayacct_tsk_exit(tsk);
912
903 exit_mm(tsk); 913 exit_mm(tsk);
904 914
905 if (group_dead) 915 if (group_dead)
diff --git a/kernel/fork.c b/kernel/fork.c
index 926e5a68ea9e..1b0f7b1e0881 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -43,6 +43,8 @@
43#include <linux/rmap.h> 43#include <linux/rmap.h>
44#include <linux/acct.h> 44#include <linux/acct.h>
45#include <linux/cn_proc.h> 45#include <linux/cn_proc.h>
46#include <linux/delayacct.h>
47#include <linux/taskstats_kern.h>
46 48
47#include <asm/pgtable.h> 49#include <asm/pgtable.h>
48#include <asm/pgalloc.h> 50#include <asm/pgalloc.h>
@@ -818,6 +820,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
818 if (clone_flags & CLONE_THREAD) { 820 if (clone_flags & CLONE_THREAD) {
819 atomic_inc(&current->signal->count); 821 atomic_inc(&current->signal->count);
820 atomic_inc(&current->signal->live); 822 atomic_inc(&current->signal->live);
823 taskstats_tgid_alloc(current->signal);
821 return 0; 824 return 0;
822 } 825 }
823 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); 826 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
@@ -862,6 +865,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
862 INIT_LIST_HEAD(&sig->cpu_timers[0]); 865 INIT_LIST_HEAD(&sig->cpu_timers[0]);
863 INIT_LIST_HEAD(&sig->cpu_timers[1]); 866 INIT_LIST_HEAD(&sig->cpu_timers[1]);
864 INIT_LIST_HEAD(&sig->cpu_timers[2]); 867 INIT_LIST_HEAD(&sig->cpu_timers[2]);
868 taskstats_tgid_init(sig);
865 869
866 task_lock(current->group_leader); 870 task_lock(current->group_leader);
867 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); 871 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
@@ -883,6 +887,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
883void __cleanup_signal(struct signal_struct *sig) 887void __cleanup_signal(struct signal_struct *sig)
884{ 888{
885 exit_thread_group_keys(sig); 889 exit_thread_group_keys(sig);
890 taskstats_tgid_free(sig);
886 kmem_cache_free(signal_cachep, sig); 891 kmem_cache_free(signal_cachep, sig);
887} 892}
888 893
@@ -1000,6 +1005,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1000 goto bad_fork_cleanup_put_domain; 1005 goto bad_fork_cleanup_put_domain;
1001 1006
1002 p->did_exec = 0; 1007 p->did_exec = 0;
1008 delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
1003 copy_flags(clone_flags, p); 1009 copy_flags(clone_flags, p);
1004 p->pid = pid; 1010 p->pid = pid;
1005 retval = -EFAULT; 1011 retval = -EFAULT;
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 39277dd6bf90..ab16a5a4cfe9 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -275,8 +275,8 @@ static void upcase_if_global(struct kallsym_iter *iter)
275static int get_ksymbol_mod(struct kallsym_iter *iter) 275static int get_ksymbol_mod(struct kallsym_iter *iter)
276{ 276{
277 iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms, 277 iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms,
278 &iter->value, 278 &iter->value, &iter->type,
279 &iter->type, iter->name); 279 iter->name, sizeof(iter->name));
280 if (iter->owner == NULL) 280 if (iter->owner == NULL)
281 return 0; 281 return 0;
282 282
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 24be714b04c7..4f9c60ef95e8 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -216,23 +216,6 @@ EXPORT_SYMBOL(kthread_bind);
216 */ 216 */
217int kthread_stop(struct task_struct *k) 217int kthread_stop(struct task_struct *k)
218{ 218{
219 return kthread_stop_sem(k, NULL);
220}
221EXPORT_SYMBOL(kthread_stop);
222
223/**
224 * kthread_stop_sem - stop a thread created by kthread_create().
225 * @k: thread created by kthread_create().
226 * @s: semaphore that @k waits on while idle.
227 *
228 * Does essentially the same thing as kthread_stop() above, but wakes
229 * @k by calling up(@s).
230 *
231 * Returns the result of threadfn(), or %-EINTR if wake_up_process()
232 * was never called.
233 */
234int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
235{
236 int ret; 219 int ret;
237 220
238 mutex_lock(&kthread_stop_lock); 221 mutex_lock(&kthread_stop_lock);
@@ -246,10 +229,7 @@ int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
246 229
247 /* Now set kthread_should_stop() to true, and wake it up. */ 230 /* Now set kthread_should_stop() to true, and wake it up. */
248 kthread_stop_info.k = k; 231 kthread_stop_info.k = k;
249 if (s) 232 wake_up_process(k);
250 up(s);
251 else
252 wake_up_process(k);
253 put_task_struct(k); 233 put_task_struct(k);
254 234
255 /* Once it dies, reset stop ptr, gather result and we're done. */ 235 /* Once it dies, reset stop ptr, gather result and we're done. */
@@ -260,7 +240,7 @@ int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
260 240
261 return ret; 241 return ret;
262} 242}
263EXPORT_SYMBOL(kthread_stop_sem); 243EXPORT_SYMBOL(kthread_stop);
264 244
265static __init int helper_init(void) 245static __init int helper_init(void)
266{ 246{
diff --git a/kernel/module.c b/kernel/module.c
index 35e1b1f859d7..2a19cd47c046 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2019,10 +2019,8 @@ const char *module_address_lookup(unsigned long addr,
2019 return NULL; 2019 return NULL;
2020} 2020}
2021 2021
2022struct module *module_get_kallsym(unsigned int symnum, 2022struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
2023 unsigned long *value, 2023 char *type, char *name, size_t namelen)
2024 char *type,
2025 char namebuf[128])
2026{ 2024{
2027 struct module *mod; 2025 struct module *mod;
2028 2026
@@ -2031,9 +2029,8 @@ struct module *module_get_kallsym(unsigned int symnum,
2031 if (symnum < mod->num_symtab) { 2029 if (symnum < mod->num_symtab) {
2032 *value = mod->symtab[symnum].st_value; 2030 *value = mod->symtab[symnum].st_value;
2033 *type = mod->symtab[symnum].st_info; 2031 *type = mod->symtab[symnum].st_info;
2034 strncpy(namebuf, 2032 strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
2035 mod->strtab + mod->symtab[symnum].st_name, 2033 namelen);
2036 127);
2037 mutex_unlock(&module_mutex); 2034 mutex_unlock(&module_mutex);
2038 return mod; 2035 return mod;
2039 } 2036 }
diff --git a/kernel/rtmutex-tester.c b/kernel/rtmutex-tester.c
index 494dac872a13..948bd8f643e2 100644
--- a/kernel/rtmutex-tester.c
+++ b/kernel/rtmutex-tester.c
@@ -275,6 +275,7 @@ static int test_func(void *data)
275 275
276 /* Wait for the next command to be executed */ 276 /* Wait for the next command to be executed */
277 schedule(); 277 schedule();
278 try_to_freeze();
278 279
279 if (signal_pending(current)) 280 if (signal_pending(current))
280 flush_signals(current); 281 flush_signals(current);
diff --git a/kernel/sched.c b/kernel/sched.c
index d714611f1691..b44b9a43b0fc 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -51,6 +51,7 @@
51#include <linux/times.h> 51#include <linux/times.h>
52#include <linux/acct.h> 52#include <linux/acct.h>
53#include <linux/kprobes.h> 53#include <linux/kprobes.h>
54#include <linux/delayacct.h>
54#include <asm/tlb.h> 55#include <asm/tlb.h>
55 56
56#include <asm/unistd.h> 57#include <asm/unistd.h>
@@ -501,9 +502,36 @@ struct file_operations proc_schedstat_operations = {
501 .release = single_release, 502 .release = single_release,
502}; 503};
503 504
505/*
506 * Expects runqueue lock to be held for atomicity of update
507 */
508static inline void
509rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
510{
511 if (rq) {
512 rq->rq_sched_info.run_delay += delta_jiffies;
513 rq->rq_sched_info.pcnt++;
514 }
515}
516
517/*
518 * Expects runqueue lock to be held for atomicity of update
519 */
520static inline void
521rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
522{
523 if (rq)
524 rq->rq_sched_info.cpu_time += delta_jiffies;
525}
504# define schedstat_inc(rq, field) do { (rq)->field++; } while (0) 526# define schedstat_inc(rq, field) do { (rq)->field++; } while (0)
505# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0) 527# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0)
506#else /* !CONFIG_SCHEDSTATS */ 528#else /* !CONFIG_SCHEDSTATS */
529static inline void
530rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
531{}
532static inline void
533rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
534{}
507# define schedstat_inc(rq, field) do { } while (0) 535# define schedstat_inc(rq, field) do { } while (0)
508# define schedstat_add(rq, field, amt) do { } while (0) 536# define schedstat_add(rq, field, amt) do { } while (0)
509#endif 537#endif
@@ -523,7 +551,7 @@ static inline struct rq *this_rq_lock(void)
523 return rq; 551 return rq;
524} 552}
525 553
526#ifdef CONFIG_SCHEDSTATS 554#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
527/* 555/*
528 * Called when a process is dequeued from the active array and given 556 * Called when a process is dequeued from the active array and given
529 * the cpu. We should note that with the exception of interactive 557 * the cpu. We should note that with the exception of interactive
@@ -551,21 +579,16 @@ static inline void sched_info_dequeued(struct task_struct *t)
551 */ 579 */
552static void sched_info_arrive(struct task_struct *t) 580static void sched_info_arrive(struct task_struct *t)
553{ 581{
554 unsigned long now = jiffies, diff = 0; 582 unsigned long now = jiffies, delta_jiffies = 0;
555 struct rq *rq = task_rq(t);
556 583
557 if (t->sched_info.last_queued) 584 if (t->sched_info.last_queued)
558 diff = now - t->sched_info.last_queued; 585 delta_jiffies = now - t->sched_info.last_queued;
559 sched_info_dequeued(t); 586 sched_info_dequeued(t);
560 t->sched_info.run_delay += diff; 587 t->sched_info.run_delay += delta_jiffies;
561 t->sched_info.last_arrival = now; 588 t->sched_info.last_arrival = now;
562 t->sched_info.pcnt++; 589 t->sched_info.pcnt++;
563 590
564 if (!rq) 591 rq_sched_info_arrive(task_rq(t), delta_jiffies);
565 return;
566
567 rq->rq_sched_info.run_delay += diff;
568 rq->rq_sched_info.pcnt++;
569} 592}
570 593
571/* 594/*
@@ -585,8 +608,9 @@ static void sched_info_arrive(struct task_struct *t)
585 */ 608 */
586static inline void sched_info_queued(struct task_struct *t) 609static inline void sched_info_queued(struct task_struct *t)
587{ 610{
588 if (!t->sched_info.last_queued) 611 if (unlikely(sched_info_on()))
589 t->sched_info.last_queued = jiffies; 612 if (!t->sched_info.last_queued)
613 t->sched_info.last_queued = jiffies;
590} 614}
591 615
592/* 616/*
@@ -595,13 +619,10 @@ static inline void sched_info_queued(struct task_struct *t)
595 */ 619 */
596static inline void sched_info_depart(struct task_struct *t) 620static inline void sched_info_depart(struct task_struct *t)
597{ 621{
598 struct rq *rq = task_rq(t); 622 unsigned long delta_jiffies = jiffies - t->sched_info.last_arrival;
599 unsigned long diff = jiffies - t->sched_info.last_arrival;
600
601 t->sched_info.cpu_time += diff;
602 623
603 if (rq) 624 t->sched_info.cpu_time += delta_jiffies;
604 rq->rq_sched_info.cpu_time += diff; 625 rq_sched_info_depart(task_rq(t), delta_jiffies);
605} 626}
606 627
607/* 628/*
@@ -610,7 +631,7 @@ static inline void sched_info_depart(struct task_struct *t)
610 * the idle task.) We are only called when prev != next. 631 * the idle task.) We are only called when prev != next.
611 */ 632 */
612static inline void 633static inline void
613sched_info_switch(struct task_struct *prev, struct task_struct *next) 634__sched_info_switch(struct task_struct *prev, struct task_struct *next)
614{ 635{
615 struct rq *rq = task_rq(prev); 636 struct rq *rq = task_rq(prev);
616 637
@@ -625,10 +646,16 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
625 if (next != rq->idle) 646 if (next != rq->idle)
626 sched_info_arrive(next); 647 sched_info_arrive(next);
627} 648}
649static inline void
650sched_info_switch(struct task_struct *prev, struct task_struct *next)
651{
652 if (unlikely(sched_info_on()))
653 __sched_info_switch(prev, next);
654}
628#else 655#else
629#define sched_info_queued(t) do { } while (0) 656#define sched_info_queued(t) do { } while (0)
630#define sched_info_switch(t, next) do { } while (0) 657#define sched_info_switch(t, next) do { } while (0)
631#endif /* CONFIG_SCHEDSTATS */ 658#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
632 659
633/* 660/*
634 * Adding/removing a task to/from a priority array: 661 * Adding/removing a task to/from a priority array:
@@ -1530,8 +1557,9 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
1530 1557
1531 INIT_LIST_HEAD(&p->run_list); 1558 INIT_LIST_HEAD(&p->run_list);
1532 p->array = NULL; 1559 p->array = NULL;
1533#ifdef CONFIG_SCHEDSTATS 1560#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
1534 memset(&p->sched_info, 0, sizeof(p->sched_info)); 1561 if (unlikely(sched_info_on()))
1562 memset(&p->sched_info, 0, sizeof(p->sched_info));
1535#endif 1563#endif
1536#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) 1564#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
1537 p->oncpu = 0; 1565 p->oncpu = 0;
@@ -1788,7 +1816,15 @@ context_switch(struct rq *rq, struct task_struct *prev,
1788 WARN_ON(rq->prev_mm); 1816 WARN_ON(rq->prev_mm);
1789 rq->prev_mm = oldmm; 1817 rq->prev_mm = oldmm;
1790 } 1818 }
1819 /*
1820 * Since the runqueue lock will be released by the next
1821 * task (which is an invalid locking op but in the case
1822 * of the scheduler it's an obvious special-case), so we
1823 * do an early lockdep release here:
1824 */
1825#ifndef __ARCH_WANT_UNLOCKED_CTXSW
1791 spin_release(&rq->lock.dep_map, 1, _THIS_IP_); 1826 spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
1827#endif
1792 1828
1793 /* Here we just switch the register state and the stack. */ 1829 /* Here we just switch the register state and the stack. */
1794 switch_to(prev, next, prev); 1830 switch_to(prev, next, prev);
@@ -4526,9 +4562,11 @@ void __sched io_schedule(void)
4526{ 4562{
4527 struct rq *rq = &__raw_get_cpu_var(runqueues); 4563 struct rq *rq = &__raw_get_cpu_var(runqueues);
4528 4564
4565 delayacct_blkio_start();
4529 atomic_inc(&rq->nr_iowait); 4566 atomic_inc(&rq->nr_iowait);
4530 schedule(); 4567 schedule();
4531 atomic_dec(&rq->nr_iowait); 4568 atomic_dec(&rq->nr_iowait);
4569 delayacct_blkio_end();
4532} 4570}
4533EXPORT_SYMBOL(io_schedule); 4571EXPORT_SYMBOL(io_schedule);
4534 4572
@@ -4537,9 +4575,11 @@ long __sched io_schedule_timeout(long timeout)
4537 struct rq *rq = &__raw_get_cpu_var(runqueues); 4575 struct rq *rq = &__raw_get_cpu_var(runqueues);
4538 long ret; 4576 long ret;
4539 4577
4578 delayacct_blkio_start();
4540 atomic_inc(&rq->nr_iowait); 4579 atomic_inc(&rq->nr_iowait);
4541 ret = schedule_timeout(timeout); 4580 ret = schedule_timeout(timeout);
4542 atomic_dec(&rq->nr_iowait); 4581 atomic_dec(&rq->nr_iowait);
4582 delayacct_blkio_end();
4543 return ret; 4583 return ret;
4544} 4584}
4545 4585
diff --git a/kernel/softirq.c b/kernel/softirq.c
index fd12f2556f0d..0f08a84ae307 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -311,8 +311,6 @@ void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
311 softirq_vec[nr].action = action; 311 softirq_vec[nr].action = action;
312} 312}
313 313
314EXPORT_UNUSED_SYMBOL(open_softirq); /* June 2006 */
315
316/* Tasklets */ 314/* Tasklets */
317struct tasklet_head 315struct tasklet_head
318{ 316{
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
new file mode 100644
index 000000000000..f45179ce028e
--- /dev/null
+++ b/kernel/taskstats.c
@@ -0,0 +1,568 @@
1/*
2 * taskstats.c - Export per-task statistics to userland
3 *
4 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
5 * (C) Balbir Singh, IBM Corp. 2006
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 */
18
19#include <linux/kernel.h>
20#include <linux/taskstats_kern.h>
21#include <linux/delayacct.h>
22#include <linux/cpumask.h>
23#include <linux/percpu.h>
24#include <net/genetlink.h>
25#include <asm/atomic.h>
26
27/*
28 * Maximum length of a cpumask that can be specified in
29 * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
30 */
31#define TASKSTATS_CPUMASK_MAXLEN (100+6*NR_CPUS)
32
33static DEFINE_PER_CPU(__u32, taskstats_seqnum) = { 0 };
34static int family_registered;
35kmem_cache_t *taskstats_cache;
36
37static struct genl_family family = {
38 .id = GENL_ID_GENERATE,
39 .name = TASKSTATS_GENL_NAME,
40 .version = TASKSTATS_GENL_VERSION,
41 .maxattr = TASKSTATS_CMD_ATTR_MAX,
42};
43
44static struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1]
45__read_mostly = {
46 [TASKSTATS_CMD_ATTR_PID] = { .type = NLA_U32 },
47 [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
48 [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
49 [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
50
51struct listener {
52 struct list_head list;
53 pid_t pid;
54 char valid;
55};
56
57struct listener_list {
58 struct rw_semaphore sem;
59 struct list_head list;
60};
61static DEFINE_PER_CPU(struct listener_list, listener_array);
62
63enum actions {
64 REGISTER,
65 DEREGISTER,
66 CPU_DONT_CARE
67};
68
69static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
70 void **replyp, size_t size)
71{
72 struct sk_buff *skb;
73 void *reply;
74
75 /*
76 * If new attributes are added, please revisit this allocation
77 */
78 skb = nlmsg_new(size);
79 if (!skb)
80 return -ENOMEM;
81
82 if (!info) {
83 int seq = get_cpu_var(taskstats_seqnum)++;
84 put_cpu_var(taskstats_seqnum);
85
86 reply = genlmsg_put(skb, 0, seq,
87 family.id, 0, 0,
88 cmd, family.version);
89 } else
90 reply = genlmsg_put(skb, info->snd_pid, info->snd_seq,
91 family.id, 0, 0,
92 cmd, family.version);
93 if (reply == NULL) {
94 nlmsg_free(skb);
95 return -EINVAL;
96 }
97
98 *skbp = skb;
99 *replyp = reply;
100 return 0;
101}
102
103/*
104 * Send taskstats data in @skb to listener with nl_pid @pid
105 */
106static int send_reply(struct sk_buff *skb, pid_t pid)
107{
108 struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
109 void *reply = genlmsg_data(genlhdr);
110 int rc;
111
112 rc = genlmsg_end(skb, reply);
113 if (rc < 0) {
114 nlmsg_free(skb);
115 return rc;
116 }
117
118 return genlmsg_unicast(skb, pid);
119}
120
121/*
122 * Send taskstats data in @skb to listeners registered for @cpu's exit data
123 */
124static int send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
125{
126 struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
127 struct listener_list *listeners;
128 struct listener *s, *tmp;
129 struct sk_buff *skb_next, *skb_cur = skb;
130 void *reply = genlmsg_data(genlhdr);
131 int rc, ret, delcount = 0;
132
133 rc = genlmsg_end(skb, reply);
134 if (rc < 0) {
135 nlmsg_free(skb);
136 return rc;
137 }
138
139 rc = 0;
140 listeners = &per_cpu(listener_array, cpu);
141 down_read(&listeners->sem);
142 list_for_each_entry_safe(s, tmp, &listeners->list, list) {
143 skb_next = NULL;
144 if (!list_is_last(&s->list, &listeners->list)) {
145 skb_next = skb_clone(skb_cur, GFP_KERNEL);
146 if (!skb_next) {
147 nlmsg_free(skb_cur);
148 rc = -ENOMEM;
149 break;
150 }
151 }
152 ret = genlmsg_unicast(skb_cur, s->pid);
153 if (ret == -ECONNREFUSED) {
154 s->valid = 0;
155 delcount++;
156 rc = ret;
157 }
158 skb_cur = skb_next;
159 }
160 up_read(&listeners->sem);
161
162 if (!delcount)
163 return rc;
164
165 /* Delete invalidated entries */
166 down_write(&listeners->sem);
167 list_for_each_entry_safe(s, tmp, &listeners->list, list) {
168 if (!s->valid) {
169 list_del(&s->list);
170 kfree(s);
171 }
172 }
173 up_write(&listeners->sem);
174 return rc;
175}
176
177static int fill_pid(pid_t pid, struct task_struct *pidtsk,
178 struct taskstats *stats)
179{
180 int rc;
181 struct task_struct *tsk = pidtsk;
182
183 if (!pidtsk) {
184 read_lock(&tasklist_lock);
185 tsk = find_task_by_pid(pid);
186 if (!tsk) {
187 read_unlock(&tasklist_lock);
188 return -ESRCH;
189 }
190 get_task_struct(tsk);
191 read_unlock(&tasklist_lock);
192 } else
193 get_task_struct(tsk);
194
195 /*
196 * Each accounting subsystem adds calls to its functions to
197 * fill in relevant parts of struct taskstsats as follows
198 *
199 * rc = per-task-foo(stats, tsk);
200 * if (rc)
201 * goto err;
202 */
203
204 rc = delayacct_add_tsk(stats, tsk);
205 stats->version = TASKSTATS_VERSION;
206
207 /* Define err: label here if needed */
208 put_task_struct(tsk);
209 return rc;
210
211}
212
213static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
214 struct taskstats *stats)
215{
216 struct task_struct *tsk, *first;
217 unsigned long flags;
218
219 /*
220 * Add additional stats from live tasks except zombie thread group
221 * leaders who are already counted with the dead tasks
222 */
223 first = tgidtsk;
224 if (!first) {
225 read_lock(&tasklist_lock);
226 first = find_task_by_pid(tgid);
227 if (!first) {
228 read_unlock(&tasklist_lock);
229 return -ESRCH;
230 }
231 get_task_struct(first);
232 read_unlock(&tasklist_lock);
233 } else
234 get_task_struct(first);
235
236 /* Start with stats from dead tasks */
237 spin_lock_irqsave(&first->signal->stats_lock, flags);
238 if (first->signal->stats)
239 memcpy(stats, first->signal->stats, sizeof(*stats));
240 spin_unlock_irqrestore(&first->signal->stats_lock, flags);
241
242 tsk = first;
243 read_lock(&tasklist_lock);
244 do {
245 if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
246 continue;
247 /*
248 * Accounting subsystem can call its functions here to
249 * fill in relevant parts of struct taskstsats as follows
250 *
251 * per-task-foo(stats, tsk);
252 */
253 delayacct_add_tsk(stats, tsk);
254
255 } while_each_thread(first, tsk);
256 read_unlock(&tasklist_lock);
257 stats->version = TASKSTATS_VERSION;
258
259 /*
260 * Accounting subsytems can also add calls here to modify
261 * fields of taskstats.
262 */
263
264 return 0;
265}
266
267
268static void fill_tgid_exit(struct task_struct *tsk)
269{
270 unsigned long flags;
271
272 spin_lock_irqsave(&tsk->signal->stats_lock, flags);
273 if (!tsk->signal->stats)
274 goto ret;
275
276 /*
277 * Each accounting subsystem calls its functions here to
278 * accumalate its per-task stats for tsk, into the per-tgid structure
279 *
280 * per-task-foo(tsk->signal->stats, tsk);
281 */
282 delayacct_add_tsk(tsk->signal->stats, tsk);
283ret:
284 spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
285 return;
286}
287
288static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd)
289{
290 struct listener_list *listeners;
291 struct listener *s, *tmp;
292 unsigned int cpu;
293 cpumask_t mask = *maskp;
294
295 if (!cpus_subset(mask, cpu_possible_map))
296 return -EINVAL;
297
298 if (isadd == REGISTER) {
299 for_each_cpu_mask(cpu, mask) {
300 s = kmalloc_node(sizeof(struct listener), GFP_KERNEL,
301 cpu_to_node(cpu));
302 if (!s)
303 goto cleanup;
304 s->pid = pid;
305 INIT_LIST_HEAD(&s->list);
306 s->valid = 1;
307
308 listeners = &per_cpu(listener_array, cpu);
309 down_write(&listeners->sem);
310 list_add(&s->list, &listeners->list);
311 up_write(&listeners->sem);
312 }
313 return 0;
314 }
315
316 /* Deregister or cleanup */
317cleanup:
318 for_each_cpu_mask(cpu, mask) {
319 listeners = &per_cpu(listener_array, cpu);
320 down_write(&listeners->sem);
321 list_for_each_entry_safe(s, tmp, &listeners->list, list) {
322 if (s->pid == pid) {
323 list_del(&s->list);
324 kfree(s);
325 break;
326 }
327 }
328 up_write(&listeners->sem);
329 }
330 return 0;
331}
332
333static int parse(struct nlattr *na, cpumask_t *mask)
334{
335 char *data;
336 int len;
337 int ret;
338
339 if (na == NULL)
340 return 1;
341 len = nla_len(na);
342 if (len > TASKSTATS_CPUMASK_MAXLEN)
343 return -E2BIG;
344 if (len < 1)
345 return -EINVAL;
346 data = kmalloc(len, GFP_KERNEL);
347 if (!data)
348 return -ENOMEM;
349 nla_strlcpy(data, na, len);
350 ret = cpulist_parse(data, *mask);
351 kfree(data);
352 return ret;
353}
354
355static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
356{
357 int rc = 0;
358 struct sk_buff *rep_skb;
359 struct taskstats stats;
360 void *reply;
361 size_t size;
362 struct nlattr *na;
363 cpumask_t mask;
364
365 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask);
366 if (rc < 0)
367 return rc;
368 if (rc == 0)
369 return add_del_listener(info->snd_pid, &mask, REGISTER);
370
371 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], &mask);
372 if (rc < 0)
373 return rc;
374 if (rc == 0)
375 return add_del_listener(info->snd_pid, &mask, DEREGISTER);
376
377 /*
378 * Size includes space for nested attributes
379 */
380 size = nla_total_size(sizeof(u32)) +
381 nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
382
383 memset(&stats, 0, sizeof(stats));
384 rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
385 if (rc < 0)
386 return rc;
387
388 if (info->attrs[TASKSTATS_CMD_ATTR_PID]) {
389 u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]);
390 rc = fill_pid(pid, NULL, &stats);
391 if (rc < 0)
392 goto err;
393
394 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID);
395 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, pid);
396 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
397 stats);
398 } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) {
399 u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]);
400 rc = fill_tgid(tgid, NULL, &stats);
401 if (rc < 0)
402 goto err;
403
404 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID);
405 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, tgid);
406 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
407 stats);
408 } else {
409 rc = -EINVAL;
410 goto err;
411 }
412
413 nla_nest_end(rep_skb, na);
414
415 return send_reply(rep_skb, info->snd_pid);
416
417nla_put_failure:
418 return genlmsg_cancel(rep_skb, reply);
419err:
420 nlmsg_free(rep_skb);
421 return rc;
422}
423
424void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
425{
426 struct listener_list *listeners;
427 struct taskstats *tmp;
428 /*
429 * This is the cpu on which the task is exiting currently and will
430 * be the one for which the exit event is sent, even if the cpu
431 * on which this function is running changes later.
432 */
433 *mycpu = raw_smp_processor_id();
434
435 *ptidstats = NULL;
436 tmp = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
437 if (!tmp)
438 return;
439
440 listeners = &per_cpu(listener_array, *mycpu);
441 down_read(&listeners->sem);
442 if (!list_empty(&listeners->list)) {
443 *ptidstats = tmp;
444 tmp = NULL;
445 }
446 up_read(&listeners->sem);
447 kfree(tmp);
448}
449
450/* Send pid data out on exit */
451void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
452 int group_dead, unsigned int mycpu)
453{
454 int rc;
455 struct sk_buff *rep_skb;
456 void *reply;
457 size_t size;
458 int is_thread_group;
459 struct nlattr *na;
460 unsigned long flags;
461
462 if (!family_registered || !tidstats)
463 return;
464
465 spin_lock_irqsave(&tsk->signal->stats_lock, flags);
466 is_thread_group = tsk->signal->stats ? 1 : 0;
467 spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
468
469 rc = 0;
470 /*
471 * Size includes space for nested attributes
472 */
473 size = nla_total_size(sizeof(u32)) +
474 nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
475
476 if (is_thread_group)
477 size = 2 * size; /* PID + STATS + TGID + STATS */
478
479 rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
480 if (rc < 0)
481 goto ret;
482
483 rc = fill_pid(tsk->pid, tsk, tidstats);
484 if (rc < 0)
485 goto err_skb;
486
487 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID);
488 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, (u32)tsk->pid);
489 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
490 *tidstats);
491 nla_nest_end(rep_skb, na);
492
493 if (!is_thread_group)
494 goto send;
495
496 /*
497 * tsk has/had a thread group so fill the tsk->signal->stats structure
498 * Doesn't matter if tsk is the leader or the last group member leaving
499 */
500
501 fill_tgid_exit(tsk);
502 if (!group_dead)
503 goto send;
504
505 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID);
506 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, (u32)tsk->tgid);
507 /* No locking needed for tsk->signal->stats since group is dead */
508 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
509 *tsk->signal->stats);
510 nla_nest_end(rep_skb, na);
511
512send:
513 send_cpu_listeners(rep_skb, mycpu);
514 return;
515
516nla_put_failure:
517 genlmsg_cancel(rep_skb, reply);
518 goto ret;
519err_skb:
520 nlmsg_free(rep_skb);
521ret:
522 return;
523}
524
525static struct genl_ops taskstats_ops = {
526 .cmd = TASKSTATS_CMD_GET,
527 .doit = taskstats_user_cmd,
528 .policy = taskstats_cmd_get_policy,
529};
530
531/* Needed early in initialization */
532void __init taskstats_init_early(void)
533{
534 unsigned int i;
535
536 taskstats_cache = kmem_cache_create("taskstats_cache",
537 sizeof(struct taskstats),
538 0, SLAB_PANIC, NULL, NULL);
539 for_each_possible_cpu(i) {
540 INIT_LIST_HEAD(&(per_cpu(listener_array, i).list));
541 init_rwsem(&(per_cpu(listener_array, i).sem));
542 }
543}
544
545static int __init taskstats_init(void)
546{
547 int rc;
548
549 rc = genl_register_family(&family);
550 if (rc)
551 return rc;
552
553 rc = genl_register_ops(&family, &taskstats_ops);
554 if (rc < 0)
555 goto err;
556
557 family_registered = 1;
558 return 0;
559err:
560 genl_unregister_family(&family);
561 return rc;
562}
563
564/*
565 * late initcall ensures initialization of statistics collection
566 * mechanisms precedes initialization of the taskstats interface
567 */
568late_initcall(taskstats_init);
diff --git a/kernel/timer.c b/kernel/timer.c
index 2a87430a58d4..05809c2e2fd6 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -374,6 +374,7 @@ int del_timer_sync(struct timer_list *timer)
374 int ret = try_to_del_timer_sync(timer); 374 int ret = try_to_del_timer_sync(timer);
375 if (ret >= 0) 375 if (ret >= 0)
376 return ret; 376 return ret;
377 cpu_relax();
377 } 378 }
378} 379}
379 380
@@ -968,6 +969,7 @@ void __init timekeeping_init(void)
968} 969}
969 970
970 971
972static int timekeeping_suspended;
971/* 973/*
972 * timekeeping_resume - Resumes the generic timekeeping subsystem. 974 * timekeeping_resume - Resumes the generic timekeeping subsystem.
973 * @dev: unused 975 * @dev: unused
@@ -983,6 +985,18 @@ static int timekeeping_resume(struct sys_device *dev)
983 write_seqlock_irqsave(&xtime_lock, flags); 985 write_seqlock_irqsave(&xtime_lock, flags);
984 /* restart the last cycle value */ 986 /* restart the last cycle value */
985 clock->cycle_last = clocksource_read(clock); 987 clock->cycle_last = clocksource_read(clock);
988 clock->error = 0;
989 timekeeping_suspended = 0;
990 write_sequnlock_irqrestore(&xtime_lock, flags);
991 return 0;
992}
993
994static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
995{
996 unsigned long flags;
997
998 write_seqlock_irqsave(&xtime_lock, flags);
999 timekeeping_suspended = 1;
986 write_sequnlock_irqrestore(&xtime_lock, flags); 1000 write_sequnlock_irqrestore(&xtime_lock, flags);
987 return 0; 1001 return 0;
988} 1002}
@@ -990,6 +1004,7 @@ static int timekeeping_resume(struct sys_device *dev)
990/* sysfs resume/suspend bits for timekeeping */ 1004/* sysfs resume/suspend bits for timekeeping */
991static struct sysdev_class timekeeping_sysclass = { 1005static struct sysdev_class timekeeping_sysclass = {
992 .resume = timekeeping_resume, 1006 .resume = timekeeping_resume,
1007 .suspend = timekeeping_suspend,
993 set_kset_name("timekeeping"), 1008 set_kset_name("timekeeping"),
994}; 1009};
995 1010
@@ -1100,13 +1115,16 @@ static void update_wall_time(void)
1100{ 1115{
1101 cycle_t offset; 1116 cycle_t offset;
1102 1117
1103 clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift; 1118 /* Make sure we're fully resumed: */
1119 if (unlikely(timekeeping_suspended))
1120 return;
1104 1121
1105#ifdef CONFIG_GENERIC_TIME 1122#ifdef CONFIG_GENERIC_TIME
1106 offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask; 1123 offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
1107#else 1124#else
1108 offset = clock->cycle_interval; 1125 offset = clock->cycle_interval;
1109#endif 1126#endif
1127 clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
1110 1128
1111 /* normally this loop will run just once, however in the 1129 /* normally this loop will run just once, however in the
1112 * case of lost or late ticks, it will accumulate correctly. 1130 * case of lost or late ticks, it will accumulate correctly.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index e5889b1a33ff..554ee688a9f8 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -158,7 +158,7 @@ config DEBUG_RWSEMS
158 158
159config DEBUG_LOCK_ALLOC 159config DEBUG_LOCK_ALLOC
160 bool "Lock debugging: detect incorrect freeing of live locks" 160 bool "Lock debugging: detect incorrect freeing of live locks"
161 depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT 161 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
162 select DEBUG_SPINLOCK 162 select DEBUG_SPINLOCK
163 select DEBUG_MUTEXES 163 select DEBUG_MUTEXES
164 select DEBUG_RWSEMS 164 select DEBUG_RWSEMS
@@ -173,7 +173,7 @@ config DEBUG_LOCK_ALLOC
173 173
174config PROVE_LOCKING 174config PROVE_LOCKING
175 bool "Lock debugging: prove locking correctness" 175 bool "Lock debugging: prove locking correctness"
176 depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT 176 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
177 select LOCKDEP 177 select LOCKDEP
178 select DEBUG_SPINLOCK 178 select DEBUG_SPINLOCK
179 select DEBUG_MUTEXES 179 select DEBUG_MUTEXES
@@ -216,7 +216,7 @@ config PROVE_LOCKING
216 216
217config LOCKDEP 217config LOCKDEP
218 bool 218 bool
219 depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT 219 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
220 select STACKTRACE 220 select STACKTRACE
221 select FRAME_POINTER 221 select FRAME_POINTER
222 select KALLSYMS 222 select KALLSYMS
@@ -224,13 +224,14 @@ config LOCKDEP
224 224
225config DEBUG_LOCKDEP 225config DEBUG_LOCKDEP
226 bool "Lock dependency engine debugging" 226 bool "Lock dependency engine debugging"
227 depends on LOCKDEP 227 depends on DEBUG_KERNEL && LOCKDEP
228 help 228 help
229 If you say Y here, the lock dependency engine will do 229 If you say Y here, the lock dependency engine will do
230 additional runtime checks to debug itself, at the price 230 additional runtime checks to debug itself, at the price
231 of more runtime overhead. 231 of more runtime overhead.
232 232
233config TRACE_IRQFLAGS 233config TRACE_IRQFLAGS
234 depends on DEBUG_KERNEL
234 bool 235 bool
235 default y 236 default y
236 depends on TRACE_IRQFLAGS_SUPPORT 237 depends on TRACE_IRQFLAGS_SUPPORT
@@ -256,6 +257,7 @@ config DEBUG_LOCKING_API_SELFTESTS
256 257
257config STACKTRACE 258config STACKTRACE
258 bool 259 bool
260 depends on DEBUG_KERNEL
259 depends on STACKTRACE_SUPPORT 261 depends on STACKTRACE_SUPPORT
260 262
261config DEBUG_KOBJECT 263config DEBUG_KOBJECT
diff --git a/lib/idr.c b/lib/idr.c
index 4d096819511a..16d2143fea48 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -38,14 +38,15 @@ static kmem_cache_t *idr_layer_cache;
38static struct idr_layer *alloc_layer(struct idr *idp) 38static struct idr_layer *alloc_layer(struct idr *idp)
39{ 39{
40 struct idr_layer *p; 40 struct idr_layer *p;
41 unsigned long flags;
41 42
42 spin_lock(&idp->lock); 43 spin_lock_irqsave(&idp->lock, flags);
43 if ((p = idp->id_free)) { 44 if ((p = idp->id_free)) {
44 idp->id_free = p->ary[0]; 45 idp->id_free = p->ary[0];
45 idp->id_free_cnt--; 46 idp->id_free_cnt--;
46 p->ary[0] = NULL; 47 p->ary[0] = NULL;
47 } 48 }
48 spin_unlock(&idp->lock); 49 spin_unlock_irqrestore(&idp->lock, flags);
49 return(p); 50 return(p);
50} 51}
51 52
@@ -59,12 +60,14 @@ static void __free_layer(struct idr *idp, struct idr_layer *p)
59 60
60static void free_layer(struct idr *idp, struct idr_layer *p) 61static void free_layer(struct idr *idp, struct idr_layer *p)
61{ 62{
63 unsigned long flags;
64
62 /* 65 /*
63 * Depends on the return element being zeroed. 66 * Depends on the return element being zeroed.
64 */ 67 */
65 spin_lock(&idp->lock); 68 spin_lock_irqsave(&idp->lock, flags);
66 __free_layer(idp, p); 69 __free_layer(idp, p);
67 spin_unlock(&idp->lock); 70 spin_unlock_irqrestore(&idp->lock, flags);
68} 71}
69 72
70/** 73/**
@@ -168,6 +171,7 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
168{ 171{
169 struct idr_layer *p, *new; 172 struct idr_layer *p, *new;
170 int layers, v, id; 173 int layers, v, id;
174 unsigned long flags;
171 175
172 id = starting_id; 176 id = starting_id;
173build_up: 177build_up:
@@ -191,14 +195,14 @@ build_up:
191 * The allocation failed. If we built part of 195 * The allocation failed. If we built part of
192 * the structure tear it down. 196 * the structure tear it down.
193 */ 197 */
194 spin_lock(&idp->lock); 198 spin_lock_irqsave(&idp->lock, flags);
195 for (new = p; p && p != idp->top; new = p) { 199 for (new = p; p && p != idp->top; new = p) {
196 p = p->ary[0]; 200 p = p->ary[0];
197 new->ary[0] = NULL; 201 new->ary[0] = NULL;
198 new->bitmap = new->count = 0; 202 new->bitmap = new->count = 0;
199 __free_layer(idp, new); 203 __free_layer(idp, new);
200 } 204 }
201 spin_unlock(&idp->lock); 205 spin_unlock_irqrestore(&idp->lock, flags);
202 return -1; 206 return -1;
203 } 207 }
204 new->ary[0] = p; 208 new->ary[0] = p;
diff --git a/mm/memory.c b/mm/memory.c
index dc0d82cf2a1c..109e9866237e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -47,6 +47,7 @@
47#include <linux/pagemap.h> 47#include <linux/pagemap.h>
48#include <linux/rmap.h> 48#include <linux/rmap.h>
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/delayacct.h>
50#include <linux/init.h> 51#include <linux/init.h>
51 52
52#include <asm/pgalloc.h> 53#include <asm/pgalloc.h>
@@ -1549,9 +1550,9 @@ gotten:
1549 flush_cache_page(vma, address, pte_pfn(orig_pte)); 1550 flush_cache_page(vma, address, pte_pfn(orig_pte));
1550 entry = mk_pte(new_page, vma->vm_page_prot); 1551 entry = mk_pte(new_page, vma->vm_page_prot);
1551 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 1552 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
1553 lazy_mmu_prot_update(entry);
1552 ptep_establish(vma, address, page_table, entry); 1554 ptep_establish(vma, address, page_table, entry);
1553 update_mmu_cache(vma, address, entry); 1555 update_mmu_cache(vma, address, entry);
1554 lazy_mmu_prot_update(entry);
1555 lru_cache_add_active(new_page); 1556 lru_cache_add_active(new_page);
1556 page_add_new_anon_rmap(new_page, vma, address); 1557 page_add_new_anon_rmap(new_page, vma, address);
1557 1558
@@ -1934,6 +1935,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
1934 migration_entry_wait(mm, pmd, address); 1935 migration_entry_wait(mm, pmd, address);
1935 goto out; 1936 goto out;
1936 } 1937 }
1938 delayacct_set_flag(DELAYACCT_PF_SWAPIN);
1937 page = lookup_swap_cache(entry); 1939 page = lookup_swap_cache(entry);
1938 if (!page) { 1940 if (!page) {
1939 swapin_readahead(entry, address, vma); 1941 swapin_readahead(entry, address, vma);
@@ -1946,6 +1948,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
1946 page_table = pte_offset_map_lock(mm, pmd, address, &ptl); 1948 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
1947 if (likely(pte_same(*page_table, orig_pte))) 1949 if (likely(pte_same(*page_table, orig_pte)))
1948 ret = VM_FAULT_OOM; 1950 ret = VM_FAULT_OOM;
1951 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
1949 goto unlock; 1952 goto unlock;
1950 } 1953 }
1951 1954
@@ -1955,6 +1958,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
1955 grab_swap_token(); 1958 grab_swap_token();
1956 } 1959 }
1957 1960
1961 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
1958 mark_page_accessed(page); 1962 mark_page_accessed(page);
1959 lock_page(page); 1963 lock_page(page);
1960 1964
diff --git a/mm/nommu.c b/mm/nommu.c
index 5151c44a8257..c576df71e3bb 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1070,6 +1070,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
1070 vma->vm_start = vma->vm_pgoff << PAGE_SHIFT; 1070 vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
1071 return 0; 1071 return 0;
1072} 1072}
1073EXPORT_SYMBOL(remap_pfn_range);
1073 1074
1074void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) 1075void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
1075{ 1076{
@@ -1090,6 +1091,7 @@ void unmap_mapping_range(struct address_space *mapping,
1090 int even_cows) 1091 int even_cows)
1091{ 1092{
1092} 1093}
1094EXPORT_SYMBOL(unmap_mapping_range);
1093 1095
1094/* 1096/*
1095 * Check that a process has enough memory to allocate a new virtual 1097 * Check that a process has enough memory to allocate a new virtual
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7b450798b458..266162d2ba28 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -340,7 +340,7 @@ void __vunmap(void *addr, int deallocate_pages)
340 __free_page(area->pages[i]); 340 __free_page(area->pages[i]);
341 } 341 }
342 342
343 if (area->nr_pages > PAGE_SIZE/sizeof(struct page *)) 343 if (area->flags & VM_VPAGES)
344 vfree(area->pages); 344 vfree(area->pages);
345 else 345 else
346 kfree(area->pages); 346 kfree(area->pages);
@@ -427,9 +427,10 @@ void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
427 427
428 area->nr_pages = nr_pages; 428 area->nr_pages = nr_pages;
429 /* Please note that the recursion is strictly bounded. */ 429 /* Please note that the recursion is strictly bounded. */
430 if (array_size > PAGE_SIZE) 430 if (array_size > PAGE_SIZE) {
431 pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node); 431 pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node);
432 else 432 area->flags |= VM_VPAGES;
433 } else
433 pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node); 434 pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node);
434 area->pages = pages; 435 area->pages = pages;
435 if (!area->pages) { 436 if (!area->pages) {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 44f6a181a754..476aa3978504 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -257,11 +257,11 @@ nodata:
257} 257}
258 258
259 259
260static void skb_drop_fraglist(struct sk_buff *skb) 260static void skb_drop_list(struct sk_buff **listp)
261{ 261{
262 struct sk_buff *list = skb_shinfo(skb)->frag_list; 262 struct sk_buff *list = *listp;
263 263
264 skb_shinfo(skb)->frag_list = NULL; 264 *listp = NULL;
265 265
266 do { 266 do {
267 struct sk_buff *this = list; 267 struct sk_buff *this = list;
@@ -270,6 +270,11 @@ static void skb_drop_fraglist(struct sk_buff *skb)
270 } while (list); 270 } while (list);
271} 271}
272 272
273static inline void skb_drop_fraglist(struct sk_buff *skb)
274{
275 skb_drop_list(&skb_shinfo(skb)->frag_list);
276}
277
273static void skb_clone_fraglist(struct sk_buff *skb) 278static void skb_clone_fraglist(struct sk_buff *skb)
274{ 279{
275 struct sk_buff *list; 280 struct sk_buff *list;
@@ -830,41 +835,75 @@ free_skb:
830 835
831int ___pskb_trim(struct sk_buff *skb, unsigned int len) 836int ___pskb_trim(struct sk_buff *skb, unsigned int len)
832{ 837{
838 struct sk_buff **fragp;
839 struct sk_buff *frag;
833 int offset = skb_headlen(skb); 840 int offset = skb_headlen(skb);
834 int nfrags = skb_shinfo(skb)->nr_frags; 841 int nfrags = skb_shinfo(skb)->nr_frags;
835 int i; 842 int i;
843 int err;
844
845 if (skb_cloned(skb) &&
846 unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
847 return err;
836 848
837 for (i = 0; i < nfrags; i++) { 849 for (i = 0; i < nfrags; i++) {
838 int end = offset + skb_shinfo(skb)->frags[i].size; 850 int end = offset + skb_shinfo(skb)->frags[i].size;
839 if (end > len) { 851
840 if (skb_cloned(skb)) { 852 if (end < len) {
841 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 853 offset = end;
842 return -ENOMEM; 854 continue;
843 }
844 if (len <= offset) {
845 put_page(skb_shinfo(skb)->frags[i].page);
846 skb_shinfo(skb)->nr_frags--;
847 } else {
848 skb_shinfo(skb)->frags[i].size = len - offset;
849 }
850 } 855 }
851 offset = end; 856
857 if (len > offset)
858 skb_shinfo(skb)->frags[i++].size = len - offset;
859
860 skb_shinfo(skb)->nr_frags = i;
861
862 for (; i < nfrags; i++)
863 put_page(skb_shinfo(skb)->frags[i].page);
864
865 if (skb_shinfo(skb)->frag_list)
866 skb_drop_fraglist(skb);
867 break;
852 } 868 }
853 869
854 if (offset < len) { 870 for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
871 fragp = &frag->next) {
872 int end = offset + frag->len;
873
874 if (skb_shared(frag)) {
875 struct sk_buff *nfrag;
876
877 nfrag = skb_clone(frag, GFP_ATOMIC);
878 if (unlikely(!nfrag))
879 return -ENOMEM;
880
881 nfrag->next = frag->next;
882 frag = nfrag;
883 *fragp = frag;
884 }
885
886 if (end < len) {
887 offset = end;
888 continue;
889 }
890
891 if (end > len &&
892 unlikely((err = pskb_trim(frag, len - offset))))
893 return err;
894
895 if (frag->next)
896 skb_drop_list(&frag->next);
897 break;
898 }
899
900 if (len > skb_headlen(skb)) {
855 skb->data_len -= skb->len - len; 901 skb->data_len -= skb->len - len;
856 skb->len = len; 902 skb->len = len;
857 } else { 903 } else {
858 if (len <= skb_headlen(skb)) { 904 skb->len = len;
859 skb->len = len; 905 skb->data_len = 0;
860 skb->data_len = 0; 906 skb->tail = skb->data + len;
861 skb->tail = skb->data + len;
862 if (skb_shinfo(skb)->frag_list && !skb_cloned(skb))
863 skb_drop_fraglist(skb);
864 } else {
865 skb->data_len -= skb->len - len;
866 skb->len = len;
867 }
868 } 907 }
869 908
870 return 0; 909 return 0;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index e1a7dba2fa8a..184c78ca79e6 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -428,6 +428,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
428 goto drop; 428 goto drop;
429 } 429 }
430 430
431 /* Remove any debris in the socket control block */
432 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
433
431 return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, 434 return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
432 ip_rcv_finish); 435 ip_rcv_finish);
433 436
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 34afe41fa2f3..cd0a973b1128 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -196,7 +196,7 @@ struct htb_class
196 struct qdisc_rate_table *rate; /* rate table of the class itself */ 196 struct qdisc_rate_table *rate; /* rate table of the class itself */
197 struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */ 197 struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
198 long buffer,cbuffer; /* token bucket depth/rate */ 198 long buffer,cbuffer; /* token bucket depth/rate */
199 long mbuffer; /* max wait time */ 199 psched_tdiff_t mbuffer; /* max wait time */
200 long tokens,ctokens; /* current number of tokens */ 200 long tokens,ctokens; /* current number of tokens */
201 psched_time_t t_c; /* checkpoint time */ 201 psched_time_t t_c; /* checkpoint time */
202}; 202};
@@ -1601,7 +1601,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1601 /* set class to be in HTB_CAN_SEND state */ 1601 /* set class to be in HTB_CAN_SEND state */
1602 cl->tokens = hopt->buffer; 1602 cl->tokens = hopt->buffer;
1603 cl->ctokens = hopt->cbuffer; 1603 cl->ctokens = hopt->cbuffer;
1604 cl->mbuffer = 60000000; /* 1min */ 1604 cl->mbuffer = PSCHED_JIFFIE2US(HZ*60) /* 1min */
1605 PSCHED_GET_TIME(cl->t_c); 1605 PSCHED_GET_TIME(cl->t_c);
1606 cl->cmode = HTB_CAN_SEND; 1606 cl->cmode = HTB_CAN_SEND;
1607 1607
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2e8b4dfcbc74..a91c961ba38b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -523,12 +523,16 @@ static int try_context_mount(struct super_block *sb, void *data)
523 goto out_free; 523 goto out_free;
524 } 524 }
525 525
526 rc = may_context_mount_sb_relabel(sid, sbsec, tsec); 526 if (!fscontext) {
527 if (rc) 527 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
528 goto out_free; 528 if (rc)
529 529 goto out_free;
530 if (!fscontext)
531 sbsec->sid = sid; 530 sbsec->sid = sid;
531 } else {
532 rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
533 if (rc)
534 goto out_free;
535 }
532 sbsec->mntpoint_sid = sid; 536 sbsec->mntpoint_sid = sid;
533 537
534 sbsec->behavior = SECURITY_FS_USE_MNTPOINT; 538 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;